diff --git a/DEPS b/DEPS
index 3dd44b33..5153173 100644
--- a/DEPS
+++ b/DEPS
@@ -112,7 +112,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '22619c2e1a6d885f397e90ec17f1d6d6650218e9',
+  'skia_revision': 'e6305f38b584ac51368a98de6a76d3f3205c21bf',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -124,7 +124,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '7310da33bc7a6fcd9c5cacf0d28db7b3d424c757',
+  'angle_revision': '5f01324fb627a502823d9e359d243c3430920258',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -168,7 +168,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
-  'harfbuzz_revision': '574d888c8a409295a952361a39c8e83a52a0fc3d',
+  'harfbuzz_revision': 'e0307de818ad1f70ef96938642bda61d7a62532a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
@@ -188,7 +188,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.
-  'feed_revision': '23d32902a8bd6f4d55dea6a46fff43325c61b532',
+  'feed_revision': '5eaab0ec4f162c4f8d7901e14333127b16bcb7ac',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling android_sdk_build-tools_version
   # and whatever else without interference from each other.
@@ -236,7 +236,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'ac71e34d4ad130a0374afc9046484a35e008c5e2',
+  'dawn_revision': '813bfbd061128113dd7b4c7c80321b536597c362',
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -404,15 +404,15 @@
       'packages': [
         {
           'package': 'infra/tools/luci/isolate/${{platform}}',
-          'version': 'git_revision:73de65b9f89014a1b6718ad3d5ce791130e7c492',
+          'version': 'git_revision:f140d0c3c6acecf6ca6cd8d66ddad9421158ab40',
         },
         {
           'package': 'infra/tools/luci/isolated/${{platform}}',
-          'version': 'git_revision:73de65b9f89014a1b6718ad3d5ce791130e7c492',
+          'version': 'git_revision:f140d0c3c6acecf6ca6cd8d66ddad9421158ab40',
         },
         {
           'package': 'infra/tools/luci/swarming/${{platform}}',
-          'version': 'git_revision:73de65b9f89014a1b6718ad3d5ce791130e7c492',
+          'version': 'git_revision:f140d0c3c6acecf6ca6cd8d66ddad9421158ab40',
         },
       ],
       'dep_type': 'cipd',
@@ -1008,7 +1008,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '70282bd00ee96291da775eef019a3a5d651d2dda',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '7b49412a6e09da8fe1d37dca67db94c12a509ffc',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1202,7 +1202,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e6732bb38dc8e20873c9d50d30a813637a301939',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@73b3bde2659f52e891abf622a706feed5dfce112',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index c3db0984..75dadcc 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -661,7 +661,6 @@
     'build/android/gyp/copy_ex.pydeps',
     'build/android/gyp/create_app_bundle.pydeps',
     'build/android/gyp/create_apk_operations_script.pydeps',
-    'build/android/gyp/create_dist_jar.pydeps',
     'build/android/gyp/create_java_binary_script.pydeps',
     'build/android/gyp/create_stack_script.pydeps',
     'build/android/gyp/create_test_runner_script.pydeps',
@@ -686,6 +685,7 @@
     'build/android/gyp/proguard.pydeps',
     'build/android/gyp/write_build_config.pydeps',
     'build/android/gyp/write_ordered_libraries.pydeps',
+    'build/android/gyp/zip.pydeps',
     'build/android/incremental_install/generate_android_manifest.pydeps',
     'build/android/incremental_install/write_installer_json.pydeps',
     'build/android/resource_sizes.pydeps',
diff --git a/WATCHLISTS b/WATCHLISTS
index 8f2a55d7..c491d19b 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -820,7 +820,12 @@
     },
     'custom_tabs': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/customtabs/|'\
-                  'chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/',
+                  'chrome/android/java/src/org/chromium/chrome/browser/browseractions/|'\
+                  'chrome/android/java/src/org/chromium/chrome/browser/browserservices/|'\
+                  'chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/|'\
+                  'chrome/android/javatests/src/org/chromium/chrome/browser/browseractions/|'\
+                  'chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/|'\
+                  'chrome/browser/android/customtabs/',
     },
     'dbus': {
       'filepath': 'dbus/',
@@ -2140,7 +2145,10 @@
                         'cywang@chromium.org',
                         'vovoy@chromium.org'],
     'crostini': ['crostini-ui@chromium.org'],
-    'custom_tabs': ['lizeb+watch-custom-tabs@chromium.org'],
+    'custom_tabs': ['lizeb+watch-custom-tabs@chromium.org',
+                    'peconn@chromium.org',
+                    'peter@chromium.org',
+                    'pshmakov@chromium.org'],
     'dbus': ['hashimoto+watch@chromium.org'],
     'deep_memory_profiler': ['dmikurube@chromium.org'],
     'device_bluetooth': ['mattreynolds+watch@chromium.org',
diff --git a/ash/shell/content/client/shell_main_delegate.cc b/ash/shell/content/client/shell_main_delegate.cc
index f7f3fda..fb897039 100644
--- a/ash/shell/content/client/shell_main_delegate.cc
+++ b/ash/shell/content/client/shell_main_delegate.cc
@@ -44,8 +44,9 @@
   return std::make_unique<tap_visualizer::TapVisualizerApp>();
 }
 
-std::unique_ptr<service_manager::Service> CreateTestImeDriver() {
-  return std::make_unique<ws::test::TestIMEApplication>();
+std::unique_ptr<service_manager::Service> CreateTestImeDriver(
+    service_manager::mojom::ServiceRequest request) {
+  return std::make_unique<ws::test::TestIMEApplication>(std::move(request));
 }
 
 class ShellContentUtilityClient : public content::ContentUtilityClient {
@@ -65,11 +66,6 @@
       info.factory = base::BindRepeating(&CreateTapVisualizer);
       (*services)[tap_visualizer::mojom::kServiceName] = info;
     }
-    {
-      service_manager::EmbeddedServiceInfo info;
-      info.factory = base::BindRepeating(&CreateTestImeDriver);
-      (*services)[test_ime_driver::mojom::kServiceName] = info;
-    }
   }
 
   std::unique_ptr<service_manager::Service> HandleServiceRequest(
@@ -77,6 +73,8 @@
       service_manager::mojom::ServiceRequest request) override {
     if (service_name == quick_launch::mojom::kServiceName)
       return CreateQuickLaunch(std::move(request));
+    if (service_name == test_ime_driver::mojom::kServiceName)
+      return CreateTestImeDriver(std::move(request));
 
     return nullptr;
   }
diff --git a/ash/test/ash_test_views_delegate.cc b/ash/test/ash_test_views_delegate.cc
index 6c41a13..26ef9e4e 100644
--- a/ash/test/ash_test_views_delegate.cc
+++ b/ash/test/ash_test_views_delegate.cc
@@ -5,7 +5,6 @@
 #include "ash/test/ash_test_views_delegate.h"
 
 #include "ash/shell.h"
-#include "ash/test/ash_test_helper.h"
 
 namespace ash {
 
@@ -31,17 +30,6 @@
   TestViewsDelegate::OnBeforeWidgetInit(params, delegate);
 }
 
-void AshTestViewsDelegate::NotifyAccessibilityEvent(
-    views::View* view,
-    ax::mojom::Event event_type) {
-  TestViewsDelegate::NotifyAccessibilityEvent(view, event_type);
-
-  if (test_accessibility_event_delegate_) {
-    test_accessibility_event_delegate_->NotifyAccessibilityEvent(view,
-                                                                 event_type);
-  }
-}
-
 views::TestViewsDelegate::ProcessMenuAcceleratorResult
 AshTestViewsDelegate::ProcessAcceleratorWhileMenuShowing(
     const ui::Accelerator& accelerator) {
diff --git a/ash/test/ash_test_views_delegate.h b/ash/test/ash_test_views_delegate.h
index d93b35d..25bbaea8 100644
--- a/ash/test/ash_test_views_delegate.h
+++ b/ash/test/ash_test_views_delegate.h
@@ -10,14 +10,6 @@
 
 namespace ash {
 
-class TestAccessibilityEventDelegate {
- public:
-  TestAccessibilityEventDelegate() {}
-  virtual ~TestAccessibilityEventDelegate() {}
-  virtual void NotifyAccessibilityEvent(views::View* view,
-                                        ax::mojom::Event event_type) = 0;
-};
-
 // Ash specific ViewsDelegate. In addition to creating a TestWebContents this
 // parents widget with no parent/context to the shell. This is created by
 // default AshTestHelper.
@@ -32,18 +24,10 @@
   // TODO: remove this and ban usage of AshTestHelper outside of ash.
   void set_running_outside_ash() { running_outside_ash_ = true; }
 
-  // Not owned.
-  void set_test_accessibility_event_delegate(
-      TestAccessibilityEventDelegate* test_accessibility_event_delegate) {
-    test_accessibility_event_delegate_ = test_accessibility_event_delegate;
-  }
-
   // Overriden from TestViewsDelegate.
   void OnBeforeWidgetInit(
       views::Widget::InitParams* params,
       views::internal::NativeWidgetDelegate* delegate) override;
-  void NotifyAccessibilityEvent(views::View* view,
-                                ax::mojom::Event event_type) override;
   views::TestViewsDelegate::ProcessMenuAcceleratorResult
   ProcessAcceleratorWhileMenuShowing(
       const ui::Accelerator& accelerator) override;
@@ -57,9 +41,6 @@
   // matches with this.
   ui::Accelerator close_menu_accelerator_;
 
-  // Not owned.
-  TestAccessibilityEventDelegate* test_accessibility_event_delegate_ = nullptr;
-
   bool running_outside_ash_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(AshTestViewsDelegate);
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
index 6342b0e5..9c887c9 100644
--- a/base/files/important_file_writer.cc
+++ b/base/files/important_file_writer.cc
@@ -102,11 +102,11 @@
 void WriteScopedStringToFileAtomically(
     const FilePath& path,
     std::unique_ptr<std::string> data,
-    Closure before_write_callback,
-    Callback<void(bool success)> after_write_callback,
+    OnceClosure before_write_callback,
+    OnceCallback<void(bool success)> after_write_callback,
     const std::string& histogram_suffix) {
   if (!before_write_callback.is_null())
-    before_write_callback.Run();
+    std::move(before_write_callback).Run();
 
   TimeTicks start_time = TimeTicks::Now();
   bool result =
@@ -117,7 +117,7 @@
   }
 
   if (!after_write_callback.is_null())
-    after_write_callback.Run(result);
+    std::move(after_write_callback).Run(result);
 }
 
 void DeleteTmpFile(const FilePath& tmp_file_path,
@@ -297,10 +297,10 @@
 }
 
 void ImportantFileWriter::RegisterOnNextWriteCallbacks(
-    const Closure& before_next_write_callback,
-    const Callback<void(bool success)>& after_next_write_callback) {
-  before_next_write_callback_ = before_next_write_callback;
-  after_next_write_callback_ = after_next_write_callback;
+    OnceClosure before_next_write_callback,
+    OnceCallback<void(bool success)> after_next_write_callback) {
+  before_next_write_callback_ = std::move(before_next_write_callback);
+  after_next_write_callback_ = std::move(after_next_write_callback);
 }
 
 void ImportantFileWriter::ClearPendingWrite() {
diff --git a/base/files/important_file_writer.h b/base/files/important_file_writer.h
index f0cbfd22..af919090 100644
--- a/base/files/important_file_writer.h
+++ b/base/files/important_file_writer.h
@@ -106,8 +106,8 @@
   // If called more than once before a write is scheduled on |task_runner|, the
   // latest callbacks clobber the others.
   void RegisterOnNextWriteCallbacks(
-      const Closure& before_next_write_callback,
-      const Callback<void(bool success)>& after_next_write_callback);
+      OnceClosure before_next_write_callback,
+      OnceCallback<void(bool success)> after_next_write_callback);
 
   TimeDelta commit_interval() const {
     return commit_interval_;
@@ -125,8 +125,8 @@
   void ClearPendingWrite();
 
   // Invoked synchronously on the next write event.
-  Closure before_next_write_callback_;
-  Callback<void(bool success)> after_next_write_callback_;
+  OnceClosure before_next_write_callback_;
+  OnceCallback<void(bool success)> after_next_write_callback_;
 
   // Path being written to.
   const FilePath path_;
diff --git a/base/ios/weak_nsobject_unittest.mm b/base/ios/weak_nsobject_unittest.mm
index ba85217..c138570 100644
--- a/base/ios/weak_nsobject_unittest.mm
+++ b/base/ios/weak_nsobject_unittest.mm
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/bind.h"
 #include "base/ios/weak_nsobject.h"
+#include "base/bind.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -119,14 +120,14 @@
 
 // Tests that the weak object can be copied on a different thread.
 TEST(WeakNSObjectTest, WeakNSObjectCopyOnOtherThread) {
-  MessageLoop loop;
+  test::ScopedTaskEnvironment scoped_task_environment;
   Thread other_thread("WeakNSObjectCopyOnOtherThread");
   other_thread.Start();
 
   scoped_nsobject<NSMutableData> data([[NSMutableData alloc] init]);
   WeakNSObject<NSMutableData> weak(data);
 
-  scoped_refptr<SingleThreadTaskRunner> runner = loop.task_runner();
+  scoped_refptr<SingleThreadTaskRunner> runner = ThreadTaskRunnerHandle::Get();
   other_thread.task_runner()->PostTask(
       FROM_HERE, Bind(&CopyWeakNSObjectAndPost, weak, runner));
   other_thread.Stop();
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm
index fb25201..855f77b 100644
--- a/base/message_loop/message_pump_mac.mm
+++ b/base/message_loop/message_pump_mac.mm
@@ -181,6 +181,7 @@
   Delegate* last_delegate = delegate_;
   SetDelegate(delegate);
 
+  ScheduleWork();
   DoRun(delegate);
 
   // Restore the previous state of the object.
diff --git a/base/observer_list_threadsafe_unittest.cc b/base/observer_list_threadsafe_unittest.cc
index 00ca1cf..f29ce308 100644
--- a/base/observer_list_threadsafe_unittest.cc
+++ b/base/observer_list_threadsafe_unittest.cc
@@ -68,47 +68,29 @@
   Foo* to_add_;
 };
 
-// A thread for use in the ThreadSafeObserver test which will add and remove
+// A task for use in the ThreadSafeObserver test which will add and remove
 // itself from the notification list repeatedly.
-class AddRemoveThread : public PlatformThread::Delegate, public Foo {
+class AddRemoveThread : public Foo {
  public:
-  AddRemoveThread(ObserverListThreadSafe<Foo>* list,
-                  bool notify,
-                  WaitableEvent* ready)
+  AddRemoveThread(ObserverListThreadSafe<Foo>* list, bool notify)
       : list_(list),
-        loop_(nullptr),
+        task_runner_(CreateSingleThreadTaskRunnerWithTraits(
+            TaskTraits(),
+            SingleThreadTaskRunnerThreadMode::DEDICATED)),
         in_list_(false),
         start_(Time::Now()),
-        count_observes_(0),
-        count_addtask_(0),
         do_notifies_(notify),
-        ready_(ready),
-        weak_factory_(this) {}
-
-  ~AddRemoveThread() override = default;
-
-  void ThreadMain() override {
-    loop_ = new MessageLoop();  // Fire up a message loop.
-    loop_->task_runner()->PostTask(
+        weak_factory_(this) {
+    task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(&AddRemoveThread::AddTask, weak_factory_.GetWeakPtr()));
-    ready_->Signal();
-    // After ready_ is signaled, loop_ is only accessed by the main test thread
-    // (i.e. not this thread) in particular by Quit() which causes Run() to
-    // return, and we "control" loop_ again.
-    RunLoop run_loop;
-    quit_loop_ = run_loop.QuitClosure();
-    run_loop.Run();
-    delete loop_;
-    loop_ = reinterpret_cast<MessageLoop*>(0xdeadbeef);
-    delete this;
   }
 
+  ~AddRemoveThread() override = default;
+
   // This task just keeps posting to itself in an attempt to race with the
   // notifier.
   void AddTask() {
-    count_addtask_++;
-
     if ((Time::Now() - start_).InMilliseconds() > kThreadRunTime) {
       VLOG(1) << "DONE!";
       return;
@@ -123,23 +105,18 @@
       list_->Notify(FROM_HERE, &Foo::Observe, 10);
     }
 
-    loop_->task_runner()->PostTask(
+    ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::BindOnce(&AddRemoveThread::AddTask, weak_factory_.GetWeakPtr()));
   }
 
-  // This function is only callable from the main thread.
-  void Quit() { std::move(quit_loop_).Run(); }
-
   void Observe(int x) override {
-    count_observes_++;
-
     // If we're getting called after we removed ourselves from the list, that is
     // very bad!
     EXPECT_TRUE(in_list_);
 
     // This callback should fire on the appropriate thread
-    EXPECT_TRUE(loop_->IsBoundToCurrentThread());
+    EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
 
     list_->RemoveObserver(this);
     in_list_ = false;
@@ -147,17 +124,12 @@
 
  private:
   ObserverListThreadSafe<Foo>* list_;
-  MessageLoop* loop_;
+  scoped_refptr<SingleThreadTaskRunner> task_runner_;
   bool in_list_;  // Are we currently registered for notifications.
                   // in_list_ is only used on |this| thread.
   Time start_;    // The time we started the test.
 
-  int count_observes_;  // Number of times we observed.
-  int count_addtask_;   // Number of times thread AddTask was called
   bool do_notifies_;    // Whether these threads should do notifications.
-  WaitableEvent* ready_;
-
-  base::OnceClosure quit_loop_;
 
   base::WeakPtrFactory<AddRemoveThread> weak_factory_;
 };
@@ -330,27 +302,13 @@
   observer_list->AddObserver(&a);
   observer_list->AddObserver(&b);
 
-  std::vector<AddRemoveThread*> threaded_observer;
-  std::vector<base::PlatformThreadHandle> threads(num_threads);
-  std::vector<std::unique_ptr<base::WaitableEvent>> ready;
+  std::vector<std::unique_ptr<AddRemoveThread>> threaded_observer;
   threaded_observer.reserve(num_threads);
-  ready.reserve(num_threads);
   for (int index = 0; index < num_threads; index++) {
-    ready.push_back(std::make_unique<WaitableEvent>(
-        WaitableEvent::ResetPolicy::MANUAL,
-        WaitableEvent::InitialState::NOT_SIGNALED));
-    threaded_observer.push_back(new AddRemoveThread(
-        observer_list.get(), cross_thread_notifies, ready.back().get()));
-    EXPECT_TRUE(
-        PlatformThread::Create(0, threaded_observer.back(), &threads[index]));
+    threaded_observer.push_back(std::make_unique<AddRemoveThread>(
+        observer_list.get(), cross_thread_notifies));
   }
   ASSERT_EQ(static_cast<size_t>(num_threads), threaded_observer.size());
-  ASSERT_EQ(static_cast<size_t>(num_threads), ready.size());
-
-  // This makes sure that threaded_observer has gotten to set
-  // scoped_task_environment_, so that we can call Quit() below safe-ish-ly.
-  for (int i = 0; i < num_threads; ++i)
-    ready[i]->Wait();
 
   Time start = Time::Now();
   while (true) {
@@ -362,10 +320,7 @@
     RunLoop().RunUntilIdle();
   }
 
-  for (int index = 0; index < num_threads; index++) {
-    threaded_observer[index]->Quit();
-    PlatformThread::Join(threads[index]);
-  }
+  scoped_task_environment.RunUntilIdle();
 }
 
 #if defined(OS_FUCHSIA)
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h
index daa50b83..8319098 100644
--- a/base/task/sequence_manager/sequence_manager.h
+++ b/base/task/sequence_manager/sequence_manager.h
@@ -172,9 +172,13 @@
 BASE_EXPORT std::unique_ptr<SequenceManager>
 CreateSequenceManagerOnCurrentThread();
 
-// Create a SequenceManager for a MessagePump on the current thread.
+// Create a SequenceManager using the given MessagePump on the current thread.
+// MessagePump instances can be created with
+// MessageLoop::CreateMessagePumpForType().
 BASE_EXPORT std::unique_ptr<SequenceManager>
-CreateSequenceManagerOnCurrentThreadWithPump(MessageLoop::Type type);
+CreateSequenceManagerOnCurrentThreadWithPump(
+    MessageLoop::Type type,
+    std::unique_ptr<MessagePump> message_pump);
 
 // Create a SequenceManager for a future thread using the provided MessageLoop.
 // The SequenceManager can be initialized on the current thread and then needs
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 246b290..3223a8a 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -41,11 +41,11 @@
 }
 
 std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThreadWithPump(
-    MessageLoop::Type type) {
+    MessageLoop::Type type,
+    std::unique_ptr<MessagePump> message_pump) {
   std::unique_ptr<SequenceManager> sequence_manager =
       internal::SequenceManagerImpl::CreateUnboundWithPump(type);
-  sequence_manager->BindToMessagePump(
-      MessageLoop::CreateMessagePumpForType(type));
+  sequence_manager->BindToMessagePump(std::move(message_pump));
   return sequence_manager;
 }
 
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 77c3fb9..3b4bc58 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
@@ -268,7 +268,7 @@
   DCHECK_GE(do_work_delay, TimeDelta());
   // Schedule a continuation.
   // TODO(altimin, gab): Make this more efficient by merging DoWork
-  // and DoDelayedWork and allowing returing base::TimeTicks() when we have
+  // and DoDelayedWork and allowing returning base::TimeTicks() when we have
   // immediate work.
   if (do_work_delay.is_zero()) {
     // Need to run new work immediately, but due to the contract of DoWork we
@@ -310,8 +310,12 @@
   }
 #endif  // defined(OS_WIN)
 
-  if (main_thread_only().task_source->OnSystemIdle())
-    return true;  // Pretend we have done work to ensure DoWork is called.
+  if (main_thread_only().task_source->OnSystemIdle()) {
+    // The OnSystemIdle() callback resulted in more immediate work, so schedule
+    // a DoWork callback.
+    pump_->ScheduleWork();
+    return false;
+  }
 
   // RunLoop::Delegate knows whether we called Run() or RunUntilIdle().
   if (ShouldQuitWhenIdle())
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc
index 7bd746a..823fc9e3 100644
--- a/base/test/scoped_task_environment.cc
+++ b/base/test/scoped_task_environment.cc
@@ -13,6 +13,8 @@
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
 #include "base/task/post_task.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
+#include "base/task/sequence_manager/time_domain.h"
 #include "base/task/task_scheduler/task_scheduler.h"
 #include "base/task/task_scheduler/task_scheduler_impl.h"
 #include "base/test/test_mock_time_task_runner.h"
@@ -20,6 +22,7 @@
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/tick_clock.h"
 #include "base/time/time.h"
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -34,24 +37,164 @@
 LazyInstance<ThreadLocalPointer<ScopedTaskEnvironment::LifetimeObserver>>::Leaky
     environment_lifetime_observer;
 
-std::unique_ptr<MessageLoop> CreateMessageLoopForMainThreadType(
+base::Optional<MessageLoop::Type> GetMessageLoopTypeForMainThreadType(
     ScopedTaskEnvironment::MainThreadType main_thread_type) {
   switch (main_thread_type) {
     case ScopedTaskEnvironment::MainThreadType::DEFAULT:
-      return std::make_unique<MessageLoop>(MessageLoop::TYPE_DEFAULT);
     case ScopedTaskEnvironment::MainThreadType::MOCK_TIME:
-      return nullptr;
+      return MessageLoop::TYPE_DEFAULT;
     case ScopedTaskEnvironment::MainThreadType::UI:
-      return std::make_unique<MessageLoop>(MessageLoop::TYPE_UI);
+    case ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME:
+      return MessageLoop::TYPE_UI;
     case ScopedTaskEnvironment::MainThreadType::IO:
-      return std::make_unique<MessageLoop>(MessageLoop::TYPE_IO);
+      return MessageLoop::TYPE_IO;
   }
   NOTREACHED();
-  return nullptr;
+  return base::nullopt;
+}
+
+std::unique_ptr<sequence_manager::SequenceManager>
+CreateSequenceManagerForMainThreadType(
+    ScopedTaskEnvironment::MainThreadType main_thread_type) {
+  auto type = GetMessageLoopTypeForMainThreadType(main_thread_type);
+  if (!type) {
+    return nullptr;
+  } else {
+    return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
+        *type, MessageLoop::CreateMessagePumpForType(*type));
+  }
 }
 
 }  // namespace
 
+class ScopedTaskEnvironment::MockTimeDomain
+    : public sequence_manager::TimeDomain,
+      public TickClock {
+ public:
+  MockTimeDomain() = default;
+  ~MockTimeDomain() override = default;
+
+  using TimeDomain::NextScheduledRunTime;
+
+  static std::unique_ptr<ScopedTaskEnvironment::MockTimeDomain> Create(
+      ScopedTaskEnvironment::MainThreadType main_thread_type) {
+    if (main_thread_type == MainThreadType::MOCK_TIME ||
+        main_thread_type == MainThreadType::UI_MOCK_TIME) {
+      return std::make_unique<ScopedTaskEnvironment::MockTimeDomain>();
+    }
+    return nullptr;
+  }
+
+  // sequence_manager::TimeDomain:
+
+  sequence_manager::LazyNow CreateLazyNow() const override {
+    base::AutoLock lock(now_ticks_lock_);
+    return sequence_manager::LazyNow(now_ticks_);
+  }
+
+  TimeTicks Now() const override {
+    // This can be called from any thread.
+    base::AutoLock lock(now_ticks_lock_);
+    return now_ticks_;
+  }
+
+  Optional<TimeDelta> DelayTillNextTask(
+      sequence_manager::LazyNow* lazy_now) override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+    // Make sure TimeDomain::NextScheduledRunTime has taken canceled tasks into
+    // account.
+    sequence_manager()->SweepCanceledDelayedTasks();
+    Optional<TimeTicks> run_time = NextScheduledRunTime();
+    // Check if we've run out of tasks.
+    if (!run_time)
+      return base::nullopt;
+
+    // Check if we have a task that should be running now.
+    if (run_time <= now_ticks_)
+      return base::TimeDelta();
+
+    // The next task is a future delayed task. Since we're using mock time, we
+    // don't want an actual OS level delayed wake up scheduled, so pretend we
+    // have no more work. This will result in MaybeFastForwardToNextTask getting
+    // called which lets us advance |now_ticks_|.
+    return base::nullopt;
+  }
+
+  // This method is called when the underlying message pump has run out of
+  // non-delayed work.
+  bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    // If we're being externally controlled by a RunLoop in client code, check
+    // if the RunLoop is due to quit when idle, if so we don't want to advance
+    // mock time.
+    if (stop_when_message_pump_is_idle_ && quit_when_idle_requested)
+      return false;
+
+    // We don't need to call SweepCanceledDelayedTasks here because
+    // DelayTillNextTask will have done it for us.
+    Optional<TimeTicks> run_time = NextScheduledRunTime();
+    if (!run_time) {
+      // We've run out of tasks, but ScopedTaskEnvironment::FastForwardBy
+      // requires the virtual time to be consumed.
+      if (now_ticks_ < allow_advance_until_ && !allow_advance_until_.is_max())
+        SetTime(allow_advance_until_);
+      return false;
+    }
+
+    // Don't advance past |allow_advance_until_|.
+    DCHECK_GT(*run_time, now_ticks_);
+    TimeTicks time_to_advance_to = std::min(allow_advance_until_, *run_time);
+    if (time_to_advance_to <= now_ticks_)
+      return false;
+
+    SetTime(time_to_advance_to);
+
+    // Make sure a DoWork is scheduled.
+    return true;
+  }
+
+  const char* GetName() const override { return "MockTimeDomain"; }
+
+  // TickClock implementation:
+  TimeTicks NowTicks() const override { return Now(); }
+
+  // Allows time to advance when reaching idle, until
+  // |now_ticks_ == advance_until|. No-op if |advance_until <= now_ticks_|.
+  // Doesn't schedule work by itself.
+  void SetAllowTimeToAutoAdvanceUntil(TimeTicks advance_until) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    allow_advance_until_ = advance_until;
+  }
+
+  void SetStopWhenMessagePumpIsIdle(bool stop_when_message_pump_is_idle) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    stop_when_message_pump_is_idle_ = stop_when_message_pump_is_idle;
+  }
+
+ private:
+  void SetTime(TimeTicks time) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    DCHECK_LE(time, allow_advance_until_);
+
+    base::AutoLock lock(now_ticks_lock_);
+    now_ticks_ = time;
+  }
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // By default we want RunLoop.Run() to advance virtual time due to the API
+  // contract.
+  TimeTicks allow_advance_until_ = TimeTicks::Max();
+  bool stop_when_message_pump_is_idle_ = true;
+
+  // Protects |now_ticks_|
+  mutable Lock now_ticks_lock_;
+
+  // Only ever written to from the main sequence.
+  TimeTicks now_ticks_;
+};
+
 class ScopedTaskEnvironment::TestTaskTracker
     : public internal::TaskSchedulerImpl::TaskTrackerImpl {
  public:
@@ -100,27 +243,37 @@
 ScopedTaskEnvironment::ScopedTaskEnvironment(
     MainThreadType main_thread_type,
     ExecutionMode execution_control_mode)
+    : ScopedTaskEnvironment(
+          CreateSequenceManagerForMainThreadType(main_thread_type),
+          nullptr,
+          main_thread_type,
+          execution_control_mode) {}
+
+ScopedTaskEnvironment::ScopedTaskEnvironment(
+    sequence_manager::SequenceManager* sequence_manager,
+    MainThreadType main_thread_type,
+    ExecutionMode execution_control_mode)
+    : ScopedTaskEnvironment(nullptr,
+                            sequence_manager,
+                            main_thread_type,
+                            execution_control_mode) {}
+
+ScopedTaskEnvironment::ScopedTaskEnvironment(
+    std::unique_ptr<sequence_manager::SequenceManager> owned_sequence_manager,
+    sequence_manager::SequenceManager* sequence_manager,
+    MainThreadType main_thread_type,
+    ExecutionMode execution_control_mode)
     : execution_control_mode_(execution_control_mode),
-      message_loop_(CreateMessageLoopForMainThreadType(main_thread_type)),
-      mock_time_task_runner_(
-          main_thread_type == MainThreadType::MOCK_TIME
-              ? MakeRefCounted<TestMockTimeTaskRunner>(
-                    TestMockTimeTaskRunner::Type::kBoundToThread)
-              : nullptr),
-      slsm_for_mock_time_(
-          main_thread_type == MainThreadType::MOCK_TIME
-              ? std::make_unique<internal::SequenceLocalStorageMap>()
-              : nullptr),
-      slsm_registration_for_mock_time_(
-          main_thread_type == MainThreadType::MOCK_TIME
-              ? std::make_unique<
-                    internal::ScopedSetSequenceLocalStorageMapForCurrentThread>(
-                    slsm_for_mock_time_.get())
-              : nullptr),
+      mock_time_domain_(MockTimeDomain::Create(main_thread_type)),
+      owned_sequence_manager_(std::move(owned_sequence_manager)),
+      sequence_manager_(owned_sequence_manager_.get()
+                            ? owned_sequence_manager_.get()
+                            : sequence_manager),
+      task_queue_(CreateDefaultTaskQueue()),
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
       file_descriptor_watcher_(main_thread_type == MainThreadType::IO
                                    ? std::make_unique<FileDescriptorWatcher>(
-                                         message_loop_->task_runner())
+                                         task_queue_->task_runner())
                                    : nullptr),
 #endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
       task_tracker_(new TestTaskTracker()) {
@@ -131,6 +284,8 @@
          "someone has explicitly disabled it with "
          "DisableCheckForLeakedGlobals().";
 
+  sequence_manager_->SetDefaultTaskRunner(task_queue_->task_runner());
+
   // Instantiate a TaskScheduler with 2 threads in each of its 4 pools. Threads
   // stay alive even when they don't have work.
   // Each pool uses two threads to prevent deadlocks in unit tests that have a
@@ -197,6 +352,20 @@
   LifetimeObserver* observer = environment_lifetime_observer.Get().Get();
   if (observer)
     observer->OnScopedTaskEnvironmentDestroyed();
+
+  task_queue_ = nullptr;
+  if (mock_time_domain_)
+    sequence_manager_->UnregisterTimeDomain(mock_time_domain_.get());
+}
+
+scoped_refptr<sequence_manager::TaskQueue>
+ScopedTaskEnvironment::CreateDefaultTaskQueue() {
+  if (mock_time_domain_)
+    sequence_manager_->RegisterTimeDomain(mock_time_domain_.get());
+
+  return sequence_manager_->CreateTaskQueue(
+      sequence_manager::TaskQueue::Spec("scoped_task_environment_default")
+          .SetTimeDomain(mock_time_domain_.get()));
 }
 
 void ScopedTaskEnvironment::SetLifetimeObserver(
@@ -207,20 +376,28 @@
 
 scoped_refptr<base::SingleThreadTaskRunner>
 ScopedTaskEnvironment::GetMainThreadTaskRunner() {
-  if (message_loop_)
-    return message_loop_->task_runner();
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_;
+  return task_queue_->task_runner();
 }
 
 bool ScopedTaskEnvironment::MainThreadHasPendingTask() const {
-  if (message_loop_)
-    return !message_loop_->IsIdleForTesting();
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->HasPendingTask();
+  sequence_manager::internal::SequenceManagerImpl* sequence_manager_impl =
+      static_cast<sequence_manager::internal::SequenceManagerImpl*>(
+          sequence_manager_);
+  sequence_manager_impl->SweepCanceledDelayedTasks();
+  // Unfortunately this API means different things depending on whether mock
+  // time is used or not. If MockTime is used then tests want to know if there
+  // are any delayed or non-delayed tasks, otherwise only non-delayed tasks are
+  // considered.
+  if (mock_time_domain_)
+    return sequence_manager_impl->HasTasks();
+  return !sequence_manager_impl->IsIdleForTesting();
 }
 
 void ScopedTaskEnvironment::RunUntilIdle() {
+  // Prevent virtual time from advancing while within this call.
+  if (mock_time_domain_)
+    mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks());
+
   // TODO(gab): This can be heavily simplified to essentially:
   //     bool HasMainThreadTasks() {
   //      if (message_loop_)
@@ -298,41 +475,50 @@
   // parallel execution before returning unless in ExecutionMode::QUEUED.
   if (execution_control_mode_ != ExecutionMode::QUEUED)
     task_tracker_->AllowRunTasks();
+
+  if (mock_time_domain_)
+    mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks::Max());
 }
 
 void ScopedTaskEnvironment::FastForwardBy(TimeDelta delta) {
-  DCHECK(mock_time_task_runner_);
-  mock_time_task_runner_->FastForwardBy(delta);
+  MessageLoopCurrent::ScopedNestableTaskAllower allow;
+  DCHECK(mock_time_domain_);
+  mock_time_domain_->SetStopWhenMessagePumpIsIdle(false);
+  mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(mock_time_domain_->Now() +
+                                                    delta);
+  RunLoop().RunUntilIdle();
+  mock_time_domain_->SetStopWhenMessagePumpIsIdle(true);
+  mock_time_domain_->SetAllowTimeToAutoAdvanceUntil(TimeTicks::Max());
 }
 
 void ScopedTaskEnvironment::FastForwardUntilNoTasksRemain() {
-  DCHECK(mock_time_task_runner_);
-  mock_time_task_runner_->FastForwardUntilNoTasksRemain();
+  // TimeTicks::operator+(TimeDelta) uses saturated arithmetic so it's safe to
+  // pass in TimeDelta::Max().
+  FastForwardBy(TimeDelta::Max());
 }
 
 const TickClock* ScopedTaskEnvironment::GetMockTickClock() {
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->GetMockTickClock();
-}
-
-std::unique_ptr<TickClock> ScopedTaskEnvironment::DeprecatedGetMockTickClock() {
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->DeprecatedGetMockTickClock();
+  DCHECK(mock_time_domain_);
+  return mock_time_domain_.get();
 }
 
 base::TimeTicks ScopedTaskEnvironment::NowTicks() const {
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->NowTicks();
+  DCHECK(mock_time_domain_);
+  return mock_time_domain_->Now();
 }
 
 size_t ScopedTaskEnvironment::GetPendingMainThreadTaskCount() const {
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->GetPendingTaskCount();
+  sequence_manager_->SweepCanceledDelayedTasks();
+  return sequence_manager_->GetPendingTaskCountForTesting();
 }
 
 TimeDelta ScopedTaskEnvironment::NextMainThreadPendingTaskDelay() const {
-  DCHECK(mock_time_task_runner_);
-  return mock_time_task_runner_->NextPendingTaskDelay();
+  sequence_manager_->SweepCanceledDelayedTasks();
+  DCHECK(mock_time_domain_);
+  Optional<TimeTicks> run_time = mock_time_domain_->NextScheduledRunTime();
+  if (run_time)
+    return *run_time - mock_time_domain_->Now();
+  return TimeDelta::Max();
 }
 
 ScopedTaskEnvironment::TestTaskTracker::TestTaskTracker()
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h
index 77ec1bc..719a640 100644
--- a/base/test/scoped_task_environment.h
+++ b/base/test/scoped_task_environment.h
@@ -9,19 +9,14 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task/lazy_task_runner.h"
+#include "base/task/sequence_manager/sequence_manager.h"
 #include "build/build_config.h"
 
 namespace base {
 
-namespace internal {
-class ScopedSetSequenceLocalStorageMapForCurrentThread;
-class SequenceLocalStorageMap;
-}  // namespace internal
 
 class FileDescriptorWatcher;
-class MessageLoop;
 class TaskScheduler;
-class TestMockTimeTaskRunner;
 class TickClock;
 
 namespace test {
@@ -76,6 +71,11 @@
     MOCK_TIME,
     // The main thread pumps UI messages.
     UI,
+    // The main thread pumps UI messages and uses a mock clock for delayed tasks
+    // (controllable via FastForward*() methods).
+    // TODO(gab@): Enable mock time on all threads and make MOCK_TIME
+    // configurable independent of MainThreadType.
+    UI_MOCK_TIME,
     // The main thread pumps asynchronous IO messages and supports the
     // FileDescriptorWatcher API on POSIX.
     IO,
@@ -94,6 +94,13 @@
       MainThreadType main_thread_type = MainThreadType::DEFAULT,
       ExecutionMode execution_control_mode = ExecutionMode::ASYNC);
 
+  // Constructs a ScopedTaskEnvironment using a preexisting |sequence_manager|.
+  // |sequence_manager| must outlive this ScopedTaskEnvironment.
+  ScopedTaskEnvironment(
+      sequence_manager::SequenceManager* sequence_manager,
+      MainThreadType main_thread_type = MainThreadType::DEFAULT,
+      ExecutionMode execution_control_mode = ExecutionMode::ASYNC);
+
   // Waits until no undelayed TaskScheduler tasks remain. Then, unregisters the
   // TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle.
   ~ScopedTaskEnvironment();
@@ -155,24 +162,25 @@
   TimeDelta NextMainThreadPendingTaskDelay() const;
 
  private:
+  class MockTimeDomain;
   class TestTaskTracker;
 
+  ScopedTaskEnvironment(
+      std::unique_ptr<sequence_manager::SequenceManager> owned_sequence_manager,
+      sequence_manager::SequenceManager* sequence_manager,
+      MainThreadType main_thread_type,
+      ExecutionMode execution_control_mode);
+
+  scoped_refptr<sequence_manager::TaskQueue> CreateDefaultTaskQueue();
+
   const ExecutionMode execution_control_mode_;
 
-  // Exactly one of these will be non-null to provide the task environment on
-  // the main thread. Users of this class should NOT rely on the presence of a
-  // MessageLoop beyond (Thread|Sequenced)TaskRunnerHandle and RunLoop as
-  // the backing implementation of each MainThreadType may change over time.
-  const std::unique_ptr<MessageLoop> message_loop_;
-  const scoped_refptr<TestMockTimeTaskRunner> mock_time_task_runner_;
+  const std::unique_ptr<MockTimeDomain> mock_time_domain_;
+  const std::unique_ptr<sequence_manager::SequenceManager>
+      owned_sequence_manager_;
+  sequence_manager::SequenceManager* const sequence_manager_;
 
-  // Non-null in MOCK_TIME, where an explicit SequenceLocalStorageMap needs to
-  // be provided. TODO(gab): This can be removed once mock time support is added
-  // to MessageLoop directly.
-  const std::unique_ptr<internal::SequenceLocalStorageMap> slsm_for_mock_time_;
-  const std::unique_ptr<
-      internal::ScopedSetSequenceLocalStorageMapForCurrentThread>
-      slsm_registration_for_mock_time_;
+  scoped_refptr<sequence_manager::TaskQueue> task_queue_;
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
   // Enables the FileDescriptorWatcher API iff running a MainThreadType::IO.
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc
index 56361df..290e39c 100644
--- a/base/test/scoped_task_environment_unittest.cc
+++ b/base/test/scoped_task_environment_unittest.cc
@@ -359,6 +359,10 @@
     ScopedTaskEnvironmentTest,
     ::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME));
 INSTANTIATE_TEST_CASE_P(
+    MainThreadUiMockTime,
+    ScopedTaskEnvironmentTest,
+    ::testing::Values(ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME));
+INSTANTIATE_TEST_CASE_P(
     MainThreadUI,
     ScopedTaskEnvironmentTest,
     ::testing::Values(ScopedTaskEnvironment::MainThreadType::UI));
@@ -573,6 +577,10 @@
     MainThreadMockTime,
     ScopedTaskEnvironmentMockedTime,
     ::testing::Values(ScopedTaskEnvironment::MainThreadType::MOCK_TIME));
+INSTANTIATE_TEST_CASE_P(
+    MainThreadUiMockTime,
+    ScopedTaskEnvironmentMockedTime,
+    ::testing::Values(ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME));
 
 }  // namespace test
 }  // namespace base
diff --git a/build/android/gn/zip.py b/build/android/gn/zip.py
deleted file mode 100755
index 3e9668d..0000000
--- a/build/android/gn/zip.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 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.
-
-"""Archives a set of files.
-"""
-
-import ast
-import optparse
-import os
-import sys
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, 'gyp'))
-from util import build_utils
-
-def main():
-  parser = optparse.OptionParser()
-  build_utils.AddDepfileOption(parser)
-
-  parser.add_option('--inputs', help='List of files to archive.')
-  parser.add_option('--output', help='Path to output archive.')
-  parser.add_option('--base-dir',
-                    help='If provided, the paths in the archive will be '
-                    'relative to this directory', default='.')
-
-  options, _ = parser.parse_args()
-
-  inputs = ast.literal_eval(options.inputs)
-  output = options.output
-  base_dir = options.base_dir
-
-  with build_utils.AtomicOutput(output) as f:
-    build_utils.DoZip(inputs, f, base_dir)
-
-  if options.depfile:
-    build_utils.WriteDepfile(options.depfile, output)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/build/android/gyp/create_dist_jar.py b/build/android/gyp/create_dist_jar.py
deleted file mode 100755
index 7f78935a..0000000
--- a/build/android/gyp/create_dist_jar.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 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.
-
-"""Merges a list of jars into a single jar."""
-
-import argparse
-import sys
-
-from util import build_utils
-
-
-def main(args):
-  args = build_utils.ExpandFileArgs(args)
-  parser = argparse.ArgumentParser()
-  build_utils.AddDepfileOption(parser)
-  parser.add_argument('--output', required=True, help='Path to output jar.')
-  parser.add_argument('--jars', required=True, help='GN list of jar inputs.')
-  options = parser.parse_args(args)
-
-  input_jars = build_utils.ParseGnList(options.jars)
-  build_utils.MergeZips(options.output, input_jars)
-
-  if options.depfile:
-    build_utils.WriteDepfile(options.depfile, options.output, input_jars,
-                             add_pydeps=False)
-
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/build/android/gyp/zip.py b/build/android/gyp/zip.py
new file mode 100755
index 0000000..854ccd0
--- /dev/null
+++ b/build/android/gyp/zip.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 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.
+"""Archives a set of files."""
+
+import argparse
+import os
+import sys
+import zipfile
+
+from util import build_utils
+
+
+def main(args):
+  args = build_utils.ExpandFileArgs(args)
+  parser = argparse.ArgumentParser(args)
+  parser.add_argument('--input-files', help='GN-list of files to zip.')
+  parser.add_argument(
+      '--input-files-base-dir',
+      help='Paths in the archive will be relative to this directory')
+  parser.add_argument('--input-zips', help='GN-list of zips to merge.')
+  parser.add_argument(
+      '--input-zips-excluded-globs',
+      help='GN-list of globs for paths to exclude.')
+  parser.add_argument('--output', required=True, help='Path to output archive.')
+  compress_group = parser.add_mutually_exclusive_group()
+  compress_group.add_argument(
+      '--compress', action='store_true', help='Compress entries')
+  compress_group.add_argument(
+      '--no-compress',
+      action='store_false',
+      dest='compress',
+      help='Do not compress entries')
+  build_utils.AddDepfileOption(parser)
+  options = parser.parse_args(args)
+
+  with build_utils.AtomicOutput(options.output) as f:
+    with zipfile.ZipFile(f.name, 'w') as out_zip:
+      depfile_deps = None
+      if options.input_files:
+        files = build_utils.ParseGnList(options.input_files)
+        build_utils.DoZip(
+            files,
+            out_zip,
+            options.input_files_base_dir,
+            compress_fn=lambda _: options.compress)
+
+      if options.input_zips:
+        files = build_utils.ParseGnList(options.input_zips)
+        depfile_deps = files
+        path_transform = None
+        if options.input_zips_excluded_globs:
+          globs = build_utils.ParseGnList(options.input_zips_excluded_globs)
+          path_transform = (
+              lambda p: None if build_utils.MatchesGlob(p, globs) else p)
+        build_utils.MergeZips(
+            out_zip,
+            files,
+            path_transform=path_transform,
+            compress=options.compress)
+
+  # Depfile used only by dist_jar().
+  if options.depfile:
+    build_utils.WriteDepfile(
+        options.depfile, options.output, inputs=depfile_deps, add_pydeps=False)
+
+
+if __name__ == '__main__':
+  main(sys.argv[1:])
diff --git a/build/android/gyp/create_dist_jar.pydeps b/build/android/gyp/zip.pydeps
similarity index 62%
rename from build/android/gyp/create_dist_jar.pydeps
rename to build/android/gyp/zip.pydeps
index f4224d7..ce99648 100644
--- a/build/android/gyp/create_dist_jar.pydeps
+++ b/build/android/gyp/zip.pydeps
@@ -1,7 +1,7 @@
 # Generated by running:
-#   build/print_python_deps.py --root build/android/gyp --output build/android/gyp/create_dist_jar.pydeps build/android/gyp/create_dist_jar.py
+#   build/print_python_deps.py --root build/android/gyp --output build/android/gyp/zip.pydeps build/android/gyp/zip.py
 ../../gn_helpers.py
-create_dist_jar.py
 util/__init__.py
 util/build_utils.py
 util/md5_check.py
+zip.py
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index c1c7ae1..008d09e 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1447,6 +1447,8 @@
   #     implementation .jars.
   #   use_unprocessed_jars: Use unprocessed / undesugared .jars.
   #   direct_deps_only: Do not recurse on deps.
+  #   jar_excluded_patterns (optional)
+  #     List of globs for paths to exclude.
   #
   # Example
   #   dist_jar("lib_fatjar") {
@@ -1509,7 +1511,7 @@
     _rebased_build_config = rebase_path(_build_config, root_build_dir)
     action_with_pydeps(_jar_target_name) {
       forward_variables_from(invoker, [ "data" ])
-      script = "//build/android/gyp/create_dist_jar.py"
+      script = "//build/android/gyp/zip.py"
       depfile = "$target_gen_dir/$target_name.d"
       deps = _deps
 
@@ -1526,15 +1528,16 @@
         rebase_path(depfile, root_build_dir),
         "--output",
         rebase_path(invoker.output, root_build_dir),
+        "--no-compress",
       ]
 
       if (_direct_deps_only) {
         if (_use_interface_jars) {
-          args += [
-            "--jars=@FileArg($_rebased_build_config:javac:interface_classpath)",
-          ]
+          args += [ "--input-zips=@FileArg($_rebased_build_config:javac:interface_classpath)" ]
         } else if (_use_unprocessed_jars) {
-          args += [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ]
+          args += [
+            "--input-zips=@FileArg($_rebased_build_config:javac:classpath)",
+          ]
         } else {
           assert(
               false,
@@ -1542,13 +1545,17 @@
         }
       } else {
         if (_use_interface_jars) {
-          args += [ "--jars=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ]
+          args += [ "--input-zips=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ]
         } else if (_use_unprocessed_jars) {
-          args += [ "--jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ]
+          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ]
         } else {
-          args += [ "--jars=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)" ]
+          args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)" ]
         }
       }
+      if (defined(invoker.jar_excluded_patterns)) {
+        args +=
+            [ "--input-zips-excluded-globs=${invoker.jar_excluded_patterns}" ]
+      }
     }
   }
 
diff --git a/build/config/zip.gni b/build/config/zip.gni
index 8265e1d..58cb692f 100644
--- a/build/config/zip.gni
+++ b/build/config/zip.gni
@@ -2,54 +2,49 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("python.gni")
+
 # Creates a zip archive of the inputs.
 #
-# inputs (required)
-#     List of input files relative to the current directory.
-#
 # output (required)
-#     File name to write.
-#
+#     Path to output zip.
+# inputs (required)
+#     List of input files to zip.
 # base_dir (optional)
 #     If provided, the archive paths will be relative to this directory.
+#     Applies only to |inputs|.
 #
-# deps, public_deps, data_deps, testonly, visibility (optional)
+# deps, public_deps, data, data_deps, testonly, visibility
 #     Normal meaning.
 template("zip") {
-  action(target_name) {
-    script = "//build/android/gn/zip.py"
-    depfile = "$target_gen_dir/$target_name.d"
+  action_with_pydeps(target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "data",
+                             "data_deps",
+                             "deps",
+                             "public_deps",
+                             "testonly",
+                             "visibility",
+                           ])
+    script = "//build/android/gyp/zip.py"
     inputs = invoker.inputs
     outputs = [
       invoker.output,
     ]
 
-    assert(defined(invoker.inputs))
-    rebase_inputs = rebase_path(invoker.inputs, root_build_dir)
-
-    assert(defined(invoker.output))
-    rebase_output = rebase_path(invoker.output, root_build_dir)
-
     args = [
-      "--depfile",
-      rebase_path(depfile, root_build_dir),
-      "--inputs=$rebase_inputs",
-      "--output=$rebase_output",
+      "--output",
+      rebase_path(invoker.output, root_build_dir),
     ]
+
+    _rebased_inputs = rebase_path(invoker.inputs, root_build_dir)
+    args += [ "--input-files=$_rebased_inputs" ]
     if (defined(invoker.base_dir)) {
       args += [
-        "--base-dir",
+        "--input-files-base-dir",
         rebase_path(invoker.base_dir, root_build_dir),
       ]
     }
-
-    forward_variables_from(invoker,
-                           [
-                             "testonly",
-                             "deps",
-                             "public_deps",
-                             "data_deps",
-                             "visibility",
-                           ])
   }
 }
diff --git a/cc/animation/keyframe_effect.h b/cc/animation/keyframe_effect.h
index 0c33cb7..a276b7d 100644
--- a/cc/animation/keyframe_effect.h
+++ b/cc/animation/keyframe_effect.h
@@ -27,8 +27,8 @@
 
 typedef size_t KeyframeEffectId;
 
-// An KeyframeEffect owns a group of KeyframeModels for a single target
-// (identified by a ElementId). It is responsible for managing the
+// A KeyframeEffect owns a group of KeyframeModels for a single target
+// (identified by an ElementId). It is responsible for managing the
 // KeyframeModels' running states (starting, running, paused, etc), as well as
 // ticking the KeyframeModels when it is requested to produce new outputs for a
 // given time.
diff --git a/cc/paint/paint_cache_unittest.cc b/cc/paint/paint_cache_unittest.cc
index 73fd313a..a686f0e 100644
--- a/cc/paint/paint_cache_unittest.cc
+++ b/cc/paint/paint_cache_unittest.cc
@@ -13,8 +13,7 @@
 constexpr size_t kDefaultBudget = 1024u;
 
 sk_sp<SkTextBlob> CreateBlob() {
-  SkPaint font;
-  font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+  SkFont font;
   font.setTypeface(SkTypeface::MakeDefault());
 
   SkTextBlobBuilder builder;
diff --git a/cc/paint/paint_op_perftest.cc b/cc/paint/paint_op_perftest.cc
index a87085d..8a4e78df 100644
--- a/cc/paint/paint_op_perftest.cc
+++ b/cc/paint/paint_op_perftest.cc
@@ -164,8 +164,7 @@
 
   auto typeface = SkTypeface::MakeDefault();
 
-  SkPaint font;
-  font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+  SkFont font;
   font.setTypeface(typeface);
 
   SkTextBlobBuilder builder;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
index 5cbfd62..dd22aed 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.autofill_assistant;
 
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
@@ -27,24 +28,43 @@
     private static final String PARAMETER_ENABLED = "ENABLED";
 
     /** Returns true if all conditions are satisfied to start Autofill Assistant. */
-    public static boolean isConfigured(Bundle intentExtras) {
+    public static boolean isConfigured(@Nullable Bundle intentExtras) {
         return getBooleanParameter(intentExtras, PARAMETER_ENABLED)
                 && !AutofillAssistantStudy.getUrl().isEmpty()
-                && AutofillAssistantPreferencesUtil.isAutofillAssistantSwitchOn();
+                && AutofillAssistantPreferencesUtil.canShowAutofillAssistant();
     }
 
     /** Starts Autofill Assistant on the given {@code activity}. */
     public static void start(ChromeActivity activity) {
         Map<String, String> parameters = extractParameters(activity.getInitialIntent().getExtras());
         parameters.remove(PARAMETER_ENABLED);
+        if (!AutofillAssistantPreferencesUtil.getSkipInitScreenPreference()) {
+            FirstRunScreen.show(activity, (result) -> {
+                if (result) initiateAutofillAssistant(activity, parameters);
+            });
+            return;
+        }
 
+        if (AutofillAssistantPreferencesUtil.isAutofillAssistantSwitchOn()
+                && AutofillAssistantPreferencesUtil.getSkipInitScreenPreference()) {
+            initiateAutofillAssistant(activity, parameters);
+        }
+        // We don't have consent to start Autofill Assistant and cannot show initial screen.
+        // Do nothing.
+    }
+
+    /**
+     * Instantiates all essential Autofill Assistant components and starts it.
+     */
+    private static void initiateAutofillAssistant(
+            ChromeActivity activity, Map<String, String> parameters) {
         AutofillAssistantUiController controller =
                 new AutofillAssistantUiController(activity, parameters);
         UiDelegateHolder delegateHolder = new UiDelegateHolder(
                 controller, new AutofillAssistantUiDelegate(activity, controller));
         initTabObservers(activity, delegateHolder);
 
-        controller.start(delegateHolder, Details.makeFromParameters(parameters));
+        controller.init(delegateHolder, Details.makeFromParameters(parameters));
     }
 
     private static void initTabObservers(ChromeActivity activity, UiDelegateHolder delegateHolder) {
@@ -74,16 +94,19 @@
     }
 
     /** Return the value if the given boolean parameter from the extras. */
-    private static boolean getBooleanParameter(Bundle extras, String parameterName) {
-        return extras.getBoolean(INTENT_EXTRA_PREFIX + parameterName, false);
+    private static boolean getBooleanParameter(@Nullable Bundle extras, String parameterName) {
+        return extras != null && extras.getBoolean(INTENT_EXTRA_PREFIX + parameterName, false);
     }
 
     /** Returns a map containing the extras starting with {@link #INTENT_EXTRA_PREFIX}. */
-    private static Map<String, String> extractParameters(Bundle extras) {
+    private static Map<String, String> extractParameters(@Nullable Bundle extras) {
         Map<String, String> result = new HashMap<>();
-        for (String key : extras.keySet()) {
-            if (key.startsWith(INTENT_EXTRA_PREFIX)) {
-                result.put(key.substring(INTENT_EXTRA_PREFIX.length()), extras.get(key).toString());
+        if (extras != null) {
+            for (String key : extras.keySet()) {
+                if (key.startsWith(INTENT_EXTRA_PREFIX)) {
+                    result.put(key.substring(INTENT_EXTRA_PREFIX.length()),
+                            extras.get(key).toString());
+                }
             }
         }
         return result;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java
index f7c7ddb6..526ef9a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferencesUtil.java
@@ -8,7 +8,7 @@
 import org.chromium.chrome.browser.preferences.autofill_assistant.AutofillAssistantPreferences;
 
 /** Autofill Assistant related preferences util class. */
-public class AutofillAssistantPreferencesUtil {
+class AutofillAssistantPreferencesUtil {
     // Avoid instatiation by accident.
     private AutofillAssistantPreferencesUtil() {}
 
@@ -19,24 +19,33 @@
             "AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN";
 
     /** Checks whether the Autofill Assistant switch preference in settings is on. */
-    public static boolean isAutofillAssistantSwitchOn() {
+    static boolean isAutofillAssistantSwitchOn() {
         return ContextUtils.getAppSharedPreferences().getBoolean(
                 AutofillAssistantPreferences.PREF_AUTOFILL_ASSISTANT_SWITCH, true);
     }
 
     /** Gets whether skip initial screen preference. */
-    public static boolean getSkipInitScreenPreference() {
+    static boolean getSkipInitScreenPreference() {
         return ContextUtils.getAppSharedPreferences().getBoolean(
                 AUTOFILL_ASSISTANT_SKIP_INIT_SCREEN, false);
     }
 
     /**
+     * Returns true if the switch for AutofillAssistant is turned on or the init screen can
+     * be shown. The later is important if the switched is turned off, but we can ask again
+     * to enable AutofillAssistant.
+     */
+    static boolean canShowAutofillAssistant() {
+        return isAutofillAssistantSwitchOn() || !getSkipInitScreenPreference();
+    }
+
+    /**
      * Sets preferences from the initial screen.
      *
      * @param accept Flag indicates whether this service is accepted.
      * @param dontShowAgain Flag indicates whether initial screen should be shown again next time.
      */
-    public static void setInitialPreferences(boolean accept, boolean dontShowAgain) {
+    static void setInitialPreferences(boolean accept, boolean dontShowAgain) {
         ContextUtils.getAppSharedPreferences()
                 .edit()
                 .putBoolean(AutofillAssistantPreferences.PREF_AUTOFILL_ASSISTANT_SWITCH, accept)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
index f382071ae..84f5f23 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -89,17 +89,9 @@
                 parameters.get(PARAMETER_USER_EMAIL), activity.getInitialIntent().getExtras());
     }
 
-    void start(UiDelegateHolder uiDelegateHolder, Details details) {
-        mUiDelegateHolder = uiDelegateHolder;
-        // Do not show details until 'onInitOk'.
-        mCurrentDetails = details;
-        mUiDelegateHolder.startOrSkipInitScreen();
-    }
-
-    @Override
-    public void onInitOk() {
-        assert mUiDelegateHolder != null;
-        mUiDelegateHolder.performUiOperation(uiDelegate -> uiDelegate.showDetails(mCurrentDetails));
+    public void init(UiDelegateHolder delegateHolder, Details details) {
+        mUiDelegateHolder = delegateHolder;
+        maybeUpdateDetails(details);
         nativeStart(mUiControllerAndroid, mInitialUrl);
     }
 
@@ -109,11 +101,6 @@
     }
 
     @Override
-    public void onInitRejected() {
-        mUiDelegateHolder.shutdown();
-    }
-
-    @Override
     public Details getDetails() {
         return mCurrentDetails;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
index 0683980..4495372 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -30,7 +30,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.CheckBox;
 import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -121,12 +120,6 @@
         void onDismiss();
 
         /**
-         * Called when the user chose not to use the assistant from the
-         * onboarding screen.
-         */
-        void onInitRejected();
-
-        /**
          * Called when a script has been selected.
          *
          * @param scriptPath The path for the selected script.
@@ -174,11 +167,6 @@
          * @return A string describing the current execution context.
          */
         String getDebugContext();
-
-        /**
-         * Called when the init was successful.
-         */
-        void onInitOk();
     }
 
     /** Describes a chip to display. */
@@ -763,47 +751,6 @@
     }
 
     /**
-     * Starts the init screen unless it has been marked to be skipped.
-     */
-    public void startOrSkipInitScreen() {
-        if (AutofillAssistantPreferencesUtil.getSkipInitScreenPreference()) {
-            mClient.onInitOk();
-            return;
-        }
-        showInitScreen();
-    }
-
-    /**
-     * Shows the init screen and launch the autofill assistant when it succeeds.
-     */
-    public void showInitScreen() {
-        View initView = LayoutInflater.from(mActivity)
-                                .inflate(R.layout.init_screen, mCoordinatorView)
-                                .findViewById(R.id.init_screen);
-        // Set focusable for accessibility.
-        initView.findViewById(R.id.init).setFocusable(true);
-
-        // Set default state to checked.
-        ((CheckBox) initView.findViewById(R.id.checkbox_dont_show_init_again)).setChecked(true);
-        initView.findViewById(R.id.button_init_ok)
-                .setOnClickListener(unusedView -> onInitClicked(true, initView));
-        initView.findViewById(R.id.button_init_not_ok)
-                .setOnClickListener(unusedView -> onInitClicked(false, initView));
-        initView.announceForAccessibility(
-                mActivity.getString(R.string.autofill_assistant_first_run_accessibility));
-    }
-
-    private void onInitClicked(boolean accept, View initView) {
-        CheckBox checkBox = initView.findViewById(R.id.checkbox_dont_show_init_again);
-        AutofillAssistantPreferencesUtil.setInitialPreferences(accept, checkBox.isChecked());
-        mCoordinatorView.removeView(initView);
-        if (accept)
-            mClient.onInitOk();
-        else
-            mClient.onInitRejected();
-    }
-
-    /**
      * Show the payment request UI.
      *
      * Show the UI and return the selected information via |callback| when done.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/FirstRunScreen.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/FirstRunScreen.java
new file mode 100644
index 0000000..777f093
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/FirstRunScreen.java
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.autofill_assistant;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+
+import org.chromium.base.Callback;
+import org.chromium.chrome.autofill_assistant.R;
+import org.chromium.chrome.browser.ChromeActivity;
+
+/** Class for managing the first run screen. */
+class FirstRunScreen {
+    /**
+     * Shows the first run screen and calls callback with the result.
+     */
+    static void show(ChromeActivity activity, Callback<Boolean> callback) {
+        ViewGroup coordinatorView = (ViewGroup) activity.findViewById(
+                org.chromium.chrome.autofill_assistant.R.id.coordinator);
+        View initView = LayoutInflater.from(activity)
+                                .inflate(R.layout.init_screen, coordinatorView)
+                                .findViewById(R.id.init_screen);
+        // Set focusable for accessibility.
+        initView.findViewById(R.id.init).setFocusable(true);
+
+        initView.findViewById(R.id.button_init_ok)
+                .setOnClickListener(unusedView -> onClicked(true, initView, activity, callback));
+        initView.findViewById(R.id.button_init_not_ok)
+                .setOnClickListener(unusedView -> onClicked(false, initView, activity, callback));
+        initView.announceForAccessibility(
+                activity.getString(R.string.autofill_assistant_first_run_accessibility));
+    }
+
+    private static void onClicked(
+            boolean accept, View initView, ChromeActivity activity, Callback<Boolean> callback) {
+        ViewGroup coordinatorView = (ViewGroup) activity.findViewById(
+                org.chromium.chrome.autofill_assistant.R.id.coordinator);
+        CheckBox checkBox = initView.findViewById(
+                org.chromium.chrome.autofill_assistant.R.id.checkbox_dont_show_init_again);
+        AutofillAssistantPreferencesUtil.setInitialPreferences(accept, checkBox.isChecked());
+        coordinatorView.removeView(initView);
+
+        callback.onResult(accept);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java
index 4ce86ac..37bfea44 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java
@@ -36,13 +36,6 @@
     }
 
     /**
-     * Starts the init screen unless it has been marked to be skipped.
-     */
-    public void startOrSkipInitScreen() {
-        mUiDelegate.startOrSkipInitScreen();
-    }
-
-    /**
      * Perform a UI operation:
      *  - directly if we are not in a pause state.
      *  - later if the shutdown is cancelled.
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index a0f23d6..3f7d803 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -134,6 +134,7 @@
   "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java",
   "java/src/org/chromium/chrome/browser/autofill_assistant/Details.java",
   "java/src/org/chromium/chrome/browser/autofill_assistant/FeedbackContext.java",
+  "java/src/org/chromium/chrome/browser/autofill_assistant/FirstRunScreen.java",
   "java/src/org/chromium/chrome/browser/autofill_assistant/UiDelegateHolder.java",
   "java/src/org/chromium/chrome/browser/autofill_assistant/ui/BottomBarAnimations.java",
   "java/src/org/chromium/chrome/browser/autofill_assistant/ui/PaymentRequestBottomBar.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataTest.java
index 6a017402..4c1fa642 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataTest.java
@@ -67,7 +67,7 @@
         BrowsingDataCounterBridge[] counter = {null};
         CallbackHelper helper = new CallbackHelper();
         BrowsingDataCounterBridge.BrowsingDataCounterCallback callback = (result) -> {
-            if (result.equals("Calculating...")) return;
+            if (result.equals("Calculating…")) return;
             out[0] = result;
             helper.notifyCalled();
         };
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index f7dc429..37df527 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-72.0.3624.3_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-72.0.3625.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index dfa919a..e0fd47a 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1451,6 +1451,10 @@
     "signin/signin_error_controller_factory.h",
     "signin/signin_manager_factory.cc",
     "signin/signin_manager_factory.h",
+    "signin/signin_profile_attributes_updater.cc",
+    "signin/signin_profile_attributes_updater.h",
+    "signin/signin_profile_attributes_updater_factory.cc",
+    "signin/signin_profile_attributes_updater_factory.h",
     "signin/signin_promo_util.cc",
     "signin/signin_promo_util.h",
     "signin/signin_status_metrics_provider_chromeos.cc",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 2833834..f94feb7 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3874,14 +3874,14 @@
     if (!g_browser_process || !g_browser_process->pref_service_factory())
       return;
 
-    service_manager::Service::RunUntilTermination(
+    service_manager::Service::RunAsyncUntilTermination(
         g_browser_process->pref_service_factory()->CreatePrefService(
             std::move(request)));
   }
 
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
   if (service_name == media::mojom::kMediaServiceName) {
-    service_manager::Service::RunUntilTermination(
+    service_manager::Service::RunAsyncUntilTermination(
         media::CreateMediaService(std::move(request)));
   }
 #endif
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 71c8fb7..de3f613d2 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -294,6 +294,8 @@
     "accessibility/switch_access_event_handler.h",
     "accessibility/switch_access_panel.cc",
     "accessibility/switch_access_panel.h",
+    "account_manager/account_migration_runner.cc",
+    "account_manager/account_migration_runner.h",
     "account_mapper_util.cc",
     "account_mapper_util.h",
     "app_mode/app_launch_utils.cc",
@@ -2067,6 +2069,7 @@
     "../resources/chromeos/zip_archiver/test/char_coding_test.cc",
     "../ui/browser_finder_chromeos_unittest.cc",
     "accessibility/ax_host_service_unittest.cc",
+    "account_manager/account_migration_runner_unittest.cc",
     "app_mode/startup_app_launcher_unittest.cc",
     "apps/intent_helper/apps_navigation_throttle_unittest.cc",
     "apps/intent_helper/page_transition_util_unittest.cc",
diff --git a/chrome/browser/chromeos/account_manager/account_migration_runner.cc b/chrome/browser/chromeos/account_manager/account_migration_runner.cc
new file mode 100644
index 0000000..e2e515f
--- /dev/null
+++ b/chrome/browser/chromeos/account_manager/account_migration_runner.cc
@@ -0,0 +1,96 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/account_manager/account_migration_runner.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+
+namespace chromeos {
+
+AccountMigrationRunner::Step::Step(const std::string& id) : id_(id) {}
+
+AccountMigrationRunner::Step::~Step() = default;
+
+const std::string& AccountMigrationRunner::Step::GetId() const {
+  return id_;
+}
+
+AccountMigrationRunner::AccountMigrationRunner() : weak_factory_(this) {}
+
+AccountMigrationRunner::~AccountMigrationRunner() = default;
+
+AccountMigrationRunner::Status AccountMigrationRunner::GetStatus() const {
+  return status_;
+}
+
+void AccountMigrationRunner::AddStep(std::unique_ptr<Step> step) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // |Step|s cannot be added after migration has begun.
+  DCHECK_EQ(Status::kNotStarted, status_);
+
+  steps_.emplace(std::move(step));
+}
+
+void AccountMigrationRunner::Run(OnMigrationDone callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (status_ != Status::kNotStarted) {
+    // Ignore calls to |Run| after migration has begun.
+    return;
+  }
+  status_ = Status::kRunning;
+  callback_ = std::move(callback);
+
+  RunNextStep();
+}
+
+void AccountMigrationRunner::RunNextStep() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (steps_.empty()) {
+    FinishWithSuccess();
+    return;
+  }
+
+  current_step_ = std::move(steps_.front());
+  steps_.pop();
+
+  current_step_->Run(base::BindOnce(&AccountMigrationRunner::OnStepCompleted,
+                                    weak_factory_.GetWeakPtr()));
+}
+
+void AccountMigrationRunner::OnStepCompleted(bool result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (result) {
+    RunNextStep();
+  } else {
+    FinishWithFailure();
+  }
+}
+
+void AccountMigrationRunner::FinishWithSuccess() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  status_ = Status::kSuccess;
+  DCHECK(callback_);
+  std::move(callback_).Run(MigrationResult{Status::kSuccess /* final_status */,
+                                           std::string() /* failed_step */});
+}
+
+void AccountMigrationRunner::FinishWithFailure() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  status_ = Status::kFailure;
+  DCHECK(callback_);
+  std::move(callback_).Run(
+      MigrationResult{Status::kFailure /* final_status */,
+                      current_step_->GetId() /* failed_step */});
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/account_manager/account_migration_runner.h b/chrome/browser/chromeos/account_manager/account_migration_runner.h
new file mode 100644
index 0000000..7b931affd
--- /dev/null
+++ b/chrome/browser/chromeos/account_manager/account_migration_runner.h
@@ -0,0 +1,128 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MIGRATION_RUNNER_H_
+#define CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MIGRATION_RUNNER_H_
+
+#include <memory>
+#include <queue>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+
+namespace chromeos {
+
+// A utility class to run account migrations for |chromeos::AccountManager|. It
+// enables the specification of a series of async migration |Step|s in a
+// declarative style (see the test cases for usage examples). If any of these
+// |Step|s fail, the entire migration fails, without running subsequent steps.
+class AccountMigrationRunner {
+ public:
+  enum class Status {
+    // Migration has not started yet.
+    kNotStarted,
+    // Migration is in progress.
+    kRunning,
+    // All migration steps completed successfully.
+    kSuccess,
+    // Migration failed at some |Step|.
+    kFailure,
+  };
+
+  struct MigrationResult {
+    // Final status of migration.
+    Status final_status;
+    // If |final_status| is |FAILURE|, this field will contain the id of the
+    // step, that caused migration to fail.
+    std::string failed_step_id;
+  };
+
+  // Type alias for the callback called at the end of a migration run.
+  using OnMigrationDone = base::OnceCallback<void(const MigrationResult&)>;
+
+  // Abstract base class for a migration step.
+  class Step {
+   public:
+    // |id| is an identifier for this step. This should be unique across |Step|s
+    // added to |AccountMigrationRunner::AddStep| but maintaining this
+    // uniqueness is a responsibility of the callers and not enforced by
+    // |AccountMigrationRunner|.
+    explicit Step(const std::string& id);
+
+    virtual ~Step();
+
+    // Runs the migration step and calls |callback| with the result (|true| for
+    // success and |false| for failure) of the migration step.
+    // Note that |AccountMigrationRunner| does not guarantee anything about the
+    // lifetime of a |Step| once it has been added via
+    // |AccountMigrationRunner::AddStep|.
+    virtual void Run(base::OnceCallback<void(bool)> callback) = 0;
+
+    // Gets this |Step|'s identifier.
+    const std::string& GetId() const;
+
+   private:
+    const std::string id_;
+    DISALLOW_COPY_AND_ASSIGN(Step);
+  };
+
+  AccountMigrationRunner();
+  ~AccountMigrationRunner();
+
+  // Gets the current status of migration.
+  Status GetStatus() const;
+
+  // Adds a migration step. |AddStep| must be called before |Run| has been
+  // called. Calls to |AddStep| create a dependency between the supplied
+  // |step|s, i.e. |step|s will be executed in the order in which they were
+  // supplied via |AddStep|. If any |step| fails, none of the following steps
+  // will be executed.
+  void AddStep(std::unique_ptr<Step> step);
+
+  // Runs all the migration steps that have previously been added via |AddStep|.
+  // |Run| must be called at most once during the lifetime of |this| object.
+  // Subsequent calls to |Run| are silently ignored.
+  // |callback| is called with the final result of the migration run.
+  void Run(OnMigrationDone callback);
+
+ private:
+  // Runs the next migration step in |steps_|.
+  void RunNextStep();
+
+  // Callback from a migration |Step|.
+  void OnStepCompleted(bool result);
+
+  // Immediately finishes migration with a |Status::SUCCESS| and informs the
+  // caller of |Run| about the result of the migration.
+  void FinishWithSuccess();
+
+  // Immediately finishes migration with a |Status::FAILURE| and informs the
+  // caller of |Run| about the result of the migration.
+  void FinishWithFailure();
+
+  // Current status of migration.
+  Status status_ = Status::kNotStarted;
+
+  // A list of migration steps.
+  std::queue<std::unique_ptr<Step>> steps_;
+
+  // The current step being executed.
+  std::unique_ptr<Step> current_step_ = nullptr;
+
+  // Supplied by the caller of |Run| to get the overall result of migration.
+  OnMigrationDone callback_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  base::WeakPtrFactory<AccountMigrationRunner> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AccountMigrationRunner);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MIGRATION_RUNNER_H_
diff --git a/chrome/browser/chromeos/account_manager/account_migration_runner_unittest.cc b/chrome/browser/chromeos/account_manager/account_migration_runner_unittest.cc
new file mode 100644
index 0000000..35bcd37
--- /dev/null
+++ b/chrome/browser/chromeos/account_manager/account_migration_runner_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/account_manager/account_migration_runner.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace {
+
+class AlwaysSucceeds : public AccountMigrationRunner::Step {
+ public:
+  AlwaysSucceeds(const std::string& id, base::RepeatingClosure closure)
+      : AccountMigrationRunner::Step(id), closure_(closure) {}
+  ~AlwaysSucceeds() override = default;
+
+  void Run(base::OnceCallback<void(bool)> callback) override {
+    closure_.Run();
+    std::move(callback).Run(true);
+  }
+
+ private:
+  base::RepeatingClosure closure_;
+  DISALLOW_COPY_AND_ASSIGN(AlwaysSucceeds);
+};
+
+class AlwaysFails : public AccountMigrationRunner::Step {
+ public:
+  AlwaysFails(const std::string& id, base::RepeatingClosure closure)
+      : AccountMigrationRunner::Step(id), closure_(closure) {}
+  ~AlwaysFails() override = default;
+
+  void Run(base::OnceCallback<void(bool)> callback) override {
+    closure_.Run();
+    std::move(callback).Run(false);
+  }
+
+ private:
+  base::RepeatingClosure closure_;
+  DISALLOW_COPY_AND_ASSIGN(AlwaysFails);
+};
+
+class MustNeverRun : public AccountMigrationRunner::Step {
+ public:
+  explicit MustNeverRun(const std::string& id)
+      : AccountMigrationRunner::Step(id) {}
+  ~MustNeverRun() override = default;
+
+  void Run(base::OnceCallback<void(bool)> callback) override {
+    EXPECT_FALSE(true);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MustNeverRun);
+};
+
+}  // namespace
+
+class AccountMigrationRunnerTest : public testing::Test {
+ protected:
+  AccountMigrationRunnerTest() : weak_factory_(this) {
+    increment_num_steps_executed_ = base::BindRepeating(
+        &AccountMigrationRunnerTest::IncrementNumStepsExecuted,
+        weak_factory_.GetWeakPtr());
+  }
+
+  ~AccountMigrationRunnerTest() override = default;
+
+  AccountMigrationRunner::MigrationResult RunMigration() {
+    AccountMigrationRunner::MigrationResult migration_result;
+    base::RunLoop run_loop;
+    AccountMigrationRunner::OnMigrationDone callback = base::BindOnce(
+        [](AccountMigrationRunner::MigrationResult* result,
+           base::OnceClosure quit_closure,
+           const AccountMigrationRunner::MigrationResult& returned_result) {
+          *result = returned_result;
+          std::move(quit_closure).Run();
+        },
+        &migration_result, run_loop.QuitClosure());
+
+    migration_runner_.Run(std::move(callback));
+    // Wait for callback from |migration_runner_|.
+    run_loop.Run();
+
+    return migration_result;
+  }
+
+  // Check base/test/scoped_task_environment.h. This must be the first member /
+  // declared before any member that cares about tasks.
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+  AccountMigrationRunner migration_runner_;
+
+  int num_steps_executed_ = 0;
+
+  base::RepeatingClosure increment_num_steps_executed_;
+
+ private:
+  void IncrementNumStepsExecuted() { ++num_steps_executed_; }
+
+  base::WeakPtrFactory<AccountMigrationRunnerTest> weak_factory_;
+  DISALLOW_COPY_AND_ASSIGN(AccountMigrationRunnerTest);
+};
+
+TEST_F(AccountMigrationRunnerTest, DoesNotRunUntilRunIsCalled) {
+  EXPECT_EQ(AccountMigrationRunner::Status::kNotStarted,
+            migration_runner_.GetStatus());
+}
+
+TEST_F(AccountMigrationRunnerTest, RunsSuccessfullyForZeroSteps) {
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_result.final_status);
+  EXPECT_EQ(0, num_steps_executed_);
+}
+
+TEST_F(AccountMigrationRunnerTest, RunsSuccessfullyForOneStep) {
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysSucceeds>("Step1", increment_num_steps_executed_));
+
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_result.final_status);
+  EXPECT_EQ(1, num_steps_executed_);
+}
+
+TEST_F(AccountMigrationRunnerTest, FailsForOneFailingStep) {
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysFails>("Step1", increment_num_steps_executed_));
+
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_result.final_status);
+  EXPECT_EQ("Step1", migration_result.failed_step_id);
+  EXPECT_EQ(1, num_steps_executed_);
+}
+
+TEST_F(AccountMigrationRunnerTest, RunsSuccessfullyForMoreThanOneStep) {
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysSucceeds>("Step1", increment_num_steps_executed_));
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysSucceeds>("Step2", increment_num_steps_executed_));
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysSucceeds>("Step3", increment_num_steps_executed_));
+
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kSuccess,
+            migration_result.final_status);
+  EXPECT_EQ(3, num_steps_executed_);
+}
+
+TEST_F(AccountMigrationRunnerTest, FailsIfFirstStepFails) {
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysFails>("Step1", increment_num_steps_executed_));
+  migration_runner_.AddStep(std::make_unique<MustNeverRun>("Step2"));
+
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_result.final_status);
+  EXPECT_EQ("Step1", migration_result.failed_step_id);
+  EXPECT_EQ(1, num_steps_executed_);
+}
+
+TEST_F(AccountMigrationRunnerTest, FailsIfIntermediateStepFails) {
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysSucceeds>("Step1", increment_num_steps_executed_));
+  migration_runner_.AddStep(
+      std::make_unique<AlwaysFails>("Step2", increment_num_steps_executed_));
+  migration_runner_.AddStep(std::make_unique<MustNeverRun>("Step3"));
+
+  AccountMigrationRunner::MigrationResult migration_result = RunMigration();
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_runner_.GetStatus());
+  EXPECT_EQ(AccountMigrationRunner::Status::kFailure,
+            migration_result.final_status);
+  EXPECT_EQ("Step2", migration_result.failed_step_id);
+  EXPECT_EQ(2, num_steps_executed_);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
index 464fe465f8..4dd146a1 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -363,11 +363,13 @@
   //
   // More details can be found in https://crbug.com/386606
   user_context.SetPasswordKey(Key(password));
-  if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY &&
-      (user_context.GetUserType() !=
-       user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY)) {
-    LOG(FATAL) << "Incorrect Active Directory user type "
-               << user_context.GetUserType();
+  if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY) {
+    if (user_context.GetUserType() !=
+        user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY) {
+      LOG(FATAL) << "Incorrect Active Directory user type "
+                 << user_context.GetUserType();
+    }
+    user_context.SetIsUsingOAuth(false);
   }
 
   existing_user_controller_->Login(user_context, chromeos::SigninSpecifics());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index b279d43..eb1b531 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -208,8 +208,8 @@
   },
   {
     "name": "ash-keyboard-shortcut-viewer-app",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "msw" ],
+    "expiry_milestone": 73
   },
   {
     "name": "ash-shelf-color",
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.cc b/chrome/browser/password_manager/password_accessory_controller_impl.cc
index 0722f7932..9f68974 100644
--- a/chrome/browser/password_manager/password_accessory_controller_impl.cc
+++ b/chrome/browser/password_manager/password_accessory_controller_impl.cc
@@ -242,9 +242,12 @@
     return;  // The favicon for this origin was already requested.
 
   favicon_service_->GetRawFaviconForPageURL(
-      origin.GetURL(), {favicon_base::IconType::kFavicon},
+      origin.GetURL(),
+      {favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon,
+       favicon_base::IconType::kTouchPrecomposedIcon,
+       favicon_base::IconType::kWebManifestIcon},
       desired_size_in_pixel,
-      /* fallback_to_host = */ false,
+      /* fallback_to_host = */ true,
       base::BindRepeating(  // FaviconService doesn't support BindOnce yet.
           &PasswordAccessoryControllerImpl::OnImageFetched,
           base::AsWeakPtr<PasswordAccessoryControllerImpl>(this), origin),
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 70e0fa0..62ee5120 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -1859,14 +1859,8 @@
 }
 #endif  // !defined(OS_MACOSX)
 
-#if (defined(OS_WIN) && defined(ADDRESS_SANITIZER)) || \
-    (defined(OS_CHROME) && defined(MEMORY_SANITIZER))
-// https://crbug.com/856169, https://crbug.com/892484
-#define MAYBE_MouseLeave DISABLED_MouseLeave
-#else
-#define MAYBE_MouseLeave MouseLeave
-#endif
-IN_PROC_BROWSER_TEST_P(PDFExtensionHitTestTest, MAYBE_MouseLeave) {
+// Flaky in nearly all configurations; see https://crbug.com/856169.
+IN_PROC_BROWSER_TEST_P(PDFExtensionHitTestTest, DISABLED_MouseLeave) {
   GURL url = embedded_test_server()->GetURL("/pdf/pdf_embed.html");
 
   // Load page with embedded PDF and make sure it succeeds.
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 42b8cc4..8d8f6ee 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -71,6 +71,7 @@
 #include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_profile_attributes_updater_factory.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
@@ -371,6 +372,7 @@
 #endif
   ShortcutsBackendFactory::GetInstance();
   SigninManagerFactory::GetInstance();
+  SigninProfileAttributesUpdaterFactory::GetInstance();
 
   if (SiteEngagementService::IsEnabled())
     SiteEngagementServiceFactory::GetInstance();
diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
index 73f18a4..ebf40f7 100644
--- a/chrome/browser/profiles/profile_downloader.cc
+++ b/chrome/browser/profiles/profile_downloader.cc
@@ -291,7 +291,7 @@
 void ProfileDownloader::OnRefreshTokenUpdatedForAccount(
     const AccountInfo& account_info,
     bool is_valid) {
-  if (!is_valid || account_info.account_id != account_id_)
+  if (account_info.account_id != account_id_)
     return;
 
   identity_manager_observer_.Remove(identity_manager_);
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 2dbe636b..7773960e 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1213,7 +1213,9 @@
 #if BUILDFLAG(ENABLE_CROS_ASSISTANT)
   if (service_name == chromeos::assistant::mojom::kServiceName) {
     return std::make_unique<chromeos::assistant::Service>(
-        std::move(request), content::GetNetworkConnectionTracker());
+        std::move(request), content::GetNetworkConnectionTracker(),
+        base::CreateSingleThreadTaskRunnerWithTraits(
+            {content::BrowserThread::IO}));
   }
 #endif
 #endif
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index a512bd1..cedb4d1 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -94,21 +94,16 @@
 
 }  // namespace
 
-ChromeSigninClient::ChromeSigninClient(
-    Profile* profile,
-    SigninErrorController* signin_error_controller)
+ChromeSigninClient::ChromeSigninClient(Profile* profile)
     : OAuth2TokenService::Consumer("chrome_signin_client"),
       profile_(profile),
-      signin_error_controller_(signin_error_controller),
       weak_ptr_factory_(this) {
-  signin_error_controller_->AddObserver(this);
 #if !defined(OS_CHROMEOS)
   content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver(this);
 #endif
 }
 
 ChromeSigninClient::~ChromeSigninClient() {
-  signin_error_controller_->RemoveObserver(this);
 #if !defined(OS_CHROMEOS)
   content::GetNetworkConnectionTracker()->RemoveNetworkConnectionObserver(this);
 #endif
@@ -128,22 +123,6 @@
 
 PrefService* ChromeSigninClient::GetPrefs() { return profile_->GetPrefs(); }
 
-void ChromeSigninClient::OnSignedOut() {
-  ProfileAttributesEntry* entry;
-  bool has_entry = g_browser_process->profile_manager()->
-      GetProfileAttributesStorage().
-      GetProfileAttributesWithPath(profile_->GetPath(), &entry);
-
-  // If sign out occurs because Sync setup was in progress and the Profile got
-  // deleted, then the profile's no longer in the ProfileAttributesStorage.
-  if (!has_entry)
-    return;
-
-  entry->SetLocalAuthCredentials(std::string());
-  entry->SetAuthInfo(std::string(), base::string16());
-  entry->SetIsSigninRequired(false);
-}
-
 scoped_refptr<network::SharedURLLoaderFactory>
 ChromeSigninClient::GetURLLoaderFactory() {
   if (url_loader_factory_for_testing_)
@@ -191,19 +170,6 @@
       ->RemoveObserver(observer);
 }
 
-void ChromeSigninClient::OnSignedIn(const std::string& account_id,
-                                    const std::string& gaia_id,
-                                    const std::string& username,
-                                    const std::string& password) {
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-  ProfileAttributesEntry* entry;
-  if (profile_manager->GetProfileAttributesStorage().
-          GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
-    entry->SetAuthInfo(gaia_id, base::UTF8ToUTF16(username));
-    ProfileMetrics::UpdateReportedProfilesStatistics(profile_manager);
-  }
-}
-
 void ChromeSigninClient::PostSignedIn(const std::string& account_id,
                                       const std::string& username,
                                       const std::string& password) {
@@ -261,21 +227,6 @@
   }
 }
 
-void ChromeSigninClient::OnErrorChanged() {
-  // Some tests don't have a ProfileManager.
-  if (g_browser_process->profile_manager() == nullptr)
-    return;
-
-  ProfileAttributesEntry* entry;
-
-  if (!g_browser_process->profile_manager()->GetProfileAttributesStorage().
-          GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
-    return;
-  }
-
-  entry->SetIsAuthError(signin_error_controller_->HasError());
-}
-
 void ChromeSigninClient::OnGetTokenInfoResponse(
     std::unique_ptr<base::DictionaryValue> token_info) {
   if (!token_info->HasKey("error")) {
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h
index 80fc85d4..b9de346 100644
--- a/chrome/browser/signin/chrome_signin_client.h
+++ b/chrome/browser/signin/chrome_signin_client.h
@@ -11,7 +11,6 @@
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
 #include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/browser/signin_error_controller.h"
 #include "google_apis/gaia/gaia_oauth_client.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -31,12 +30,10 @@
 #if !defined(OS_CHROMEOS)
       public network::NetworkConnectionTracker::NetworkConnectionObserver,
 #endif
-      public SigninErrorController::Observer,
       public gaia::GaiaOAuthClient::Delegate,
       public OAuth2TokenService::Consumer {
  public:
-  explicit ChromeSigninClient(
-      Profile* profile, SigninErrorController* signin_error_controller);
+  explicit ChromeSigninClient(Profile* profile);
   ~ChromeSigninClient() override;
 
   void DoFinalInit() override;
@@ -49,7 +46,6 @@
   void PreSignOut(
       base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached,
       signin_metrics::ProfileSignout signout_source_metric) override;
-  void OnSignedOut() override;
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
   network::mojom::CookieManager* GetCookieManager() override;
   bool IsFirstRun() const override;
@@ -70,17 +66,10 @@
   // <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel">
   // If version information is unavailable, returns "invalid."
   std::string GetProductVersion() override;
-  void OnSignedIn(const std::string& account_id,
-                  const std::string& gaia_id,
-                  const std::string& username,
-                  const std::string& password) override;
   void PostSignedIn(const std::string& account_id,
                     const std::string& username,
                     const std::string& password) override;
 
-  // SigninErrorController::Observer implementation.
-  void OnErrorChanged() override;
-
   // gaia::GaiaOAuthClient::Delegate implementation.
   void OnGetTokenInfoResponse(
       std::unique_ptr<base::DictionaryValue> token_info) override;
@@ -122,8 +111,6 @@
 
   Profile* profile_;
 
-  SigninErrorController* signin_error_controller_;
-
   // Stored callback from PreSignOut();
   base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached_;
 
diff --git a/chrome/browser/signin/chrome_signin_client_factory.cc b/chrome/browser/signin/chrome_signin_client_factory.cc
index 0daef05c..72b8b766 100644
--- a/chrome/browser/signin/chrome_signin_client_factory.cc
+++ b/chrome/browser/signin/chrome_signin_client_factory.cc
@@ -4,18 +4,14 @@
 
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 
-#include "base/bind.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
-#include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/signin/core/browser/account_consistency_method.h"
 
 ChromeSigninClientFactory::ChromeSigninClientFactory()
     : BrowserContextKeyedServiceFactory(
           "ChromeSigninClient",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(SigninErrorControllerFactory::GetInstance());
 }
 
 ChromeSigninClientFactory::~ChromeSigninClientFactory() {}
@@ -33,10 +29,7 @@
 
 KeyedService* ChromeSigninClientFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
-  Profile* profile = static_cast<Profile*>(context);
-  ChromeSigninClient* client = new ChromeSigninClient(
-      profile, SigninErrorControllerFactory::GetForProfile(profile));
-  return client;
+  return new ChromeSigninClient(Profile::FromBrowserContext(context));
 }
 
 void ChromeSigninClientFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc
index 02f56ae..483617b 100644
--- a/chrome/browser/signin/chrome_signin_client_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -14,13 +14,13 @@
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/signin/signin_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/core/browser/account_consistency_method.h"
+#include "components/signin/core/browser/signin_error_controller.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/network/test/test_network_connection_tracker.h"
@@ -131,8 +131,8 @@
 
 class MockChromeSigninClient : public ChromeSigninClient {
  public:
-  MockChromeSigninClient(Profile* profile, SigninErrorController* controller)
-      : ChromeSigninClient(profile, controller) {}
+  explicit MockChromeSigninClient(Profile* profile)
+      : ChromeSigninClient(profile) {}
 
   MOCK_METHOD1(ShowUserManager, void(const base::FilePath&));
   MOCK_METHOD1(LockForceSigninProfile, void(const base::FilePath&));
@@ -177,9 +177,9 @@
   }
 
   void CreateClient(Profile* profile) {
+    client_.reset(new MockChromeSigninClient(profile));
     SigninErrorController* controller = new SigninErrorController(
         SigninErrorController::AccountMode::ANY_ACCOUNT);
-    client_.reset(new MockChromeSigninClient(profile, controller));
     fake_controller_.reset(controller);
   }
 
diff --git a/chrome/browser/signin/signin_profile_attributes_updater.cc b/chrome/browser/signin/signin_profile_attributes_updater.cc
new file mode 100644
index 0000000..e7e8e1d7
--- /dev/null
+++ b/chrome/browser/signin/signin_profile_attributes_updater.cc
@@ -0,0 +1,82 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/signin/signin_profile_attributes_updater.h"
+
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "components/signin/core/browser/account_info.h"
+
+SigninProfileAttributesUpdater::SigninProfileAttributesUpdater(
+    SigninManagerBase* signin_manager,
+    SigninErrorController* signin_error_controller,
+    const base::FilePath& profile_path)
+    : signin_error_controller_(signin_error_controller),
+      profile_path_(profile_path),
+      signin_error_controller_observer_(this),
+      signin_manager_observer_(this) {
+  signin_error_controller_observer_.Add(signin_error_controller);
+  // TODO(crbug.com/908457): Call OnErrorChanged() here, to catch any change
+  // that happened since the construction of SigninErrorController. Profile
+  // metrics depend on this bug and must be fixed first.
+}
+
+SigninProfileAttributesUpdater::~SigninProfileAttributesUpdater() = default;
+
+void SigninProfileAttributesUpdater::Shutdown() {
+  signin_error_controller_observer_.RemoveAll();
+  signin_manager_observer_.RemoveAll();
+}
+
+void SigninProfileAttributesUpdater::OnErrorChanged() {
+  // Some tests don't have a ProfileManager.
+  if (g_browser_process->profile_manager() == nullptr)
+    return;
+
+  ProfileAttributesEntry* entry;
+  if (!g_browser_process->profile_manager()
+           ->GetProfileAttributesStorage()
+           .GetProfileAttributesWithPath(profile_path_, &entry)) {
+    return;
+  }
+
+  entry->SetIsAuthError(signin_error_controller_->HasError());
+}
+
+#if !defined(OS_CHROMEOS)
+void SigninProfileAttributesUpdater::GoogleSigninSucceeded(
+    const AccountInfo& account_info) {
+  ProfileAttributesEntry* entry;
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  if (!profile_manager->GetProfileAttributesStorage()
+           .GetProfileAttributesWithPath(profile_path_, &entry)) {
+    return;
+  }
+
+  entry->SetAuthInfo(account_info.gaia, base::UTF8ToUTF16(account_info.email));
+  ProfileMetrics::UpdateReportedProfilesStatistics(profile_manager);
+}
+
+void SigninProfileAttributesUpdater::GoogleSignedOut(
+    const AccountInfo& account_info) {
+  ProfileAttributesEntry* entry;
+  bool has_entry = g_browser_process->profile_manager()
+                       ->GetProfileAttributesStorage()
+                       .GetProfileAttributesWithPath(profile_path_, &entry);
+
+  // If sign out occurs because Sync setup was in progress and the Profile got
+  // deleted, then the profile's no longer in the ProfileAttributesStorage.
+  if (!has_entry)
+    return;
+
+  entry->SetLocalAuthCredentials(std::string());
+  entry->SetAuthInfo(std::string(), base::string16());
+  entry->SetIsSigninRequired(false);
+}
+#endif  // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/signin/signin_profile_attributes_updater.h b/chrome/browser/signin/signin_profile_attributes_updater.h
new file mode 100644
index 0000000..699593c
--- /dev/null
+++ b/chrome/browser/signin/signin_profile_attributes_updater.h
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_H_
+#define CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "build/build_config.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/signin/core/browser/signin_error_controller.h"
+#include "components/signin/core/browser/signin_manager_base.h"
+
+// This class listens to various signin events and updates the signin-related
+// fields of ProfileAttributes.
+class SigninProfileAttributesUpdater : public KeyedService,
+                                       public SigninErrorController::Observer,
+                                       public SigninManagerBase::Observer {
+ public:
+  SigninProfileAttributesUpdater(SigninManagerBase* signin_manager,
+                                 SigninErrorController* signin_error_controller,
+                                 const base::FilePath& profile_path);
+
+  ~SigninProfileAttributesUpdater() override;
+
+ private:
+  // KeyedService:
+  void Shutdown() override;
+
+  // SigninErrorController::Observer:
+  void OnErrorChanged() override;
+
+// These observer methods are never called on ChromeOS.
+#if !defined(OS_CHROMEOS)
+  // SigninManagerBase::Observer:
+  void GoogleSigninSucceeded(const AccountInfo& account_info) override;
+  void GoogleSignedOut(const AccountInfo& account_info) override;
+#endif
+
+  SigninErrorController* signin_error_controller_;
+  const base::FilePath profile_path_;
+  ScopedObserver<SigninErrorController, SigninProfileAttributesUpdater>
+      signin_error_controller_observer_;
+  ScopedObserver<SigninManagerBase, SigninProfileAttributesUpdater>
+      signin_manager_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(SigninProfileAttributesUpdater);
+};
+
+#endif  // CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_H_
diff --git a/chrome/browser/signin/signin_profile_attributes_updater_factory.cc b/chrome/browser/signin/signin_profile_attributes_updater_factory.cc
new file mode 100644
index 0000000..cf7f154a
--- /dev/null
+++ b/chrome/browser/signin/signin_profile_attributes_updater_factory.cc
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/signin/signin_profile_attributes_updater_factory.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/signin_error_controller_factory.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_profile_attributes_updater.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/signin/core/browser/signin_manager.h"
+
+// static
+SigninProfileAttributesUpdater*
+SigninProfileAttributesUpdaterFactory::GetForProfile(Profile* profile) {
+  return static_cast<SigninProfileAttributesUpdater*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+SigninProfileAttributesUpdaterFactory*
+SigninProfileAttributesUpdaterFactory::GetInstance() {
+  return base::Singleton<SigninProfileAttributesUpdaterFactory>::get();
+}
+
+SigninProfileAttributesUpdaterFactory::SigninProfileAttributesUpdaterFactory()
+    : BrowserContextKeyedServiceFactory(
+          "SigninProfileAttributesUpdater",
+          BrowserContextDependencyManager::GetInstance()) {
+  DependsOn(SigninErrorControllerFactory::GetInstance());
+  DependsOn(SigninManagerFactory::GetInstance());
+}
+
+SigninProfileAttributesUpdaterFactory::
+    ~SigninProfileAttributesUpdaterFactory() {}
+
+KeyedService* SigninProfileAttributesUpdaterFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  Profile* profile = Profile::FromBrowserContext(context);
+  return new SigninProfileAttributesUpdater(
+      SigninManagerFactory::GetForProfile(profile),
+      SigninErrorControllerFactory::GetForProfile(profile), profile->GetPath());
+}
+
+bool SigninProfileAttributesUpdaterFactory::ServiceIsCreatedWithBrowserContext()
+    const {
+  return true;
+}
diff --git a/chrome/browser/signin/signin_profile_attributes_updater_factory.h b/chrome/browser/signin/signin_profile_attributes_updater_factory.h
new file mode 100644
index 0000000..0d67c842
--- /dev/null
+++ b/chrome/browser/signin/signin_profile_attributes_updater_factory.h
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_FACTORY_H_
+#define CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+class SigninProfileAttributesUpdater;
+
+class SigninProfileAttributesUpdaterFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  // Returns nullptr if this profile cannot have a
+  // SigninProfileAttributesUpdater (for example, if |profile| is incognito).
+  static SigninProfileAttributesUpdater* GetForProfile(Profile* profile);
+
+  // Returns an instance of the factory singleton.
+  static SigninProfileAttributesUpdaterFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<
+      SigninProfileAttributesUpdaterFactory>;
+
+  SigninProfileAttributesUpdaterFactory();
+  ~SigninProfileAttributesUpdaterFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+
+  DISALLOW_COPY_AND_ASSIGN(SigninProfileAttributesUpdaterFactory);
+};
+
+#endif  // CHROME_BROWSER_SIGNIN_SIGNIN_PROFILE_ATTRIBUTES_UPDATER_FACTORY_H_
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
index 2bbf497..29c5291 100644
--- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -6,6 +6,7 @@
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/secondary_account_helper.h"
@@ -212,7 +213,47 @@
     }
   }
 
+  void ExpectAddressesDiffInHistograms(int added, int removed) {
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddresses.Added",
+                                         /*bucket=*/added,
+                                         /*count=*/1);
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddresses.Removed",
+                                         /*bucket=*/removed,
+                                         /*count=*/1);
+    histogram_tester_.ExpectUniqueSample(
+        "Autofill.WalletAddresses.AddedOrRemoved",
+        /*bucket=*/added + removed,
+        /*count=*/1);
+  }
+
+  void ExpectNoHistogramsForAddressesDiff() {
+    histogram_tester_.ExpectTotalCount("Autofill.WalletAddresses.Added", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletAddresses.Removed", 0);
+    histogram_tester_.ExpectTotalCount(
+        "Autofill.WalletAddresses.AddedOrRemoved", 0);
+  }
+
+  void ExpectCardsDiffInHistograms(int added, int removed) {
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.Added",
+                                         /*bucket=*/added,
+                                         /*count=*/1);
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.Removed",
+                                         /*bucket=*/removed,
+                                         /*count=*/1);
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.AddedOrRemoved",
+                                         /*bucket=*/added + removed,
+                                         /*count=*/1);
+  }
+
+  void ExpectNoHistogramsForCardsDiff() {
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.Added", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.Removed", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.AddedOrRemoved",
+                                       0);
+  }
+
   PersonalDataLoadedObserverMock personal_data_observer_;
+  base::HistogramTester histogram_tester_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSyncTest);
@@ -233,8 +274,9 @@
   InitWithFeatures(/*enabled_features=*/{},
                    /*disabled_features=*/
                    {autofill::features::kAutofillEnableAccountWalletStorage});
-  GetFakeServer()->SetWalletData(
-      {CreateDefaultSyncWalletAddress(), CreateDefaultSyncWalletCard()});
+  GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
+                                  CreateDefaultSyncWalletCard(),
+                                  CreateDefaultSyncPaymentsCustomerData()});
   ASSERT_TRUE(SetupSync());
 
   auto profile_data = GetProfileWebDataService(0);
@@ -256,6 +298,10 @@
   // Check that the data is stored in the profile storage.
   EXPECT_EQ(1U, GetServerCards(GetProfileWebDataService(0)).size());
   EXPECT_EQ(1U, GetServerProfiles(GetProfileWebDataService(0)).size());
+
+  // No histograms for initial sync.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // ChromeOS does not support late signin after profile creation, so the test
@@ -277,8 +323,9 @@
   autofill::PersonalDataManager* pdm = GetPersonalDataManager(0);
   pdm->OnSyncServiceInitialized(GetSyncService(0));
 
-  GetFakeServer()->SetWalletData(
-      {CreateDefaultSyncWalletAddress(), CreateDefaultSyncWalletCard()});
+  GetFakeServer()->SetWalletData({CreateDefaultSyncWalletAddress(),
+                                  CreateDefaultSyncWalletCard(),
+                                  CreateDefaultSyncPaymentsCustomerData()});
 
   ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
   ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization(
@@ -358,6 +405,10 @@
 
   EXPECT_EQ(1uL, pdm->GetCreditCards().size());
   EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
+
+  // No histograms for initial sync & for clearing.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // Wallet data should get cleared from the database when sync is (temporarily)
@@ -389,6 +440,10 @@
 
   EXPECT_EQ(1uL, pdm->GetCreditCards().size());
   EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
+
+  // No histograms for initial sync & for clearing.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // ChromeOS does not sign out, so the test below does not apply.
@@ -413,6 +468,10 @@
 
   EXPECT_EQ(0uL, pdm->GetCreditCards().size());
   EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
+
+  // No histograms for initial sync & for clearing.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 #endif  // !defined(OS_CHROMEOS)
 
@@ -441,6 +500,10 @@
                              profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
   EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
 
+  // No histograms for initial sync.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
+
   // Put some completely new data in the sync server.
   GetFakeServer()->SetWalletData(
       {CreateSyncWalletCard(/*name=*/"new-card", /*last_four=*/"0002",
@@ -465,6 +528,10 @@
   EXPECT_EQ("Company-2", TruncateUTF8(base::UTF16ToUTF8(
                              profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
   EXPECT_EQ("newid", pdm->GetPaymentsCustomerData()->customer_id);
+
+  // Expect correct histograms are reported for the update.
+  ExpectCardsDiffInHistograms(/*added=*/1, /*removed=*/1);
+  ExpectAddressesDiffInHistograms(/*added=*/1, /*removed=*/1);
 }
 
 // Wallet is not using incremental updates. The server either sends a non-empty
@@ -514,6 +581,10 @@
   EXPECT_EQ("Company-1", TruncateUTF8(base::UTF16ToUTF8(
                              profiles[0]->GetRawInfo(autofill::COMPANY_NAME))));
   EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
+
+  // No histograms for initial sync, nor for an empty update.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // Wallet data should get cleared from the database when the wallet sync type
@@ -537,6 +608,10 @@
 
   EXPECT_EQ(0uL, pdm->GetCreditCards().size());
   EXPECT_EQ(nullptr, pdm->GetPaymentsCustomerData());
+
+  // No histograms for initial sync & for clearing.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // Wallet data should get cleared from the database when the wallet autofill
@@ -559,6 +634,10 @@
   autofill::prefs::SetPaymentsIntegrationEnabled(GetProfile(0)->GetPrefs(),
                                                  false);
   EXPECT_EQ(0uL, pdm->GetCreditCards().size());
+
+  // No histograms for initial sync & for clearing.
+  ExpectNoHistogramsForCardsDiff();
+  ExpectNoHistogramsForAddressesDiff();
 }
 
 // Wallet data present on the client should be cleared in favor of the new data
@@ -618,6 +697,10 @@
 
   // The PaymentsCustomerData should still be there.
   EXPECT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id);
+
+  // Expect correct histograms are reported for the update.
+  ExpectCardsDiffInHistograms(/*added=*/1, /*removed=*/1);
+  ExpectAddressesDiffInHistograms(/*added=*/0, /*removed=*/1);
 }
 
 // Wallet data present on the client should be cleared in favor of the new data
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc
index d026808..51c26d8 100644
--- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc
+++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.cc
@@ -21,6 +21,7 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
+#include "ui/views/accessibility/ax_event_manager.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
@@ -43,6 +44,8 @@
   Reset(false);
 
   SendEvent(current_tree_->GetRoot(), ax::mojom::Event::kLoadComplete);
+  // Intentionally not reset at shutdown since we cannot rely on the shutdown
+  // ordering of two base::Singletons.
   views::AXAuraObjCache::GetInstance()->SetDelegate(this);
 
 #if defined(OS_CHROMEOS)
@@ -70,7 +73,7 @@
 #endif
 }
 
-void AutomationManagerAura::HandleEvent(views::View* view,
+void AutomationManagerAura::OnViewEvent(views::View* view,
                                         ax::mojom::Event event_type) {
   CHECK(view);
 
@@ -161,9 +164,12 @@
     : AXHostDelegate(ui::DesktopAXTreeID()),
       enabled_(false),
       processing_events_(false),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this) {
+  views::AXEventManager::Get()->AddObserver(this);
+}
 
 AutomationManagerAura::~AutomationManagerAura() {
+  views::AXEventManager::Get()->RemoveObserver(this);
 }
 
 void AutomationManagerAura::Reset(bool reset_serializer) {
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
index a5cc37d..1ed601be 100644
--- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
+++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
@@ -18,6 +18,7 @@
 #include "ui/accessibility/ax_host_delegate.h"
 #include "ui/accessibility/ax_tree_serializer.h"
 #include "ui/views/accessibility/ax_aura_obj_cache.h"
+#include "ui/views/accessibility/ax_event_observer.h"
 
 namespace base {
 template <typename T>
@@ -36,7 +37,8 @@
 
 // Manages a tree of automation nodes.
 class AutomationManagerAura : public ui::AXHostDelegate,
-                              public views::AXAuraObjCache::Delegate {
+                              public views::AXAuraObjCache::Delegate,
+                              public views::AXEventObserver {
  public:
   // Get the single instance of this class.
   static AutomationManagerAura* GetInstance();
@@ -47,9 +49,6 @@
   // Disable automation support for views.
   void Disable();
 
-  // Handle an event fired upon a |View|.
-  void HandleEvent(views::View* view, ax::mojom::Event event_type);
-
   // Handle an event fired upon the root view.
   void HandleEvent(ax::mojom::Event event_type);
 
@@ -63,6 +62,9 @@
   void OnEvent(views::AXAuraObjWrapper* aura_obj,
                ax::mojom::Event event_type) override;
 
+  // views::AXEventObserver:
+  void OnViewEvent(views::View* view, ax::mojom::Event event_type) override;
+
   void set_event_bundle_callback_for_testing(
       base::RepeatingCallback<void(ExtensionMsg_AccessibilityEventBundleParams)>
           callback) {
diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc
index 265e6da..0f1ca68 100644
--- a/chrome/browser/ui/views/chrome_views_delegate.cc
+++ b/chrome/browser/ui/views/chrome_views_delegate.cc
@@ -20,10 +20,6 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/widget/widget.h"
 
-#if defined(USE_AURA)
-#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
-#endif
-
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/ui/views/touch_selection_menu_runner_chromeos.h"
 #endif
@@ -136,14 +132,6 @@
   return true;
 }
 
-void ChromeViewsDelegate::NotifyAccessibilityEvent(
-    views::View* view,
-    ax::mojom::Event event_type) {
-#if defined(USE_AURA)
-  AutomationManagerAura::GetInstance()->HandleEvent(view, event_type);
-#endif
-}
-
 void ChromeViewsDelegate::AddRef() {
   if (ref_count_ == 0u) {
     keep_alive_.reset(
diff --git a/chrome/browser/ui/views/chrome_views_delegate.h b/chrome/browser/ui/views/chrome_views_delegate.h
index c24f97b..b33def5 100644
--- a/chrome/browser/ui/views/chrome_views_delegate.h
+++ b/chrome/browser/ui/views/chrome_views_delegate.h
@@ -14,7 +14,6 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/views/views_delegate.h"
 
 class ScopedKeepAlive;
@@ -33,8 +32,6 @@
                                const std::string& window_name,
                                gfx::Rect* bounds,
                                ui::WindowShowState* show_state) const override;
-  void NotifyAccessibilityEvent(views::View* view,
-                                ax::mojom::Event event_type) override;
 #if defined(OS_CHROMEOS)
   ProcessMenuAcceleratorResult ProcessAcceleratorWhileMenuShowing(
       const ui::Accelerator& accelerator) override;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
index 5e351b1..22207585 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
 #include "chrome/browser/ui/views/tabs/tab_style.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chrome/test/views/chrome_test_views_delegate.h"
 #include "chrome/test/views/chrome_views_test_base.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -27,6 +26,8 @@
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/skia_util.h"
+#include "ui/views/accessibility/ax_event_manager.h"
+#include "ui/views/accessibility/ax_event_observer.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/view.h"
 #include "ui/views/view_targeter.h"
@@ -44,12 +45,16 @@
   return current;
 }
 
-class TabStripTestViewsDelegate : public ChromeTestViewsDelegate {
+class TestAXEventObserver : public views::AXEventObserver {
  public:
-  TabStripTestViewsDelegate() = default;
-  ~TabStripTestViewsDelegate() override = default;
-  void NotifyAccessibilityEvent(views::View* view,
-                                ax::mojom::Event event_type) override {
+  TestAXEventObserver() { views::AXEventManager::Get()->AddObserver(this); }
+
+  ~TestAXEventObserver() override {
+    views::AXEventManager::Get()->RemoveObserver(this);
+  }
+
+  // views::AXEventObserver:
+  void OnViewEvent(views::View* view, ax::mojom::Event event_type) override {
     if (event_type == ax::mojom::Event::kSelectionRemove) {
       remove_count_++;
     }
@@ -64,7 +69,8 @@
  private:
   int add_count_ = 0;
   int remove_count_ = 0;
-  DISALLOW_COPY_AND_ASSIGN(TabStripTestViewsDelegate);
+
+  DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
 };
 
 class AnimationWaiter {
@@ -170,13 +176,6 @@
   }
 
  protected:
-  std::unique_ptr<views::TestViewsDelegate> CreateTestViewsDelegate() override {
-    std::unique_ptr<TabStripTestViewsDelegate> delegate =
-        std::make_unique<TabStripTestViewsDelegate>();
-    test_views_delegate_ = delegate.get();
-    return delegate;
-  }
-
   bool IsShowingAttentionIndicator(Tab* tab) {
     return tab->icon_->ShowingAttentionIndicator();
   }
@@ -222,7 +221,6 @@
   // Owns |tab_strip_|.
   views::View parent_;
   TabStrip* tab_strip_ = nullptr;
-  TabStripTestViewsDelegate* test_views_delegate_ = nullptr;
   std::unique_ptr<views::Widget> widget_;
 
  private:
@@ -236,6 +234,8 @@
 }
 
 TEST_P(TabStripTest, AccessibilityEvents) {
+  TestAXEventObserver observer;
+
   // When adding tabs, SetSelection() is called after AddTabAt(), as
   // otherwise the index would not be meaningful.
   tab_strip_->AddTabAt(0, TabRendererData(), false);
@@ -243,16 +243,16 @@
   ui::ListSelectionModel selection;
   selection.SetSelectedIndex(1);
   tab_strip_->SetSelection(selection);
-  EXPECT_EQ(1, test_views_delegate_->add_count());
-  EXPECT_EQ(0, test_views_delegate_->remove_count());
+  EXPECT_EQ(1, observer.add_count());
+  EXPECT_EQ(0, observer.remove_count());
 
   // When removing tabs, SetSelection() is called before RemoveTabAt(), as
   // otherwise the index would not be meaningful.
   selection.SetSelectedIndex(0);
   tab_strip_->SetSelection(selection);
   tab_strip_->RemoveTabAt(nullptr, 1, true);
-  EXPECT_EQ(2, test_views_delegate_->add_count());
-  EXPECT_EQ(1, test_views_delegate_->remove_count());
+  EXPECT_EQ(2, observer.add_count());
+  EXPECT_EQ(1, observer.remove_count());
 }
 
 TEST_P(TabStripTest, IsValidModelIndex) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index c7e98947f..13f3646 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -1220,11 +1220,13 @@
   // network. See https://crbug.com/386606 for details.
   user_context.SetPasswordKey(Key(password));
   user_context.SetIsUsingPin(authenticated_by_pin);
-  if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY &&
-      (user_context.GetUserType() !=
-       user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY)) {
-    LOG(FATAL) << "Incorrect Active Directory user type "
-               << user_context.GetUserType();
+  if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY) {
+    if (user_context.GetUserType() !=
+        user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY) {
+      LOG(FATAL) << "Incorrect Active Directory user type "
+                 << user_context.GetUserType();
+    }
+    user_context.SetIsUsingOAuth(false);
   }
 
   delegate_->Login(user_context, SigninSpecifics());
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc
new file mode 100644
index 0000000..98e5637e4
--- /dev/null
+++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -0,0 +1,139 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/test/metrics/histogram_tester.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/profile_sync_test_util.h"
+#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
+#include "chrome/browser/sync/test/integration/sync_test.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/unified_consent/chrome_unified_consent_service_client.h"
+#include "chrome/browser/unified_consent/unified_consent_service_factory.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/sync/test/fake_server/fake_server_network_resources.h"
+#include "components/unified_consent/scoped_unified_consent.h"
+#include "components/unified_consent/unified_consent_metrics.h"
+#include "components/unified_consent/unified_consent_service.h"
+
+namespace unified_consent {
+namespace {
+
+class UnifiedConsentBrowserTest : public SyncTest {
+ public:
+  UnifiedConsentBrowserTest() : SyncTest(SINGLE_CLIENT) {}
+  ~UnifiedConsentBrowserTest() override = default;
+
+  void DisableGoogleServices() {
+    ChromeUnifiedConsentServiceClient consent_service_client(
+        browser()->profile()->GetPrefs());
+    for (int i = 0;
+         i <= static_cast<int>(UnifiedConsentServiceClient::Service::kLast);
+         ++i) {
+      UnifiedConsentServiceClient::Service service =
+          static_cast<UnifiedConsentServiceClient::Service>(i);
+      if (consent_service_client.IsServiceSupported(service)) {
+        consent_service_client.SetServiceEnabled(service, false);
+        EXPECT_EQ(UnifiedConsentServiceClient::ServiceState::kDisabled,
+                  consent_service_client.GetServiceState(service));
+      }
+    }
+  }
+
+  void EnableSync() {
+    Profile* profile = browser()->profile();
+    ProfileSyncServiceFactory::GetForProfile(profile)
+        ->OverrideNetworkResourcesForTest(
+            std::make_unique<fake_server::FakeServerNetworkResources>(
+                GetFakeServer()->AsWeakPtr()));
+
+    std::unique_ptr<ProfileSyncServiceHarness> harness =
+        ProfileSyncServiceHarness::Create(
+            profile, "user@gmail.com", "fake_password",
+            ProfileSyncServiceHarness::SigninType::FAKE_SIGNIN);
+    EXPECT_TRUE(harness->SetupSync());
+  }
+
+  UnifiedConsentService* consent_service() {
+    return UnifiedConsentServiceFactory::GetForProfile(browser()->profile());
+  }
+
+ protected:
+  base::HistogramTester histogram_tester_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedConsentBrowserTest);
+};
+
+class UnifiedConsentDisabledBrowserTest : public UnifiedConsentBrowserTest {
+ public:
+  UnifiedConsentDisabledBrowserTest()
+      : scoped_unified_consent_disabled(UnifiedConsentFeatureState::kDisabled) {
+  }
+  ~UnifiedConsentDisabledBrowserTest() override = default;
+
+ private:
+  ScopedUnifiedConsent scoped_unified_consent_disabled;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedConsentDisabledBrowserTest);
+};
+
+// Tests that the settings histogram is recorded if unified consent is enabled.
+// The histogram is recorded during profile initialization.
+IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest, PRE_SettingsHistogram_None) {
+  DisableGoogleServices();
+}
+
+IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest, SettingsHistogram_None) {
+  histogram_tester_.ExpectUniqueSample(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kNone, 1);
+}
+
+// Tests that the settings histogram is recorded if unified consent is disabled.
+// The histogram is recorded during profile initialization.
+IN_PROC_BROWSER_TEST_F(UnifiedConsentDisabledBrowserTest,
+                       PRE_SettingsHistogram_None) {
+  DisableGoogleServices();
+}
+
+IN_PROC_BROWSER_TEST_F(UnifiedConsentDisabledBrowserTest,
+                       SettingsHistogram_None) {
+  histogram_tester_.ExpectUniqueSample(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kNone, 1);
+}
+
+// Tests that all service entries in the settings histogram are recorded after
+// enabling them.
+IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest,
+                       PRE_SettingsHistogram_AllGoogleServicesEnabled) {
+  EnableSync();
+  consent_service()->EnableGoogleServices();
+}
+
+IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest,
+                       SettingsHistogram_AllGoogleServicesEnabled) {
+  histogram_tester_.ExpectBucketCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kNone, 0);
+  histogram_tester_.ExpectBucketCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kAllServicesWereEnabled, 1);
+  histogram_tester_.ExpectBucketCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection, 1);
+  histogram_tester_.ExpectBucketCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting, 1);
+  histogram_tester_.ExpectBucketCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings",
+      metrics::SettingsHistogramValue::kSpellCheck, 1);
+  histogram_tester_.ExpectTotalCount(
+      "UnifiedConsent.SyncAndGoogleServicesSettings", 4);
+}
+
+}  // namespace
+}  // namespace unified_consent
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.cc b/chrome/browser/unified_consent/unified_consent_service_factory.cc
index 8799f93..a27f7942 100644
--- a/chrome/browser/unified_consent/unified_consent_service_factory.cc
+++ b/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -14,8 +14,12 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "components/unified_consent/feature.h"
+#include "components/unified_consent/unified_consent_metrics.h"
 #include "components/unified_consent/unified_consent_service.h"
 
+using unified_consent::UnifiedConsentService;
+using unified_consent::metrics::RecordSettingsHistogram;
+
 UnifiedConsentServiceFactory::UnifiedConsentServiceFactory()
     : BrowserContextKeyedServiceFactory(
           "UnifiedConsentService",
@@ -27,9 +31,9 @@
 UnifiedConsentServiceFactory::~UnifiedConsentServiceFactory() = default;
 
 // static
-unified_consent::UnifiedConsentService*
-UnifiedConsentServiceFactory::GetForProfile(Profile* profile) {
-  return static_cast<unified_consent::UnifiedConsentService*>(
+UnifiedConsentService* UnifiedConsentServiceFactory::GetForProfile(
+    Profile* profile) {
+  return static_cast<UnifiedConsentService*>(
       GetInstance()->GetServiceForBrowserContext(profile, true));
 }
 
@@ -40,28 +44,32 @@
 
 void UnifiedConsentServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
-  unified_consent::UnifiedConsentService::RegisterPrefs(registry);
+  UnifiedConsentService::RegisterPrefs(registry);
 }
 
 KeyedService* UnifiedConsentServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
+  PrefService* pref_service = profile->GetPrefs();
+  auto service_client =
+      std::make_unique<ChromeUnifiedConsentServiceClient>(pref_service);
+  // Record settings for pre- and post-UnifiedConsent users.
+  RecordSettingsHistogram(service_client.get(), pref_service);
+
   syncer::SyncService* sync_service =
       ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(profile);
   if (!sync_service)
     return nullptr;
 
   if (!unified_consent::IsUnifiedConsentFeatureEnabled()) {
-    ChromeUnifiedConsentServiceClient service_client(profile->GetPrefs());
-    unified_consent::UnifiedConsentService::RollbackIfNeeded(
-        profile->GetPrefs(), sync_service, &service_client);
+    UnifiedConsentService::RollbackIfNeeded(pref_service, sync_service,
+                                            service_client.get());
     return nullptr;
   }
 
-  return new unified_consent::UnifiedConsentService(
-      std::make_unique<ChromeUnifiedConsentServiceClient>(profile->GetPrefs()),
-      profile->GetPrefs(), IdentityManagerFactory::GetForProfile(profile),
-      sync_service);
+  return new UnifiedConsentService(
+      std::move(service_client), pref_service,
+      IdentityManagerFactory::GetForProfile(profile), sync_service);
 }
 
 bool UnifiedConsentServiceFactory::ServiceIsNULLWhileTesting() const {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f9968d3d..fbcc2c9 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1161,7 +1161,10 @@
           [ "../browser/ssl/captive_portal_blocking_page_browsertest.cc" ]
     }
     if (enable_dice_support) {
-      sources += [ "../browser/signin/dice_browsertest.cc" ]
+      sources += [
+        "../browser/signin/dice_browsertest.cc",
+        "../browser/unified_consent/unified_consent_browsertest.cc",
+      ]
     }
     if (!enable_one_click_signin) {
       sources -= [ "../browser/ui/sync/one_click_signin_links_delegate_impl_browsertest.cc" ]
diff --git a/chrome/test/origin_policy/origin_policy_browsertest.cc b/chrome/test/origin_policy/origin_policy_browsertest.cc
index 02a3ad9..f5090485 100644
--- a/chrome/test/origin_policy/origin_policy_browsertest.cc
+++ b/chrome/test/origin_policy/origin_policy_browsertest.cc
@@ -15,7 +15,7 @@
 
 // The title of the Origin Policy error interstitial. This is used to determine
 // whether the page load was blocked by the origin policy throttle.
-const char kErrorInterstitialTitle[] = "Origin Policy Error Interstitial";
+const char kErrorInterstitialTitle[] = "Origin Policy Error";
 }  // namespace
 
 namespace content {
diff --git a/chrome/test/views/chrome_views_test_base.cc b/chrome/test/views/chrome_views_test_base.cc
index 2e2a5ef..bdb29a46 100644
--- a/chrome/test/views/chrome_views_test_base.cc
+++ b/chrome/test/views/chrome_views_test_base.cc
@@ -11,11 +11,6 @@
 ChromeViewsTestBase::~ChromeViewsTestBase() {}
 
 void ChromeViewsTestBase::SetUp() {
-  set_views_delegate(CreateTestViewsDelegate());
+  set_views_delegate(std::make_unique<ChromeTestViewsDelegate>());
   views::ViewsTestBase::SetUp();
 }
-
-std::unique_ptr<views::TestViewsDelegate>
-ChromeViewsTestBase::CreateTestViewsDelegate() {
-  return std::make_unique<ChromeTestViewsDelegate>();
-}
diff --git a/chrome/test/views/chrome_views_test_base.h b/chrome/test/views/chrome_views_test_base.h
index 5d8ca48..ccc6d09 100644
--- a/chrome/test/views/chrome_views_test_base.h
+++ b/chrome/test/views/chrome_views_test_base.h
@@ -20,9 +20,6 @@
   // views::ViewsTestBase:
   void SetUp() override;
 
-  // Subclasses can override to provide their own TestViewsDelegate
-  virtual std::unique_ptr<views::TestViewsDelegate> CreateTestViewsDelegate();
-
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeViewsTestBase);
 };
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index e71a58c5..b33e86e 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -146,7 +146,7 @@
       std::move(mojo_media_client), std::move(request));
 #endif  // defined(OS_ANDROID)
 
-  service_manager::Service::RunUntilTermination(std::move(service));
+  service_manager::Service::RunAsyncUntilTermination(std::move(service));
 }
 #endif  // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
 
diff --git a/chromecast/browser/exo/wm_helper_cast_shell.cc b/chromecast/browser/exo/wm_helper_cast_shell.cc
index e8724a2..80268f8 100644
--- a/chromecast/browser/exo/wm_helper_cast_shell.cc
+++ b/chromecast/browser/exo/wm_helper_cast_shell.cc
@@ -183,7 +183,7 @@
 void WMHelperCastShell::CastDisplayObserver::OnDisplayMetricsChanged(
     const display::Display& display,
     uint32_t changed_metrics) {
-  if (!base::ContainsValue(display_info_, display.id())) {
+  if (display_info_.find(display.id()) == display_info_.end()) {
     display::ManagedDisplayInfo md(display.id(), "CastDisplayInfo", true);
     md.SetBounds(display.bounds());
     display_info_.emplace(display.id(), md);
diff --git a/chromeos/components/tether/connect_tethering_operation_unittest.cc b/chromeos/components/tether/connect_tethering_operation_unittest.cc
index 8336e47..4199168 100644
--- a/chromeos/components/tether/connect_tethering_operation_unittest.cc
+++ b/chromeos/components/tether/connect_tethering_operation_unittest.cc
@@ -298,8 +298,7 @@
 
   // Simulate the device failing to connect.
   fake_ble_connection_manager_->SimulateUnansweredConnectionAttempts(
-      test_device_.GetDeviceId(),
-      MessageTransferOperation::kMaxEmptyScansPerDevice);
+      test_device_.GetDeviceId(), 0 /* num_attempts */);
 
   // The maximum number of connection failures has occurred.
   EXPECT_TRUE(test_observer_->has_received_failure());
diff --git a/chromeos/components/tether/host_scanner_operation_unittest.cc b/chromeos/components/tether/host_scanner_operation_unittest.cc
index a4d662a..ef62995b 100644
--- a/chromeos/components/tether/host_scanner_operation_unittest.cc
+++ b/chromeos/components/tether/host_scanner_operation_unittest.cc
@@ -428,8 +428,7 @@
 
   // Simulate device 1 failing to connect.
   fake_ble_connection_manager_->SimulateUnansweredConnectionAttempts(
-      test_devices_[1].GetDeviceId(),
-      MessageTransferOperation::kMaxEmptyScansPerDevice);
+      test_devices_[1].GetDeviceId(), 0 /* num_attempts */);
 
   // The scan should still not be over, and no new scan results should have
   // come in.
@@ -438,8 +437,7 @@
 
   // Simulate device 3 failing to connect.
   fake_ble_connection_manager_->SimulateUnansweredConnectionAttempts(
-      test_devices_[3].GetDeviceId(),
-      MessageTransferOperation::kMaxEmptyScansPerDevice);
+      test_devices_[3].GetDeviceId(), 0 /* num_attempts */);
 
   // The scan should still not be over, and no new scan results should have
   // come in.
diff --git a/chromeos/components/tether/keep_alive_operation_unittest.cc b/chromeos/components/tether/keep_alive_operation_unittest.cc
index 315bc066..7597026 100644
--- a/chromeos/components/tether/keep_alive_operation_unittest.cc
+++ b/chromeos/components/tether/keep_alive_operation_unittest.cc
@@ -155,8 +155,7 @@
 TEST_F(KeepAliveOperationTest, DISABLED_TestCannotConnect) {
   // Simulate the device failing to connect.
   fake_ble_connection_manager_->SimulateUnansweredConnectionAttempts(
-      test_device_.GetDeviceId(),
-      MessageTransferOperation::kMaxEmptyScansPerDevice);
+      test_device_.GetDeviceId(), 0 /* num_attempts */);
 
   // The maximum number of connection failures has occurred.
   EXPECT_TRUE(test_observer_->has_run_callback());
diff --git a/chromeos/components/tether/message_transfer_operation.cc b/chromeos/components/tether/message_transfer_operation.cc
index 038b27183..64e0fe9 100644
--- a/chromeos/components/tether/message_transfer_operation.cc
+++ b/chromeos/components/tether/message_transfer_operation.cc
@@ -36,13 +36,6 @@
 
 }  // namespace
 
-// static
-const uint32_t MessageTransferOperation::kMaxEmptyScansPerDevice = 3;
-
-// static
-const uint32_t MessageTransferOperation::kMaxGattConnectionAttemptsPerDevice =
-    6;
-
 MessageTransferOperation::ConnectionAttemptDelegate::ConnectionAttemptDelegate(
     MessageTransferOperation* operation,
     cryptauth::RemoteDeviceRef remote_device,
diff --git a/chromeos/components/tether/message_transfer_operation.h b/chromeos/components/tether/message_transfer_operation.h
index c6e1330..2cc5ae5 100644
--- a/chromeos/components/tether/message_transfer_operation.h
+++ b/chromeos/components/tether/message_transfer_operation.h
@@ -31,21 +31,6 @@
 // from remote devices.
 class MessageTransferOperation {
  public:
-  // The number of times to attempt to connect to a device without receiving any
-  // response before giving up. When a connection to a device is attempted, a
-  // BLE discovery session listens for advertisements from the remote device as
-  // the first step of the connection; if no advertisement is picked up, it is
-  // likely that the remote device is not nearby or is not currently responding
-  // to Instant Tethering requests.
-  static const uint32_t kMaxEmptyScansPerDevice;
-
-  // The number of times to attempt a GATT connection to a device, after a BLE
-  // discovery session has already detected a nearby device. GATT connections
-  // may fail for a variety of reasons, but most failures are ephemeral. Thus,
-  // more connection attempts are allowed in such cases since it is likely that
-  // a subsequent attempt will succeed. See https://crbug.com/805218.
-  static const uint32_t kMaxGattConnectionAttemptsPerDevice;
-
   MessageTransferOperation(
       const cryptauth::RemoteDeviceRefList& devices_to_connect,
       secure_channel::ConnectionPriority connection_priority,
diff --git a/chromeos/components/tether/message_transfer_operation_unittest.cc b/chromeos/components/tether/message_transfer_operation_unittest.cc
index ae79ee4..4b409d4 100644
--- a/chromeos/components/tether/message_transfer_operation_unittest.cc
+++ b/chromeos/components/tether/message_transfer_operation_unittest.cc
@@ -175,14 +175,7 @@
       : test_local_device_(cryptauth::RemoteDeviceRefBuilder()
                                .SetPublicKey("local device")
                                .Build()),
-        test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(4)) {
-    // These tests are written under the assumption that there are a maximum of
-    // 3 "empty scan" connection attempts and 6 "GATT" connection attempts; the
-    // tests need to be edited if these values change.
-    EXPECT_EQ(3u, MessageTransferOperation::kMaxEmptyScansPerDevice);
-    EXPECT_EQ(6u,
-              MessageTransferOperation::kMaxGattConnectionAttemptsPerDevice);
-  }
+        test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(4)) {}
 
   void SetUp() override {
     fake_device_sync_client_ =
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc
index efb75bc0..f6a2861a 100644
--- a/chromeos/services/assistant/assistant_manager_service_impl.cc
+++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -107,7 +107,7 @@
     network::NetworkConnectionTracker* network_connection_tracker)
     : action_module_(std::make_unique<action::CrosActionModule>(this)),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      chromium_api_delegate_(),
+      chromium_api_delegate_(service->io_task_runner()),
       assistant_settings_manager_(
           std::make_unique<AssistantSettingsManagerImpl>(this)),
       display_connection_(std::make_unique<CrosDisplayConnection>(this)),
diff --git a/chromeos/services/assistant/chromium_api_delegate.cc b/chromeos/services/assistant/chromium_api_delegate.cc
index 31e8aa7..5b044c03 100644
--- a/chromeos/services/assistant/chromium_api_delegate.cc
+++ b/chromeos/services/assistant/chromium_api_delegate.cc
@@ -4,15 +4,17 @@
 
 #include "chromeos/services/assistant/chromium_api_delegate.h"
 
+#include "base/single_thread_task_runner.h"
 #include "chromeos/services/assistant/default_url_request_context_getter.h"
 
 namespace chromeos {
 namespace assistant {
 
-ChromiumApiDelegate::ChromiumApiDelegate()
+ChromiumApiDelegate::ChromiumApiDelegate(
+    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
     : http_connection_factory_(
           base::MakeRefCounted<DefaultURLRequestContextGetter>(
-              "chromium_http_connection")) {}
+              io_task_runner)) {}
 
 ChromiumApiDelegate::~ChromiumApiDelegate() = default;
 
diff --git a/chromeos/services/assistant/chromium_api_delegate.h b/chromeos/services/assistant/chromium_api_delegate.h
index b958832..124166c 100644
--- a/chromeos/services/assistant/chromium_api_delegate.h
+++ b/chromeos/services/assistant/chromium_api_delegate.h
@@ -19,7 +19,8 @@
 
 class ChromiumApiDelegate : public assistant_client::FuchsiaApiDelegate {
  public:
-  ChromiumApiDelegate();
+  ChromiumApiDelegate(
+      scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
   ~ChromiumApiDelegate() override;
   // assistant_client::FuchsiaApiDelegate overrides:
   assistant_client::HttpConnectionFactory* GetHttpConnectionFactory() override;
diff --git a/chromeos/services/assistant/default_url_request_context_getter.cc b/chromeos/services/assistant/default_url_request_context_getter.cc
index 0575a476..0cff7b8 100644
--- a/chromeos/services/assistant/default_url_request_context_getter.cc
+++ b/chromeos/services/assistant/default_url_request_context_getter.cc
@@ -38,28 +38,12 @@
 namespace assistant {
 
 DefaultURLRequestContextGetter::DefaultURLRequestContextGetter(
-    const std::string& network_thread_name)
-    : thread_(new base::Thread(network_thread_name)) {
-  thread_->StartWithOptions(
-      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-  network_task_runner_ = thread_->task_runner();
-  DCHECK(network_task_runner_);
-}
-
-DefaultURLRequestContextGetter::DefaultURLRequestContextGetter(
     scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
-    : network_task_runner_(network_task_runner) {
+    : network_task_runner_(std::move(network_task_runner)) {
   DCHECK(network_task_runner_);
 }
 
-DefaultURLRequestContextGetter::~DefaultURLRequestContextGetter() {
-  if (request_context_) {
-    // The context should be destroyed on the network thread.
-    network_task_runner_->DeleteSoon(FROM_HERE, request_context_.release());
-  }
-  if (thread_)
-    thread_->Stop();
-}
+DefaultURLRequestContextGetter::~DefaultURLRequestContextGetter() = default;
 
 void DefaultURLRequestContextGetter::CreateContext() {
   // Context must be created on network thread since its internal objects
diff --git a/chromeos/services/assistant/default_url_request_context_getter.h b/chromeos/services/assistant/default_url_request_context_getter.h
index c96d36b..0a6798585 100644
--- a/chromeos/services/assistant/default_url_request_context_getter.h
+++ b/chromeos/services/assistant/default_url_request_context_getter.h
@@ -13,10 +13,6 @@
 #include "base/memory/ref_counted.h"
 #include "net/url_request/url_request_context_getter.h"
 
-namespace base {
-class Thread;
-}  // namespace base
-
 namespace chromeos {
 namespace assistant {
 
@@ -54,8 +50,6 @@
   void SetProxyConfigurationInternal(const std::string& proxy_server,
                                      const std::string& bypass_list);
 
-  // |thread_| is non-null if created by this class.
-  std::unique_ptr<base::Thread> thread_;
   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
   std::unique_ptr<::net::URLRequestContext> request_context_;
 
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc
index 52c1d31..61555a5 100644
--- a/chromeos/services/assistant/service.cc
+++ b/chromeos/services/assistant/service.cc
@@ -53,7 +53,8 @@
 }  // namespace
 
 Service::Service(service_manager::mojom::ServiceRequest request,
-                 network::NetworkConnectionTracker* network_connection_tracker)
+                 network::NetworkConnectionTracker* network_connection_tracker,
+                 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
     : service_binding_(this, std::move(request)),
       platform_binding_(this),
       session_observer_binding_(this),
@@ -61,6 +62,7 @@
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       power_manager_observer_(this),
       network_connection_tracker_(network_connection_tracker),
+      io_task_runner_(std::move(io_task_runner)),
       weak_ptr_factory_(this) {
   registry_.AddInterface<mojom::AssistantPlatform>(base::BindRepeating(
       &Service::BindAssistantPlatformConnection, base::Unretained(this)));
diff --git a/chromeos/services/assistant/service.h b/chromeos/services/assistant/service.h
index 1a6a5c6..26afd9a 100644
--- a/chromeos/services/assistant/service.h
+++ b/chromeos/services/assistant/service.h
@@ -17,6 +17,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/scoped_observer.h"
+#include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
@@ -54,7 +55,8 @@
                 public ash::DefaultVoiceInteractionObserver {
  public:
   Service(service_manager::mojom::ServiceRequest request,
-          network::NetworkConnectionTracker* network_connection_tracker);
+          network::NetworkConnectionTracker* network_connection_tracker,
+          scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
   ~Service() override;
 
   mojom::Client* client() { return client_.get(); }
@@ -71,6 +73,9 @@
   }
 
   ash::AssistantStateBase* assistant_state() { return &assistant_state_; }
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() {
+    return io_task_runner_;
+  }
 
   void RequestAccessToken();
 
@@ -168,6 +173,7 @@
   ash::AssistantStateProxy assistant_state_;
 
   network::NetworkConnectionTracker* network_connection_tracker_;
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
 
   base::WeakPtrFactory<Service> weak_ptr_factory_;
 
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc
index 3c7308c..ee1dc4b6 100644
--- a/chromeos/services/assistant/service_unittest.cc
+++ b/chromeos/services/assistant/service_unittest.cc
@@ -17,7 +17,6 @@
 #include "chromeos/dbus/fake_power_manager_client.h"
 #include "chromeos/services/assistant/fake_assistant_manager_service_impl.h"
 #include "chromeos/services/assistant/public/mojom/constants.mojom.h"
-#include "chromeos/services/assistant/service.h"
 #include "services/identity/public/mojom/identity_manager.mojom.h"
 #include "services/service_manager/public/cpp/service_binding.h"
 #include "services/service_manager/public/cpp/test/test_connector_factory.h"
@@ -168,7 +167,7 @@
 
     service_ = std::make_unique<Service>(
         test_connector_factory_.RegisterInstance(mojom::kServiceName),
-        nullptr /* network_connection_tracker */);
+        nullptr /* network_connection_tracker */, nullptr /* io_task_runner */);
 
     mock_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
         base::Time::Now(), base::TimeTicks::Now());
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
index 9699f36..eb9f740 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -269,16 +269,21 @@
   PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, &wallet_addresses,
                                   &customer_data);
 
-  wallet_data_changed |= SetWalletCards(std::move(wallet_cards));
-  wallet_data_changed |= SetWalletAddresses(std::move(wallet_addresses));
-  wallet_data_changed |= SetPaymentsCustomerData(std::move(customer_data));
+  bool should_log_diff;
+  wallet_data_changed |=
+      SetPaymentsCustomerData(std::move(customer_data), &should_log_diff);
+  wallet_data_changed |=
+      SetWalletCards(std::move(wallet_cards), should_log_diff);
+  wallet_data_changed |=
+      SetWalletAddresses(std::move(wallet_addresses), should_log_diff);
 
   if (web_data_backend_ && wallet_data_changed)
     web_data_backend_->NotifyOfMultipleAutofillChanges();
 }
 
 bool AutofillWalletSyncBridge::SetWalletCards(
-    std::vector<CreditCard> wallet_cards) {
+    std::vector<CreditCard> wallet_cards,
+    bool log_diff) {
   // Users can set billing address of the server credit card locally, but that
   // information does not propagate to either Chrome Sync or Google Payments
   // server. To preserve user's preferred billing address and most recent use
@@ -295,12 +300,11 @@
   AutofillWalletDiff<CreditCard> diff =
       ComputeAutofillWalletDiff(existing_cards, wallet_cards);
 
-  // Record only local changes that correspond to changes in the payments
-  // backend and not local changes due to initial sync.
-  if (initial_sync_done_) {
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAdded", diff.items_added);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsRemoved", diff.items_removed);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAddedOrRemoved",
+  if (log_diff) {
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.Added", diff.items_added);
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.Removed",
+                             diff.items_removed);
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.AddedOrRemoved",
                              diff.items_added + diff.items_removed);
   }
 
@@ -314,7 +318,8 @@
 }
 
 bool AutofillWalletSyncBridge::SetWalletAddresses(
-    std::vector<AutofillProfile> wallet_addresses) {
+    std::vector<AutofillProfile> wallet_addresses,
+    bool log_diff) {
   // In the common case, the database won't have changed. Committing an update
   // to the database will require at least one DB page write and will schedule
   // a fsync. To avoid this I/O, it should be more efficient to do a read and
@@ -325,13 +330,12 @@
   AutofillWalletDiff<AutofillProfile> diff =
       ComputeAutofillWalletDiff(existing_addresses, wallet_addresses);
 
-  // Record only local changes that correspond to changes in the payments
-  // backend and not local changes due to initial sync.
-  if (initial_sync_done_) {
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddressesAdded", diff.items_added);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddressesRemoved",
+  if (log_diff) {
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddresses.Added",
+                             diff.items_added);
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddresses.Removed",
                              diff.items_removed);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddressesAddedOrRemoved",
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddresses.AddedOrRemoved",
                              diff.items_added + diff.items_removed);
   }
 
@@ -345,11 +349,8 @@
 }
 
 bool AutofillWalletSyncBridge::SetPaymentsCustomerData(
-    std::vector<PaymentsCustomerData> customer_data) {
-  // In the common case, the database won't have changed. Committing an update
-  // to the database will require at least one DB page write and will schedule
-  // a fsync. To avoid this I/O, it should be more efficient to do a read and
-  // only do the writes if something changed.
+    std::vector<PaymentsCustomerData> customer_data,
+    bool* should_log_diff) {
   AutofillTable* table = GetAutofillTable();
   std::unique_ptr<PaymentsCustomerData> existing_entry;
   table->GetPaymentsCustomerData(&existing_entry);
@@ -366,6 +367,15 @@
   }
 #endif  // DCHECK_IS_ON()
 
+  // We report the diff to metrics only if this is an incremental change where
+  // the user had sync set-up (having PaymentsCustomerData is a pre-requisite
+  // for having any other data) and continues to have sync set-up (continuing
+  // having a PaymentsCustomerData entity). As a side effect, this excludes
+  // reporting diffs for users that newly got a GPay account and sync
+  // PaymentsCustomerData for the first time but this is the best we can do to
+  // have the metrics consistent with Directory implementation.
+  *should_log_diff = existing_entry && new_entry;
+
   if (!new_entry && existing_entry) {
     // Clear the existing entry in the DB.
     GetAutofillTable()->SetPaymentsCustomerData(nullptr);
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
index 07c99809..46d91c2 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -88,19 +88,23 @@
   // about added/deleted data.
   void SetSyncData(const syncer::EntityChangeList& entity_data);
 
+  // Sets |customer_data| to this client and returns whether any change has been
+  // applied (i.e., whether |customer_data| was different from local data) and
+  // whether we |should_log_diff|, i.e. metrics for diffs in counts of addresses
+  // and cards.
+  bool SetPaymentsCustomerData(std::vector<PaymentsCustomerData> customer_data,
+                               bool* should_log_diff);
+
   // Sets |wallet_cards| to this client, records metrics about added/deleted
-  // data and returns whether any change has been applied (i.e., whether
-  // |wallet_cards| was different from local data).
-  bool SetWalletCards(std::vector<CreditCard> wallet_cards);
+  // data (if |log_diff| is true) and returns whether any change has been
+  // applied (i.e., whether |wallet_cards| was different from local data).
+  bool SetWalletCards(std::vector<CreditCard> wallet_cards, bool log_diff);
 
   // Sets |wallet_addresses| to this client, records metrics about added/deleted
-  // data and returns whether any change has been applied (i.e., whether
-  // |wallet_addresses| was different from local data).
-  bool SetWalletAddresses(std::vector<AutofillProfile> wallet_addresses);
-
-  // Sets |customer_data| to this client and returns whether any change has been
-  // applied (i.e., whether |customer_data| was different from local data).
-  bool SetPaymentsCustomerData(std::vector<PaymentsCustomerData> customer_data);
+  // data (if |log_diff| is true) and returns whether any change has been
+  // applied (i.e., whether |wallet_addresses| was different from local data).
+  bool SetWalletAddresses(std::vector<AutofillProfile> wallet_addresses,
+                          bool log_diff);
 
   // Computes a "diff" (items added, items removed) of two vectors of items,
   // which should be either CreditCard or AutofillProfile. This is used for
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
index df87843c..84edb01 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -253,41 +253,42 @@
   }
 
   void ExpectAddressesDiffInHistograms(int added, int removed) {
-    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddressesAdded",
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddresses.Added",
                                          /*bucket=*/added,
                                          /*count=*/1);
-    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddressesRemoved",
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletAddresses.Removed",
                                          /*bucket=*/removed,
                                          /*count=*/1);
     histogram_tester_.ExpectUniqueSample(
-        "Autofill.WalletAddressesAddedOrRemoved",
+        "Autofill.WalletAddresses.AddedOrRemoved",
         /*bucket=*/added + removed,
         /*count=*/1);
   }
 
   void ExpectNoHistogramsForAddressesDiff() {
-    histogram_tester_.ExpectTotalCount("Autofill.WalletAddressesAdded", 0);
-    histogram_tester_.ExpectTotalCount("Autofill.WalletAddressesRemoved", 0);
-    histogram_tester_.ExpectTotalCount("Autofill.WalletAddressesAddedOrRemoved",
-                                       0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletAddresses.Added", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletAddresses.Removed", 0);
+    histogram_tester_.ExpectTotalCount(
+        "Autofill.WalletAddresses.AddedOrRemoved", 0);
   }
 
   void ExpectCardsDiffInHistograms(int added, int removed) {
-    histogram_tester_.ExpectUniqueSample("Autofill.WalletCardsAdded",
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.Added",
                                          /*bucket=*/added,
                                          /*count=*/1);
-    histogram_tester_.ExpectUniqueSample("Autofill.WalletCardsRemoved",
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.Removed",
                                          /*bucket=*/removed,
                                          /*count=*/1);
-    histogram_tester_.ExpectUniqueSample("Autofill.WalletCardsAddedOrRemoved",
+    histogram_tester_.ExpectUniqueSample("Autofill.WalletCards.AddedOrRemoved",
                                          /*bucket=*/added + removed,
                                          /*count=*/1);
   }
 
   void ExpectNoHistogramsForCardsDiff() {
-    histogram_tester_.ExpectTotalCount("Autofill.WalletCardsAdded", 0);
-    histogram_tester_.ExpectTotalCount("Autofill.WalletCardsRemoved", 0);
-    histogram_tester_.ExpectTotalCount("Autofill.WalletCardsAddedOrRemoved", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.Added", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.Removed", 0);
+    histogram_tester_.ExpectTotalCount("Autofill.WalletCards.AddedOrRemoved",
+                                       0);
   }
 
   EntityData SpecificsToEntity(const AutofillWalletSpecifics& specifics) {
@@ -549,8 +550,9 @@
   StartSyncing({});
 
   EXPECT_TRUE(GetAllLocalData().empty());
-  ExpectAddressesDiffInHistograms(/*added=*/0, /*removed=*/1);
-  ExpectCardsDiffInHistograms(/*added=*/0, /*removed=*/1);
+  // No diff metrics reported when new data is empty.
+  ExpectNoHistogramsForAddressesDiff();
+  ExpectNoHistogramsForCardsDiff();
 }
 
 // Test that when the server sends the same address and card as the client has,
@@ -597,6 +599,8 @@
   table()->SetServerProfiles({profile, profile2});
   CreditCard card = test::GetMaskedServerCard();
   table()->SetServerCreditCards({card});
+  PaymentsCustomerData customer_data{/*customer_id=*/kCustomerDataId};
+  table()->SetPaymentsCustomerData(&customer_data);
 
   // Create one of the same profiles and a different card on the server.
   AutofillWalletSpecifics profile_specifics;
@@ -605,6 +609,9 @@
   CreditCard card2 = test::GetMaskedServerCardAmex();
   AutofillWalletSpecifics card2_specifics;
   SetAutofillWalletSpecificsFromServerCard(card2, &card2_specifics);
+  AutofillWalletSpecifics customer_data_specifics;
+  SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
+                                                     &customer_data_specifics);
 
   EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
   EXPECT_CALL(*backend(),
@@ -612,12 +619,13 @@
   EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(RemoveChange(card.guid())));
   EXPECT_CALL(*backend(),
               NotifyOfCreditCardChanged(AddChange(card2.guid(), card2)));
-  StartSyncing({profile_specifics, card2_specifics});
+  StartSyncing({profile_specifics, card2_specifics, customer_data_specifics});
 
   // Make sure that the client only has the data from the server.
   EXPECT_THAT(GetAllLocalData(),
               UnorderedElementsAre(EqualsSpecifics(profile_specifics),
-                                   EqualsSpecifics(card2_specifics)));
+                                   EqualsSpecifics(card2_specifics),
+                                   EqualsSpecifics(customer_data_specifics)));
   ExpectAddressesDiffInHistograms(/*added=*/0, /*removed=*/1);
   ExpectCardsDiffInHistograms(/*added=*/1, /*removed=*/1);
 }
@@ -744,8 +752,9 @@
       std::make_unique<syncer::InMemoryMetadataChangeList>());
 
   EXPECT_TRUE(GetAllLocalData().empty());
-  ExpectAddressesDiffInHistograms(/*added=*/0, /*removed=*/1);
-  ExpectCardsDiffInHistograms(/*added=*/0, /*removed=*/1);
+  // No diff metrics reported when clearing data.
+  ExpectNoHistogramsForAddressesDiff();
+  ExpectNoHistogramsForCardsDiff();
 }
 
 TEST_F(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_KeepData) {
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
index 6d86082..211c6f15 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
@@ -213,8 +213,7 @@
     std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) {
   DCHECK(thread_checker_.CalledOnValidThread());
   sync_processor_ = std::move(sync_processor);
-  syncer::SyncMergeResult result =
-      SetSyncData(initial_sync_data, /*is_initial_data=*/true);
+  syncer::SyncMergeResult result = SetSyncData(initial_sync_data);
   if (webdata_backend_)
     webdata_backend_->NotifyThatSyncHasStarted(type);
   return result;
@@ -240,8 +239,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   // Don't bother handling incremental updates. Wallet data changes very rarely
   // and has few items. Instead, just get all the current data and save it.
-  SetSyncData(sync_processor_->GetAllSyncData(syncer::AUTOFILL_WALLET_DATA),
-              /*is_initial_data=*/false);
+  SetSyncData(sync_processor_->GetAllSyncData(syncer::AUTOFILL_WALLET_DATA));
   return syncer::SyncError();
 }
 
@@ -342,8 +340,7 @@
 }
 
 syncer::SyncMergeResult AutofillWalletSyncableService::SetSyncData(
-    const syncer::SyncDataList& data_list,
-    bool is_initial_data) {
+    const syncer::SyncDataList& data_list) {
   std::vector<CreditCard> wallet_cards;
   std::vector<AutofillProfile> wallet_addresses;
   std::vector<PaymentsCustomerData> customer_data;
@@ -362,6 +359,7 @@
   // to the database will require at least one DB page write and will schedule
   // a fsync. To avoid this I/O, it should be more efficient to do a read and
   // only do the writes if something changed.
+
   std::vector<std::unique_ptr<CreditCard>> existing_cards;
   table->GetServerCreditCards(&existing_cards);
   Diff cards_diff = ComputeDiff(existing_cards, wallet_cards);
@@ -380,30 +378,44 @@
   merge_result.set_num_items_after_association(
       static_cast<int>(wallet_cards.size() + wallet_addresses.size()));
 
+  // We report the diff to metrics only if this is an incremental change where
+  // the user had sync set-up (having PaymentsCustomerData is a pre-requisite
+  // for having any other data) and continues to have sync set-up (continuing
+  // having a PaymentsCustomerData entity). As a side effect, this excludes
+  // reporting diffs for users that newly got a GPay account and sync
+  // PaymentsCustomerData for the first time but this is the best we can do to
+  // have the metrics consistent with USS implementation.
+  bool should_report_diff;
+
   if (customer_data.empty()) {
     // Clears the data only.
     table->SetPaymentsCustomerData(nullptr);
+    should_report_diff = false;
   } else {
+    std::unique_ptr<PaymentsCustomerData> existing_entry;
+    table->GetPaymentsCustomerData(&existing_entry);
+    should_report_diff = existing_entry != nullptr;
+
     // In case there were multiple entries (and there shouldn't!), we take the
     // first entry in the vector.
     DCHECK_EQ(1u, customer_data.size());
     table->SetPaymentsCustomerData(&customer_data.front());
   }
 
-  if (!is_initial_data) {
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAdded",
+  if (should_report_diff) {
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.Added",
                              cards_diff.items_added);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsRemoved",
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.Removed",
                              cards_diff.items_removed);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAddedOrRemoved",
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCards.AddedOrRemoved",
                              cards_diff.items_added + cards_diff.items_removed);
 
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddressesAdded",
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddresses.Added",
                              addresses_diff.items_added);
-    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddressesRemoved",
+    UMA_HISTOGRAM_COUNTS_100("Autofill.WalletAddresses.Removed",
                              addresses_diff.items_removed);
     UMA_HISTOGRAM_COUNTS_100(
-        "Autofill.WalletAddressesAddedOrRemoved",
+        "Autofill.WalletAddresses.AddedOrRemoved",
         addresses_diff.items_added + addresses_diff.items_removed);
   }
 
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
index bcaa296..256d1a5 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
+++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
@@ -102,8 +102,7 @@
   static Diff ComputeDiff(const std::vector<std::unique_ptr<Item>>& old_data,
                           const std::vector<Item>& new_data);
 
-  syncer::SyncMergeResult SetSyncData(const syncer::SyncDataList& data_list,
-                                      bool is_initial_data);
+  syncer::SyncMergeResult SetSyncData(const syncer::SyncDataList& data_list);
 
   // Populates the wallet datatypes from the sync data and uses the sync data to
   // link the card to its billing address.
diff --git a/components/autofill_assistant/browser/actions/get_payment_information_action.cc b/components/autofill_assistant/browser/actions/get_payment_information_action.cc
index 5498cc4..408e009 100644
--- a/components/autofill_assistant/browser/actions/get_payment_information_action.cc
+++ b/components/autofill_assistant/browser/actions/get_payment_information_action.cc
@@ -123,6 +123,8 @@
     processed_action_proto_->mutable_payment_details()
         ->set_is_terms_and_conditions_accepted(
             payment_information->is_terms_and_conditions_accepted);
+    processed_action_proto_->mutable_payment_details()->set_payer_email(
+        payment_information->payer_email);
   }
 
   UpdateProcessedAction(succeed ? ACTION_APPLIED : PAYMENT_REQUEST_ERROR);
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc
index d861f3b..a1c7b668 100644
--- a/components/autofill_assistant/browser/protocol_utils.cc
+++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -79,32 +79,38 @@
 
   scripts->clear();
   for (const auto& script_proto : response_proto.scripts()) {
-    auto script = std::make_unique<Script>();
-    script->handle.path = script_proto.path();
-
-    const auto& presentation = script_proto.presentation();
-    script->handle.name = presentation.name();
-    script->handle.autostart = presentation.autostart();
-    script->handle.interrupt = presentation.interrupt();
-    script->handle.initial_prompt = presentation.initial_prompt();
-    script->handle.highlight = presentation.highlight();
-    script->precondition = ScriptPrecondition::FromProto(
-        script_proto.path(), presentation.precondition());
-    script->priority = presentation.priority();
-
-    if (script->handle.path.empty() || !script->precondition ||
-        (script->handle.name.empty() && !script->handle.interrupt)) {
-      LOG(ERROR) << "Ignored invalid or incomplete script '"
-                 << script->handle.path << "'";
-      continue;
-    }
-    scripts->emplace_back(std::move(script));
+    ProtocolUtils::AddScript(script_proto, scripts);
   }
 
   return true;
 }
 
 // static
+void ProtocolUtils::AddScript(const SupportedScriptProto& script_proto,
+                              std::vector<std::unique_ptr<Script>>* scripts) {
+  auto script = std::make_unique<Script>();
+  script->handle.path = script_proto.path();
+
+  const auto& presentation = script_proto.presentation();
+  script->handle.name = presentation.name();
+  script->handle.autostart = presentation.autostart();
+  script->handle.interrupt = presentation.interrupt();
+  script->handle.initial_prompt = presentation.initial_prompt();
+  script->handle.highlight = presentation.highlight();
+  script->precondition = ScriptPrecondition::FromProto(
+      script_proto.path(), presentation.precondition());
+  script->priority = presentation.priority();
+
+  if (script->handle.path.empty() || !script->precondition ||
+      (script->handle.name.empty() && !script->handle.interrupt)) {
+    LOG(ERROR) << "Ignored invalid or incomplete script '"
+               << script->handle.path << "'";
+    return;
+  }
+  scripts->emplace_back(std::move(script));
+}
+
+// static
 std::string ProtocolUtils::CreateInitialScriptActionsRequest(
     const std::string& script_path,
     const GURL& url,
@@ -160,12 +166,14 @@
 }
 
 // static
-bool ProtocolUtils::ParseActions(
-    const std::string& response,
-    std::string* return_global_payload,
-    std::string* return_script_payload,
-    std::vector<std::unique_ptr<Action>>* actions) {
+bool ProtocolUtils::ParseActions(const std::string& response,
+                                 std::string* return_global_payload,
+                                 std::string* return_script_payload,
+                                 std::vector<std::unique_ptr<Action>>* actions,
+                                 std::vector<std::unique_ptr<Script>>* scripts,
+                                 bool* should_update_scripts) {
   DCHECK(actions);
+  DCHECK(scripts);
 
   ActionsResponseProto response_proto;
   if (!response_proto.ParseFromString(response)) {
@@ -263,6 +271,12 @@
     }
   }
 
+  *should_update_scripts = response_proto.has_update_script_list();
+  for (const auto& script_proto :
+       response_proto.update_script_list().scripts()) {
+    ProtocolUtils::AddScript(script_proto, scripts);
+  }
+
   return true;
 }
 
diff --git a/components/autofill_assistant/browser/protocol_utils.h b/components/autofill_assistant/browser/protocol_utils.h
index 1d58b2a..aa977cc 100644
--- a/components/autofill_assistant/browser/protocol_utils.h
+++ b/components/autofill_assistant/browser/protocol_utils.h
@@ -40,6 +40,11 @@
   static bool ParseScripts(const std::string& response,
                            std::vector<std::unique_ptr<Script>>* scripts);
 
+  // Convert |script_proto| to a script struct and if the script is valid, add
+  // it to |scripts|.
+  static void AddScript(const SupportedScriptProto& script_proto,
+                        std::vector<std::unique_ptr<Script>>* scripts);
+
   // Create initial request to get script actions for the given |script_path|.
   //
   // TODO(b/806868): Remove the script payload from initial requests once the
@@ -63,12 +68,17 @@
   //
   // Pass in nullptr for |return_global_payload| or |return_script_payload| to
   // indicate no need to return that payload. Parsed actions are returned
-  // through |actions|, which should not be nullptr. Return false if parse
-  // failed, otherwise return true.
+  // through |actions|, which should not be nullptr. Optionally, parsed scripts
+  // are returned through |scripts| and used to update the list of cached
+  // scripts. The bool |should_update_scripts| makes clear the destinction
+  // between an empty list of |scripts| or the scripts field not even set in the
+  // proto. Return false if parse failed, otherwise return true.
   static bool ParseActions(const std::string& response,
                            std::string* return_global_payload,
                            std::string* return_script_payload,
-                           std::vector<std::unique_ptr<Action>>* actions);
+                           std::vector<std::unique_ptr<Action>>* actions,
+                           std::vector<std::unique_ptr<Script>>* scripts,
+                           bool* should_update_scripts);
 
  private:
   // To avoid instantiate this class by accident.
diff --git a/components/autofill_assistant/browser/protocol_utils_unittest.cc b/components/autofill_assistant/browser/protocol_utils_unittest.cc
index 37a39bf..185cf717 100644
--- a/components/autofill_assistant/browser/protocol_utils_unittest.cc
+++ b/components/autofill_assistant/browser/protocol_utils_unittest.cc
@@ -12,10 +12,11 @@
 namespace autofill_assistant {
 namespace {
 
-using ::testing::SizeIs;
-using ::testing::Not;
-using ::testing::IsEmpty;
 using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::Not;
+using ::testing::SizeIs;
 
 ClientContextProto CreateClientContextProto() {
   ClientContextProto context;
@@ -142,5 +143,112 @@
   EXPECT_EQ("d", request.script_parameters(1).value());
 }
 
+TEST(ProtocolUtilsTest, AddScriptIgnoreInvalid) {
+  SupportedScriptProto script_proto;
+  std::vector<std::unique_ptr<Script>> scripts;
+  ProtocolUtils::AddScript(script_proto, &scripts);
+  EXPECT_TRUE(scripts.empty());
+}
+
+TEST(ProtocolUtilsTest, AddScriptValid) {
+  SupportedScriptProto script_proto;
+  script_proto.set_path("path");
+  auto* presentation = script_proto.mutable_presentation();
+  presentation->set_name("name");
+  presentation->set_autostart(true);
+  presentation->set_initial_prompt("prompt");
+  presentation->mutable_precondition()->add_domain("www.example.com");
+
+  std::vector<std::unique_ptr<Script>> scripts;
+  ProtocolUtils::AddScript(script_proto, &scripts);
+  std::unique_ptr<Script> script = std::move(scripts[0]);
+
+  EXPECT_NE(nullptr, script);
+  EXPECT_EQ("path", script->handle.path);
+  EXPECT_EQ("name", script->handle.name);
+  EXPECT_EQ("prompt", script->handle.initial_prompt);
+  EXPECT_TRUE(script->handle.autostart);
+  EXPECT_NE(nullptr, script->precondition);
+}
+
+TEST(ProtocolUtilsTest, ParseActionsParseError) {
+  bool unused;
+  std::vector<std::unique_ptr<Action>> unused_actions;
+  std::vector<std::unique_ptr<Script>> unused_scripts;
+  EXPECT_FALSE(ProtocolUtils::ParseActions(
+      "invalid", nullptr, nullptr, &unused_actions, &unused_scripts, &unused));
+}
+
+TEST(ProtocolUtilsTest, ParseActionsValid) {
+  ActionsResponseProto proto;
+  proto.set_global_payload("global_payload");
+  proto.set_script_payload("script_payload");
+  proto.add_actions()->mutable_tell();
+  proto.add_actions()->mutable_click();
+
+  std::string proto_str;
+  proto.SerializeToString(&proto_str);
+
+  std::string global_payload;
+  std::string script_payload;
+  bool should_update_scripts = true;
+  std::vector<std::unique_ptr<Action>> actions;
+  std::vector<std::unique_ptr<Script>> scripts;
+
+  EXPECT_TRUE(ProtocolUtils::ParseActions(proto_str, &global_payload,
+                                          &script_payload, &actions, &scripts,
+                                          &should_update_scripts));
+  EXPECT_EQ("global_payload", global_payload);
+  EXPECT_EQ("script_payload", script_payload);
+  EXPECT_THAT(actions, SizeIs(2));
+  EXPECT_FALSE(should_update_scripts);
+  EXPECT_TRUE(scripts.empty());
+}
+
+TEST(ProtocolUtilsTest, ParseActionsEmptyUpdateScriptList) {
+  ActionsResponseProto proto;
+  proto.mutable_update_script_list();
+
+  std::string proto_str;
+  proto.SerializeToString(&proto_str);
+
+  bool should_update_scripts = false;
+  std::vector<std::unique_ptr<Script>> scripts;
+  std::vector<std::unique_ptr<Action>> unused_actions;
+
+  EXPECT_TRUE(ProtocolUtils::ParseActions(
+      proto_str, /* global_payload= */ nullptr, /* script_payload */ nullptr,
+      &unused_actions, &scripts, &should_update_scripts));
+  EXPECT_TRUE(should_update_scripts);
+  EXPECT_TRUE(scripts.empty());
+}
+
+TEST(ProtocolUtilsTest, ParseActionsUpdateScriptListFullFeatured) {
+  ActionsResponseProto proto;
+  auto* script_list = proto.mutable_update_script_list();
+  auto* script_a = script_list->add_scripts();
+  script_a->set_path("a");
+  auto* presentation = script_a->mutable_presentation();
+  presentation->set_name("name");
+  presentation->mutable_precondition();
+  // One invalid script.
+  script_list->add_scripts();
+
+  std::string proto_str;
+  proto.SerializeToString(&proto_str);
+
+  bool should_update_scripts = false;
+  std::vector<std::unique_ptr<Script>> scripts;
+  std::vector<std::unique_ptr<Action>> unused_actions;
+
+  EXPECT_TRUE(ProtocolUtils::ParseActions(
+      proto_str, /* global_payload= */ nullptr, /* script_payload= */ nullptr,
+      &unused_actions, &scripts, &should_update_scripts));
+  EXPECT_TRUE(should_update_scripts);
+  EXPECT_THAT(scripts, SizeIs(1));
+  EXPECT_THAT("a", Eq(scripts[0]->handle.path));
+  EXPECT_THAT("name", Eq(scripts[0]->handle.name));
+}
+
 }  // namespace
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 5a122ee..580641c 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -312,13 +312,20 @@
   processed_actions_.clear();
   actions_.clear();
 
+  bool should_update_scripts = false;
+  std::vector<std::unique_ptr<Script>> scripts;
   bool parse_result = ProtocolUtils::ParseActions(
-      response, &last_global_payload_, &last_script_payload_, &actions_);
+      response, &last_global_payload_, &last_script_payload_, &actions_,
+      &scripts, &should_update_scripts);
+
   if (!parse_result) {
     RunCallback(false);
     return;
   }
   ReportPayloadsToListener();
+  if (should_update_scripts) {
+    ReportScriptsUpdateToListener(std::move(scripts));
+  }
 
   if (actions_.empty()) {
     // Finished executing the script if there are no more actions.
@@ -336,6 +343,14 @@
   listener_->OnServerPayloadChanged(last_global_payload_, last_script_payload_);
 }
 
+void ScriptExecutor::ReportScriptsUpdateToListener(
+    std::vector<std::unique_ptr<Script>> scripts) {
+  if (!listener_)
+    return;
+
+  listener_->OnScriptListChanged(std::move(scripts));
+}
+
 void ScriptExecutor::RunCallback(bool success) {
   DCHECK(callback_);
   if (should_clean_contextual_ui_on_finish_ || !success) {
@@ -506,6 +521,11 @@
   main_script_->ReportPayloadsToListener();
 }
 
+void ScriptExecutor::WaitWithInterrupts::OnScriptListChanged(
+    std::vector<std::unique_ptr<Script>> scripts) {
+  main_script_->ReportScriptsUpdateToListener(std::move(scripts));
+}
+
 void ScriptExecutor::WaitWithInterrupts::OnPreconditionCheckDone(
     const Script* interrupt,
     bool precondition_match) {
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index 9ad36f0..d36cda8 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -37,6 +37,10 @@
     // transitioned to global payloads.
     virtual void OnServerPayloadChanged(const std::string& global_payload,
                                         const std::string& script_payload) = 0;
+
+    // Called when an update list of scripts is available.
+    virtual void OnScriptListChanged(
+        std::vector<std::unique_ptr<Script>> scripts) = 0;
   };
 
   // |delegate|, |listener|, |script_state| and |ordered_interrupts| should
@@ -180,6 +184,8 @@
     // Implements ScriptExecutor::Listener
     void OnServerPayloadChanged(const std::string& global_payload,
                                 const std::string& script_payload) override;
+    void OnScriptListChanged(
+        std::vector<std::unique_ptr<Script>> scripts) override;
 
     void OnPreconditionCheckDone(const Script* interrupt,
                                  bool precondition_match);
@@ -230,6 +236,8 @@
 
   void OnGetActions(bool result, const std::string& response);
   void ReportPayloadsToListener();
+  void ReportScriptsUpdateToListener(
+      std::vector<std::unique_ptr<Script>> scripts);
   void RunCallback(bool success);
   void RunCallbackWithResult(const Result& result);
   void ProcessNextAction();
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc
index 52d1bbc..28d7eb2 100644
--- a/components/autofill_assistant/browser/script_executor_unittest.cc
+++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -35,6 +35,7 @@
 using ::testing::Pair;
 using ::testing::ReturnRef;
 using ::testing::SaveArg;
+using ::testing::SizeIs;
 using ::testing::StrEq;
 using ::testing::StrictMock;
 
@@ -105,6 +106,13 @@
     last_script_payload_ = script_payload;
   }
 
+  void OnScriptListChanged(
+      std::vector<std::unique_ptr<Script>> scripts) override {
+    should_update_scripts_ = true;
+    scripts_update_ = std::move(scripts);
+    ++scripts_update_count_;
+  }
+
   std::string Serialize(const google::protobuf::MessageLite& message) {
     std::string output;
     message.SerializeToString(&output);
@@ -170,6 +178,9 @@
   std::vector<Script*> ordered_interrupts_;
   std::string last_global_payload_;
   std::string last_script_payload_;
+  bool should_update_scripts_ = false;
+  std::vector<std::unique_ptr<Script>> scripts_update_;
+  int scripts_update_count_ = 0;
   std::unique_ptr<ScriptExecutor> executor_;
   std::map<std::string, std::string> parameters_;
   StrictMock<base::MockCallback<ScriptExecutor::RunScriptCallback>>
@@ -717,5 +728,114 @@
               Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS)));
 }
 
+TEST_F(ScriptExecutorTest, UpdateScriptListGetNext) {
+  should_update_scripts_ = false;
+  scripts_update_.clear();
+  scripts_update_count_ = 0;
+
+  ActionsResponseProto initial_actions_response;
+  initial_actions_response.add_actions()->mutable_tell()->set_message("1");
+  EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _))
+      .WillOnce(RunOnceCallback<5>(true, Serialize(initial_actions_response)));
+
+  ActionsResponseProto next_actions_response;
+  next_actions_response.add_actions()->mutable_tell()->set_message("2");
+  auto* script =
+      next_actions_response.mutable_update_script_list()->add_scripts();
+  script->set_path("path");
+  auto* presentation = script->mutable_presentation();
+  presentation->set_name("name");
+  presentation->mutable_precondition();
+
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _))
+      .WillOnce(RunOnceCallback<3>(true, Serialize(next_actions_response)))
+      .WillOnce(RunOnceCallback<3>(true, ""));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  executor_->Run(executor_callback_.Get());
+
+  EXPECT_TRUE(should_update_scripts_);
+  EXPECT_THAT(scripts_update_, SizeIs(1));
+  EXPECT_THAT(scripts_update_count_, Eq(1));
+  EXPECT_THAT("path", scripts_update_[0]->handle.path);
+  EXPECT_THAT("name", scripts_update_[0]->handle.name);
+}
+
+TEST_F(ScriptExecutorTest, UpdateScriptListShouldNotifyMultipleTimes) {
+  should_update_scripts_ = false;
+  scripts_update_.clear();
+  scripts_update_count_ = 0;
+
+  ActionsResponseProto actions_response;
+  actions_response.add_actions()->mutable_tell()->set_message("hi");
+  auto* script = actions_response.mutable_update_script_list()->add_scripts();
+  script->set_path("path");
+  auto* presentation = script->mutable_presentation();
+  presentation->set_name("name");
+  presentation->mutable_precondition();
+
+  EXPECT_CALL(mock_service_, OnGetActions(StrEq(kScriptPath), _, _, _, _, _))
+      .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response)));
+
+  script->set_path("path2");
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _))
+      .WillOnce(RunOnceCallback<3>(true, Serialize(actions_response)))
+      .WillOnce(RunOnceCallback<3>(true, ""));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  executor_->Run(executor_callback_.Get());
+
+  EXPECT_TRUE(should_update_scripts_);
+  EXPECT_THAT(scripts_update_count_, Eq(2));
+  EXPECT_THAT(scripts_update_, SizeIs(1));
+  EXPECT_THAT("path2", scripts_update_[0]->handle.path);
+}
+
+TEST_F(ScriptExecutorTest, UpdateScriptListFromInterrupt) {
+  should_update_scripts_ = false;
+  scripts_update_.clear();
+  scripts_update_count_ = 0;
+
+  SetupInterruptibleScript(kScriptPath, "element");
+
+  RegisterInterrupt("interrupt", "interrupt_trigger");
+  ActionsResponseProto interrupt_actions;
+  interrupt_actions.add_actions()->mutable_tell()->set_message("abc");
+
+  EXPECT_CALL(mock_service_, OnGetActions(StrEq("interrupt"), _, _, _, _, _))
+      .WillOnce(RunOnceCallback<5>(true, Serialize(interrupt_actions)));
+
+  auto* script = interrupt_actions.mutable_update_script_list()->add_scripts();
+  script->set_path("path");
+  auto* presentation = script->mutable_presentation();
+  presentation->set_name("update_from_interrupt");
+  presentation->mutable_precondition();
+
+  // We expect a call from the interrupt which will update the script list and a
+  // second call from the interrupt to terminate. Then a call from the main
+  // script which will finish without running any actions.
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _))
+      .Times(3)
+      .WillOnce(RunOnceCallback<3>(true, Serialize(interrupt_actions)))
+      .WillRepeatedly(RunOnceCallback<3>(true, ""));
+
+  EXPECT_CALL(executor_callback_,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  executor_->Run(executor_callback_.Get());
+
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair(kScriptPath, SCRIPT_STATUS_SUCCESS)));
+  EXPECT_THAT(scripts_state_,
+              Contains(Pair("interrupt", SCRIPT_STATUS_SUCCESS)));
+
+  EXPECT_TRUE(should_update_scripts_);
+  EXPECT_THAT(scripts_update_, SizeIs(1));
+  EXPECT_THAT(scripts_update_count_, Eq(1));
+  EXPECT_THAT("path", scripts_update_[0]->handle.path);
+  EXPECT_THAT("update_from_interrupt", scripts_update_[0]->handle.name);
+}
+
 }  // namespace
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_tracker.cc b/components/autofill_assistant/browser/script_tracker.cc
index a723484b..62ea8cd3 100644
--- a/components/autofill_assistant/browser/script_tracker.cc
+++ b/components/autofill_assistant/browser/script_tracker.cc
@@ -183,9 +183,17 @@
     ScriptExecutor::RunScriptCallback original_callback,
     const ScriptExecutor::Result& result) {
   executor_.reset();
+  MaybeSwapInScripts();
   std::move(original_callback).Run(result);
 }
 
+void ScriptTracker::MaybeSwapInScripts() {
+  if (scripts_update_) {
+    SetScripts(std::move(*scripts_update_));
+    scripts_update_.reset();
+  }
+}
+
 void ScriptTracker::UpdateRunnableScriptsIfNecessary() {
   if (!RunnablesHaveChanged())
     return;
@@ -240,4 +248,10 @@
   last_script_payload_ = script_payload;
 }
 
+void ScriptTracker::OnScriptListChanged(
+    std::vector<std::unique_ptr<Script>> scripts) {
+  scripts_update_.reset(
+      new std::vector<std::unique_ptr<Script>>(std::move(scripts)));
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_tracker.h b/components/autofill_assistant/browser/script_tracker.h
index 90ad7b7..efa62fc7 100644
--- a/components/autofill_assistant/browser/script_tracker.h
+++ b/components/autofill_assistant/browser/script_tracker.h
@@ -113,9 +113,15 @@
   void UpdateRunnableScriptsIfNecessary();
   void OnCheckDone();
 
+  // Updates the list of available scripts if there is a pending update from
+  // when a script was still being executed.
+  void MaybeSwapInScripts();
+
   // Overrides ScriptExecutor::Listener.
   void OnServerPayloadChanged(const std::string& global_payload,
                               const std::string& script_payload) override;
+  void OnScriptListChanged(
+      std::vector<std::unique_ptr<Script>> scripts) override;
 
   // Stops running pending checks and cleans up any state used by pending
   // checks. This can safely be called at any time, including when no checks are
@@ -167,6 +173,10 @@
   std::string last_global_payload_;
   std::string last_script_payload_;
 
+  // List of scripts to replace the currently available scripts. The replacement
+  // only occurse when |scripts_update| is not nullptr.
+  std::unique_ptr<std::vector<std::unique_ptr<Script>>> scripts_update_;
+
   base::WeakPtrFactory<ScriptTracker> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ScriptTracker);
diff --git a/components/autofill_assistant/browser/script_tracker_unittest.cc b/components/autofill_assistant/browser/script_tracker_unittest.cc
index c276fc61b..445a39cf 100644
--- a/components/autofill_assistant/browser/script_tracker_unittest.cc
+++ b/components/autofill_assistant/browser/script_tracker_unittest.cc
@@ -26,6 +26,8 @@
 using ::testing::NiceMock;
 using ::testing::ReturnRef;
 using ::testing::SizeIs;
+using ::testing::StrEq;
+using ::testing::StrictMock;
 using ::testing::UnorderedElementsAre;
 
 class ScriptTrackerTest : public testing::Test,
@@ -116,12 +118,6 @@
     return script;
   }
 
-  static SupportedScriptProto* AddRunnableScript(
-      SupportsScriptResponseProto* response,
-      const std::string& name_and_path) {
-    return AddScript(response, name_and_path, name_and_path, "exists");
-  }
-
   const std::vector<ScriptHandle>& runnable_scripts() {
     return runnable_scripts_;
   }
@@ -134,6 +130,12 @@
     return paths;
   }
 
+  std::string Serialize(const google::protobuf::MessageLite& message) {
+    std::string output;
+    message.SerializeToString(&output);
+    return output;
+  }
+
   GURL url_;
   NiceMock<MockService> mock_service_;
   NiceMock<MockWebController> mock_web_controller_;
@@ -322,4 +324,89 @@
   ASSERT_THAT(runnable_script_paths(), ElementsAre("script path"));
 }
 
+TEST_F(ScriptTrackerTest, UpdateScriptList) {
+  // 1. Initialize runnable scripts with a single valid script.
+  SupportsScriptResponseProto scripts;
+  AddScript(&scripts, "runnable name", "runnable path", "exists");
+  SetAndCheckScripts(scripts);
+
+  EXPECT_EQ(1, runnable_scripts_changed_);
+  ASSERT_THAT(runnable_scripts(), SizeIs(1));
+  EXPECT_EQ("runnable name", runnable_scripts()[0].name);
+  EXPECT_EQ("runnable path", runnable_scripts()[0].path);
+
+  // 2. Run the action and trigger a script list update.
+  ActionsResponseProto actions_response;
+  actions_response.add_actions()->mutable_tell()->set_message("hi");
+
+  *actions_response.mutable_update_script_list()->add_scripts() =
+      *AddScript(&scripts, "update name", "update path", "exists");
+  *actions_response.mutable_update_script_list()->add_scripts() =
+      *AddScript(&scripts, "update name 2", "update path 2", "exists");
+
+  EXPECT_CALL(mock_service_,
+              OnGetActions(StrEq("runnable name"), _, _, _, _, _))
+      .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response)));
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _))
+      .WillOnce(RunOnceCallback<3>(true, ""));
+
+  base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback;
+  EXPECT_CALL(execute_callback,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  tracker_.ExecuteScript("runnable name", execute_callback.Get());
+  tracker_.CheckScripts(base::TimeDelta::FromSeconds(0));
+
+  // 3. Verify that the runnable scripts have changed to the updated list.
+  EXPECT_EQ(2, runnable_scripts_changed_);
+  ASSERT_THAT(runnable_scripts(), SizeIs(2));
+  EXPECT_EQ("update name", runnable_scripts()[0].name);
+  EXPECT_EQ("update path", runnable_scripts()[0].path);
+  EXPECT_EQ("update name 2", runnable_scripts()[1].name);
+  EXPECT_EQ("update path 2", runnable_scripts()[1].path);
+}
+
+TEST_F(ScriptTrackerTest, UpdateScriptListFromInterrupt) {
+  // 1. Initialize runnable scripts with a single valid interrupt script.
+  SupportsScriptResponseProto scripts;
+  auto* script =
+      AddScript(&scripts, "runnable name", "runnable path", "exists");
+  script->mutable_presentation()->set_interrupt(true);
+  SetAndCheckScripts(scripts);
+
+  EXPECT_EQ(1, runnable_scripts_changed_);
+  ASSERT_THAT(runnable_scripts(), SizeIs(1));
+  EXPECT_EQ("runnable name", runnable_scripts()[0].name);
+  EXPECT_EQ("runnable path", runnable_scripts()[0].path);
+
+  // 2. Run the interrupt action and trigger a script list update from an
+  // interrupt.
+  ActionsResponseProto actions_response;
+  actions_response.add_actions()->mutable_tell()->set_message("hi");
+
+  *actions_response.mutable_update_script_list()->add_scripts() =
+      *AddScript(&scripts, "update name", "update path", "exists");
+  *actions_response.mutable_update_script_list()->add_scripts() =
+      *AddScript(&scripts, "update name 2", "update path 2", "exists");
+
+  EXPECT_CALL(mock_service_,
+              OnGetActions(StrEq("runnable name"), _, _, _, _, _))
+      .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response)));
+  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _))
+      .WillOnce(RunOnceCallback<3>(true, ""));
+
+  base::MockCallback<ScriptExecutor::RunScriptCallback> execute_callback;
+  EXPECT_CALL(execute_callback,
+              Run(Field(&ScriptExecutor::Result::success, true)));
+  tracker_.ExecuteScript("runnable name", execute_callback.Get());
+  tracker_.CheckScripts(base::TimeDelta::FromSeconds(0));
+
+  // 3. Verify that the runnable scripts have changed to the updated list.
+  EXPECT_EQ(2, runnable_scripts_changed_);
+  ASSERT_THAT(runnable_scripts(), SizeIs(2));
+  EXPECT_EQ("update name", runnable_scripts()[0].name);
+  EXPECT_EQ("update path", runnable_scripts()[0].path);
+  EXPECT_EQ("update name 2", runnable_scripts()[1].name);
+  EXPECT_EQ("update path 2", runnable_scripts()[1].path);
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 653f45c..2c31f30 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -216,6 +216,19 @@
   // Actions to be performed in order.
   // Should stop processing as soon as an action fails.
   repeated ActionProto actions = 3;
+
+  // List of scripts to update.
+  //
+  // The client is expected to update the cache of scripts with this new
+  // information. No action is needed when this field is not set. If the field
+  // is set with an empty list of scripts, then no script is eligible to run
+  // anymore.
+  //
+  // Note: This is an intermediate solution and the logic associated with this
+  // field will eventually be absorbed into the supports script response from
+  // the backend.
+  message UpdateScriptListProto { repeated SupportedScriptProto scripts = 1; }
+  optional UpdateScriptListProto update_script_list = 5;
 }
 
 // An action could be performed.
@@ -259,6 +272,8 @@
   optional string card_issuer_network = 1;
   // Whether the integrated terms and conditions approval checkbox was checked.
   optional bool is_terms_and_conditions_accepted = 2;
+  // The email address of the payer.
+  optional string payer_email = 3;
 }
 
 message ProcessedActionProto {
diff --git a/components/blacklist/opt_out_blacklist/opt_out_blacklist_unittest.cc b/components/blacklist/opt_out_blacklist/opt_out_blacklist_unittest.cc
index 44fa9f6..2967635e 100644
--- a/components/blacklist/opt_out_blacklist/opt_out_blacklist_unittest.cc
+++ b/components/blacklist/opt_out_blacklist/opt_out_blacklist_unittest.cc
@@ -15,11 +15,11 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/test/simple_test_clock.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
@@ -271,7 +271,7 @@
   }
 
  protected:
-  base::MessageLoop loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
   // Observer to |black_list_|.
   TestOptOutBlacklistDelegate blacklist_delegate_;
diff --git a/components/blacklist/opt_out_blacklist/sql/opt_out_store_sql_unittest.cc b/components/blacklist/opt_out_blacklist/sql/opt_out_store_sql_unittest.cc
index 9caad5a..fe8db6a7 100644
--- a/components/blacklist/opt_out_blacklist/sql/opt_out_store_sql_unittest.cc
+++ b/components/blacklist/opt_out_blacklist/sql/opt_out_store_sql_unittest.cc
@@ -13,10 +13,10 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/test/simple_test_clock.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
@@ -93,7 +93,7 @@
   void TearDown() override { DestroyStore(); }
 
  protected:
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
   // The backing SQL store.
   std::unique_ptr<OptOutStoreSQL> store_;
diff --git a/components/browser_sync/sync_auth_manager.cc b/components/browser_sync/sync_auth_manager.cc
index df053436..f2e8be80 100644
--- a/components/browser_sync/sync_auth_manager.cc
+++ b/components/browser_sync/sync_auth_manager.cc
@@ -269,7 +269,25 @@
     return;
   }
 
-  if (!is_valid) {
+  // Compute the validity of the new refresh token: The identity code sets an
+  // account's refresh token to be invalid (error
+  // CREDENTIALS_REJECTED_BY_CLIENT) if the user signs out of that account on
+  // the web.
+  // TODO(blundell): Hide this logic inside IdentityManager.
+  // NOTE: We don't use |is_valid| because we will shortly be eliminating that
+  // parameter. TODO(https://crbug.com/908412): Eliminate that parameter and
+  // this comment.
+  bool is_refresh_token_valid = true;
+  GoogleServiceAuthError token_error =
+      identity_manager_->GetErrorStateOfRefreshTokenForAccount(
+          account_info.account_id);
+  if (token_error == GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+                         GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+                             CREDENTIALS_REJECTED_BY_CLIENT)) {
+    is_refresh_token_valid = false;
+  }
+
+  if (!is_refresh_token_valid) {
     // When the refresh token is replaced by an invalid token, Sync must be
     // stopped immediately, even if the current access token is still valid.
     // This happens e.g. when the user signs out of the web with Dice enabled.
diff --git a/components/consent_auditor/consent_sync_bridge_impl_unittest.cc b/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
index dcb8a486..8bee16056 100644
--- a/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
+++ b/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
@@ -10,8 +10,8 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "components/sync/model/data_batch.h"
 #include "components/sync/model/mock_model_type_change_processor.h"
 #include "components/sync/model/model_type_store_test_util.h"
@@ -154,7 +154,7 @@
   }
 
  private:
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
   std::unique_ptr<ConsentSyncBridgeImpl> bridge_;
 };
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index bc63f8e..4170df2 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/buildflag_header.gni")
 import("//build/config/android/config.gni")
 import("//build/config/android/rules.gni")
+import("//build/config/zip.gni")
 import("//build/util/lastchange.gni")
 import("//build/util/process_version.gni")
 import("//build/util/version.gni")
@@ -50,7 +51,7 @@
   ]
 }
 
-java_library("cronet_jni_registration_java") {
+android_library("cronet_jni_registration_java") {
   srcjar_deps = [ ":cronet_jni_registration" ]
 }
 
@@ -455,7 +456,7 @@
 android_java_prebuilt("package_api_java") {
   jar_path = "$_package_dir/cronet_api.jar"
   deps = [
-    ":copy_cronet_java8_jars_cronet_api_javaX",
+    ":repackage_api",
   ]
 }
 
@@ -463,7 +464,7 @@
   jar_path = "$_package_dir/cronet_impl_common_java.jar"
   deps = [
     ":package_api_java",
-    ":repackage_extracted_common_jars",
+    ":repackage_common",
   ]
 }
 
@@ -472,7 +473,7 @@
   deps = [
     ":package_api_java",
     ":package_impl_common_java",
-    ":repackage_extracted_native_jars",
+    ":repackage_native",
     "//third_party/android_deps:android_support_v4_java",
     "//third_party/jsr-305:jsr_305_javalib",
   ]
@@ -481,9 +482,9 @@
 android_java_prebuilt("package_impl_platform_java") {
   jar_path = "$_package_dir/cronet_impl_platform_java.jar"
   deps = [
-    ":copy_cronet_java8_jars_cronet_impl_platform_base_javaX",
     ":package_api_java",
     ":package_impl_common_java",
+    ":repackage_platform",
   ]
 }
 
@@ -584,58 +585,8 @@
   jar_path = "$_package_dir/cronet_impl_platform_java-src.jar"
 }
 
-template("copy_java8_jars") {
-  _deps = []
-  foreach(_dep, invoker.deps) {
-    _dep_name = get_label_info(_dep, "name")
-    _source_jar =
-        get_label_info(_dep, "target_gen_dir") + "/" + _dep_name + ".javac.jar"
-    _output_jar = "$_package_dir/" + _dep_name + ".jar"
-
-    # Adjust file names that are different from the target name that builds it.
-    if (_output_jar == "$_package_dir/" + "cronet_api_java.jar") {
-      _output_jar = "$_package_dir/" + "cronet_api.jar"
-    }
-    if (_output_jar == "$_package_dir/" + "cronet_impl_platform_base_java.jar") {
-      _output_jar = "$_package_dir/" + "cronet_impl_platform_java.jar"
-    }
-
-    # _deps have targets which match the java target whitelist. Add a
-    # trailing X to avoid the copy() target matching the whitelist.
-    # See _java_target_whitelist in build/config/android/internal_rules.gni.
-    _copy_target_name = "${target_name}_${_dep_name}X"
-    copy(_copy_target_name) {
-      sources = [
-        _source_jar,
-      ]
-      outputs = [
-        _output_jar,
-      ]
-      deps = [
-        ":$_dep_name",
-      ]
-    }
-
-    _deps += [ ":" + _copy_target_name ]
-  }
-
-  group(target_name) {
-    deps = _deps
-  }
-}
-
-copy_java8_jars("copy_cronet_java8_jars") {
-  deps = [
-    ":cronet_api_java",
-    ":cronet_impl_platform_base_java",
-  ]
-}
-
-_extract_cronet_native_jars_dir = "$target_gen_dir/cronet_native_jar_extract"
-_extract_cronet_common_jars_dir = "$target_gen_dir/cronet_common_jar_extract"
-
 # List of patterns of .class files to exclude from the jar.
-jar_excluded_patterns = [
+_jar_excluded_patterns = [
   # Excludes Android support libraries crbug.com/832770.
   "android/*",
   "*/library_loader/*.class",
@@ -646,118 +597,43 @@
   "org/chromium/base/memory/MemoryPressureMonitor*.class",
 ]
 
-action("extract_cronet_native_jars") {
-  # extract_from_jars.py deletes the target directory before extracting.
-  script = "//components/cronet/tools/extract_from_jars.py"
-  depfile = "$target_gen_dir/$target_name.d"
-
-  _stamp_file = "$target_gen_dir/$target_name.stamp"
-  outputs = [
-    _stamp_file,
-  ]
-
-  deps = [
-    ":cronet_impl_native_base_java",
-    ":cronet_jni_registration_java",
-  ]
-  deps += cronet_impl_native_java_deps_to_package
-
-  sources = []
-
-  # Extract pre-desugared jar for each dependency.
-  foreach(dep, deps) {
-    sources += [ get_label_info(dep, "target_gen_dir") + "/" +
-                 get_label_info(dep, "name") + ".javac.jar" ]
+template("repackage_jars") {
+  dist_jar(target_name) {
+    requires_android = true
+    direct_deps_only = true
+    use_unprocessed_jars = true
+    no_build_hooks = true
+    forward_variables_from(invoker, "*")
   }
+}
 
-  _rebased_sources = rebase_path(sources, root_build_dir)
-
-  args = [
-    "--classes-dir",
-    rebase_path(_extract_cronet_native_jars_dir, root_build_dir),
-    "--jars=${_rebased_sources}",
-    "--depfile",
-    rebase_path(depfile, root_build_dir),
-    "--stamp",
-    rebase_path(_stamp_file, root_build_dir),
+repackage_jars("repackage_api") {
+  output = "$_package_dir/cronet_api.jar"
+  deps = [
+    ":cronet_api_java",
   ]
 }
 
-action("repackage_extracted_native_jars") {
-  _output_jar = "$_package_dir/cronet_impl_native_java.jar"
-
-  script = "//build/android/gyp/jar.py"
-  outputs = [
-    _output_jar,
-  ]
-
-  args = [
-    "--classes-dir",
-    rebase_path(_extract_cronet_native_jars_dir, root_build_dir),
-    "--excluded-classes=$jar_excluded_patterns",
-    "--jar-path",
-    rebase_path(_output_jar, root_build_dir),
-  ]
-
+repackage_jars("repackage_platform") {
+  output = "$_package_dir/cronet_impl_platform_java.jar"
   deps = [
-    ":extract_cronet_native_jars",
+    ":cronet_impl_platform_base_java",
   ]
 }
 
-action("extract_cronet_common_jars") {
-  # extract_from_jars.py deletes the target directory before extracting.
-  script = "//components/cronet/tools/extract_from_jars.py"
-  depfile = "$target_gen_dir/$target_name.d"
-
-  _stamp_file = "$target_gen_dir/$target_name.stamp"
-  outputs = [
-    _stamp_file,
-  ]
-
-  deps = [
-    ":cronet_impl_common_base_java",
-  ]
-  deps += cronet_impl_common_java_deps_to_package
-
-  sources = []
-
-  # Extract pre-desugared jar for each dependency.
-  foreach(dep, deps) {
-    sources += [ get_label_info(dep, "target_gen_dir") + "/" +
-                 get_label_info(dep, "name") + ".javac.jar" ]
-  }
-
-  _rebased_sources = rebase_path(sources, root_build_dir)
-
-  args = [
-    "--classes-dir",
-    rebase_path(_extract_cronet_common_jars_dir, root_build_dir),
-    "--jars=${_rebased_sources}",
-    "--depfile",
-    rebase_path(depfile, root_build_dir),
-    "--stamp",
-    rebase_path(_stamp_file, root_build_dir),
-  ]
+repackage_jars("repackage_native") {
+  output = "$_package_dir/cronet_impl_native_java.jar"
+  deps = cronet_impl_native_java_deps_to_package + [
+           ":cronet_impl_native_base_java",
+           ":cronet_jni_registration_java",
+         ]
+  jar_excluded_patterns = _jar_excluded_patterns
 }
 
-action("repackage_extracted_common_jars") {
-  _output_jar = "$_package_dir/cronet_impl_common_java.jar"
-
-  script = "//build/android/gyp/jar.py"
-  outputs = [
-    _output_jar,
-  ]
-
-  args = [
-    "--classes-dir",
-    rebase_path(_extract_cronet_common_jars_dir, root_build_dir),
-    "--jar-path",
-    rebase_path(_output_jar, root_build_dir),
-  ]
-
-  deps = [
-    ":extract_cronet_common_jars",
-  ]
+repackage_jars("repackage_common") {
+  output = "$_package_dir/cronet_impl_common_java.jar"
+  deps = cronet_impl_common_java_deps_to_package +
+         [ ":cronet_impl_common_base_java" ]
 }
 
 if (!is_component_build) {
@@ -1251,69 +1127,14 @@
   }
 
   _test_package_dir = "$root_out_dir/cronet/test"
-  _extract_cronet_test_jars_dir = "$target_gen_dir/cronet_test_jar_extract"
 
-  cronet_test_deps = [ ":cronet_javatests" ]
-  cronet_test_deps += cronet_javatests_deps_to_package
-
-  action("extract_cronet_test_jars") {
-    # extract_from_jars.py deletes the target directory before extracting.
-    script = "//components/cronet/tools/extract_from_jars.py"
-    depfile = "$target_gen_dir/$target_name.d"
+  repackage_jars("repackage_test_jars") {
+    output = "$_test_package_dir/cronet_tests_java.jar"
     testonly = true
-
-    sources = [
-      NETTY4_JAR_FILE,
-    ]
-
-    # Extract pre-desugared jar for each cronet_test_deps.
-    foreach(dep, cronet_test_deps) {
-      sources += [ get_label_info(dep, "target_gen_dir") + "/" +
-                   get_label_info(dep, "name") + ".javac.jar" ]
-    }
-
-    _stamp_file = "$target_gen_dir/$target_name.stamp"
-    outputs = [
-      _stamp_file,
-    ]
-
-    _rebased_sources = rebase_path(sources, root_build_dir)
-
-    args = [
-      "--classes-dir",
-      rebase_path(_extract_cronet_test_jars_dir, root_build_dir),
-      "--jars=${_rebased_sources}",
-      "--depfile",
-      rebase_path(depfile, root_build_dir),
-      "--stamp",
-      rebase_path(_stamp_file, root_build_dir),
-    ]
-
-    deps = [
-      "//third_party/netty4:netty_all_java",
-    ]
-    deps += cronet_test_deps
-  }
-
-  action("repackage_extracted_test_jars") {
-    _output_jar = "$_test_package_dir/cronet_tests_java.jar"
-    testonly = true
-
-    script = "//build/android/gyp/jar.py"
-    outputs = [
-      _output_jar,
-    ]
-
-    args = [
-      "--classes-dir",
-      rebase_path(_extract_cronet_test_jars_dir, root_build_dir),
-      "--jar-path",
-      rebase_path(_output_jar, root_build_dir),
-    ]
-
-    deps = [
-      ":extract_cronet_test_jars",
-    ]
+    deps = cronet_javatests_deps_to_package + [
+             ":cronet_javatests",
+             "//third_party/netty4:netty_all_java",
+           ]
   }
 
   zip("jar_cronet_sample_source") {
@@ -1353,7 +1174,7 @@
                     "//net/android:net_android_java_enums_srcjar",
                     "//net/android:net_errors_java",
                   ]
-    excluded_patterns = jar_excluded_patterns
+    excluded_patterns = _jar_excluded_patterns
     jar_path = "$_package_dir/cronet_impl_native_java-src.jar"
   }
 
@@ -1609,7 +1430,6 @@
         (!(target_cpu == "arm" && arm_version == 7) || !arm_use_neon)) {
       deps = [
         ":api_static_checks",
-        ":copy_cronet_java8_jars",
         ":cronet_package_copy",
         ":cronet_package_copy_native_lib",
         ":cronet_package_copy_native_lib_unstripped",
@@ -1622,8 +1442,10 @@
         ":jar_cronet_impl_native_java_source",
         ":jar_cronet_impl_platform_java_source",
         ":jar_cronet_sample_source",
-        ":repackage_extracted_common_jars",
-        ":repackage_extracted_native_jars",
+        ":repackage_api",
+        ":repackage_common",
+        ":repackage_native",
+        ":repackage_platform",
       ]
       if (current_cpu == "arm" && arm_version == 7) {
         deps += [ ":enforce_no_neon" ]
@@ -1642,7 +1464,7 @@
         ":cronet_package_copy_test_assets",
         ":cronet_package_copy_test_files",
         ":cronet_package_copy_test_support_apks",
-        ":repackage_extracted_test_jars",
+        ":repackage_test_jars",
       ]
     }
   }
diff --git a/components/cronet/native/runnables_unittest.cc b/components/cronet/native/runnables_unittest.cc
index bff3243..868d99ac 100644
--- a/components/cronet/native/runnables_unittest.cc
+++ b/components/cronet/native/runnables_unittest.cc
@@ -9,8 +9,8 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "components/cronet/native/generated/cronet.idl_impl_interface.h"
 #include "components/cronet/native/include/cronet_c.h"
 #include "components/cronet/native/test/test_util.h"
@@ -43,7 +43,7 @@
   bool callback_called() const { return callback_called_; }
 
   // Provide a message loop for use by TestExecutor instances.
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
  private:
   bool callback_called_ = false;
diff --git a/components/cronet/tools/extract_from_jars.py b/components/cronet/tools/extract_from_jars.py
deleted file mode 100755
index ccddea41..0000000
--- a/components/cronet/tools/extract_from_jars.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 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 optparse
-import os
-import sys
-
-REPOSITORY_ROOT = os.path.abspath(os.path.join(
-    os.path.dirname(__file__), '..', '..', '..'))
-
-sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util'))
-import build_utils
-
-
-def ExtractJars(options):
-  # The paths of the files in the jar will be the same as they are passed in to
-  # the command. Because of this, the command should be run in
-  # options.classes_dir so the .class file paths in the jar are correct.
-  jar_cwd = options.classes_dir
-  build_utils.DeleteDirectory(jar_cwd)
-  build_utils.MakeDirectory(jar_cwd)
-  for jar in build_utils.ParseGnList(options.jars):
-    jar_path = os.path.abspath(jar)
-    jar_cmd = ['jar', 'xf', jar_path]
-    build_utils.CheckOutput(jar_cmd, cwd=jar_cwd)
-
-
-def main():
-  parser = optparse.OptionParser()
-  build_utils.AddDepfileOption(parser)
-  parser.add_option('--classes-dir', help='Directory to extract .class files.')
-  parser.add_option('--jars', help='Paths to jars to extract.')
-  parser.add_option('--stamp', help='Path to touch on success.')
-
-  options, _ = parser.parse_args()
-
-  ExtractJars(options)
-
-  if options.depfile:
-    assert options.stamp
-    build_utils.WriteDepfile(options.depfile, options.stamp)
-
-  if options.stamp:
-    build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
-
diff --git a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
index fe358b6..88d6492 100644
--- a/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
+++ b/components/cryptauth/ble/bluetooth_low_energy_weave_client_connection_unittest.cc
@@ -11,9 +11,9 @@
 
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/timer/mock_timer.h"
 #include "base/timer/timer.h"
@@ -659,7 +659,7 @@
   std::unique_ptr<device::MockBluetoothGattCharacteristic> tx_characteristic_;
   std::unique_ptr<device::MockBluetoothGattCharacteristic> rx_characteristic_;
   std::vector<uint8_t> last_value_written_on_tx_characteristic_;
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   int32_t rssi_for_channel_ = device::BluetoothDevice::kUnknownPower;
   bool last_wire_message_success_;
   bool has_verified_connection_result_;
diff --git a/components/discardable_memory/service/BUILD.gn b/components/discardable_memory/service/BUILD.gn
index 59f8817d..f8bf879 100644
--- a/components/discardable_memory/service/BUILD.gn
+++ b/components/discardable_memory/service/BUILD.gn
@@ -32,6 +32,7 @@
   deps = [
     ":service",
     "//base",
+    "//base/test:test_support",
     "//testing/gtest",
   ]
 }
diff --git a/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc b/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
index bf6ef200..ba0b7aa 100644
--- a/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
+++ b/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
@@ -7,7 +7,7 @@
 #include <stdint.h>
 #include <string.h>
 
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/simple_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -66,7 +66,7 @@
   }
 
   // DiscardableSharedMemoryManager requires a message loop.
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   std::unique_ptr<TestDiscardableSharedMemoryManager> manager_;
 };
 
@@ -240,7 +240,7 @@
   void SetUp() override { manager_.reset(new DiscardableSharedMemoryManager); }
 
   // DiscardableSharedMemoryManager requires a message loop.
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   std::unique_ptr<DiscardableSharedMemoryManager> manager_;
 };
 
diff --git a/components/history/core/browser/history_querying_unittest.cc b/components/history/core/browser/history_querying_unittest.cc
index ffba6cf..3cdc1660c 100644
--- a/components/history/core/browser/history_querying_unittest.cc
+++ b/components/history/core/browser/history_querying_unittest.cc
@@ -10,10 +10,10 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "base/test/scoped_task_environment.h"
 #include "components/history/core/browser/history_database_params.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/test/test_history_database.h"
@@ -198,7 +198,7 @@
 
   base::ScopedTempDir temp_dir_;
 
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
   base::FilePath history_dir_;
 
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
index 2b5fe941..be84297 100644
--- a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
+++ b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
@@ -8,8 +8,8 @@
 
 #include "base/big_endian.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/history/core/browser/history_backend.h"
 #include "components/history/core/browser/history_backend_client.h"
@@ -502,7 +502,7 @@
   RecordingModelTypeChangeProcessor& processor() { return *processor_; }
 
  protected:
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   base::ScopedTempDir test_dir_;
   scoped_refptr<TestHistoryBackend> fake_history_backend_;
   TypedURLSyncBridge* typed_url_sync_bridge_;
diff --git a/components/metrics/child_call_stack_profile_collector_unittest.cc b/components/metrics/child_call_stack_profile_collector_unittest.cc
index 3ced131b..84f33bb 100644
--- a/components/metrics/child_call_stack_profile_collector_unittest.cc
+++ b/components/metrics/child_call_stack_profile_collector_unittest.cc
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/metrics_proto/sampled_profile.pb.h"
@@ -50,7 +50,7 @@
     return child_collector_.profiles_;
   }
 
-  base::MessageLoop loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   mojom::CallStackProfileCollectorPtr receiver_;
   std::unique_ptr<Receiver> receiver_impl_;
   ChildCallStackProfileCollector child_collector_;
diff --git a/components/metrics/single_sample_metrics_factory_impl_unittest.cc b/components/metrics/single_sample_metrics_factory_impl_unittest.cc
index 7362085..8113de5 100644
--- a/components/metrics/single_sample_metrics_factory_impl_unittest.cc
+++ b/components/metrics/single_sample_metrics_factory_impl_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "components/metrics/single_sample_metrics_factory_impl.h"
 
-#include "base/message_loop/message_loop.h"
 #include "base/metrics/dummy_histogram.h"
 #include "base/run_loop.h"
 #include "base/test/gtest_util.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread.h"
 #include "components/metrics/single_sample_metrics.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -74,7 +74,7 @@
                                                  kBucketCount);
   }
 
-  base::MessageLoop message_looqp_;
+  base::test::ScopedTaskEnvironment task_environment_;
   SingleSampleMetricsFactoryImpl* factory_;
   base::Thread thread_;
   size_t provider_count_ = 0;
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc
index 3f3608b9..b8f93fa9 100644
--- a/components/ntp_tiles/most_visited_sites_unittest.cc
+++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -17,11 +17,11 @@
 #include "base/callback_list.h"
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "components/history/core/browser/top_sites.h"
@@ -535,7 +535,7 @@
       suggestions_service_callbacks_;
   TopSitesCallbackList top_sites_callbacks_;
 
-  base::MessageLoop message_loop_;
+  base::test::ScopedTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   PopularSitesFactoryForTest popular_sites_factory_;
   scoped_refptr<StrictMock<MockTopSites>> mock_top_sites_;
diff --git a/components/ntp_tiles/popular_sites_impl_unittest.cc b/components/ntp_tiles/popular_sites_impl_unittest.cc
index bc89950c..b3b88f6 100644
--- a/components/ntp_tiles/popular_sites_impl_unittest.cc
+++ b/components/ntp_tiles/popular_sites_impl_unittest.cc
@@ -13,12 +13,12 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/json/json_writer.h"
-#include "base/message_loop/message_loop.h"
 #include "base/optional.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "build/build_config.h"
@@ -211,7 +211,8 @@
   const TestPopularSite kYouTube;
   const TestPopularSite kChromium;
 
-  base::MessageLoopForUI ui_loop_;
+  base::test::ScopedTaskEnvironment task_environment_{
+      base::test::ScopedTaskEnvironment::MainThreadType::UI};
   std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index f78d4677..390ff850 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -235,6 +235,8 @@
           processed_field =
               FindFieldWithUniqueRendererId(processed_fields, prediction.first);
           if (processed_field) {
+            if (!processed_field->is_password)
+              return nullptr;
             result->password = processed_field->field;
           }
         }
@@ -254,6 +256,8 @@
           processed_field =
               FindFieldWithUniqueRendererId(processed_fields, prediction.first);
           if (processed_field) {
+            if (!processed_field->is_password)
+              return nullptr;
             result->new_password = processed_field->field;
           }
         }
@@ -262,6 +266,8 @@
         processed_field =
             FindFieldWithUniqueRendererId(processed_fields, prediction.first);
         if (processed_field) {
+          if (!processed_field->is_password)
+            return nullptr;
           result->confirmation_password = processed_field->field;
         }
         break;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index 3a81112..a32db154 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -1045,6 +1045,17 @@
               },
           .number_of_all_possible_passwords = 4,
       },
+      {
+          "password prediction for a non-password field is ignored",
+          {
+              {.role = ElementRole::USERNAME,
+               .prediction = {.type = autofill::PASSWORD},
+               .form_control_type = "text"},
+              {.role = ElementRole::CURRENT_PASSWORD,
+               .form_control_type = "password"},
+          },
+      },
+
   });
 }
 
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index cd077fe6..69ff44c4 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -367,7 +367,12 @@
       is_new_form_parsing_for_saving_enabled_(
           base::FeatureList::IsEnabled(
               features::kNewPasswordFormParsingForSaving) &&
-          base::FeatureList::IsEnabled(features::kNewPasswordFormParsing)) {
+          base::FeatureList::IsEnabled(features::kNewPasswordFormParsing)),
+      is_only_new_parser_enabled_(
+          base::FeatureList::IsEnabled(
+              features::kNewPasswordFormParsingForSaving) &&
+          base::FeatureList::IsEnabled(features::kNewPasswordFormParsing) &&
+          base::FeatureList::IsEnabled(features::kOnlyNewParser)) {
   DCHECK(client_);
 }
 
@@ -768,7 +773,7 @@
                       pending_login_managers_.size());
   }
 
-  if (skip_old_form_managers_in_tests_)
+  if (is_only_new_parser_enabled_)
     return;
 
   for (const PasswordForm& form : forms) {
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h
index 69ea3f1..9aee964 100644
--- a/components/password_manager/core/browser/password_manager.h
+++ b/components/password_manager/core/browser/password_manager.h
@@ -177,10 +177,6 @@
     return GetSubmittedManager();
   }
 
-  void set_skip_old_form_managers_in_tests(bool value) {
-    skip_old_form_managers_in_tests_ = value;
-  }
-
 #endif
 
   NavigationEntryToCheck entry_to_check() const { return entry_to_check_; }
@@ -363,10 +359,8 @@
 
   const bool is_new_form_parsing_for_saving_enabled_;
 
-  // If true, it turns off using PasswordFormManager in PasswordManager. Now it
-  // is used only in tests and later the old PasswordFormManager will disappear
-  // and with it also this flag.
-  bool skip_old_form_managers_in_tests_ = false;
+  // If true, it turns off using PasswordFormManager in PasswordManager.
+  const bool is_only_new_parser_enabled_;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordManager);
 };
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index c150b82..a6ec1bb 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -74,9 +74,7 @@
 class MockPasswordManagerClient : public StubPasswordManagerClient {
  public:
   MockPasswordManagerClient() {
-    EXPECT_CALL(*this, GetStoreResultFilter())
-        .Times(AnyNumber())
-        .WillRepeatedly(Return(&filter_));
+    ON_CALL(*this, GetStoreResultFilter()).WillByDefault(Return(&filter_));
     ON_CALL(filter_, ShouldSave(_)).WillByDefault(Return(true));
     ON_CALL(filter_, ShouldSaveGaiaPasswordHash(_))
         .WillByDefault(Return(false));
@@ -214,10 +212,9 @@
         .Times(AnyNumber());
     CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
 
-    EXPECT_CALL(client_, GetPasswordStore())
-        .WillRepeatedly(Return(store_.get()));
+    ON_CALL(client_, GetPasswordStore()).WillByDefault(Return(store_.get()));
     EXPECT_CALL(*store_, GetSiteStatsImpl(_)).Times(AnyNumber());
-    EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
+    ON_CALL(client_, GetDriver()).WillByDefault(Return(&driver_));
 
     manager_.reset(new PasswordManager(&client_));
     password_autofill_manager_.reset(
@@ -227,7 +224,7 @@
         .WillRepeatedly(Return(manager_.get()));
     EXPECT_CALL(driver_, GetPasswordAutofillManager())
         .WillRepeatedly(Return(password_autofill_manager_.get()));
-    EXPECT_CALL(client_, GetMainFrameCertStatus()).WillRepeatedly(Return(0));
+    ON_CALL(client_, GetMainFrameCertStatus()).WillByDefault(Return(0));
 
     EXPECT_CALL(*store_, IsAbleToSavePasswords()).WillRepeatedly(Return(true));
 
@@ -382,6 +379,15 @@
     manager_.reset(new PasswordManager(&client_));
   }
 
+  void TurnOnOnlyNewPassword(
+      base::test::ScopedFeatureList* scoped_feature_list) {
+    scoped_feature_list->InitWithFeatures(
+        {features::kNewPasswordFormParsing,
+         features::kNewPasswordFormParsingForSaving, features::kOnlyNewParser},
+        {});
+    manager_.reset(new PasswordManager(&client_));
+  }
+
   const GURL test_url_;
   base::MessageLoop message_loop_;
   scoped_refptr<MockPasswordStore> store_;
@@ -2679,15 +2685,16 @@
 // new parsing. For details see scheme 1 in comments before
 // |form_managers_| in password_manager.h.
 TEST_F(PasswordManagerTest, ProcessingNormalFormSubmission) {
-  for (bool skip_old_form_managers_in_tests : {false, true}) {
+  for (bool only_new_parser : {false, true}) {
     for (bool successful_submission : {false, true}) {
-      SCOPED_TRACE(testing::Message("skip_old_form_managers_in_tests = ")
-                   << skip_old_form_managers_in_tests
+      SCOPED_TRACE(testing::Message("only_new_parser = ")
+                   << only_new_parser
                    << "  successful_submission = " << successful_submission);
       base::test::ScopedFeatureList scoped_feature_list;
-      TurnOnNewParsingForSaving(&scoped_feature_list);
-      manager()->set_skip_old_form_managers_in_tests(
-          skip_old_form_managers_in_tests);
+      if (only_new_parser)
+        TurnOnOnlyNewPassword(&scoped_feature_list);
+      else
+        TurnOnNewParsingForSaving(&scoped_feature_list);
 
       EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage())
           .WillRepeatedly(Return(true));
@@ -2701,10 +2708,12 @@
       manager()->OnPasswordFormsParsed(&driver_, observed);
       manager()->OnPasswordFormsRendered(&driver_, observed, true);
 
+      if (only_new_parser)
+        EXPECT_TRUE(manager()->pending_login_managers().empty());
+
       auto submitted_form = form;
       submitted_form.form_data.fields[0].value = ASCIIToUTF16("username");
-      submitted_form.form_data.fields[1].value =
-          ASCIIToUTF16("strong_password");
+      submitted_form.form_data.fields[1].value = ASCIIToUTF16("password1");
 
       OnPasswordFormSubmitted(submitted_form);
       EXPECT_TRUE(manager()->GetSubmittedManagerForTest());
@@ -2724,6 +2733,7 @@
 
       // Multiple calls of OnPasswordFormsRendered should be handled gracefully.
       manager()->OnPasswordFormsRendered(&driver_, observed, true);
+      testing::Mock::VerifyAndClearExpectations(&client_);
     }
   }
 }
@@ -2732,11 +2742,13 @@
 // with the new parsing. For details see scheme 2 in comments before
 // |form_managers_| in password_manager.h.
 TEST_F(PasswordManagerTest, ProcessingOtherSubmissionTypes) {
-  for (bool skip_old_form_managers_in_tests : {false, true}) {
-    SCOPED_TRACE(testing::Message("skip_old_form_managers_in_tests = ")
-                 << skip_old_form_managers_in_tests);
+  for (bool only_new_parser : {false, true}) {
+    SCOPED_TRACE(testing::Message("only_new_parser = ") << only_new_parser);
     base::test::ScopedFeatureList scoped_feature_list;
-    TurnOnNewParsingForSaving(&scoped_feature_list);
+    if (only_new_parser)
+      TurnOnOnlyNewPassword(&scoped_feature_list);
+    else
+      TurnOnNewParsingForSaving(&scoped_feature_list);
 
     EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage())
         .WillRepeatedly(Return(true));
@@ -2759,6 +2771,7 @@
         .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save)));
     manager()->OnPasswordFormSubmittedNoChecks(&driver_, submitted_form);
     EXPECT_TRUE(manager()->form_managers().empty());
+    testing::Mock::VerifyAndClearExpectations(&client_);
   }
 }
 
diff --git a/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html b/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html
index 3fe3c0d..d47e5568 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html
+++ b/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html
@@ -1,12 +1,13 @@
 <!doctype html>
 <html>
 <head>
-  <title>Origin Policy Error Interstitial</title>
+  <title>Origin Policy Error</title>
 </head>
 <body>
-  <p>Well, well, well. What do we have here? An Origin Policy violation.</p>
-  <p>And what do we not have? A page!</p>
-
+  <p>The server has requested that an
+    <a href="https://github.com/WICG/origin-policy">Origin Policy</a>
+    is applied to this origin, but it is not currently serving a suitable
+    policy.</p>
   <p><ul>
     <li>You're trying to go to: $i18n{url}</li>
     <li>The policy applies to: $i18n{origin}</li>
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index 43e217c..7113c3b1 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -226,6 +226,12 @@
   }
 }
 
+#if defined(OS_IOS)
+void AccountReconcilor::SetIsWKHTTPSystemCookieStoreEnabled(bool is_enabled) {
+  is_wkhttp_system_cookie_store_enabled_ = is_enabled;
+}
+#endif  // defined(OS_IOS)
+
 void AccountReconcilor::EnableReconcile() {
   DCHECK(delegate_->IsReconcileEnabled());
   RegisterWithCookieManagerService();
@@ -568,7 +574,7 @@
     return;
   }
 
-  if (base::FeatureList::IsEnabled(kUseMultiloginEndpoint)) {
+  if (IsMultiloginEndpointEnabled()) {
     FinishReconcileWithMultiloginEndpoint(primary_account,
                                           LoadValidAccountsFromTokenService(),
                                           std::move(verified_gaia_accounts));
@@ -905,3 +911,14 @@
   AbortReconcile();
   DCHECK(!timer_->IsRunning());
 }
+
+bool AccountReconcilor::IsMultiloginEndpointEnabled() const {
+#if defined(OS_IOS)
+  // kUseMultiloginEndpoint feature should not be used if
+  // kWKHTTPSystemCookieStore feature is disabbled.
+  // See http://crbug.com/902584.
+  if (!is_wkhttp_system_cookie_store_enabled_)
+    return false;
+#endif  // defined(OS_IOS)
+  return base::FeatureList::IsEnabled(kUseMultiloginEndpoint);
+}
diff --git a/components/signin/core/browser/account_reconcilor.h b/components/signin/core/browser/account_reconcilor.h
index 01fb781..c13ed7f 100644
--- a/components/signin/core/browser/account_reconcilor.h
+++ b/components/signin/core/browser/account_reconcilor.h
@@ -18,6 +18,7 @@
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "build/build_config.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -109,6 +110,11 @@
   // construction.
   void Initialize(bool start_reconcile_if_tokens_available);
 
+#if defined(OS_IOS)
+  // Sets the WKHTTPSystemCookieStore flag value.
+  void SetIsWKHTTPSystemCookieStoreEnabled(bool is_enabled);
+#endif  // defined(OS_IOS)
+
   // Enables and disables the reconciliation.
   void EnableReconcile();
   void DisableReconcile(bool logout_all_gaia_accounts);
@@ -303,6 +309,9 @@
 
   void HandleReconcileTimeout();
 
+  // Returns true is multilogin endpoint can be enabled.
+  bool IsMultiloginEndpointEnabled() const;
+
   std::unique_ptr<signin::AccountReconcilorDelegate> delegate_;
 
   // The ProfileOAuth2TokenService associated with this reconcilor.
@@ -371,6 +380,11 @@
   // not invalidate the primary token while this is happening.
   int synced_data_deletion_in_progress_count_ = 0;
 
+#if defined(OS_IOS)
+  // Stores the WKHTTPSystemCookieStore flag value.
+  bool is_wkhttp_system_cookie_store_enabled_ = false;
+#endif  // defined(OS_IOS)
+
   base::WeakPtrFactory<AccountReconcilor> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
diff --git a/components/signin/core/browser/account_reconcilor_unittest.cc b/components/signin/core/browser/account_reconcilor_unittest.cc
index 4b9b45e..b4128da 100644
--- a/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -131,6 +131,9 @@
             CreateAccountReconcilorDelegate(client,
                                             identity_manager,
                                             account_consistency)) {
+#if defined(OS_IOS)
+    SetIsWKHTTPSystemCookieStoreEnabled(true);
+#endif  // defined(OS_IOS)
     Initialize(false /* start_reconcile_if_tokens_available */);
   }
 
@@ -148,6 +151,9 @@
             client,
             cookie_manager_service,
             std::unique_ptr<signin::AccountReconcilorDelegate>(delegate)) {
+#if defined(OS_IOS)
+    SetIsWKHTTPSystemCookieStoreEnabled(true);
+#endif  // defined(OS_IOS)
     Initialize(false /* start_reconcile_if_tokens_available */);
   }
 
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc
index 786bcc2c..b9020bde 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -10,6 +10,7 @@
 #include <set>
 
 #include "base/json/json_reader.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
@@ -24,6 +25,7 @@
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 #include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
 #include "net/cookies/cookie_change_dispatcher.h"
 #include "net/http/http_status_code.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -73,7 +75,7 @@
     0.2,  // 20%
 
     // Maximum amount of time we are willing to delay our request in ms.
-    1000 * 60 * 60 * 4,  // 4 hours.
+    1000 * 60 * 15,  // 15 minutes.
 
     // Time to keep an entry from being discarded even when it
     // has no significant state, -1 to never discard.
@@ -116,6 +118,30 @@
                             GoogleServiceAuthError::NUM_STATES);
 }
 
+// Record ListAccounts errors for individual retries.
+void RecordListAccountsRetryResult(GoogleServiceAuthError error,
+                                   int retry_attempt_number) {
+  int net_error = net::OK;
+  switch (error.state()) {
+    case GoogleServiceAuthError::NONE:
+      net_error = net::OK;
+      break;
+    case GoogleServiceAuthError::CONNECTION_FAILED:
+      net_error = error.network_error();
+      break;
+    case GoogleServiceAuthError::REQUEST_CANCELED:
+      net_error = net::ERR_ABORTED;
+      break;
+    default:
+      return;  // There is an error not related to network.
+  }
+
+  std::string histogram_name =
+      base::StringPrintf("Gaia.AuthFetcher.ListAccounts.NetErrorCodes.Retry_%i",
+                         retry_attempt_number);
+  base::UmaHistogramSparse(histogram_name, -net_error);
+}
+
 }  // namespace
 
 GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
@@ -854,12 +880,16 @@
           data, &listed_accounts_, &signed_out_accounts_)) {
     listed_accounts_.clear();
     signed_out_accounts_.clear();
-    OnListAccountsFailure(GoogleServiceAuthError(
-        GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE));
+    GoogleServiceAuthError error(
+        GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE);
+    RecordListAccountsFailure(error.state());
+    OnListAccountsFailure(error);
     return;
   }
 
   RecordListAccountsFailure(GoogleServiceAuthError::NONE);
+  RecordListAccountsRetryResult(GoogleServiceAuthError::AuthErrorNone(),
+                                fetcher_retries_);
 
   for (gaia::ListedAccount& account : listed_accounts_) {
     DCHECK(account.id.empty());
@@ -885,6 +915,8 @@
   VLOG(1) << "ListAccounts failed";
   DCHECK(requests_.front().request_type() ==
          GaiaCookieRequestType::LIST_ACCOUNTS);
+  RecordListAccountsRetryResult(error, fetcher_retries_);
+
   if (++fetcher_retries_ < signin::kMaxFetcherRetries &&
       error.IsTransientError()) {
     fetcher_backoff_.InformOfRequest(false);
diff --git a/components/signin/core/browser/signin_client.h b/components/signin/core/browser/signin_client.h
index d32e266..6b43910 100644
--- a/components/signin/core/browser/signin_client.h
+++ b/components/signin/core/browser/signin_client.h
@@ -41,9 +41,6 @@
 
   ~SigninClient() override = default;
 
-  // Perform Chrome-specific sign out. This happens when user signs out.
-  virtual void OnSignedOut() = 0;
-
   // Call when done local initialization and SigninClient can initiate any work
   // it has to do that may require other components (like ProfileManager) to be
   // available.
@@ -64,12 +61,6 @@
   // Signin component is being used.
   virtual std::string GetProductVersion() = 0;
 
-  // Called after Google signin has succeeded.
-  virtual void OnSignedIn(const std::string& account_id,
-                          const std::string& gaia_id,
-                          const std::string& username,
-                          const std::string& password) {}
-
   // Called after Google signin has succeeded and GetUserInfo has returned.
   virtual void PostSignedIn(const std::string& account_id,
                             const std::string& username,
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc
index 4a557290..f3c819f 100644
--- a/components/signin/core/browser/signin_manager.cc
+++ b/components/signin/core/browser/signin_manager.cc
@@ -228,7 +228,6 @@
   client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId);
   client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
   client_->GetPrefs()->ClearPref(prefs::kSignedInTime);
-  client_->OnSignedOut();
 
   // Determine the duration the user was logged in and log that to UMA.
   if (!signin_time.is_null()) {
@@ -434,9 +433,6 @@
   if (!reauth_in_progress)
     FireGoogleSigninSucceeded();
 
-  client_->OnSignedIn(GetAuthenticatedAccountId(), gaia_id,
-                      GetAuthenticatedAccountInfo().email, password_);
-
   signin_metrics::LogSigninProfile(client_->IsFirstRun(),
                                    client_->GetInstallDate());
 
diff --git a/components/signin/core/browser/test_signin_client.cc b/components/signin/core/browser/test_signin_client.cc
index 3478335..c137b2f 100644
--- a/components/signin/core/browser/test_signin_client.cc
+++ b/components/signin/core/browser/test_signin_client.cc
@@ -67,8 +67,6 @@
   std::move(callback).Run(false);
 }
 
-void TestSigninClient::OnSignedOut() {}
-
 void TestSigninClient::PostSignedIn(const std::string& account_id,
                   const std::string& username,
                   const std::string& password) {
diff --git a/components/signin/core/browser/test_signin_client.h b/components/signin/core/browser/test_signin_client.h
index 6a71316..d401d8540 100644
--- a/components/signin/core/browser/test_signin_client.h
+++ b/components/signin/core/browser/test_signin_client.h
@@ -38,9 +38,6 @@
   // once there is a unit test that requires it.
   PrefService* GetPrefs() override;
 
-  // Does nothing.
-  void OnSignedOut() override;
-
   // Trace that this was called.
   void PostSignedIn(const std::string& account_id,
                     const std::string& username,
diff --git a/components/unified_consent/unified_consent_metrics.cc b/components/unified_consent/unified_consent_metrics.cc
index d792614..0ecc8801 100644
--- a/components/unified_consent/unified_consent_metrics.cc
+++ b/components/unified_consent/unified_consent_metrics.cc
@@ -6,6 +6,7 @@
 
 #include "base/metrics/histogram_macros.h"
 #include "components/prefs/pref_service.h"
+#include "components/unified_consent/pref_names.h"
 
 namespace {
 
@@ -33,6 +34,28 @@
                         eligible);
 }
 
+void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client,
+                             PrefService* pref_service) {
+  bool metric_recorded = false;
+
+  metric_recorded |= RecordSettingsHistogramFromPref(
+      prefs::kAllUnifiedConsentServicesWereEnabled, pref_service,
+      metrics::SettingsHistogramValue::kAllServicesWereEnabled);
+  metric_recorded |= RecordSettingsHistogramFromPref(
+      prefs::kUrlKeyedAnonymizedDataCollectionEnabled, pref_service,
+      metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection);
+  metric_recorded |= RecordSettingsHistogramFromService(
+      service_client,
+      UnifiedConsentServiceClient::Service::kSafeBrowsingExtendedReporting,
+      metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting);
+  metric_recorded |= RecordSettingsHistogramFromService(
+      service_client, UnifiedConsentServiceClient::Service::kSpellCheck,
+      metrics::SettingsHistogramValue::kSpellCheck);
+
+  if (!metric_recorded)
+    RecordSettingsHistogramSample(metrics::SettingsHistogramValue::kNone);
+}
+
 void RecordSettingsHistogramSample(SettingsHistogramValue value) {
   UMA_HISTOGRAM_ENUMERATION(kSyncAndGoogleServicesSettingsHistogram, value);
 }
diff --git a/components/unified_consent/unified_consent_metrics.h b/components/unified_consent/unified_consent_metrics.h
index b7184ca..b0e55a9a8e 100644
--- a/components/unified_consent/unified_consent_metrics.h
+++ b/components/unified_consent/unified_consent_metrics.h
@@ -70,6 +70,11 @@
 // be called at startup.
 void RecordConsentBumpEligibility(bool eligible);
 
+// Records settings entries in the kSyncAndGoogleServicesSettingsHistogram.
+// kNone is recorded when none of the settings is enabled.
+void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client,
+                             PrefService* pref_service);
+
 // Records a sample in the kSyncAndGoogleServicesSettingsHistogram. Wrapped in a
 // function to avoid code size issues caused by histogram macros.
 void RecordSettingsHistogramSample(SettingsHistogramValue value);
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc
index 15a5ade..ed27965 100644
--- a/components/unified_consent/unified_consent_service.cc
+++ b/components/unified_consent/unified_consent_service.cc
@@ -42,8 +42,6 @@
 
   identity_manager_->AddObserver(this);
   sync_service_->AddObserver(this);
-
-  RecordSettingsHistogram();
 }
 
 UnifiedConsentService::~UnifiedConsentService() {}
@@ -274,27 +272,6 @@
   return true;
 }
 
-void UnifiedConsentService::RecordSettingsHistogram() {
-  bool metric_recorded = false;
-
-  metric_recorded |= RecordSettingsHistogramFromPref(
-      prefs::kAllUnifiedConsentServicesWereEnabled, pref_service_,
-      metrics::SettingsHistogramValue::kAllServicesWereEnabled);
-  metric_recorded |= RecordSettingsHistogramFromPref(
-      prefs::kUrlKeyedAnonymizedDataCollectionEnabled, pref_service_,
-      metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection);
-  metric_recorded |= RecordSettingsHistogramFromService(
-      service_client_.get(),
-      UnifiedConsentServiceClient::Service::kSafeBrowsingExtendedReporting,
-      metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting);
-  metric_recorded |= RecordSettingsHistogramFromService(
-      service_client_.get(), UnifiedConsentServiceClient::Service::kSpellCheck,
-      metrics::SettingsHistogramValue::kSpellCheck);
-
-  if (!metric_recorded)
-    RecordSettingsHistogramSample(metrics::SettingsHistogramValue::kNone);
-}
-
 void UnifiedConsentService::CheckConsentBumpEligibility() {
   // Only check eligility if the user was eligible before.
   if (!ShouldShowConsentBump()) {
diff --git a/components/unified_consent/unified_consent_service.h b/components/unified_consent/unified_consent_service.h
index e5cb80b..9f927c2 100644
--- a/components/unified_consent/unified_consent_service.h
+++ b/components/unified_consent/unified_consent_service.h
@@ -104,10 +104,6 @@
   // Checks if all on-by-default non-personalized services are on.
   bool AreAllOnByDefaultPrivacySettingsOn();
 
-  // Records a sample for each bucket enabled by the user (except kNone).
-  // kNone is recorded when none of the other buckets are recorded.
-  void RecordSettingsHistogram();
-
   // This method is called on startup to check the eligibility criteria for
   // showing the consent bump. The check is only done when the profile was
   // eligible before. If the user is not eligible anymore, the
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc
index 375dc41..48454eb 100644
--- a/components/unified_consent/unified_consent_service_unittest.cc
+++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -40,6 +40,8 @@
 
  private:
   syncer::SyncServiceObserver* observer_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(TestSyncService);
 };
 
 const char kSpellCheckDummyEnabled[] = "spell_check_dummy.enabled";
@@ -97,6 +99,8 @@
   static std::map<Service, bool> is_not_supported_;
 
   PrefService* pref_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeUnifiedConsentServiceClient);
 };
 
 std::map<Service, bool> FakeUnifiedConsentServiceClient::service_enabled_;
@@ -191,6 +195,8 @@
   std::unique_ptr<FakeUnifiedConsentServiceClient> service_client_;
 
   std::unique_ptr<ScopedUnifiedConsent> scoped_unified_consent_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceTest);
 };
 
 TEST_F(UnifiedConsentServiceTest, DefaultValuesWhenSignedOut) {
@@ -414,60 +420,6 @@
             service_client_->GetServiceState(Service::kContextualSearch));
 }
 
-TEST_F(UnifiedConsentServiceTest, SettingsHistogram_None) {
-  base::HistogramTester histogram_tester;
-  // Disable all services.
-  sync_service_.GetUserSettings()->SetChosenDataTypes(false,
-                                                      syncer::ModelTypeSet());
-  CreateConsentService();
-
-  histogram_tester.ExpectUniqueSample(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kNone, 1);
-}
-
-TEST_F(UnifiedConsentServiceTest, SettingsHistogram_UnifiedConsentGiven) {
-  base::HistogramTester histogram_tester;
-  // Unified consent is given.
-  identity_test_environment_.SetPrimaryAccount("testaccount");
-  pref_service_.SetInteger(
-      prefs::kUnifiedConsentMigrationState,
-      static_cast<int>(unified_consent::MigrationState::kCompleted));
-  pref_service_.SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled, true);
-  CreateConsentService(true);
-
-  histogram_tester.ExpectBucketCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kNone, 0);
-  histogram_tester.ExpectBucketCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kAllServicesWereEnabled, 1);
-  histogram_tester.ExpectBucketCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection, 1);
-  histogram_tester.ExpectBucketCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting, 1);
-  histogram_tester.ExpectBucketCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kSpellCheck, 1);
-  histogram_tester.ExpectTotalCount(
-      "UnifiedConsent.SyncAndGoogleServicesSettings", 4);
-}
-
-TEST_F(UnifiedConsentServiceTest, SettingsHistogram_NoUnifiedConsentGiven) {
-  base::HistogramTester histogram_tester;
-  // Unified consent is not given. Only spellcheck is enabled.
-  pref_service_.SetBoolean(kSpellCheckDummyEnabled, true);
-  CreateConsentService();
-
-  // kUserEvents should have no sample even though the sync preference is set,
-  // because the user is not signed in.
-  histogram_tester.ExpectUniqueSample(
-      "UnifiedConsent.SyncAndGoogleServicesSettings",
-      metrics::SettingsHistogramValue::kSpellCheck, 1);
-}
-
 TEST_F(UnifiedConsentServiceTest, ConsentBump_EligibleOnSecondStartup) {
   base::HistogramTester histogram_tester;
 
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index ddb42b1..c89b65d 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1742,8 +1742,6 @@
     "tracing/background_tracing_manager_impl.h",
     "tracing/background_tracing_rule.cc",
     "tracing/background_tracing_rule.h",
-    "tracing/etw_tracing_agent_win.cc",
-    "tracing/etw_tracing_agent_win.h",
     "tracing/file_tracing_provider_impl.cc",
     "tracing/file_tracing_provider_impl.h",
     "tracing/trace_message_filter.cc",
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index ea07493..97192a6 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -154,7 +154,7 @@
   // Unlike OnResponseStarted, OnRequestRedirected will NOT be preceded by
   // OnWillRead.
   DCHECK(!has_controller());
-  DCHECK(!shared_writer_);
+  DCHECK(shared_writer_);
 
   request()->LogBlockedBy("MojoAsyncResourceHandler");
   HoldController(std::move(controller));
@@ -204,6 +204,9 @@
         std::vector<uint8_t>(data, data + metadata->size()));
   }
 
+  url_loader_client_->OnStartLoadingResponseBody(
+      std::move(response_body_consumer_handle_));
+
   if (url_loader_options_ &
       network::mojom::kURLLoadOptionPauseOnResponseStarted) {
     did_defer_on_response_started_ = true;
@@ -219,6 +222,25 @@
 void MojoAsyncResourceHandler::OnWillStart(
     const GURL& url,
     std::unique_ptr<ResourceController> controller) {
+  // Create the response's body datapipe.
+  MojoCreateDataPipeOptions options;
+  options.struct_size = sizeof(MojoCreateDataPipeOptions);
+  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+  options.element_num_bytes = 1;
+  options.capacity_num_bytes = g_allocation_size;
+  mojo::ScopedDataPipeProducerHandle response_body_producer_handle_;
+  if (mojo::CreateDataPipe(&options, &response_body_producer_handle_,
+                           &response_body_consumer_handle_) != MOJO_RESULT_OK) {
+    controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
+    return;
+  }
+
+  shared_writer_ = new SharedWriter(std::move(response_body_producer_handle_));
+  handle_watcher_.Watch(
+      shared_writer_->writer(), MOJO_HANDLE_SIGNAL_WRITABLE,
+      base::BindRepeating(&MojoAsyncResourceHandler::OnWritable,
+                          base::Unretained(this)));
+
   if (GetRequestInfo()->is_upload_progress_enabled() &&
       request()->has_upload()) {
     upload_progress_tracker_ = CreateUploadProgressTracker(
@@ -245,33 +267,6 @@
     return;
   }
 
-  bool first_call = false;
-  if (!shared_writer_) {
-    first_call = true;
-    MojoCreateDataPipeOptions options;
-    options.struct_size = sizeof(MojoCreateDataPipeOptions);
-    options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
-    options.element_num_bytes = 1;
-    options.capacity_num_bytes = g_allocation_size;
-    mojo::ScopedDataPipeProducerHandle producer;
-    mojo::ScopedDataPipeConsumerHandle consumer;
-
-    MojoResult result = mojo::CreateDataPipe(&options, &producer, &consumer);
-    if (result != MOJO_RESULT_OK) {
-      controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
-      return;
-    }
-    DCHECK(producer.is_valid());
-    DCHECK(consumer.is_valid());
-
-    response_body_consumer_handle_ = std::move(consumer);
-    shared_writer_ = new SharedWriter(std::move(producer));
-    handle_watcher_.Watch(shared_writer_->writer(), MOJO_HANDLE_SIGNAL_WRITABLE,
-                          base::Bind(&MojoAsyncResourceHandler::OnWritable,
-                                     base::Unretained(this)));
-    handle_watcher_.ArmOrNotify();
-  }
-
   bool defer = false;
   if (!AllocateWriterIOBuffer(&buffer_, &defer)) {
     controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
@@ -288,18 +283,23 @@
     return;
   }
 
-  // The first call to OnWillRead must return a buffer of at least
-  // kMinAllocationSize. If the Mojo buffer is too small, need to allocate an
-  // intermediary buffer.
-  if (first_call && static_cast<size_t>(buffer_->size()) < kMinAllocationSize) {
-    // The allocated buffer is too small, so need to create an intermediary one.
-    if (EndWrite(0) != MOJO_RESULT_OK) {
-      controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
-      return;
+  if (!did_check_for_intermediary_buffer_) {
+    did_check_for_intermediary_buffer_ = true;
+
+    // The first call to OnWillRead must return a buffer of at least
+    // kMinAllocationSize. If the Mojo buffer is too small, need to allocate an
+    // intermediary buffer.
+    if (static_cast<size_t>(buffer_->size()) < kMinAllocationSize) {
+      // The allocated buffer is too small, so need to create an intermediary
+      // one.
+      if (EndWrite(0) != MOJO_RESULT_OK) {
+        controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
+        return;
+      }
+      DCHECK(!is_using_io_buffer_not_from_writer_);
+      is_using_io_buffer_not_from_writer_ = true;
+      buffer_ = base::MakeRefCounted<net::IOBufferWithSize>(kMinAllocationSize);
     }
-    DCHECK(!is_using_io_buffer_not_from_writer_);
-    is_using_io_buffer_not_from_writer_ = true;
-    buffer_ = base::MakeRefCounted<net::IOBufferWithSize>(kMinAllocationSize);
   }
 
   *buf = buffer_;
@@ -356,13 +356,6 @@
     EnsureTransferSizeUpdate();
   }
 
-  if (response_body_consumer_handle_.is_valid()) {
-    // Send the data pipe on the first OnReadCompleted call.
-    url_loader_client_->OnStartLoadingResponseBody(
-        std::move(response_body_consumer_handle_));
-    response_body_consumer_handle_.reset();
-  }
-
   if (is_using_io_buffer_not_from_writer_) {
     // Couldn't allocate a large enough buffer on the data pipe in OnWillRead.
     DCHECK_EQ(0u, buffer_bytes_read_);
@@ -421,6 +414,7 @@
 }
 
 void MojoAsyncResourceHandler::ProceedWithResponse() {
+  was_proceed_with_response_called_ = true;
   DCHECK(did_defer_on_response_started_);
 
   request()->LogUnblocked();
@@ -651,8 +645,20 @@
   if (custom_reason == network::mojom::URLLoader::kClientDisconnectReason)
     info->set_custom_cancel_reason(description);
 
-  ResourceDispatcherHostImpl::Get()->CancelRequestFromRenderer(
-      GlobalRequestID(info->GetChildID(), info->GetRequestID()));
+  // Navigation requests are handled by the browser process until
+  // ProceedWithResponse() is called.
+  bool canceled_from_browser =
+      !was_proceed_with_response_called_ &&
+      IsResourceTypeFrame(
+          ResourceRequestInfoImpl::ForRequest(request())->GetResourceType());
+
+  if (canceled_from_browser) {
+    ResourceDispatcherHostImpl::Get()->CancelRequest(info->GetChildID(),
+                                                     info->GetRequestID());
+  } else {
+    ResourceDispatcherHostImpl::Get()->CancelRequestFromRenderer(
+        GlobalRequestID(info->GetChildID(), info->GetRequestID()));
+  }
 }
 
 int64_t MojoAsyncResourceHandler::CalculateRecentlyReceivedBytes() {
diff --git a/content/browser/loader/mojo_async_resource_handler.h b/content/browser/loader/mojo_async_resource_handler.h
index 26465a47f..b1b01b6 100644
--- a/content/browser/loader/mojo_async_resource_handler.h
+++ b/content/browser/loader/mojo_async_resource_handler.h
@@ -149,12 +149,14 @@
   bool has_checked_for_sufficient_resources_ = false;
   bool sent_received_response_message_ = false;
   bool is_using_io_buffer_not_from_writer_ = false;
+  bool was_proceed_with_response_called_ = false;
   // True if OnWillRead was deferred, in order to wait to be able to allocate a
   // buffer.
   bool did_defer_on_will_read_ = false;
   bool did_defer_on_writing_ = false;
   bool did_defer_on_redirect_ = false;
   bool did_defer_on_response_started_ = false;
+  bool did_check_for_intermediary_buffer_ = false;
 
   int64_t total_written_bytes_ = 0;
 
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc
index ab64cd8a..d3acc08 100644
--- a/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -1275,7 +1275,7 @@
 
   ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
 
-  ASSERT_FALSE(url_loader_client_.response_body().is_valid());
+  ASSERT_TRUE(url_loader_client_.response_body().is_valid());
 
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnReadCompleted("A"));
@@ -1328,7 +1328,7 @@
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnReadCompleted("B"));
 
-  ASSERT_FALSE(url_loader_client_.response_body().is_valid());
+  ASSERT_TRUE(url_loader_client_.response_body().is_valid());
   url_loader_client_.RunUntilResponseBodyArrived();
   ASSERT_TRUE(url_loader_client_.response_body().is_valid());
 
@@ -1542,8 +1542,6 @@
 
   // Prepare for loader read complete.
   ASSERT_TRUE(CallOnWillStartAndOnResponseStarted());
-  EXPECT_EQ(MockResourceLoader::Status::IDLE,
-            mock_loader_->OnWillStart(request_->url()));
   EXPECT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
   // Only headers are read by the time the response is started.
   mock_loader_->OnReadCompleted(kResponseHeaders);
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index 3b21258..ba1db40 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
+#include "base/test/bind_test_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
@@ -40,6 +41,8 @@
 #include "content/public/test/download_test_observer.h"
 #include "content/public/test/navigation_handle_observer.h"
 #include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_navigation_throttle.h"
+#include "content/public/test/test_navigation_throttle_inserter.h"
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_content_browser_client.h"
 #include "content/shell/browser/shell_download_manager_delegate.h"
@@ -1446,4 +1449,43 @@
                                 1);
 }
 
+// Regression test for https://crbug.com/872284.
+// A NavigationThrottle cancels a download in WillProcessResponse.
+// The navigation request must be canceled and it must also cancel the network
+// request. Failing to do so resulted in the network socket being leaked.
+IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
+                       CancelDownloadOnResponseStarted) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  GURL url(embedded_test_server()->GetURL("/title1.html"));
+  NavigateToURL(shell(), url);
+
+  // Block every iframe in WillProcessResponse.
+  content::TestNavigationThrottleInserter throttle_inserter(
+      shell()->web_contents(),
+      base::BindLambdaForTesting(
+          [&](NavigationHandle* handle) -> std::unique_ptr<NavigationThrottle> {
+            auto throttle = std::make_unique<TestNavigationThrottle>(handle);
+            throttle->SetResponse(TestNavigationThrottle::WILL_PROCESS_RESPONSE,
+                                  TestNavigationThrottle::SYNCHRONOUS,
+                                  NavigationThrottle::CANCEL_AND_IGNORE);
+
+            return throttle;
+          }));
+
+  // Insert enough iframes so that if sockets are not properly released: there
+  // will not be enough of them to complete all navigations. As of today, only 6
+  // sockets can be used simultaneously. So using 7 iframes is enough. This test
+  // uses 33 as a margin.
+  EXPECT_TRUE(ExecJs(shell(), R"(
+    for(let i = 0; i<33; ++i) {
+      let iframe = document.createElement('iframe');
+      iframe.src = './download-test1.lib'
+      document.body.appendChild(iframe);
+    }
+  )"));
+
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 0d1e75f..34a92a5 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -1304,7 +1304,7 @@
   // event gets dispatched.
   base::RunLoop run_loop;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, run_loop.QuitClosure(),
+      FROM_HERE, run_loop.QuitWhenIdleClosure(),
       base::TimeDelta::FromMilliseconds(100));
   run_loop.Run();
 
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index 90c8d39c..7c6aaed 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -424,7 +424,7 @@
       FROM_HERE, base::BindOnce(
                      [](media::AudioManager* audio_manager,
                         service_manager::mojom::ServiceRequest request) {
-                       service_manager::Service::RunUntilTermination(
+                       service_manager::Service::RunAsyncUntilTermination(
                            audio::CreateEmbeddedService(audio_manager,
                                                         std::move(request)));
                      },
@@ -634,7 +634,7 @@
   packaged_services_connection_->AddServiceRequestHandler(
       resource_coordinator::mojom::kServiceName,
       base::BindRepeating([](service_manager::mojom::ServiceRequest request) {
-        service_manager::Service::RunUntilTermination(
+        service_manager::Service::RunAsyncUntilTermination(
             std::make_unique<resource_coordinator::ResourceCoordinatorService>(
                 std::move(request)));
       }));
@@ -650,7 +650,7 @@
   packaged_services_connection_->AddServiceRequestHandler(
       tracing::mojom::kServiceName,
       base::BindRepeating([](service_manager::mojom::ServiceRequest request) {
-        service_manager::Service::RunUntilTermination(
+        service_manager::Service::RunAsyncUntilTermination(
             std::make_unique<tracing::TracingService>(std::move(request)));
       }));
 
@@ -716,7 +716,7 @@
           mojom::kNetworkServiceName,
           base::BindRepeating(
               [](service_manager::mojom::ServiceRequest request) {
-                service_manager::Service::RunUntilTermination(
+                service_manager::Service::RunAsyncUntilTermination(
                     CreateNetworkService(std::move(request)));
               }));
     } else {
@@ -885,7 +885,7 @@
             base::Unretained(GetContentClient()->browser())),
         std::move(request));
 #endif
-    service_manager::Service::RunUntilTermination(std::move(service));
+    service_manager::Service::RunAsyncUntilTermination(std::move(service));
     return;
   }
 
diff --git a/content/browser/tracing/etw_tracing_agent_win.cc b/content/browser/tracing/etw_tracing_agent_win.cc
deleted file mode 100644
index 391250a..0000000
--- a/content/browser/tracing/etw_tracing_agent_win.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2014 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/browser/tracing/etw_tracing_agent_win.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/base64.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/lazy_instance.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
-#include "base/task/post_task.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_config.h"
-#include "base/trace_event/trace_event_impl.h"
-#include "base/values.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "services/service_manager/public/cpp/connector.h"
-
-namespace content {
-
-namespace {
-
-EtwTracingAgent* g_etw_tracing_agent = nullptr;
-
-const char kETWTraceLabel[] = "systemTraceEvents";
-
-const int kEtwBufferSizeInKBytes = 16;
-const int kEtwBufferFlushTimeoutInSeconds = 1;
-
-std::string GuidToString(const GUID& guid) {
-  return base::StringPrintf("%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
-                            guid.Data1, guid.Data2, guid.Data3, guid.Data4[0],
-                            guid.Data4[1], guid.Data4[2], guid.Data4[3],
-                            guid.Data4[4], guid.Data4[5], guid.Data4[6],
-                            guid.Data4[7]);
-}
-
-}  // namespace
-
-EtwTracingAgent::EtwTracingAgent(service_manager::Connector* connector)
-    : BaseAgent(connector,
-                kETWTraceLabel,
-                tracing::mojom::TraceDataType::OBJECT,
-                false /* supports_explicit_clock_sync */,
-                base::kNullProcessId),
-      tracing_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::USER_VISIBLE})),
-      is_tracing_(false) {
-  DCHECK(!g_etw_tracing_agent);
-  g_etw_tracing_agent = this;
-}
-
-EtwTracingAgent::~EtwTracingAgent() {
-  if (is_tracing_)
-    StopKernelSessionTracing();
-  g_etw_tracing_agent = nullptr;
-}
-
-void EtwTracingAgent::StartTracing(const std::string& config,
-                                   base::TimeTicks coordinator_time,
-                                   Agent::StartTracingCallback callback) {
-  base::trace_event::TraceConfig trace_config(config);
-  // Activate kernel tracing.
-  if (!trace_config.IsSystraceEnabled() || !StartKernelSessionTracing()) {
-    std::move(callback).Run(false /* success */);
-    return;
-  }
-  is_tracing_ = true;
-
-  // Tracing agents, e.g. this, live as long as BrowserMainLoop lives and so
-  // using base::Unretained here is safe.
-  tracing_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&EtwTracingAgent::TraceAndConsumeOnTracingSequence,
-                     base::Unretained(this)));
-  std::move(callback).Run(true /* success */);
-}
-
-void EtwTracingAgent::StopAndFlush(tracing::mojom::RecorderPtr recorder) {
-  DCHECK(is_tracing_);
-  // Deactivate kernel tracing.
-  if (!StopKernelSessionTracing()) {
-    LOG(FATAL) << "Could not stop system tracing.";
-  }
-  recorder_ = std::move(recorder);
-  // Stop consuming and flush events. Tracing agents, e.g. this, live as long as
-  // BrowserMainLoop lives and so using base::Unretained here is safe.
-  tracing_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&EtwTracingAgent::FlushOnTracingSequence,
-                                base::Unretained(this)));
-}
-
-void EtwTracingAgent::OnStopSystemTracingDone(const std::string& output) {
-  recorder_->AddChunk(output);
-  recorder_.reset();
-  is_tracing_ = false;
-}
-
-bool EtwTracingAgent::StartKernelSessionTracing() {
-  // Enabled flags (tracing facilities).
-  uint32_t enabled_flags = EVENT_TRACE_FLAG_IMAGE_LOAD |
-                           EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_THREAD |
-                           EVENT_TRACE_FLAG_CSWITCH;
-
-  EVENT_TRACE_PROPERTIES& p = *properties_.get();
-  p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
-  p.FlushTimer = kEtwBufferFlushTimeoutInSeconds;
-  p.BufferSize = kEtwBufferSizeInKBytes;
-  p.LogFileNameOffset = 0;
-  p.EnableFlags = enabled_flags;
-  p.Wnode.ClientContext = 1;  // QPC timer accuracy.
-
-  HRESULT hr = base::win::EtwTraceController::Start(
-      KERNEL_LOGGER_NAME, &properties_, &session_handle_);
-
-  // It's possible that a previous tracing session has been orphaned. If so
-  // try stopping and restarting it.
-  if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) {
-    VLOG(1) << "Session already exists, stopping and restarting it.";
-    hr = base::win::EtwTraceController::Stop(
-        KERNEL_LOGGER_NAME, &properties_);
-    if (FAILED(hr)) {
-      VLOG(1) << "EtwTraceController::Stop failed with " << hr << ".";
-      return false;
-    }
-
-    // The session was successfully shutdown so try to restart it.
-    hr = base::win::EtwTraceController::Start(
-        KERNEL_LOGGER_NAME, &properties_, &session_handle_);
-  }
-
-  if (FAILED(hr)) {
-    VLOG(1) << "EtwTraceController::Start failed with " << hr << ".";
-    return false;
-  }
-
-  return true;
-}
-
-bool EtwTracingAgent::StopKernelSessionTracing() {
-  HRESULT hr = base::win::EtwTraceController::Stop(
-      KERNEL_LOGGER_NAME, &properties_);
-  return SUCCEEDED(hr);
-}
-
-// static
-EtwTracingAgent* EtwTracingAgent::GetInstance() {
-  return g_etw_tracing_agent;
-}
-
-// static
-void EtwTracingAgent::ProcessEvent(EVENT_TRACE* event) {
-  auto* instance = EtwTracingAgent::GetInstance();
-  // Ignore events that are received after the browser is closed.
-  if (instance)
-    instance->AppendEventToBuffer(event);
-}
-
-void EtwTracingAgent::AddSyncEventToBuffer() {
-  // Sync the clocks.
-  base::Time walltime = base::subtle::TimeNowFromSystemTimeIgnoringOverride();
-  base::TimeTicks now = TRACE_TIME_TICKS_NOW();
-
-  LARGE_INTEGER walltime_in_us;
-  walltime_in_us.QuadPart = walltime.ToInternalValue();
-  LARGE_INTEGER now_in_us;
-  now_in_us.QuadPart = now.ToInternalValue();
-
-  // Add fields to the event.
-  auto value = std::make_unique<base::DictionaryValue>();
-  value->SetString("guid", "ClockSync");
-  value->SetString("walltime",
-                   base::StringPrintf("%08lX%08lX", walltime_in_us.HighPart,
-                                      walltime_in_us.LowPart));
-  value->SetString("tick", base::StringPrintf("%08lX%08lX", now_in_us.HighPart,
-                                              now_in_us.LowPart));
-
-  // Append it to the events buffer.
-  events_->Append(std::move(value));
-}
-
-void EtwTracingAgent::AppendEventToBuffer(EVENT_TRACE* event) {
-  auto value = std::make_unique<base::DictionaryValue>();
-
-  // Add header fields to the event.
-  LARGE_INTEGER ts_us;
-  ts_us.QuadPart = event->Header.TimeStamp.QuadPart / 10;
-  value->SetString(
-      "ts", base::StringPrintf("%08lX%08lX", ts_us.HighPart, ts_us.LowPart));
-
-  value->SetString("guid", GuidToString(event->Header.Guid));
-
-  value->SetInteger("op", event->Header.Class.Type);
-  value->SetInteger("ver", event->Header.Class.Version);
-  value->SetInteger("pid", static_cast<int>(event->Header.ProcessId));
-  value->SetInteger("tid", static_cast<int>(event->Header.ThreadId));
-  value->SetInteger("cpu", event->BufferContext.ProcessorNumber);
-
-  // Base64 encode the payload bytes.
-  base::StringPiece buffer(static_cast<const char*>(event->MofData),
-                           event->MofLength);
-  std::string payload;
-  base::Base64Encode(buffer, &payload);
-  value->SetString("payload", payload);
-
-  // Append it to the events buffer.
-  events_->Append(std::move(value));
-}
-
-void EtwTracingAgent::TraceAndConsumeOnTracingSequence() {
-  DCHECK(tracing_task_runner_->RunsTasksInCurrentSequence());
-
-  // Create the events buffer.
-  events_.reset(new base::ListValue());
-
-  // Output a clock sync event.
-  AddSyncEventToBuffer();
-
-  HRESULT hr = OpenRealtimeSession(KERNEL_LOGGER_NAME);
-  if (FAILED(hr))
-    return;
-  Consume();
-  Close();
-}
-
-void EtwTracingAgent::FlushOnTracingSequence() {
-  DCHECK(tracing_task_runner_->RunsTasksInCurrentSequence());
-
-  // Add the header information to the stream.
-  auto header = std::make_unique<base::DictionaryValue>();
-  header->SetString("name", "ETW");
-
-  // Release and pass the events buffer.
-  header->Set("content", std::move(events_));
-
-  // Serialize the results as a JSon string.
-  std::string output;
-  JSONStringValueSerializer serializer(&output);
-  serializer.Serialize(*header.get());
-  // TODO(chiniforooshan): Find a way to eliminate the extra string copy here.
-  // This is not too bad for now, since it happens only once when tracing is
-  // stopped.
-  DCHECK_EQ('{', output.front());
-  DCHECK_EQ('}', output.back());
-  output = output.substr(1, output.size() - 2);
-
-  // Tracing agents, e.g. this, live as long as BrowserMainLoop lives and so
-  // using base::Unretained here is safe.
-  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
-                           base::Bind(&EtwTracingAgent::OnStopSystemTracingDone,
-                                      base::Unretained(this), output));
-}
-
-}  // namespace content
diff --git a/content/browser/tracing/etw_tracing_agent_win.h b/content/browser/tracing/etw_tracing_agent_win.h
deleted file mode 100644
index 762e57e..0000000
--- a/content/browser/tracing/etw_tracing_agent_win.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 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_BROWSER_TRACING_ETW_TRACING_AGENT_H_
-#define CONTENT_BROWSER_TRACING_ETW_TRACING_AGENT_H_
-
-#include <memory>
-#include <string>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/sequenced_task_runner.h"
-#include "base/values.h"
-#include "base/win/event_trace_consumer.h"
-#include "base/win/event_trace_controller.h"
-#include "services/tracing/public/cpp/base_agent.h"
-#include "services/tracing/public/mojom/tracing.mojom.h"
-
-namespace service_manager {
-class Connector;
-}
-
-namespace content {
-
-class EtwTracingAgent : public base::win::EtwTraceConsumerBase<EtwTracingAgent>,
-                        public tracing::BaseAgent {
- public:
-  explicit EtwTracingAgent(service_manager::Connector* connector);
-
-  // Retrieve the ETW consumer instance.
-  static EtwTracingAgent* GetInstance();
-
- private:
-  friend std::default_delete<EtwTracingAgent>;
-
-  ~EtwTracingAgent() override;
-
-  void AddSyncEventToBuffer();
-  void AppendEventToBuffer(EVENT_TRACE* event);
-
-  // tracing::mojom::Agent. Called by Mojo internals on the UI thread.
-  void StartTracing(const std::string& config,
-                    base::TimeTicks coordinator_time,
-                    Agent::StartTracingCallback callback) override;
-  void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
-
-  // Static override of EtwTraceConsumerBase::ProcessEvent.
-  // @param event the raw ETW event to process.
-  friend class base::win::EtwTraceConsumerBase<EtwTracingAgent>;
-  static void ProcessEvent(EVENT_TRACE* event);
-
-  // Request the ETW trace controller to activate the kernel tracing.
-  // returns true on success, false if the kernel tracing isn't activated.
-  bool StartKernelSessionTracing();
-
-  // Request the ETW trace controller to deactivate the kernel tracing.
-  // @param callback the callback to call with the consumed events.
-  // @returns true on success, false if an error occurred.
-  bool StopKernelSessionTracing();
-
-  void OnStopSystemTracingDone(const std::string& output);
-  void TraceAndConsumeOnTracingSequence();
-  void FlushOnTracingSequence();
-
-  // Task runner used to communicate with the native tracing interface.
-  scoped_refptr<base::SequencedTaskRunner> tracing_task_runner_;
-
-  std::unique_ptr<base::ListValue> events_;
-  TRACEHANDLE session_handle_;
-  base::win::EtwTraceProperties properties_;
-  tracing::mojom::RecorderPtr recorder_;
-  bool is_tracing_;
-
-  DISALLOW_COPY_AND_ASSIGN(EtwTracingAgent);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_TRACING_ETW_TRACING_AGENT_H_
diff --git a/content/browser/tracing/tracing_controller_browsertest.cc b/content/browser/tracing/tracing_controller_browsertest.cc
index 481af66..a267fe7a5 100644
--- a/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/content/browser/tracing/tracing_controller_browsertest.cc
@@ -519,7 +519,7 @@
   run_loop.Run();
 }
 
-// Only CrOS, and Cast support system tracing.
+// Only CrOS and Cast support system tracing.
 #if defined(OS_CHROMEOS) || (defined(IS_CHROMECAST) && defined(OS_LINUX))
 #define MAYBE_SystemTraceEvents SystemTraceEvents
 #else
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index ab897f90..ff179d793 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -50,7 +50,6 @@
 
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
-#include "content/browser/tracing/etw_tracing_agent_win.h"
 #endif
 
 #if defined(OS_ANDROID)
@@ -136,8 +135,6 @@
   agents_.push_back(std::make_unique<CrOSTracingAgent>(connector));
 #elif defined(CAST_TRACING_AGENT)
   agents_.push_back(std::make_unique<CastTracingAgent>(connector));
-#elif defined(OS_WIN)
-  agents_.push_back(std::make_unique<EtwTracingAgent>(connector));
 #endif
 
   auto trace_event_agent = tracing::TraceEventAgent::Create(
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index ef486db..7b3fab6f 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -421,21 +421,21 @@
     {"view-source.css", IDR_UASTYLE_VIEW_SOURCE_CSS, ui::SCALE_FACTOR_NONE,
      true},
     // Not limited to Android since it's used for mobile layouts in inspector.
-    {"themeChromiumAndroid.css", IDR_UASTYLE_THEME_CHROMIUM_ANDROID_CSS,
+    {"android.css", IDR_UASTYLE_THEME_CHROMIUM_ANDROID_CSS,
      ui::SCALE_FACTOR_NONE, true},
     // Not limited to Android since it's used for mobile layouts in inspector.
     {"fullscreenAndroid.css", IDR_UASTYLE_FULLSCREEN_ANDROID_CSS,
      ui::SCALE_FACTOR_NONE, true},
     // Not limited to Linux since it's used for mobile layouts in inspector.
-    {"themeChromiumLinux.css", IDR_UASTYLE_THEME_CHROMIUM_LINUX_CSS,
+    {"linux.css", IDR_UASTYLE_THEME_CHROMIUM_LINUX_CSS,
      ui::SCALE_FACTOR_NONE, true},
-    {"themeInputMultipleFields.css",
+    {"input_multiple_fields.css",
      IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS, ui::SCALE_FACTOR_NONE, true},
 #if defined(OS_MACOSX)
-    {"themeMac.css", IDR_UASTYLE_THEME_MAC_CSS, ui::SCALE_FACTOR_NONE, true},
+    {"mac.css", IDR_UASTYLE_THEME_MAC_CSS, ui::SCALE_FACTOR_NONE, true},
 #endif
-    {"themeWin.css", IDR_UASTYLE_THEME_WIN_CSS, ui::SCALE_FACTOR_NONE, true},
-    {"themeWinQuirks.css", IDR_UASTYLE_THEME_WIN_QUIRKS_CSS,
+    {"win.css", IDR_UASTYLE_THEME_WIN_CSS, ui::SCALE_FACTOR_NONE, true},
+    {"win_quirks.css", IDR_UASTYLE_THEME_WIN_QUIRKS_CSS,
      ui::SCALE_FACTOR_NONE, true},
     {"svg.css", IDR_UASTYLE_SVG_CSS, ui::SCALE_FACTOR_NONE, true},
     {"mathml.css", IDR_UASTYLE_MATHML_CSS, ui::SCALE_FACTOR_NONE, true},
diff --git a/content/common/mime_sniffing_throttle_unittest.cc b/content/common/mime_sniffing_throttle_unittest.cc
index ab74617f..ea5bfe6 100644
--- a/content/common/mime_sniffing_throttle_unittest.cc
+++ b/content/common/mime_sniffing_throttle_unittest.cc
@@ -300,6 +300,33 @@
 
   // Call OnComplete() without sending body.
   delegate->source_loader_client()->OnComplete(
+      network::URLLoaderCompletionStatus(net::ERR_FAILED));
+  delegate->destination_loader_client()->RunUntilComplete();
+
+  // The mime type should be updated to the default mime type ("text/plain").
+  EXPECT_TRUE(delegate->destination_loader_client()->has_received_response());
+  EXPECT_EQ("text/plain",
+            delegate->destination_loader_client()->response_head().mime_type);
+}
+
+TEST_F(MimeSniffingThrottleTest, EmptyBody) {
+  auto throttle = std::make_unique<MimeSniffingThrottle>();
+  auto delegate = std::make_unique<MockDelegate>();
+  throttle->set_delegate(delegate.get());
+
+  GURL response_url("https://example.com");
+  network::ResourceResponseHead response_head;
+  bool defer = false;
+  throttle->WillProcessResponse(response_url, &response_head, &defer);
+  EXPECT_TRUE(defer);
+  EXPECT_TRUE(delegate->is_intercepted());
+
+  mojo::DataPipe pipe;
+  delegate->source_loader_client()->OnStartLoadingResponseBody(
+      std::move(pipe.consumer_handle));
+  pipe.producer_handle.reset();  // The pipe is empty.
+
+  delegate->source_loader_client()->OnComplete(
       network::URLLoaderCompletionStatus());
   delegate->destination_loader_client()->RunUntilComplete();
 
diff --git a/content/common/mime_sniffing_url_loader.cc b/content/common/mime_sniffing_url_loader.cc
index d11e5ff..38cf1e1 100644
--- a/content/common/mime_sniffing_url_loader.cc
+++ b/content/common/mime_sniffing_url_loader.cc
@@ -109,9 +109,8 @@
   DCHECK(!complete_status_.has_value());
   switch (state_) {
     case State::kWaitForBody:
-      // OnComplete() is called without OnStartLoadingResponseBody(). There is
-      // no response body in this case. Use |kDefaultMimeType| as its mime type
-      // even though it's empty.
+      // An error occured before receiving any data.
+      DCHECK_NE(net::OK, status.error_code);
       state_ = State::kCompleted;
       response_head_.mime_type = kDefaultMimeType;
       if (!throttle_) {
@@ -231,19 +230,9 @@
 void MimeSniffingURLLoader::CompleteSniffing() {
   DCHECK_EQ(State::kSniffing, state_);
   if (buffered_body_.empty()) {
-    // A data pipe for the body was received but no body was provided. Don't
-    // propagate OnStartLoadingResponseBody() in this case. We treat this
-    // situation as the same as when OnStartLoadingResponseBody() was not
-    // called.
-    //
-    // TODO(crbug.com/826868): Remove this once all loaders are aligned.
-    state_ = State::kWaitForBody;
-    if (complete_status_.has_value()) {
-      auto status = complete_status_.value();
-      complete_status_.reset();
-      OnComplete(status);
-    }
-    return;
+    // The URLLoader ended before sending any data. There is not enough
+    // informations to determine the MIME type.
+    response_head_.mime_type = kDefaultMimeType;
   }
 
   state_ = State::kSending;
@@ -272,7 +261,13 @@
   // Call OnComplete() if OnComplete() has already been called.
   if (complete_status_.has_value())
     destination_url_loader_client_->OnComplete(complete_status_.value());
-  SendReceivedBodyToClient();
+
+  if (bytes_remaining_in_buffer_) {
+    SendReceivedBodyToClient();
+    return;
+  }
+
+  CompleteSending();
 }
 
 void MimeSniffingURLLoader::CompleteSending() {
diff --git a/content/gpu/gpu_service_factory.cc b/content/gpu/gpu_service_factory.cc
index 07f13ddf..56d9a6b3 100644
--- a/content/gpu/gpu_service_factory.cc
+++ b/content/gpu/gpu_service_factory.cc
@@ -73,19 +73,19 @@
         gpu_workarounds_, gpu_feature_info_, task_runner_,
         media_gpu_channel_manager_, android_overlay_factory_cb_,
         std::move(cdm_proxy_factory_cb));
-    task_runner->PostTask(FROM_HERE,
-                          base::BindOnce(
-                              [](FactoryCallback factory) {
-                                service_manager::Service::RunUntilTermination(
-                                    std::move(factory).Run());
-                              },
-                              std::move(factory)));
+    task_runner->PostTask(
+        FROM_HERE, base::BindOnce(
+                       [](FactoryCallback factory) {
+                         service_manager::Service::RunAsyncUntilTermination(
+                             std::move(factory).Run());
+                       },
+                       std::move(factory)));
     return true;
   }
 #endif  // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
 
   if (service_name == shape_detection::mojom::kServiceName) {
-    service_manager::Service::RunUntilTermination(
+    service_manager::Service::RunAsyncUntilTermination(
         std::make_unique<shape_detection::ShapeDetectionService>(
             std::move(request)));
     return true;
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index a113eab..36cdbc0 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -18,7 +18,7 @@
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/shell/browser/shell_content_browser_client.h"
 #include "content/shell/common/shell_switches.h"
-#include "content/shell/renderer/layout_test/layout_test_content_renderer_client.h"
+#include "content/shell/renderer/web_test/web_test_content_renderer_client.h"
 #include "content/test/test_content_client.h"
 
 #if defined(OS_ANDROID)
@@ -70,7 +70,7 @@
     // destroyed.
     ContentRendererClient* old_client =
         switches::IsRunWebTestsSwitchPresent()
-            ? SetRendererClientForTesting(new LayoutTestContentRendererClient)
+            ? SetRendererClientForTesting(new WebTestContentRendererClient)
             : SetRendererClientForTesting(new ShellContentRendererClient);
     // No-one should have set this value before we did.
     DCHECK(!old_client);
diff --git a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
index 90bc2ab..38ef5fb 100644
--- a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
+++ b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -1114,6 +1114,9 @@
               CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight)));
   message_loop_controller_.RunAndWaitForStatus(
       media::PipelineStatus::PIPELINE_OK);
+  // The exact ordering of delayed vs non-delayed tasks is not defined.
+  // Make sure we run all non-delayed tasks before testing state.
+  base::RunLoop().RunUntilIdle();
   blink::WebSize natural_size = player_->NaturalSize();
   // Check that height and width are flipped.
   EXPECT_EQ(kStandardHeight, natural_size.width);
@@ -1132,6 +1135,7 @@
   }
   message_loop_controller_.RunAndWaitForStatus(
       media::PipelineStatus::PIPELINE_OK);
+  base::RunLoop().RunUntilIdle();
   natural_size = player_->NaturalSize();
   EXPECT_EQ(kStandardHeight, natural_size.height);
   EXPECT_EQ(kStandardWidth, natural_size.width);
@@ -1172,6 +1176,9 @@
               CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight)));
   message_loop_controller_.RunAndWaitForStatus(
       media::PipelineStatus::PIPELINE_OK);
+  // The exact ordering of delayed vs non-delayed tasks is not defined.
+  // Make sure we run all non-delayed tasks before testing state.
+  base::RunLoop().RunUntilIdle();
   if (!enable_surface_layer_for_video_) {
     ASSERT_TRUE(layer_ != nullptr);
     EXPECT_TRUE(layer_->contents_opaque());
@@ -1187,6 +1194,7 @@
   }
   message_loop_controller_.RunAndWaitForStatus(
       media::PipelineStatus::PIPELINE_OK);
+  base::RunLoop().RunUntilIdle();
   if (!enable_surface_layer_for_video_) {
     EXPECT_FALSE(layer_->contents_opaque());
   }
@@ -1201,6 +1209,7 @@
   }
   message_loop_controller_.RunAndWaitForStatus(
       media::PipelineStatus::PIPELINE_OK);
+  base::RunLoop().RunUntilIdle();
   if (!enable_surface_layer_for_video_)
     EXPECT_TRUE(layer_->contents_opaque());
 
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index e0bd1f69..3aa93d2a 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1295,7 +1295,7 @@
   unobscured_rect_ = unobscured;
 
   view_data_.rect = PP_FromGfxRect(window);
-  view_data_.clip_rect = PP_FromGfxRect(clip);
+  view_data_.clip_rect = PP_FromGfxRect(new_clip);
   view_data_.device_scale = container_->DeviceScaleFactor();
   view_data_.css_scale =
       container_->PageZoomFactor() * container_->PageScaleFactor();
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index e09a908..ed59ce35 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/debug/debugger.h"
 #include "base/debug/leak_annotations.h"
+#include "base/feature_list.h"
 #include "base/i18n/rtl.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram_macros.h"
@@ -18,6 +19,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/system/sys_info.h"
+#include "base/task/sequence_manager/sequence_manager.h"
 #include "base/threading/platform_thread.h"
 #include "base/timer/hi_res_timer_manager.h"
 #include "base/trace_event/trace_event.h"
@@ -59,6 +61,10 @@
 
 namespace content {
 namespace {
+
+const base::Feature kMainThreadUsesSequenceManager{
+    "BlinkMainThreadUsesSequenceManager", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // This function provides some ways to test crash and assertion handling
 // behavior of the renderer.
 static void HandleRendererErrorTestParameters(
@@ -70,6 +76,18 @@
     WaitForDebugger("Renderer");
 }
 
+std::unique_ptr<base::MessagePump> CreateMainThreadMessagePump() {
+#if defined(OS_MACOSX)
+  // As long as scrollbars on Mac are painted with Cocoa, the message pump
+  // needs to be backed by a Foundation-level loop to process NSTimers. See
+  // http://crbug.com/306348#c24 for details.
+  return std::make_unique<base::MessagePumpNSRunLoop>();
+#else
+  return base::MessageLoop::CreateMessagePumpForType(
+      base::MessageLoop::TYPE_DEFAULT);
+#endif
+}
+
 }  // namespace
 
 // mainline routine for running as the Renderer process
@@ -121,17 +139,6 @@
   HandleRendererErrorTestParameters(command_line);
 
   RendererMainPlatformDelegate platform(parameters);
-#if defined(OS_MACOSX)
-  // As long as scrollbars on Mac are painted with Cocoa, the message pump
-  // needs to be backed by a Foundation-level loop to process NSTimers. See
-  // http://crbug.com/306348#c24 for details.
-  std::unique_ptr<base::MessagePump> pump(new base::MessagePumpNSRunLoop());
-  std::unique_ptr<base::MessageLoop> main_message_loop(
-      new base::MessageLoop(std::move(pump)));
-#else
-  // The main message loop of the renderer services doesn't have IO or UI tasks.
-  std::unique_ptr<base::MessageLoop> main_message_loop(new base::MessageLoop());
-#endif
 
   base::PlatformThread::SetName("CrRendererMain");
 
@@ -149,9 +156,20 @@
       initial_virtual_time = base::Time::FromDoubleT(initial_time);
     }
   }
-  std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler(
-      blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
-          initial_virtual_time));
+
+  std::unique_ptr<base::MessageLoop> main_message_loop;
+  std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler;
+  if (!base::FeatureList::IsEnabled(kMainThreadUsesSequenceManager)) {
+    main_message_loop =
+        std::make_unique<base::MessageLoop>(CreateMainThreadMessagePump());
+    main_thread_scheduler =
+        blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
+            /*message_pump=*/nullptr, initial_virtual_time);
+  } else {
+    main_thread_scheduler =
+        blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
+            CreateMainThreadMessagePump(), initial_virtual_time);
+  }
 
   platform.PlatformInitialize();
 
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 7431fdc..791da47 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -19,8 +19,8 @@
 } else if (is_mac) {
   import("//build/config/mac/rules.gni")
   import("//build/mac/tweak_info_plist.gni")
-  import("//ui/gl/features.gni")
   import("//third_party/icu/config.gni")
+  import("//ui/gl/features.gni")
   import("//v8/gni/v8.gni")
 }
 
@@ -200,26 +200,26 @@
     "common/shell_switches.h",
     "gpu/shell_content_gpu_client.cc",
     "gpu/shell_content_gpu_client.h",
-    "renderer/layout_test/blink_test_helpers.cc",
-    "renderer/layout_test/blink_test_helpers.h",
-    "renderer/layout_test/blink_test_runner.cc",
-    "renderer/layout_test/blink_test_runner.h",
-    "renderer/layout_test/layout_test_content_renderer_client.cc",
-    "renderer/layout_test/layout_test_content_renderer_client.h",
-    "renderer/layout_test/layout_test_render_frame_observer.cc",
-    "renderer/layout_test/layout_test_render_frame_observer.h",
-    "renderer/layout_test/layout_test_render_thread_observer.cc",
-    "renderer/layout_test/layout_test_render_thread_observer.h",
-    "renderer/layout_test/test_media_stream_renderer_factory.cc",
-    "renderer/layout_test/test_media_stream_renderer_factory.h",
-    "renderer/layout_test/test_media_stream_video_renderer.cc",
-    "renderer/layout_test/test_media_stream_video_renderer.h",
-    "renderer/layout_test/test_websocket_handshake_throttle_provider.cc",
-    "renderer/layout_test/test_websocket_handshake_throttle_provider.h",
     "renderer/shell_content_renderer_client.cc",
     "renderer/shell_content_renderer_client.h",
     "renderer/shell_render_view_observer.cc",
     "renderer/shell_render_view_observer.h",
+    "renderer/web_test/blink_test_helpers.cc",
+    "renderer/web_test/blink_test_helpers.h",
+    "renderer/web_test/blink_test_runner.cc",
+    "renderer/web_test/blink_test_runner.h",
+    "renderer/web_test/test_media_stream_renderer_factory.cc",
+    "renderer/web_test/test_media_stream_renderer_factory.h",
+    "renderer/web_test/test_media_stream_video_renderer.cc",
+    "renderer/web_test/test_media_stream_video_renderer.h",
+    "renderer/web_test/test_websocket_handshake_throttle_provider.cc",
+    "renderer/web_test/test_websocket_handshake_throttle_provider.h",
+    "renderer/web_test/web_test_content_renderer_client.cc",
+    "renderer/web_test/web_test_content_renderer_client.h",
+    "renderer/web_test/web_test_render_frame_observer.cc",
+    "renderer/web_test/web_test_render_frame_observer.h",
+    "renderer/web_test/web_test_render_thread_observer.cc",
+    "renderer/web_test/web_test_render_thread_observer.h",
     "utility/shell_content_utility_client.cc",
     "utility/shell_content_utility_client.h",
   ]
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index fe768c59..fbce89c 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -36,8 +36,8 @@
 #include "content/shell/common/shell_content_client.h"
 #include "content/shell/common/shell_switches.h"
 #include "content/shell/gpu/shell_content_gpu_client.h"
-#include "content/shell/renderer/layout_test/layout_test_content_renderer_client.h"
 #include "content/shell/renderer/shell_content_renderer_client.h"
+#include "content/shell/renderer/web_test/web_test_content_renderer_client.h"
 #include "content/shell/utility/shell_content_utility_client.h"
 #include "gpu/config/gpu_switches.h"
 #include "ipc/ipc_buildflags.h"
@@ -453,7 +453,7 @@
 
 ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
   renderer_client_.reset(switches::IsRunWebTestsSwitchPresent()
-                             ? new LayoutTestContentRendererClient
+                             ? new WebTestContentRendererClient
                              : new ShellContentRendererClient);
 
   return renderer_client_.get();
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index f7a9c24..d6d9dfd 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -71,7 +71,7 @@
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/layout_test/layout_test_utils.h"
 #include "content/shell/common/shell_messages.h"
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
 #include "content/shell/test_runner/test_common.h"
 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
 #include "services/network/public/cpp/features.h"
diff --git a/content/shell/browser/layout_test/layout_test_browser_main.cc b/content/shell/browser/layout_test/layout_test_browser_main.cc
index d02d967c..d434d94 100644
--- a/content/shell/browser/layout_test/layout_test_browser_main.cc
+++ b/content/shell/browser/layout_test/layout_test_browser_main.cc
@@ -28,7 +28,7 @@
 #include "content/shell/browser/shell.h"
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_switches.h"
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
 #include "gpu/config/gpu_switches.h"
 #include "net/base/filename_util.h"
 
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index b5bf6e4..393a34c2 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -34,7 +34,7 @@
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_messages.h"
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
 #include "content/test/mock_clipboard_host.h"
 #include "content/test/mock_platform_notification_service.h"
 #include "device/bluetooth/test/fake_bluetooth.h"
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 423e0c6..0b32b02c 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -231,7 +231,7 @@
     service_manager::mojom::ServiceRequest request) {
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
   if (service_name == media::mojom::kMediaServiceName) {
-    service_manager::Service::RunUntilTermination(
+    service_manager::Service::RunAsyncUntilTermination(
         media::CreateMediaServiceForTesting(std::move(request)));
   }
 #endif
diff --git a/content/shell/renderer/layout_test/blink_test_helpers.cc b/content/shell/renderer/web_test/blink_test_helpers.cc
similarity index 97%
rename from content/shell/renderer/layout_test/blink_test_helpers.cc
rename to content/shell/renderer/web_test/blink_test_helpers.cc
index ea7f36e..f383912 100644
--- a/content/shell/renderer/layout_test/blink_test_helpers.cc
+++ b/content/shell/renderer/web_test/blink_test_helpers.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
 
 #include "base/command_line.h"
 #include "base/files/file_util.h"
@@ -89,11 +89,9 @@
   to->allow_running_insecure_content = from.allow_running_of_insecure_content;
   to->should_respect_image_orientation = from.should_respect_image_orientation;
   to->allow_file_access_from_file_urls = from.allow_file_access_from_file_urls;
-  to->web_security_enabled =
-      from.web_security_enabled;
+  to->web_security_enabled = from.web_security_enabled;
   to->disable_reading_from_canvas = from.disable_reading_from_canvas;
-  to->strict_mixed_content_checking =
-      from.strict_mixed_content_checking;
+  to->strict_mixed_content_checking = from.strict_mixed_content_checking;
   to->strict_powerful_feature_restrictions =
       from.strict_powerful_feature_restrictions;
   to->spatial_navigation_enabled = from.spatial_navigation_enabled;
diff --git a/content/shell/renderer/layout_test/blink_test_helpers.h b/content/shell/renderer/web_test/blink_test_helpers.h
similarity index 86%
rename from content/shell/renderer/layout_test/blink_test_helpers.h
rename to content/shell/renderer/web_test/blink_test_helpers.h
index f463198..63d72f6 100644
--- a/content/shell/renderer/layout_test/blink_test_helpers.h
+++ b/content/shell/renderer/web_test/blink_test_helpers.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_HELPERS_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_HELPERS_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_HELPERS_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_HELPERS_H_
 
 #include "third_party/blink/public/platform/web_url.h"
 
@@ -39,4 +39,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_HELPERS_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_HELPERS_H_
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/web_test/blink_test_runner.cc
similarity index 94%
rename from content/shell/renderer/layout_test/blink_test_runner.cc
rename to content/shell/renderer/web_test/blink_test_runner.cc
index d9bed3a4..99e897bf 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/web_test/blink_test_runner.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/blink_test_runner.h"
+#include "content/shell/renderer/web_test/blink_test_runner.h"
 
 #include <stddef.h>
 
@@ -44,8 +44,8 @@
 #include "content/shell/common/layout_test/layout_test_messages.h"
 #include "content/shell/common/shell_messages.h"
 #include "content/shell/common/shell_switches.h"
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
-#include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/web_test_render_thread_observer.h"
 #include "content/shell/test_runner/app_banner_service.h"
 #include "content/shell/test_runner/gamepad_controller.h"
 #include "content/shell/test_runner/layout_and_paint_async_then.h"
@@ -93,19 +93,18 @@
 using blink::Platform;
 using blink::WebContextMenuData;
 using blink::WebElement;
-using blink::WebLocalFrame;
-using blink::WebHistoryItem;
 using blink::WebFrame;
+using blink::WebHistoryItem;
 using blink::WebLocalFrame;
 using blink::WebPoint;
 using blink::WebRect;
 using blink::WebScriptSource;
 using blink::WebSize;
 using blink::WebString;
+using blink::WebTestingSupport;
 using blink::WebURL;
 using blink::WebURLError;
 using blink::WebURLRequest;
-using blink::WebTestingSupport;
 using blink::WebVector;
 using blink::WebView;
 
@@ -174,8 +173,7 @@
       is_main_window_(false),
       focus_on_next_commit_(false) {}
 
-BlinkTestRunner::~BlinkTestRunner() {
-}
+BlinkTestRunner::~BlinkTestRunner() {}
 
 // WebTestDelegate  -----------------------------------------------------------
 
@@ -211,14 +209,14 @@
   for (size_t i = 0; i < absolute_filenames.size(); ++i)
     files.push_back(blink::WebStringToFilePath(absolute_filenames[i]));
   std::string filesystem_id;
-  Send(new LayoutTestHostMsg_RegisterIsolatedFileSystem(
-      routing_id(), files, &filesystem_id));
+  Send(new LayoutTestHostMsg_RegisterIsolatedFileSystem(routing_id(), files,
+                                                        &filesystem_id));
   return WebString::FromUTF8(filesystem_id);
 }
 
 long long BlinkTestRunner::GetCurrentTimeInMillisecond() {
-  return base::TimeDelta(base::Time::Now() -
-                         base::Time::UnixEpoch()).ToInternalValue() /
+  return base::TimeDelta(base::Time::Now() - base::Time::UnixEpoch())
+             .ToInternalValue() /
          base::Time::kMicrosecondsPerMillisecond;
 }
 
@@ -240,8 +238,8 @@
     return WebURL();
 
   std::string contents;
-  Send(new LayoutTestHostMsg_ReadFileToString(
-        routing_id(), local_path, &contents));
+  Send(new LayoutTestHostMsg_ReadFileToString(routing_id(), local_path,
+                                              &contents));
 
   std::string contents_base64;
   base::Base64Encode(contents, &contents_base64);
@@ -339,8 +337,8 @@
 }
 
 void BlinkTestRunner::EnableUseZoomForDSF() {
-  base::CommandLine::ForCurrentProcess()->
-      AppendSwitch(switches::kEnableUseZoomForDSF);
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableUseZoomForDSF);
 }
 
 bool BlinkTestRunner::IsUseZoomForDSFEnabled() {
@@ -415,7 +413,7 @@
   // layout flag changes in either OnReplicateTestConfiguration or
   // OnSetTestConfiguration.
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   if (!interfaces->TestIsRunning())
     return;
 
@@ -425,7 +423,7 @@
 
 void BlinkTestRunner::TestFinished() {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   // We might get multiple TestFinished calls, ensure to only process the dump
   // once.
   if (!interfaces->TestIsRunning())
@@ -481,7 +479,7 @@
 void BlinkTestRunner::CaptureLocalAudioDump() {
   TRACE_EVENT0("shell", "BlinkTestRunner::CaptureLocalAudioDump");
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   if (!interfaces->TestRunner()->ShouldDumpAsAudio())
     return;
 
@@ -492,7 +490,7 @@
 void BlinkTestRunner::CaptureLocalLayoutDump() {
   TRACE_EVENT0("shell", "BlinkTestRunner::CaptureLocalLayoutDump");
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
 
   if (interfaces->TestRunner()->ShouldDumpAsAudio())
     return;
@@ -514,7 +512,7 @@
 bool BlinkTestRunner::CaptureLocalPixelsDump() {
   TRACE_EVENT0("shell", "BlinkTestRunner::CaptureLocalPixelsDump");
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   if (!interfaces->TestRunner()->ShouldGeneratePixelResults() ||
       interfaces->TestRunner()->ShouldDumpAsAudio()) {
     return false;
@@ -605,8 +603,7 @@
 
 void BlinkTestRunner::LoadURLForFrame(const WebURL& url,
                                       const std::string& frame_name) {
-  Send(new ShellViewHostMsg_LoadURLForFrame(
-      routing_id(), url, frame_name));
+  Send(new ShellViewHostMsg_LoadURLForFrame(routing_id(), url, frame_name));
 }
 
 bool BlinkTestRunner::AllowExternalPages() {
@@ -635,8 +632,8 @@
     status = blink::mojom::PermissionStatus::DENIED;
   }
 
-  Send(new LayoutTestHostMsg_SetPermission(
-      routing_id(), name, status, origin, embedding_origin));
+  Send(new LayoutTestHostMsg_SetPermission(routing_id(), name, status, origin,
+                                           embedding_origin));
 }
 
 void BlinkTestRunner::ResetPermissions() {
@@ -797,7 +794,7 @@
   DCHECK(!is_main_window_);
 
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   interfaces->SetTestIsRunning(true);
   ForceResizeRenderView(render_view(), WebSize(800, 600));
 }
@@ -805,7 +802,7 @@
 void BlinkTestRunner::ApplyTestConfiguration(
     mojom::ShellTestConfigurationPtr params) {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
 
   test_config_ = params.Clone();
 
@@ -834,7 +831,7 @@
   render_view()->UpdateBrowserControlsState(
       BROWSER_CONTROLS_STATE_BOTH, BROWSER_CONTROLS_STATE_HIDDEN, false);
 
-  LayoutTestRenderThreadObserver::GetInstance()
+  WebTestRenderThreadObserver::GetInstance()
       ->test_interfaces()
       ->TestRunner()
       ->SetFocus(render_view()->GetWebView(), true);
@@ -846,7 +843,7 @@
   WebLocalFrame* main_frame =
       render_view()->GetWebView()->MainFrame()->ToWebLocalFrame();
 
-  LayoutTestRenderThreadObserver::GetInstance()->test_interfaces()->ResetAll();
+  WebTestRenderThreadObserver::GetInstance()->test_interfaces()->ResetAll();
   Reset(true /* for_new_test */);
   // Navigating to about:blank will make sure that no new loads are initiated
   // by the renderer. We know that about:blank navigation will finish
@@ -861,7 +858,7 @@
   // Avoid a situation where TestFinished is called twice, because
   // of a racey test finish in 2 secondary renderers.
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   if (!interfaces->TestIsRunning())
     return;
 
diff --git a/content/shell/renderer/layout_test/blink_test_runner.h b/content/shell/renderer/web_test/blink_test_runner.h
similarity index 95%
rename from content/shell/renderer/layout_test/blink_test_runner.h
rename to content/shell/renderer/web_test/blink_test_runner.h
index 940e53a..e3549214 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.h
+++ b/content/shell/renderer/web_test/blink_test_runner.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_RUNNER_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_RUNNER_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_RUNNER_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_RUNNER_H_
 
 #include <memory>
 #include <vector>
@@ -32,7 +32,7 @@
 namespace blink {
 class WebURLRequest;
 class WebView;
-}
+}  // namespace blink
 
 namespace test_runner {
 class AppBannerService;
@@ -141,10 +141,9 @@
   void DispatchBeforeInstallPromptEvent(
       const std::vector<std::string>& event_platforms,
       base::OnceCallback<void(bool)> callback) override;
-  void ResolveBeforeInstallPromptPromise(
-      const std::string& platform) override;
+  void ResolveBeforeInstallPromptPromise(const std::string& platform) override;
   blink::WebPlugin* CreatePluginPlaceholder(
-    const blink::WebPluginParams& params) override;
+      const blink::WebPluginParams& params) override;
   float GetDeviceScaleFactor() const override;
   void RunIdleTasks(base::OnceClosure callback) override;
   void ForceTextInputStateUpdate(blink::WebLocalFrame* frame) override;
@@ -189,8 +188,7 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
 
-  mojom::LayoutTestBluetoothFakeAdapterSetter&
-  GetBluetoothFakeAdapterSetter();
+  mojom::LayoutTestBluetoothFakeAdapterSetter& GetBluetoothFakeAdapterSetter();
   mojom::LayoutTestBluetoothFakeAdapterSetterPtr bluetooth_fake_adapter_setter_;
 
   test_runner::TestPreferences prefs_;
@@ -217,4 +215,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_BLINK_TEST_RUNNER_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_BLINK_TEST_RUNNER_H_
diff --git a/content/shell/renderer/layout_test/test_media_stream_renderer_factory.cc b/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc
similarity index 91%
rename from content/shell/renderer/layout_test/test_media_stream_renderer_factory.cc
rename to content/shell/renderer/web_test/test_media_stream_renderer_factory.cc
index f17dc37..d7905c1 100644
--- a/content/shell/renderer/layout_test/test_media_stream_renderer_factory.cc
+++ b/content/shell/renderer/web_test/test_media_stream_renderer_factory.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/test_media_stream_renderer_factory.h"
+#include "content/shell/renderer/web_test/test_media_stream_renderer_factory.h"
 
-#include "content/shell/renderer/layout_test/test_media_stream_video_renderer.h"
+#include "content/shell/renderer/web_test/test_media_stream_video_renderer.h"
 #include "media/media_buildflags.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
diff --git a/content/shell/renderer/layout_test/test_media_stream_renderer_factory.h b/content/shell/renderer/web_test/test_media_stream_renderer_factory.h
similarity index 83%
rename from content/shell/renderer/layout_test/test_media_stream_renderer_factory.h
rename to content/shell/renderer/web_test/test_media_stream_renderer_factory.h
index fbd8e45..eb90f20 100644
--- a/content/shell/renderer/layout_test/test_media_stream_renderer_factory.h
+++ b/content/shell/renderer/web_test/test_media_stream_renderer_factory.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
 
 #include <string>
 
@@ -35,4 +35,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_RENDERER_FACTORY_H_
diff --git a/content/shell/renderer/layout_test/test_media_stream_video_renderer.cc b/content/shell/renderer/web_test/test_media_stream_video_renderer.cc
similarity index 92%
rename from content/shell/renderer/layout_test/test_media_stream_video_renderer.cc
rename to content/shell/renderer/web_test/test_media_stream_video_renderer.cc
index b211332..054c79dc 100644
--- a/content/shell/renderer/layout_test/test_media_stream_video_renderer.cc
+++ b/content/shell/renderer/web_test/test_media_stream_video_renderer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/test_media_stream_video_renderer.h"
+#include "content/shell/renderer/web_test/test_media_stream_video_renderer.h"
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -67,8 +67,8 @@
   if (state_ == kStarted) {
     // Always allocate a new frame filled with white color.
     scoped_refptr<media::VideoFrame> video_frame =
-        media::VideoFrame::CreateColorFrame(
-            size_, 255, 128, 128, current_time_);
+        media::VideoFrame::CreateColorFrame(size_, 255, 128, 128,
+                                            current_time_);
 
     // TODO(wjia): set pixel data to pre-defined patterns if it's desired to
     // verify frame content.
diff --git a/content/shell/renderer/layout_test/test_media_stream_video_renderer.h b/content/shell/renderer/web_test/test_media_stream_video_renderer.h
similarity index 86%
rename from content/shell/renderer/layout_test/test_media_stream_video_renderer.h
rename to content/shell/renderer/web_test/test_media_stream_video_renderer.h
index a0f3143..6d67232 100644
--- a/content/shell/renderer/layout_test/test_media_stream_video_renderer.h
+++ b/content/shell/renderer/web_test/test_media_stream_video_renderer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
 
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -61,6 +61,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestMediaStreamVideoRenderer);
 };
 
-} // namespace content
+}  // namespace content
 
-#endif // CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_TEST_MEDIA_STREAM_VIDEO_RENDERER_H_
diff --git a/content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.cc b/content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.cc
similarity index 96%
rename from content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.cc
rename to content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.cc
index 299eb2b..00f9acd 100644
--- a/content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.cc
+++ b/content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.h"
+#include "content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.h"
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
diff --git a/content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.h b/content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.h
similarity index 79%
rename from content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.h
rename to content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.h
index 29c1b66..0810d029 100644
--- a/content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.h
+++ b/content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
 
 #include <memory>
 #include "base/macros.h"
@@ -28,4 +28,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_TEST_WEBSOCKET_HANDSHAKE_THROTTLE_PROVIDER_H_
diff --git a/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc b/content/shell/renderer/web_test/web_test_content_renderer_client.cc
similarity index 74%
rename from content/shell/renderer/layout_test/layout_test_content_renderer_client.cc
rename to content/shell/renderer/web_test/web_test_content_renderer_client.cc
index fb1373d..2c42642 100644
--- a/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc
+++ b/content/shell/renderer/web_test/web_test_content_renderer_client.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/layout_test_content_renderer_client.h"
+#include "content/shell/renderer/web_test/web_test_content_renderer_client.h"
 
 #include <string>
 #include <utility>
@@ -20,13 +20,13 @@
 #include "content/public/test/layouttest_support.h"
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_switches.h"
-#include "content/shell/renderer/layout_test/blink_test_helpers.h"
-#include "content/shell/renderer/layout_test/blink_test_runner.h"
-#include "content/shell/renderer/layout_test/layout_test_render_frame_observer.h"
-#include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h"
-#include "content/shell/renderer/layout_test/test_media_stream_renderer_factory.h"
-#include "content/shell/renderer/layout_test/test_websocket_handshake_throttle_provider.h"
 #include "content/shell/renderer/shell_render_view_observer.h"
+#include "content/shell/renderer/web_test/blink_test_helpers.h"
+#include "content/shell/renderer/web_test/blink_test_runner.h"
+#include "content/shell/renderer/web_test/test_media_stream_renderer_factory.h"
+#include "content/shell/renderer/web_test/test_websocket_handshake_throttle_provider.h"
+#include "content/shell/renderer/web_test/web_test_render_frame_observer.h"
+#include "content/shell/renderer/web_test/web_test_render_thread_observer.h"
 #include "content/shell/test_runner/web_frame_test_proxy.h"
 #include "content/shell/test_runner/web_test_interfaces.h"
 #include "content/shell/test_runner/web_test_runner.h"
@@ -50,9 +50,9 @@
 using blink::WebAudioDevice;
 using blink::WebFrame;
 using blink::WebLocalFrame;
+using blink::WebMediaStreamCenter;
 using blink::WebMIDIAccessor;
 using blink::WebMIDIAccessorClient;
-using blink::WebMediaStreamCenter;
 using blink::WebPlugin;
 using blink::WebPluginParams;
 using blink::WebRTCPeerConnectionHandler;
@@ -61,29 +61,27 @@
 
 namespace content {
 
-LayoutTestContentRendererClient::LayoutTestContentRendererClient() {
+WebTestContentRendererClient::WebTestContentRendererClient() {
   EnableWebTestProxyCreation();
   SetWorkerRewriteURLFunction(RewriteLayoutTestsURL);
 }
 
-LayoutTestContentRendererClient::~LayoutTestContentRendererClient() {
-}
+WebTestContentRendererClient::~WebTestContentRendererClient() {}
 
-void LayoutTestContentRendererClient::RenderThreadStarted() {
+void WebTestContentRendererClient::RenderThreadStarted() {
   ShellContentRendererClient::RenderThreadStarted();
-  shell_observer_.reset(new LayoutTestRenderThreadObserver());
+  shell_observer_.reset(new WebTestRenderThreadObserver());
 }
 
-void LayoutTestContentRendererClient::RenderFrameCreated(
+void WebTestContentRendererClient::RenderFrameCreated(
     RenderFrame* render_frame) {
   test_runner::WebFrameTestProxyBase* frame_proxy =
       GetWebFrameTestProxyBase(render_frame);
   frame_proxy->set_web_frame(render_frame->GetWebFrame());
-  new LayoutTestRenderFrameObserver(render_frame);
+  new WebTestRenderFrameObserver(render_frame);
 }
 
-void LayoutTestContentRendererClient::RenderViewCreated(
-    RenderView* render_view) {
+void WebTestContentRendererClient::RenderViewCreated(RenderView* render_view) {
   new ShellRenderViewObserver(render_view);
 
   test_runner::WebViewTestProxyBase* proxy =
@@ -101,36 +99,36 @@
 }
 
 std::unique_ptr<WebMIDIAccessor>
-LayoutTestContentRendererClient::OverrideCreateMIDIAccessor(
+WebTestContentRendererClient::OverrideCreateMIDIAccessor(
     WebMIDIAccessorClient* client) {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
   return interfaces->CreateMIDIAccessor(client);
 }
 
-WebThemeEngine* LayoutTestContentRendererClient::OverrideThemeEngine() {
-  return LayoutTestRenderThreadObserver::GetInstance()
+WebThemeEngine* WebTestContentRendererClient::OverrideThemeEngine() {
+  return WebTestRenderThreadObserver::GetInstance()
       ->test_interfaces()
       ->ThemeEngine();
 }
 
 std::unique_ptr<MediaStreamRendererFactory>
-LayoutTestContentRendererClient::CreateMediaStreamRendererFactory() {
+WebTestContentRendererClient::CreateMediaStreamRendererFactory() {
   return std::unique_ptr<MediaStreamRendererFactory>(
       new TestMediaStreamRendererFactory());
 }
 
 std::unique_ptr<content::WebSocketHandshakeThrottleProvider>
-LayoutTestContentRendererClient::CreateWebSocketHandshakeThrottleProvider() {
+WebTestContentRendererClient::CreateWebSocketHandshakeThrottleProvider() {
   return std::make_unique<TestWebSocketHandshakeThrottleProvider>();
 }
 
-void LayoutTestContentRendererClient::DidInitializeWorkerContextOnWorkerThread(
+void WebTestContentRendererClient::DidInitializeWorkerContextOnWorkerThread(
     v8::Local<v8::Context> context) {
   blink::WebTestingSupport::InjectInternalsObject(context);
 }
 
-void LayoutTestContentRendererClient::
+void WebTestContentRendererClient::
     SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
   // We always expose GC to layout tests.
   std::string flags("--expose-gc");
@@ -145,13 +143,13 @@
   }
 }
 
-bool LayoutTestContentRendererClient::IsIdleMediaSuspendEnabled() {
+bool WebTestContentRendererClient::IsIdleMediaSuspendEnabled() {
   // Disable idle media suspend to avoid layout tests getting into accidentally
   // bad states if they take too long to run.
   return false;
 }
 
-bool LayoutTestContentRendererClient::SuppressLegacyTLSVersionConsoleMessage() {
+bool WebTestContentRendererClient::SuppressLegacyTLSVersionConsoleMessage() {
 #if defined(OS_WIN) || defined(OS_MACOSX)
   // Blink uses an outdated test server on Windows and older versions of macOS.
   // Until those are fixed, suppress the warning. See https://crbug.com/747666
diff --git a/content/shell/renderer/layout_test/layout_test_content_renderer_client.h b/content/shell/renderer/web_test/web_test_content_renderer_client.h
similarity index 70%
rename from content/shell/renderer/layout_test/layout_test_content_renderer_client.h
rename to content/shell/renderer/web_test/web_test_content_renderer_client.h
index e7c0dbfb..a87d765 100644
--- a/content/shell/renderer/layout_test/layout_test_content_renderer_client.h
+++ b/content/shell/renderer/web_test/web_test_content_renderer_client.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_CONTENT_RENDERER_CLIENT_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_CONTENT_RENDERER_CLIENT_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_CONTENT_RENDERER_CLIENT_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_CONTENT_RENDERER_CLIENT_H_
 
 #include <memory>
 
@@ -11,12 +11,12 @@
 
 namespace content {
 
-class LayoutTestRenderThreadObserver;
+class WebTestRenderThreadObserver;
 
-class LayoutTestContentRendererClient : public ShellContentRendererClient {
+class WebTestContentRendererClient : public ShellContentRendererClient {
  public:
-  LayoutTestContentRendererClient();
-  ~LayoutTestContentRendererClient() override;
+  WebTestContentRendererClient();
+  ~WebTestContentRendererClient() override;
 
   // ShellContentRendererClient implementation.
   void RenderThreadStarted() override;
@@ -36,9 +36,9 @@
   bool SuppressLegacyTLSVersionConsoleMessage() override;
 
  private:
-  std::unique_ptr<LayoutTestRenderThreadObserver> shell_observer_;
+  std::unique_ptr<WebTestRenderThreadObserver> shell_observer_;
 };
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_CONTENT_RENDERER_CLIENT_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_CONTENT_RENDERER_CLIENT_H_
diff --git a/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc b/content/shell/renderer/web_test/web_test_render_frame_observer.cc
similarity index 67%
rename from content/shell/renderer/layout_test/layout_test_render_frame_observer.cc
rename to content/shell/renderer/web_test/web_test_render_frame_observer.cc
index d13d9616..5114126 100644
--- a/content/shell/renderer/layout_test/layout_test_render_frame_observer.cc
+++ b/content/shell/renderer/web_test/web_test_render_frame_observer.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/layout_test_render_frame_observer.h"
+#include "content/shell/renderer/web_test/web_test_render_frame_observer.h"
 
 #include <string>
 
 #include "content/public/renderer/render_frame.h"
-#include "content/shell/renderer/layout_test/blink_test_runner.h"
-#include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h"
+#include "content/shell/renderer/web_test/blink_test_runner.h"
+#include "content/shell/renderer/web_test/web_test_render_thread_observer.h"
 #include "content/shell/test_runner/web_test_interfaces.h"
 #include "content/shell/test_runner/web_test_runner.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
@@ -20,11 +20,11 @@
 
 namespace content {
 
-LayoutTestRenderFrameObserver::LayoutTestRenderFrameObserver(
+WebTestRenderFrameObserver::WebTestRenderFrameObserver(
     RenderFrame* render_frame)
     : RenderFrameObserver(render_frame), binding_(this) {
   test_runner::WebTestRunner* test_runner =
-      LayoutTestRenderThreadObserver::GetInstance()
+      WebTestRenderThreadObserver::GetInstance()
           ->test_interfaces()
           ->TestRunner();
   render_frame->GetWebFrame()->SetContentSettingsClient(
@@ -32,27 +32,27 @@
   render_frame->GetWebFrame()->SetTextCheckClient(
       test_runner->GetWebTextCheckClient());
   render_frame->GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
-      &LayoutTestRenderFrameObserver::BindRequest, base::Unretained(this)));
+      &WebTestRenderFrameObserver::BindRequest, base::Unretained(this)));
 }
 
-LayoutTestRenderFrameObserver::~LayoutTestRenderFrameObserver() = default;
+WebTestRenderFrameObserver::~WebTestRenderFrameObserver() = default;
 
-void LayoutTestRenderFrameObserver::BindRequest(
+void WebTestRenderFrameObserver::BindRequest(
     mojom::LayoutTestControlAssociatedRequest request) {
   binding_.Bind(std::move(request),
                 blink::scheduler::GetSingleThreadTaskRunnerForTesting());
 }
 
-void LayoutTestRenderFrameObserver::OnDestruct() {
+void WebTestRenderFrameObserver::OnDestruct() {
   delete this;
 }
 
-void LayoutTestRenderFrameObserver::CaptureDump(CaptureDumpCallback callback) {
+void WebTestRenderFrameObserver::CaptureDump(CaptureDumpCallback callback) {
   BlinkTestRunner::Get(render_frame()->GetRenderView())
       ->CaptureDump(std::move(callback));
 }
 
-void LayoutTestRenderFrameObserver::CompositeWithRaster(
+void WebTestRenderFrameObserver::CompositeWithRaster(
     CompositeWithRasterCallback callback) {
   blink::WebWidget* widget = render_frame()->GetWebFrame()->FrameWidget();
   if (widget) {
@@ -63,29 +63,28 @@
   std::move(callback).Run();
 }
 
-void LayoutTestRenderFrameObserver::DumpFrameLayout(
+void WebTestRenderFrameObserver::DumpFrameLayout(
     DumpFrameLayoutCallback callback) {
-  std::string dump =
-      LayoutTestRenderThreadObserver::GetInstance()
-          ->test_interfaces()
-          ->TestRunner()
-          ->DumpLayout(render_frame()->GetWebFrame());
+  std::string dump = WebTestRenderThreadObserver::GetInstance()
+                         ->test_interfaces()
+                         ->TestRunner()
+                         ->DumpLayout(render_frame()->GetWebFrame());
   std::move(callback).Run(dump);
 }
 
-void LayoutTestRenderFrameObserver::ReplicateTestConfiguration(
+void WebTestRenderFrameObserver::ReplicateTestConfiguration(
     mojom::ShellTestConfigurationPtr config) {
   BlinkTestRunner::Get(render_frame()->GetRenderView())
       ->OnReplicateTestConfiguration(std::move(config));
 }
 
-void LayoutTestRenderFrameObserver::SetTestConfiguration(
+void WebTestRenderFrameObserver::SetTestConfiguration(
     mojom::ShellTestConfigurationPtr config) {
   BlinkTestRunner::Get(render_frame()->GetRenderView())
       ->OnSetTestConfiguration(std::move(config));
 }
 
-void LayoutTestRenderFrameObserver::SetupSecondaryRenderer() {
+void WebTestRenderFrameObserver::SetupSecondaryRenderer() {
   BlinkTestRunner::Get(render_frame()->GetRenderView())
       ->OnSetupSecondaryRenderer();
 }
diff --git a/content/shell/renderer/layout_test/layout_test_render_frame_observer.h b/content/shell/renderer/web_test/web_test_render_frame_observer.h
similarity index 65%
rename from content/shell/renderer/layout_test/layout_test_render_frame_observer.h
rename to content/shell/renderer/web_test/web_test_render_frame_observer.h
index 2e18be6..624caff 100644
--- a/content/shell/renderer/layout_test/layout_test_render_frame_observer.h
+++ b/content/shell/renderer/web_test/web_test_render_frame_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_FRAME_OBSERVER_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_FRAME_OBSERVER_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_FRAME_OBSERVER_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_FRAME_OBSERVER_H_
 
 #include "base/macros.h"
 #include "content/public/renderer/render_frame_observer.h"
@@ -12,11 +12,11 @@
 
 namespace content {
 
-class LayoutTestRenderFrameObserver : public RenderFrameObserver,
-                                      public mojom::LayoutTestControl {
+class WebTestRenderFrameObserver : public RenderFrameObserver,
+                                   public mojom::LayoutTestControl {
  public:
-  explicit LayoutTestRenderFrameObserver(RenderFrame* render_frame);
-  ~LayoutTestRenderFrameObserver() override;
+  explicit WebTestRenderFrameObserver(RenderFrame* render_frame);
+  ~WebTestRenderFrameObserver() override;
 
  private:
   // RenderFrameObserver implementation.
@@ -32,9 +32,9 @@
   void BindRequest(mojom::LayoutTestControlAssociatedRequest request);
 
   mojo::AssociatedBinding<mojom::LayoutTestControl> binding_;
-  DISALLOW_COPY_AND_ASSIGN(LayoutTestRenderFrameObserver);
+  DISALLOW_COPY_AND_ASSIGN(WebTestRenderFrameObserver);
 };
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_FRAME_OBSERVER_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_FRAME_OBSERVER_H_
diff --git a/content/shell/renderer/layout_test/layout_test_render_thread_observer.cc b/content/shell/renderer/web_test/web_test_render_thread_observer.cc
similarity index 73%
rename from content/shell/renderer/layout_test/layout_test_render_thread_observer.cc
rename to content/shell/renderer/web_test/web_test_render_thread_observer.cc
index 99abe77..5a6ede4 100644
--- a/content/shell/renderer/layout_test/layout_test_render_thread_observer.cc
+++ b/content/shell/renderer/web_test/web_test_render_thread_observer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h"
+#include "content/shell/renderer/web_test/web_test_render_thread_observer.h"
 
 #include "content/public/common/content_client.h"
 #include "content/public/renderer/render_thread.h"
@@ -17,16 +17,15 @@
 namespace content {
 
 namespace {
-LayoutTestRenderThreadObserver* g_instance = nullptr;
+WebTestRenderThreadObserver* g_instance = nullptr;
 }
 
 // static
-LayoutTestRenderThreadObserver*
-LayoutTestRenderThreadObserver::GetInstance() {
+WebTestRenderThreadObserver* WebTestRenderThreadObserver::GetInstance() {
   return g_instance;
 }
 
-LayoutTestRenderThreadObserver::LayoutTestRenderThreadObserver() {
+WebTestRenderThreadObserver::WebTestRenderThreadObserver() {
   CHECK(!g_instance);
   g_instance = this;
   RenderThread::Get()->AddObserver(this);
@@ -36,15 +35,15 @@
   test_interfaces_->ResetAll();
 }
 
-LayoutTestRenderThreadObserver::~LayoutTestRenderThreadObserver() {
+WebTestRenderThreadObserver::~WebTestRenderThreadObserver() {
   CHECK(g_instance == this);
   g_instance = nullptr;
 }
 
-bool LayoutTestRenderThreadObserver::OnControlMessageReceived(
+bool WebTestRenderThreadObserver::OnControlMessageReceived(
     const IPC::Message& message) {
   bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(LayoutTestRenderThreadObserver, message)
+  IPC_BEGIN_MESSAGE_MAP(WebTestRenderThreadObserver, message)
     IPC_MESSAGE_HANDLER(LayoutTestMsg_ReplicateLayoutTestRuntimeFlagsChanges,
                         OnReplicateLayoutTestRuntimeFlagsChanges)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -53,7 +52,7 @@
   return handled;
 }
 
-void LayoutTestRenderThreadObserver::OnReplicateLayoutTestRuntimeFlagsChanges(
+void WebTestRenderThreadObserver::OnReplicateLayoutTestRuntimeFlagsChanges(
     const base::DictionaryValue& changed_layout_test_runtime_flags) {
   test_interfaces()->TestRunner()->ReplicateLayoutTestRuntimeFlagsChanges(
       changed_layout_test_runtime_flags);
diff --git a/content/shell/renderer/layout_test/layout_test_render_thread_observer.h b/content/shell/renderer/web_test/web_test_render_thread_observer.h
similarity index 65%
rename from content/shell/renderer/layout_test/layout_test_render_thread_observer.h
rename to content/shell/renderer/web_test/web_test_render_thread_observer.h
index 85c903065e..ee4a5d5e 100644
--- a/content/shell/renderer/layout_test/layout_test_render_thread_observer.h
+++ b/content/shell/renderer/web_test/web_test_render_thread_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_THREAD_OBSERVER_H_
-#define CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_THREAD_OBSERVER_H_
+#ifndef CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_THREAD_OBSERVER_H_
+#define CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_THREAD_OBSERVER_H_
 
 #include <memory>
 
@@ -23,12 +23,12 @@
 
 namespace content {
 
-class LayoutTestRenderThreadObserver : public RenderThreadObserver {
+class WebTestRenderThreadObserver : public RenderThreadObserver {
  public:
-  static LayoutTestRenderThreadObserver* GetInstance();
+  static WebTestRenderThreadObserver* GetInstance();
 
-  LayoutTestRenderThreadObserver();
-  ~LayoutTestRenderThreadObserver() override;
+  WebTestRenderThreadObserver();
+  ~WebTestRenderThreadObserver() override;
 
   // RenderThreadObserver implementation.
   bool OnControlMessageReceived(const IPC::Message& message) override;
@@ -44,9 +44,9 @@
 
   std::unique_ptr<test_runner::WebTestInterfaces> test_interfaces_;
 
-  DISALLOW_COPY_AND_ASSIGN(LayoutTestRenderThreadObserver);
+  DISALLOW_COPY_AND_ASSIGN(WebTestRenderThreadObserver);
 };
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_RENDERER_LAYOUT_TEST_LAYOUT_TEST_RENDER_THREAD_OBSERVER_H_
+#endif  // CONTENT_SHELL_RENDERER_WEB_TEST_WEB_TEST_RENDER_THREAD_OBSERVER_H_
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc
index 1631adf..9f041d7f 100644
--- a/content/shell/test_runner/test_runner.cc
+++ b/content/shell/test_runner/test_runner.cc
@@ -1293,12 +1293,18 @@
   base::Optional<int> action_index;
   base::Optional<base::string16> reply;
 
-  args->GetNext(&title);
+  if (!args->GetNext(&title)) {
+    args->ThrowError();
+    return;
+  }
 
   // Optional |action_index| argument.
   if (args->Length() >= 2) {
     int action_index_int;
-    args->GetNext(&action_index_int);
+    if (!args->GetNext(&action_index_int)) {
+      args->ThrowError();
+      return;
+    }
 
     action_index = action_index_int;
   }
@@ -1306,7 +1312,10 @@
   // Optional |reply| argument.
   if (args->Length() >= 3) {
     std::string reply_string;
-    args->GetNext(&reply_string);
+    if (!args->GetNext(&reply_string)) {
+      args->ThrowError();
+      return;
+    }
 
     reply = base::UTF8ToUTF16(reply_string);
   }
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index dfc1222..b96fe23 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -42,8 +42,8 @@
 #include "content/renderer/renderer_blink_platform_impl.h"
 #include "content/shell/common/layout_test/layout_test_switches.h"
 #include "content/shell/common/shell_switches.h"
-#include "content/shell/renderer/layout_test/blink_test_runner.h"
-#include "content/shell/renderer/layout_test/layout_test_render_thread_observer.h"
+#include "content/shell/renderer/web_test/blink_test_runner.h"
+#include "content/shell/renderer/web_test/web_test_render_thread_observer.h"
 #include "content/shell/test_runner/test_common.h"
 #include "content/shell/test_runner/web_frame_test_proxy.h"
 #include "content/shell/test_runner/web_test_interfaces.h"
@@ -83,7 +83,7 @@
 RenderViewImpl* CreateWebViewTestProxy(CompositorDependencies* compositor_deps,
                                        const mojom::CreateViewParams& params) {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
 
   auto* render_view_proxy =
       new test_runner::WebViewTestProxy(compositor_deps, params);
@@ -119,7 +119,7 @@
 
 void RenderWidgetInitialized(RenderWidget* render_widget) {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
 
   blink::WebWidget* web_widget = render_widget->GetWebWidget();
   // This callback is run only for RenderWidgets that are for a frame.
@@ -141,7 +141,7 @@
 
 RenderFrameImpl* CreateWebFrameTestProxy(RenderFrameImpl::CreateParams params) {
   test_runner::WebTestInterfaces* interfaces =
-      LayoutTestRenderThreadObserver::GetInstance()->test_interfaces();
+      WebTestRenderThreadObserver::GetInstance()->test_interfaces();
 
   // RenderFrameImpl always has a RenderViewImpl for it.
   RenderViewImpl* render_view_impl = params.render_view;
diff --git a/docs/README.md b/docs/README.md
index 915d1aa9..c03c6537 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -143,6 +143,9 @@
 *   [Guidelines for considering branch dates in project planning](release_branch_guidance.md) -
     What to do (and not to do) around branch dates when scheduling your project
     work.
+*   [WebUI Explainer](webui_explainer.md) - An explanation of C++ and JavaScript
+    infrastructural code for Chrome UIs implemented with web technologies (i.e.
+    chrome:// URLs).
 
 ### Testing
 *   [Running and Debugging Web Tests](testing/web_tests.md)
@@ -275,6 +278,10 @@
 ### Misc Chrome-OS-Specific Docs
 *   [Chrome Logging on Chrome OS](chrome_os_logging.md)
 
+### Misc WebUI-Specific Docs
+*   [Creating WebUI Interfaces in components/](webui_in_components.md) How to
+    create a new WebUI component in the `components/` directory.
+
 ### Media
 *   [Audio Focus Handling](media/audio_focus.md) - How multiple MediaSession
     audio streams interact
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index eb0c4447..e46ab62 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -3043,7 +3043,11 @@
     builders { mixins: "linux-try" name: "linux-blink-heap-incremental-marking" }
     builders { mixins: "linux-try" name: "linux-blink-heap-verification-try" }
     builders { mixins: "linux-try" name: "linux-dcheck-off-rel" }
-    builders { mixins: "linux-try" name: "linux-goma-rbe-staging-rel" }
+    builders {
+      mixins: "linux-try"
+      mixins: "goma-j150"
+      name: "linux-goma-rbe-staging-rel"
+    }
     builders { mixins: "linux-try" name: "linux-gcc-rel" }
     builders { mixins: "linux-try" name: "linux-jumbo-rel" }
     builders {
@@ -3422,8 +3426,8 @@
 
     # Android
 
-    # builders { mixins: "linux"  name: "WebRTC Chromium Android Builder" }
-    # builders { mixins: "linux"  name: "WebRTC Chromium Android Tester" }
+    builders { mixins: "linux"  name: "WebRTC Chromium Android Builder" }
+    builders { mixins: "linux"  name: "WebRTC Chromium Android Tester" }
 
     # Linux
 
@@ -3432,31 +3436,15 @@
 
     # Mac
 
-    # builders { mixins: "mac"  name: "WebRTC Chromium Mac Builder" }
-    # builders { mixins: "mac"  name: "WebRTC Chromium Mac Tester" }
+    builders { mixins: "mac"  name: "WebRTC Chromium Mac Builder" }
+    builders { mixins: "mac"  name: "WebRTC Chromium Mac Tester" }
 
     # Win
 
-    # builders {
-    #   mixins: "win"
-    #   name: "WebRTC Chromium Win Builder"
-    #   dimensions: "os:Windows-10"
-    # }
-    # builders {
-    #   mixins: "win"
-    #   name: "WebRTC Chromium Win10 Tester"
-    #   dimensions: "os:Windows-10"
-    # }
-    # builders {
-    #   mixins: "win"
-    #   name: "WebRTC Chromium Win7 Tester"
-    #   dimensions: "os:Windows-7"
-    # }
-    # builders {
-    #   mixins: "win"
-    #   name: "WebRTC Chromium Win8 Tester"
-    #   dimensions: "os:Windows-8.1"
-    # }
+    builders { mixins: "win" name: "WebRTC Chromium Win Builder" }
+    builders { mixins: "win" name: "WebRTC Chromium Win10 Tester" }
+    builders { mixins: "win" name: "WebRTC Chromium Win7 Tester" }
+    builders { mixins: "win" name: "WebRTC Chromium Win8 Tester" }
   }
 }
 
@@ -3512,31 +3500,11 @@
 
     # Win
 
-    builders {
-      mixins: "win"
-      name: "WebRTC Chromium FYI Win Builder"
-      dimensions: "os:Windows-10"
-    }
-    builders {
-      mixins: "win"
-      name: "WebRTC Chromium FYI Win Builder (dbg)"
-      dimensions: "os:Windows-10"
-    }
-    builders {
-      mixins: "win"
-      name: "WebRTC Chromium FYI Win10 Tester"
-      dimensions: "os:Windows-10"
-    }
-    builders {
-      mixins: "win"
-      name: "WebRTC Chromium FYI Win7 Tester"
-      dimensions: "os:Windows-7"
-    }
-    builders {
-      mixins: "win"
-      name: "WebRTC Chromium FYI Win8 Tester"
-      dimensions: "os:Windows-8.1"
-    }
+    builders { mixins: "win" name: "WebRTC Chromium FYI Win Builder" }
+    builders { mixins: "win" name: "WebRTC Chromium FYI Win Builder (dbg)" }
+    builders { mixins: "win" name: "WebRTC Chromium FYI Win10 Tester" }
+    builders { mixins: "win" name: "WebRTC Chromium FYI Win7 Tester" }
+    builders { mixins: "win" name: "WebRTC Chromium FYI Win8 Tester" }
   }
 }
 
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
index 34b677a9..b6b50d8 100644
--- a/infra/config/global/luci-scheduler.cfg
+++ b/infra/config/global/luci-scheduler.cfg
@@ -328,10 +328,10 @@
   triggers: "mac-mojo-rel"
   triggers: "mac-rel"
   triggers: "mac-views-rel"
-  # triggers: "WebRTC Chromium Android Builder"
+  triggers: "WebRTC Chromium Android Builder"
   triggers: "WebRTC Chromium Linux Builder"
-  # triggers: "WebRTC Chromium Mac Builder"
-  # triggers: "WebRTC Chromium Win Builder"
+  triggers: "WebRTC Chromium Mac Builder"
+  triggers: "WebRTC Chromium Win Builder"
   triggers: "win-annotator-rel"
   triggers: "win-asan"
   triggers: "win-dbg"
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 084fe5fd..e8843fbed 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -705,12 +705,6 @@
       <message name="IDS_IOS_GOOGLE_APPS_SM_SETTINGS" desc="Title for the view in Settings for managing Google apps specific settings. Translate 'Google Apps'. [Length: 15em] [iOS only]">
         Google Apps
       </message>
-      <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_DETAIL" desc="Detail text for a feature in the settings for the user to enable/disable, to personalize the user experience. Related to 'Activity and interactions'. [iOS only]">
-        Uses content on sites you visit and browser activity and interactions for personalization
-      </message>
-      <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_TEXT" desc="Title for a feature in the settings for the user to enable/disable, to personalize the user experience. Related to 'Uses content on sites you visit and browser activity and interactions for personalization'. [iOS only]">
-        Activity and interactions
-      </message>
       <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_AUTOCOMPLETE_SEARCHES_AND_URLS_DETAIL" desc="Feature detail text in the settings for the user to enable/disable, to have autocomplete searches and URLs. Text related to 'Autocomplete Searches and URLs' [iOS only]">
         Sends searches from the address bar and search box, and some cookies to your default search engine
       </message>
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 8bc59050..393701b 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -152,6 +152,29 @@
     {"Magnifying glass", kIconForSearchButtonMagnifying,
      base::size(kIconForSearchButtonMagnifying), nullptr}};
 
+const FeatureEntry::FeatureParam kDetectMainThreadFreezeTimeout3s[] = {
+    {crash_report::kDetectMainThreadFreezeParameterName,
+     crash_report::kDetectMainThreadFreezeParameter3s}};
+const FeatureEntry::FeatureParam kDetectMainThreadFreezeTimeout5s[] = {
+    {crash_report::kDetectMainThreadFreezeParameterName,
+     crash_report::kDetectMainThreadFreezeParameter5s}};
+const FeatureEntry::FeatureParam kDetectMainThreadFreezeTimeout7s[] = {
+    {crash_report::kDetectMainThreadFreezeParameterName,
+     crash_report::kDetectMainThreadFreezeParameter7s}};
+const FeatureEntry::FeatureParam kDetectMainThreadFreezeTimeout9s[] = {
+    {crash_report::kDetectMainThreadFreezeParameterName,
+     crash_report::kDetectMainThreadFreezeParameter9s}};
+
+const FeatureEntry::FeatureVariation kDetectMainThreadFreezeVariations[] = {
+    {"3s", kDetectMainThreadFreezeTimeout3s,
+     base::size(kDetectMainThreadFreezeTimeout3s), nullptr},
+    {"5s", kDetectMainThreadFreezeTimeout5s,
+     base::size(kDetectMainThreadFreezeTimeout5s), nullptr},
+    {"7s", kDetectMainThreadFreezeTimeout7s,
+     base::size(kDetectMainThreadFreezeTimeout7s), nullptr},
+    {"9s", kDetectMainThreadFreezeTimeout9s,
+     base::size(kDetectMainThreadFreezeTimeout9s), nullptr}};
+
 // To add a new entry, add to the end of kFeatureEntries. There are four
 // distinct types of entries:
 // . ENABLE_DISABLE_VALUE: entry is either enabled, disabled, or uses the
@@ -458,6 +481,12 @@
      flag_descriptions::kSyncPseudoUSSSupervisedUsersDescription,
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(switches::kSyncPseudoUSSSupervisedUsers)},
+    {"detect-main-thread-freeze",
+     flag_descriptions::kDetectMainThreadFreezeName,
+     flag_descriptions::kDetectMainThreadFreezeDescription, flags_ui::kOsIos,
+     FEATURE_WITH_PARAMS_VALUE_TYPE(crash_report::kDetectMainThreadFreeze,
+                                    kDetectMainThreadFreezeVariations,
+                                    "DetectMainThreadFreeze")},
 };
 
 // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
index bbd7e25..40e70848 100644
--- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -262,7 +262,10 @@
 
   accessory_mediator_ =
       [[FormInputAccessoryMediator alloc] initWithConsumer:nil
-                                              webStateList:NULL];
+                                              webStateList:NULL
+                                       personalDataManager:NULL
+                                             passwordStore:NULL];
+
   [accessory_mediator_ injectWebState:web_state()];
   [accessory_mediator_ injectProviders:@[ suggestion_controller_ ]];
   auto suggestionManager = base::mac::ObjCCastStrict<JsSuggestionManager>(
diff --git a/ios/chrome/browser/autofill/form_input_accessory_consumer.h b/ios/chrome/browser/autofill/form_input_accessory_consumer.h
index bb636d1..4264e64 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_consumer.h
+++ b/ios/chrome/browser/autofill/form_input_accessory_consumer.h
@@ -17,6 +17,15 @@
 @property(nonatomic, weak) id<FormInputAccessoryViewDelegate>
     navigationDelegate;
 
+// Hides or shows the manual fill password button.
+@property(nonatomic) BOOL passwordButtonHidden;
+
+// Hides or shows the manual fill credit card button.
+@property(nonatomic) BOOL creditCardButtonHidden;
+
+// Hides or shows the manual fill address button.
+@property(nonatomic) BOOL addressButtonHidden;
+
 // Enables or disables the next button if any.
 @property(nonatomic) BOOL formInputNextButtonEnabled;
 
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.h b/ios/chrome/browser/autofill/form_input_accessory_view_controller.h
index 70fae0d..93bb005 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.h
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.h
@@ -14,6 +14,7 @@
 }  // namespace autofill
 
 @class ManualFillAccessoryViewController;
+@protocol ManualFillAccessoryViewControllerDelegate;
 
 // Creates and manages a custom input accessory view while the user is
 // interacting with a form. Also handles hiding and showing the default
@@ -21,11 +22,6 @@
 @interface FormInputAccessoryViewController
     : NSObject<FormInputAccessoryConsumer>
 
-// The manual fill accessory view controller to add at the end of the
-// suggestions.
-@property(nonatomic, weak)
-    ManualFillAccessoryViewController* manualFillAccessoryViewController;
-
 // Presents a view above the keyboard.
 - (void)presentView:(UIView*)view;
 
@@ -37,6 +33,22 @@
 // and locks them in that position.
 - (void)lockManualFallbackView;
 
+// Tells the view to restore the manual fallback icons to a clean state. That
+// means no icon selected.
+- (void)resetManualFallbackIcons;
+
+// Instances an object with the desired delegate.
+//
+// @param manualFillAccessoryViewControllerDelegate the delegate for the actions
+// in the manual fallback icons.
+// @return A fresh object with the passed delegate.
+- (instancetype)initWithManualFillAccessoryViewControllerDelegate:
+    (id<ManualFillAccessoryViewControllerDelegate>)
+        manualFillAccessoryViewControllerDelegate;
+
+// Unavailable
+- (instancetype)init NS_UNAVAILABLE;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_AUTOFILL_FORM_INPUT_ACCESSORY_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
index 355900f..2621200 100644
--- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
+++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h"
 
 #include "base/mac/foundation_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "components/autofill/core/common/autofill_features.h"
 #import "ios/chrome/browser/autofill/form_input_accessory_view.h"
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
@@ -21,7 +22,8 @@
 CGFloat const kInputAccessoryHeight = 44.0f;
 }  // namespace autofill
 
-@interface FormInputAccessoryViewController ()
+@interface FormInputAccessoryViewController () <
+    ManualFillAccessoryViewControllerDelegate>
 
 // Grey view used as the background of the keyboard to fix
 // http://crbug.com/847523
@@ -39,6 +41,16 @@
 // If this view controller is paused it shouldn't add its views to the keyboard.
 @property(nonatomic, getter=isPaused) BOOL paused;
 
+// The manual fill accessory view controller to add at the end of the
+// suggestions.
+@property(nonatomic, strong, readonly)
+    ManualFillAccessoryViewController* manualFillAccessoryViewController;
+
+// Delegate to handle interactions with the manual fill buttons.
+@property(nonatomic, readonly, weak)
+    id<ManualFillAccessoryViewControllerDelegate>
+        manualFillAccessoryViewControllerDelegate;
+
 // Called when the keyboard will or did change frame.
 - (void)keyboardWillOrDidChangeFrame:(NSNotification*)notification;
 
@@ -52,15 +64,27 @@
   BOOL _suggestionsHaveBeenShown;
 }
 
-@synthesize navigationDelegate = _navigationDelegate;
+@synthesize addressButtonHidden = _addressButtonHidden;
+@synthesize creditCardButtonHidden = _creditCardButtonHidden;
 @synthesize formInputNextButtonEnabled = _formInputNextButtonEnabled;
 @synthesize formInputPreviousButtonEnabled = _formInputPreviousButtonEnabled;
+@synthesize navigationDelegate = _navigationDelegate;
+@synthesize passwordButtonHidden = _passwordButtonHidden;
 
 #pragma mark - Life Cycle
 
-- (instancetype)init {
+- (instancetype)initWithManualFillAccessoryViewControllerDelegate:
+    (id<ManualFillAccessoryViewControllerDelegate>)
+        manualFillAccessoryViewControllerDelegate {
   self = [super init];
   if (self) {
+    _manualFillAccessoryViewControllerDelegate =
+        manualFillAccessoryViewControllerDelegate;
+    if (autofill::features::IsPasswordManualFallbackEnabled()) {
+      _manualFillAccessoryViewController =
+          [[ManualFillAccessoryViewController alloc] initWithDelegate:self];
+    }
+
     _suggestionsHaveBeenShown = NO;
     if (IsIPadIdiom()) {
       _grayBackgroundView = [[UIView alloc] init];
@@ -115,6 +139,10 @@
   [self.formSuggestionView lockTrailingView];
 }
 
+- (void)resetManualFallbackIcons {
+  [self.manualFillAccessoryViewController reset];
+}
+
 #pragma mark - FormInputAccessoryConsumer
 
 - (void)showAccessorySuggestions:(NSArray<FormSuggestion*>*)suggestions
@@ -207,6 +235,24 @@
 
 #pragma mark - Setters
 
+- (void)setPasswordButtonHidden:(BOOL)passwordButtonHidden {
+  _passwordButtonHidden = passwordButtonHidden;
+  self.manualFillAccessoryViewController.passwordButtonHidden =
+      passwordButtonHidden;
+}
+
+- (void)setAddressButtonHidden:(BOOL)addressButtonHidden {
+  _addressButtonHidden = addressButtonHidden;
+  self.manualFillAccessoryViewController.addressButtonHidden =
+      addressButtonHidden;
+}
+
+- (void)setCreditCardButtonHidden:(BOOL)creditCardButtonHidden {
+  _creditCardButtonHidden = creditCardButtonHidden;
+  self.manualFillAccessoryViewController.creditCardButtonHidden =
+      creditCardButtonHidden;
+}
+
 - (void)setFormInputNextButtonEnabled:(BOOL)formInputNextButtonEnabled {
   if (formInputNextButtonEnabled == _formInputNextButtonEnabled) {
     return;
@@ -365,4 +411,28 @@
   }
 }
 
+#pragma mark - ManualFillAccessoryViewControllerDelegate
+
+- (void)keyboardButtonPressed {
+  [self.manualFillAccessoryViewControllerDelegate keyboardButtonPressed];
+}
+
+- (void)accountButtonPressed:(UIButton*)sender {
+  UMA_HISTOGRAM_COUNTS_100("ManualFallback.VisibleSuggestions.OpenProfiles",
+                           self.formSuggestionView.suggestions.count);
+  [self.manualFillAccessoryViewControllerDelegate accountButtonPressed:sender];
+}
+
+- (void)cardButtonPressed:(UIButton*)sender {
+  UMA_HISTOGRAM_COUNTS_100("ManualFallback.VisibleSuggestions.OpenCreditCards",
+                           self.formSuggestionView.suggestions.count);
+  [self.manualFillAccessoryViewControllerDelegate cardButtonPressed:sender];
+}
+
+- (void)passwordButtonPressed:(UIButton*)sender {
+  UMA_HISTOGRAM_COUNTS_100("ManualFallback.VisibleSuggestions.OpenPasswords",
+                           self.formSuggestionView.suggestions.count);
+  [self.manualFillAccessoryViewControllerDelegate passwordButtonPressed:sender];
+}
+
 @end
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
index c30d0b29..3287aa4e 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller_unittest.mm
@@ -196,7 +196,9 @@
 
     accessory_mediator_ =
         [[FormInputAccessoryMediator alloc] initWithConsumer:mock_consumer_
-                                                webStateList:NULL];
+                                                webStateList:NULL
+                                         personalDataManager:NULL
+                                               passwordStore:NULL];
 
     [accessory_mediator_ injectWebState:&test_web_state_];
     [accessory_mediator_ injectProviders:@[ suggestion_controller_ ]];
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
index 2f9e70254..528a88b 100644
--- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
+++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -42,6 +42,7 @@
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "ios/chrome/browser/signin/signin_browser_state_info_updater_factory.h"
 #include "ios/chrome/browser/signin/signin_client_factory.h"
 #include "ios/chrome/browser/signin/signin_error_controller_factory.h"
 #include "ios/chrome/browser/signin/signin_manager_factory.h"
@@ -79,6 +80,7 @@
 void EnsureBrowserStateKeyedServiceFactoriesBuilt() {
   autofill::PersonalDataManagerFactory::GetInstance();
   dom_distiller::DomDistillerServiceFactory::GetInstance();
+  feature_engagement::TrackerFactory::GetInstance();
   ios::AboutSigninInternalsFactory::GetInstance();
   ios::AccountConsistencyServiceFactory::GetInstance();
   ios::AccountFetcherServiceFactory::GetInstance();
@@ -102,36 +104,36 @@
   ios::WebDataServiceFactory::GetInstance();
   ios::WebHistoryServiceFactory::GetInstance();
   translate::TranslateRankerFactory::GetInstance();
+  suggestions::SuggestionsServiceFactory::GetInstance();
   AuthenticationServiceFactory::GetInstance();
+  BrowserDownloadServiceFactory::GetInstance();
   BrowserListFactory::GetInstance();
   BrowserListSessionServiceFactory::GetInstance();
   BrowsingDataRemoverFactory::GetInstance();
   ConsentAuditorFactory::GetInstance();
-  feature_engagement::TrackerFactory::GetInstance();
+  FullscreenControllerFactory::GetInstance();
+  GoogleLogoServiceFactory::GetInstance();
+  IOSChromeContentSuggestionsServiceFactory::GetInstance();
+  IOSChromeDeprecatedProfileInvalidationProviderFactory::GetInstance();
+  IOSChromeFaviconLoaderFactory::GetInstance();
   IOSChromeGCMProfileServiceFactory::GetInstance();
   IOSChromeLargeIconCacheFactory::GetInstance();
   IOSChromeLargeIconServiceFactory::GetInstance();
-  IOSChromeFaviconLoaderFactory::GetInstance();
-  IOSChromeContentSuggestionsServiceFactory::GetInstance();
   IOSChromePasswordStoreFactory::GetInstance();
-  IOSChromeDeprecatedProfileInvalidationProviderFactory::GetInstance();
-  ModelTypeStoreServiceFactory::GetInstance();
-  ProfileSyncServiceFactory::GetInstance();
   IOSUserEventServiceFactory::GetInstance();
-  GoogleLogoServiceFactory::GetInstance();
   LanguageModelManagerFactory::GetInstance();
+  ModelTypeStoreServiceFactory::GetInstance();
   ProfileOAuth2TokenServiceFactory::GetInstance();
+  ProfileSyncServiceFactory::GetInstance();
   ReadingListModelFactory::GetInstance();
+  SigninBrowserStateInfoUpdaterFactory::GetInstance();
   SigninClientFactory::GetInstance();
-  suggestions::SuggestionsServiceFactory::GetInstance();
   SnapshotCacheFactory::GetInstance();
   SyncSetupServiceFactory::GetInstance();
   TabRestoreServiceDelegateImplIOSFactory::GetInstance();
+  TextToSpeechPlaybackControllerFactory::GetInstance();
   TranslateAcceptLanguagesFactory::GetInstance();
   UnifiedConsentServiceFactory::GetInstance();
   UrlLanguageHistogramFactory::GetInstance();
-  BrowserDownloadServiceFactory::GetInstance();
-  FullscreenControllerFactory::GetInstance();
-  TextToSpeechPlaybackControllerFactory::GetInstance();
   WebStateListWebUsageEnablerFactory::GetInstance();
 }
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
index 9048cbee..0d729ff 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl_io_data.mm
@@ -8,6 +8,7 @@
 #include <set>
 #include <utility>
 
+#include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/logging.h"
@@ -347,13 +348,14 @@
     const base::Closure& completion) {
   DCHECK_CURRENTLY_ON(web::WebThread::IO);
   DCHECK(initialized());
-
   DCHECK(transport_security_state());
-  // Completes synchronously.
-  transport_security_state()->DeleteAllDynamicDataSince(time);
-  http_server_properties()->Clear(base::BindOnce(
-      [](const base::Closure& completion) {
-        base::PostTaskWithTraits(FROM_HERE, {web::WebThread::UI}, completion);
-      },
-      completion));
+  auto barrier = base::BarrierClosure(
+      2, base::BindOnce(
+             [](base::OnceClosure callback) {
+               base::PostTaskWithTraits(FROM_HERE, {web::WebThread::UI},
+                                        std::move(callback));
+             },
+             completion));
+  transport_security_state()->DeleteAllDynamicDataSince(time, barrier);
+  http_server_properties()->Clear(barrier);
 }
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
index 9f028ca1..3a410a0 100644
--- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
+++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -142,8 +142,6 @@
       testing_prefs_(nullptr),
       otr_browser_state_(nullptr),
       original_browser_state_(nullptr) {
-  Init();
-
   for (const auto& pair : testing_factories) {
     pair.first->SetTestingFactory(this, std::move(pair.second));
   }
@@ -151,6 +149,8 @@
   for (const auto& pair : refcounted_testing_factories) {
     pair.first->SetTestingFactory(this, std::move(pair.second));
   }
+
+  Init();
 }
 
 TestChromeBrowserState::~TestChromeBrowserState() {
diff --git a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
index 6b509e6..f0822b7d 100644
--- a/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
+++ b/ios/chrome/browser/browsing_data/cache_counter_unittest.cc
@@ -18,10 +18,7 @@
 #include "base/time/time.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
-#include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/testing_pref_service.h"
-#include "components/sync_preferences/pref_service_mock_factory.h"
-#include "components/sync_preferences/pref_service_syncable.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "ios/web/public/web_task_traits.h"
@@ -40,9 +37,7 @@
  public:
   CacheCounterTest() {
     TestChromeBrowserState::Builder builder;
-    builder.SetPrefService(CreatePrefService());
     browser_state_ = builder.Build();
-
     context_getter_ = browser_state_->GetRequestContext();
   }
 
@@ -52,19 +47,6 @@
 
   PrefService* prefs() { return browser_state_->GetPrefs(); }
 
-  std::unique_ptr<sync_preferences::PrefServiceSyncable> CreatePrefService() {
-    sync_preferences::PrefServiceMockFactory factory;
-    scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
-        new user_prefs::PrefRegistrySyncable);
-    std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs =
-        factory.CreateSyncable(registry.get());
-    registry->RegisterIntegerPref(
-        browsing_data::prefs::kDeleteTimePeriod,
-        static_cast<int>(browsing_data::TimePeriod::ALL_TIME));
-    registry->RegisterBooleanPref(browsing_data::prefs::kDeleteCache, true);
-    return prefs;
-  }
-
   void SetCacheDeletionPref(bool value) {
     prefs()->SetBoolean(browsing_data::prefs::kDeleteCache, value);
   }
diff --git a/ios/chrome/browser/crash_report/BUILD.gn b/ios/chrome/browser/crash_report/BUILD.gn
index 261f4fc5..e7860ed 100644
--- a/ios/chrome/browser/crash_report/BUILD.gn
+++ b/ios/chrome/browser/crash_report/BUILD.gn
@@ -12,6 +12,8 @@
     "crash_report_user_application_state.mm",
     "crash_upload_list.cc",
     "crash_upload_list.h",
+    "main_thread_freeze_detector.h",
+    "main_thread_freeze_detector.mm",
   ]
 
   configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/crash_report/breakpad_helper.mm b/ios/chrome/browser/crash_report/breakpad_helper.mm
index ed2a942..ec15461 100644
--- a/ios/chrome/browser/crash_report/breakpad_helper.mm
+++ b/ios/chrome/browser/crash_report/breakpad_helper.mm
@@ -21,6 +21,7 @@
 #include "ios/chrome/browser/chrome_paths.h"
 #include "ios/chrome/browser/crash_report/crash_report_flags.h"
 #import "ios/chrome/browser/crash_report/crash_report_user_application_state.h"
+#import "ios/chrome/browser/crash_report/main_thread_freeze_detector.h"
 
 // TODO(stuartmorgan): Move this up where it belongs once
 // https://crbug.com/google-breakpad/487 is fixed. For now, put it at the end to
@@ -124,6 +125,7 @@
 void Start(const std::string& channel_name) {
   DCHECK(!g_crash_reporter_enabled);
   [[BreakpadController sharedInstance] start:YES];
+  [[MainThreadFreezeDetector sharedInstance] start];
   logging::SetLogMessageHandler(&FatalMessageHandler);
   g_crash_reporter_enabled = true;
   // Register channel information.
@@ -143,6 +145,9 @@
 }
 
 void SetEnabled(bool enabled) {
+  // It is necessary to always call |MainThreadFreezeDetector setEnabled| as
+  // the function will update its preference based on finch.
+  [[MainThreadFreezeDetector sharedInstance] setEnabled:enabled];
   if (g_crash_reporter_enabled == enabled)
     return;
   g_crash_reporter_enabled = enabled;
@@ -226,10 +231,13 @@
 }
 
 void SetCurrentlyInBackground(bool background) {
-  if (background)
+  if (background) {
     AddReportParameter(kCrashedInBackground, @"yes", true);
-  else
+    [[MainThreadFreezeDetector sharedInstance] stop];
+  } else {
     RemoveReportParameter(kCrashedInBackground);
+    [[MainThreadFreezeDetector sharedInstance] start];
+  }
 }
 
 void SetMemoryWarningCount(int count) {
diff --git a/ios/chrome/browser/crash_report/crash_report_flags.cc b/ios/chrome/browser/crash_report/crash_report_flags.cc
index b30b56cf..b7c3edf 100644
--- a/ios/chrome/browser/crash_report/crash_report_flags.cc
+++ b/ios/chrome/browser/crash_report/crash_report_flags.cc
@@ -4,9 +4,42 @@
 
 #include "ios/chrome/browser/crash_report/crash_report_flags.h"
 
+#include "base/metrics/field_trial_params.h"
+
 namespace crash_report {
 
 const base::Feature kBreakpadNoDelayInitialUpload{
     "BreakpadNoDelayInitialUpload", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kDetectMainThreadFreeze{"DetectMainThreadFreeze",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+
+// The different timeout value for kDetectMainThreadFreeze.
+const char kDetectMainThreadFreezeParameterName[] = "timeout";
+const char kDetectMainThreadFreezeParameter3s[] = "3s";
+const char kDetectMainThreadFreezeParameter5s[] = "5s";
+const char kDetectMainThreadFreezeParameter7s[] = "7s";
+const char kDetectMainThreadFreezeParameter9s[] = "9s";
+
+int TimeoutForMainThreadFreezeDetection() {
+  if (!base::FeatureList::IsEnabled(kDetectMainThreadFreeze)) {
+    return 0;
+  }
+  std::string parameter = base::GetFieldTrialParamValueByFeature(
+      kDetectMainThreadFreeze, kDetectMainThreadFreezeParameterName);
+  if (parameter == kDetectMainThreadFreezeParameter3s) {
+    return 3;
+  }
+  if (parameter == kDetectMainThreadFreezeParameter5s) {
+    return 5;
+  }
+  if (parameter == kDetectMainThreadFreezeParameter7s) {
+    return 7;
+  }
+  if (parameter == kDetectMainThreadFreezeParameter9s) {
+    return 9;
+  }
+  return 0;
+}
+
 }  // namespace crash_report
diff --git a/ios/chrome/browser/crash_report/crash_report_flags.h b/ios/chrome/browser/crash_report/crash_report_flags.h
index 2c95022..27f3fbb 100644
--- a/ios/chrome/browser/crash_report/crash_report_flags.h
+++ b/ios/chrome/browser/crash_report/crash_report_flags.h
@@ -11,6 +11,20 @@
 
 extern const base::Feature kBreakpadNoDelayInitialUpload;
 
+// Feature to enable the detection of freeze in the main thread
+extern const base::Feature kDetectMainThreadFreeze;
+
+// The different timeout value for kDetectMainThreadFreeze.
+extern const char kDetectMainThreadFreezeParameterName[];
+extern const char kDetectMainThreadFreezeParameter3s[];
+extern const char kDetectMainThreadFreezeParameter5s[];
+extern const char kDetectMainThreadFreezeParameter7s[];
+extern const char kDetectMainThreadFreezeParameter9s[];
+
+// Returns a delay after which a crash report is generated if the main thread is
+// frozen. Returns 0 if the feature is disabled.
+int TimeoutForMainThreadFreezeDetection();
+
 }  // namespace crash_report
 
 #endif  // IOS_CHROME_BROWSER_CRASH_REPORT_CRASH_REPORT_FLAGS_H_
diff --git a/ios/chrome/browser/crash_report/main_thread_freeze_detector.h b/ios/chrome/browser/crash_report/main_thread_freeze_detector.h
new file mode 100644
index 0000000..26827e5
--- /dev/null
+++ b/ios/chrome/browser/crash_report/main_thread_freeze_detector.h
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_CRASH_REPORT_MAIN_THREAD_FREEZE_DETECTOR_H_
+#define IOS_CHROME_BROWSER_CRASH_REPORT_MAIN_THREAD_FREEZE_DETECTOR_H_
+
+#import <Foundation/Foundation.h>
+
+// Detects freezes of the main thread.
+// This class that the main thread runloop is run at least every
+// |TimeoutForMainThreadFreezeDetection|. If this is not the case, a
+// NSUserDefault flag is raised and a crash report is generated capturing the
+// stack of the main frame at that time.
+// Only one report is generated for each foreground/background session.
+// This class uses NSUserDefault as persistent storage as profile may not be
+// available (both because initialization is too early and because main thread
+// is often frozen at the point the class is used).
+@interface MainThreadFreezeDetector : NSObject
+// Returns the sharedInstance of the watchdog.
+// Note that on first access, the instance is immediately started without
+// checking the new preferences values. This is necessary to detect freezes
+// during applicationDidFinishLaunching.
++ (instancetype)sharedInstance;
+// The result of the previous session. If this is true, the last time the
+// application was terminated, main thread was not responding.
+@property(nonatomic, readonly) BOOL lastSessionEndedFrozen;
+// Starts the watchdog of the main thread.
+- (void)start;
+// Stops the watchdog of the main thread.
+- (void)stop;
+// Enables or disables the main thread watchdog. This will also start or stop
+// the monitoring of the main thread.
+- (void)setEnabled:(BOOL)enabled;
+@end
+
+#endif  // IOS_CHROME_BROWSER_CRASH_REPORT_MAIN_THREAD_FREEZE_DETECTOR_H_
diff --git a/ios/chrome/browser/crash_report/main_thread_freeze_detector.mm b/ios/chrome/browser/crash_report/main_thread_freeze_detector.mm
new file mode 100644
index 0000000..3973ffe
--- /dev/null
+++ b/ios/chrome/browser/crash_report/main_thread_freeze_detector.mm
@@ -0,0 +1,162 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/crash_report/main_thread_freeze_detector.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/time/time.h"
+#include "ios/chrome/browser/crash_report/crash_report_flags.h"
+#import "third_party/breakpad/breakpad/src/client/ios/Breakpad.h"
+#import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+namespace {
+const char kNsUserDefaultKeyLastSession[] =
+    "MainThreadDetectionLastThreadWasFrozen";
+const char kNsUserDefaultKeyDelay[] = "MainThreadDetectionDelay";
+
+void LogRecoveryTime(base::TimeDelta time) {
+  UMA_HISTOGRAM_TIMES("IOS.MainThreadFreezeDetection.RecoveredAfter", time);
+}
+
+}
+
+@interface MainThreadFreezeDetector ()
+// The callback that is called regularly on main thread.
+- (void)runInMainLoop;
+// The callback that is called regularly on watchdog thread.
+- (void)runInFreezeDetectionQueue;
+// These 4 properties will be accessed from both thread. Make them atomic.
+// The date at which |runInMainLoop| was last called.
+@property(atomic) NSDate* lastSeenMainThread;
+// Whether the watchdog should continue running.
+@property(atomic) BOOL running;
+// Whether a report was sent.
+@property(atomic) BOOL reportSent;
+// The delay in seconds after which main thread will be considered frozen.
+@property(atomic) NSInteger delay;
+@end
+
+@implementation MainThreadFreezeDetector {
+  dispatch_queue_t _freezeDetectionQueue;
+  BOOL _enabled;
+  BOOL _lastSessionEndedFrozen;
+  BOOL _experimentChecked;
+}
+
++ (instancetype)sharedInstance {
+  static MainThreadFreezeDetector* instance;
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    instance = [[MainThreadFreezeDetector alloc] init];
+  });
+  return instance;
+}
+
+- (instancetype)init {
+  self = [super init];
+  if (self) {
+    _lastSessionEndedFrozen = [[NSUserDefaults standardUserDefaults]
+        boolForKey:@(kNsUserDefaultKeyLastSession)];
+    [[NSUserDefaults standardUserDefaults]
+        setBool:NO
+         forKey:@(kNsUserDefaultKeyLastSession)];
+    self.delay = [[NSUserDefaults standardUserDefaults]
+        integerForKey:@(kNsUserDefaultKeyDelay)];
+    _freezeDetectionQueue = dispatch_queue_create(
+        "org.chromium.freeze_detection", DISPATCH_QUEUE_SERIAL);
+    // Like breakpad, the feature is created immediately in the enabled state as
+    // the settings are not available yet when it is started.
+    _enabled = YES;
+  }
+  return self;
+}
+
+- (void)setEnabled:(BOOL)enabled {
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    int newDelay = crash_report::TimeoutForMainThreadFreezeDetection();
+    self.delay = newDelay;
+    [[NSUserDefaults standardUserDefaults]
+        setInteger:newDelay
+            forKey:@(kNsUserDefaultKeyDelay)];
+    if (_lastSessionEndedFrozen) {
+      LogRecoveryTime(base::TimeDelta::FromSeconds(0));
+    }
+  });
+  _enabled = enabled;
+  if (_enabled) {
+    [self start];
+  } else {
+    [self stop];
+    [[NSUserDefaults standardUserDefaults]
+        setBool:NO
+         forKey:@(kNsUserDefaultKeyLastSession)];
+  }
+}
+
+- (void)start {
+  if (self.delay == 0 || self.running || !_enabled) {
+    return;
+  }
+  self.running = YES;
+  [self runInMainLoop];
+  dispatch_async(_freezeDetectionQueue, ^{
+    [self runInFreezeDetectionQueue];
+  });
+}
+
+- (void)stop {
+  self.running = NO;
+}
+
+- (void)runInMainLoop {
+  if (self.reportSent) {
+    self.reportSent = NO;
+    [[NSUserDefaults standardUserDefaults]
+        setBool:NO
+         forKey:@(kNsUserDefaultKeyLastSession)];
+    LogRecoveryTime(base::TimeDelta::FromSecondsD(
+        [[NSDate date] timeIntervalSinceDate:self.lastSeenMainThread]));
+  }
+  if (!self.running) {
+    return;
+  }
+  self.lastSeenMainThread = [NSDate date];
+  dispatch_after(
+      dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),
+      dispatch_get_main_queue(), ^{
+        [self runInMainLoop];
+      });
+}
+
+- (void)runInFreezeDetectionQueue {
+  if (!self.running) {
+    return;
+  }
+  if ([[NSDate date] timeIntervalSinceDate:self.lastSeenMainThread] >
+      self.delay) {
+    [[BreakpadController sharedInstance]
+        withBreakpadRef:^(BreakpadRef breakpadRef) {
+          if (!breakpadRef) {
+            return;
+          }
+          BreakpadGenerateReport(breakpadRef, nil);
+        }];
+    self.reportSent = YES;
+    self.running = NO;
+    [[NSUserDefaults standardUserDefaults]
+        setBool:YES
+         forKey:@(kNsUserDefaultKeyLastSession)];
+    return;
+  }
+  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
+                 _freezeDetectionQueue, ^{
+                   [self runInFreezeDetectionQueue];
+                 });
+}
+
+@end
diff --git a/ios/chrome/browser/find_in_page/resources/find_in_page.js b/ios/chrome/browser/find_in_page/resources/find_in_page.js
index b282c1b..9c05d80 100644
--- a/ios/chrome/browser/find_in_page/resources/find_in_page.js
+++ b/ios/chrome/browser/find_in_page/resources/find_in_page.js
@@ -147,6 +147,11 @@
  * each PartialMatch.
  */
 class PartialMatch {
+  /**
+   * @param {number} matchId ID of the Match to which this PartialMatch belongs.
+   * @param {number} begin Beginning index of partial match text in |allText_|.
+   * @param {number} end Ending index of partial match text in |allText_|.
+   */
   constructor(matchId, begin, end) {
     this.matchId = matchId;
     this.begin = begin;
@@ -169,8 +174,9 @@
  */
 class Replacement {
   /**
-   * @param {Node} The HTML Node containing search result.
-   * @param {Array<Node>} New HTML Nodes created for substitution of |oldNode|.
+   * @param {Node} oldNode The HTML Node containing search result.
+   * @param {Array<Node>} newNodes New HTML Nodes created for substitution of
+   *     |oldNode|.
    */
   constructor(oldNode, newNodes) {
     this.oldNode = oldNode;
@@ -338,11 +344,20 @@
 const NO_RESULTS = '[0,[0,0,0]]';
 
 /**
+ * Result passed back to app to indicate pumpSearch has reached timeout.
+ * @type {string}
+ */
+const TIMEOUT = '[false]';
+
+/**
  * Regex to escape regex special characters in a string.
  * @type {RegExp}
  */
 const REGEX_ESCAPER = /([.?*+^$[\]\\(){}|-])/g;
 
+/**
+ * @return {Match} The currently selected Match.
+ */
 function getCurrentSelectedMatch_() {
   return __gCrWeb.findInPage.matches[__gCrWeb.findInPage.selectedMatchIndex];
 };
@@ -387,16 +402,13 @@
 __gCrWeb.findInPage.highlightWord = function(findText, timeout) {
   if (__gCrWeb.findInPage.matches && __gCrWeb.findInPage.matches.length) {
     // Clean up a previous run.
-    clearHighlight_();
+    cleanUp_();
   }
   if (!findText) {
     // No searching for emptyness.
     return NO_RESULTS;
   }
 
-  // Node is what we are currently looking at.
-  __gCrWeb.findInPage.node = document.body;
-
   // Holds what nodes we have not processed yet.
   __gCrWeb.findInPage.stack = [];
 
@@ -405,6 +417,7 @@
     let doc = frameDocs_[i];
     __gCrWeb.findInPage.stack.push(doc);
   }
+  __gCrWeb.findInPage.stack.push(document.body);
 
   // Number of visible elements found.
   __gCrWeb.findInPage.visibleFound = 0;
@@ -431,7 +444,7 @@
  *   4. Check the visibility of each Match;
  *   5. Call __gCrWeb.findInPage.goNext.
  *
- * If |timeout| has been reached, the function will return '[false]', and the
+ * If |timeout| has been reached, the function will return TIMEOUT, and the
  * caller need to call this function again to continue searching. This prevents
  * the Js thread from blocking the WebView's UI.
  *
@@ -447,8 +460,8 @@
   let timer = new Timer(timeout);
 
   // Go through every node in DFS fashion.
-  while (__gCrWeb.findInPage.node) {
-    let node = __gCrWeb.findInPage.node;
+  while (__gCrWeb.findInPage.stack.length) {
+    let node = __gCrWeb.findInPage.stack.pop();
     let children = node.childNodes;
     if (children && children.length) {
       // add all (reasonable) children
@@ -469,13 +482,7 @@
     }
 
     if (timer.overtime())
-      return '[false]';
-
-    if (__gCrWeb.findInPage.stack.length > 0) {
-      __gCrWeb.findInPage.node = __gCrWeb.findInPage.stack.pop();
-    } else {
-      __gCrWeb.findInPage.node = null;
-    }
+      return TIMEOUT;
   }
 
   // Do regex match in |allText_|, create |matches| and |replacements|. The
@@ -518,7 +525,7 @@
       ++matchId_;
 
       if (timer.overtime())
-        return '[false]';
+        return TIMEOUT;
     }
     // Process remaining PartialMatches.
     processPartialMatchesInCurrentSection();
@@ -529,7 +536,7 @@
   for (let i = replacementsIndex_; i < replacements_.length; ++i) {
     if (timer.overtime()) {
       replacementsIndex_ = i;
-      return __gCrWeb.stringify([false]);
+      return TIMEOUT;
     }
     replacements_[i].doSwap();
   }
@@ -541,7 +548,7 @@
     let match = __gCrWeb.findInPage.matches[index];
     if (timer.overtime()) {
       __gCrWeb.findInPage.visibleIndex = index;
-      return __gCrWeb.stringify([false]);
+      return TIMEOUT;
     }
 
     // Stop after |maxVisible| elements.
@@ -567,22 +574,25 @@
 };
 
 /**
- * Removes all currently highlighted matches.
- * Note: It does not restore previous state, just removes the class name.
+ * Removes highlights of previous search and reset all global vars.
+ * @return {undefined}
  */
-function clearHighlight_() {
+function cleanUp_() {
   for (let i = 0; i < replacements_.length; ++i) {
     replacements_[i].undoSwap();
   }
-  replacements_ = [];
-  replacementsIndex_ = 0;
-  __gCrWeb.findInPage.matches = [];
-  __gCrWeb.findInPage.selectedMatchIndex = -1;
+
   allText_ = '';
   sections_ = [];
   sectionsIndex_ = 0;
+
+  __gCrWeb.findInPage.matches = [];
+  __gCrWeb.findInPage.selectedMatchIndex = -1;
   matchId_ = 0;
   partialMatches_ = [];
+
+  replacements_ = [];
+  replacementsIndex_ = 0;
 };
 
 /**
@@ -836,7 +846,7 @@
 __gCrWeb.findInPage.disable = function() {
   if (styleElement_) {
     removeStyle_();
-    window.setTimeout(clearHighlight_, 0);
+    window.setTimeout(cleanUp_, 0);
   }
   __gCrWeb.findInPage.hasInitialized = false;
 };
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index a7310ea..4973335 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -209,6 +209,11 @@
 const char kCopyImageDescription[] =
     "Enable copying image to system pasteboard via context menu.";
 
+const char kDetectMainThreadFreezeName[] = "Detect freeze in the main thread.";
+const char kDetectMainThreadFreezeDescription[] =
+    "A crash report will be uploaded if the main thread is frozen more than "
+    "the time specified by this flag.";
+
 const char kDragAndDropName[] = "Drag and Drop";
 const char kDragAndDropDescription[] = "Enable support for drag and drop.";
 
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 46b456b9..0eb188b 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -29,6 +29,11 @@
 extern const char kBreakpadNoDelayInitialUploadName[];
 extern const char kBreakpadNoDelayInitialUploadDescription[];
 
+// Title and description for the flag to control if a crash report is generated
+// on main thread freeze.
+extern const char kDetectMainThreadFreezeName[];
+extern const char kDetectMainThreadFreezeDescription[];
+
 // Title and description for the flag to control the updated prompt explanation
 // when offering credit card upload.
 extern const char kEnableAutofillCreditCardUploadUpdatePromptExplanationName[];
diff --git a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h
index bbe20d5..50c1b44 100644
--- a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h
+++ b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h
@@ -23,6 +23,7 @@
   SHUTDOWN_IN_FOREGROUND_NO_CRASH_LOG_WITH_MEMORY_WARNING,
   SHUTDOWN_IN_FOREGROUND_WITH_CRASH_LOG_WITH_MEMORY_WARNING,
   FIRST_LAUNCH_AFTER_UPGRADE,
+  SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN,
   MOBILE_SESSION_SHUTDOWN_TYPE_COUNT,
 };
 
@@ -52,6 +53,9 @@
   // Whether there was a memory warning shortly before last shutdown.
   virtual bool ReceivedMemoryWarningBeforeLastShutdown();
 
+  // Whether the main thread was frozen on previous session termination.
+  virtual bool LastSessionEndedFrozen();
+
  private:
   metrics::MetricsService* metrics_service_;
   DISALLOW_COPY_AND_ASSIGN(MobileSessionShutdownMetricsProvider);
diff --git a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm
index edcbe16..edcf1333 100644
--- a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm
+++ b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.mm
@@ -10,6 +10,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "components/metrics/metrics_service.h"
 #include "ios/chrome/browser/crash_report/breakpad_helper.h"
+#include "ios/chrome/browser/crash_report/main_thread_freeze_detector.h"
 #import "ios/chrome/browser/metrics/previous_session_info.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -65,6 +66,13 @@
     return;
   }
 
+  // If the last app lifetime ended with main thread not responding, log it as
+  // main thread frozen shutdown.
+  if (LastSessionEndedFrozen()) {
+    LogShutdownType(SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN);
+    return;
+  }
+
   // If the last app lifetime ended in a crash, log the type of crash.
   MobileSessionShutdownType shutdown_type;
   if (ReceivedMemoryWarningBeforeLastShutdown()) {
@@ -91,6 +99,10 @@
   return breakpad_helper::HasReportToUpload();
 }
 
+bool MobileSessionShutdownMetricsProvider::LastSessionEndedFrozen() {
+  return [MainThreadFreezeDetector sharedInstance].lastSessionEndedFrozen;
+}
+
 bool MobileSessionShutdownMetricsProvider::
     ReceivedMemoryWarningBeforeLastShutdown() {
   return [[PreviousSessionInfo sharedInstance]
diff --git a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider_unittest.mm b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider_unittest.mm
index 37cbe56b..088a6da 100644
--- a/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider_unittest.mm
+++ b/ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider_unittest.mm
@@ -41,6 +41,9 @@
   void set_received_memory_warning_before_last_shutdown(bool value) {
     received_memory_warning_before_last_shutdown_ = value;
   }
+  void set_was_last_shutdown_frozen(bool value) {
+    was_last_shutdown_frozen_ = value;
+  }
 
  protected:
   // MobileSessionShutdownMetricsProvider:
@@ -51,11 +54,13 @@
   bool ReceivedMemoryWarningBeforeLastShutdown() override {
     return received_memory_warning_before_last_shutdown_;
   }
+  bool LastSessionEndedFrozen() override { return was_last_shutdown_frozen_; }
 
  private:
   bool is_first_launch_after_upgrade_;
   bool has_crash_logs_;
   bool received_memory_warning_before_last_shutdown_;
+  bool was_last_shutdown_frozen_;
 
   DISALLOW_COPY_AND_ASSIGN(MobileSessionShutdownMetricsProviderForTesting);
 };
@@ -94,8 +99,9 @@
 TEST_P(MobileSessionShutdownMetricsProviderTest, ProvideStabilityMetrics) {
   const bool received_memory_warning = GetParam() % 2;
   const bool has_crash_logs = (GetParam() >> 1) % 2;
-  const bool was_last_shutdown_clean = (GetParam() >> 2) % 2;
-  const bool is_first_launch_after_upgrade = (GetParam() >> 3) % 2;
+  const bool was_last_shutdown_frozen = (GetParam() >> 2) % 2;
+  const bool was_last_shutdown_clean = (GetParam() >> 3) % 2;
+  const bool is_first_launch_after_upgrade = (GetParam() >> 4) % 2;
 
   // Expected bucket for each possible value of GetParam().
   const MobileSessionShutdownType expected_buckets[] = {
@@ -103,12 +109,20 @@
       SHUTDOWN_IN_FOREGROUND_NO_CRASH_LOG_WITH_MEMORY_WARNING,
       SHUTDOWN_IN_FOREGROUND_WITH_CRASH_LOG_NO_MEMORY_WARNING,
       SHUTDOWN_IN_FOREGROUND_WITH_CRASH_LOG_WITH_MEMORY_WARNING,
+      SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN,
+      SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN,
+      SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN,
+      SHUTDOWN_IN_FOREGROUND_WITH_MAIN_THREAD_FROZEN,
       // If wasLastShutdownClean is true, the memory warning and crash log don't
       // matter.
       SHUTDOWN_IN_BACKGROUND,
       SHUTDOWN_IN_BACKGROUND,
       SHUTDOWN_IN_BACKGROUND,
       SHUTDOWN_IN_BACKGROUND,
+      SHUTDOWN_IN_BACKGROUND,
+      SHUTDOWN_IN_BACKGROUND,
+      SHUTDOWN_IN_BACKGROUND,
+      SHUTDOWN_IN_BACKGROUND,
       // If firstLaunchAfterUpgrade is true, the other flags don't matter.
       FIRST_LAUNCH_AFTER_UPGRADE,
       FIRST_LAUNCH_AFTER_UPGRADE,
@@ -118,6 +132,14 @@
       FIRST_LAUNCH_AFTER_UPGRADE,
       FIRST_LAUNCH_AFTER_UPGRADE,
       FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
+      FIRST_LAUNCH_AFTER_UPGRADE,
   };
 
   // Setup the MetricsService.
@@ -140,6 +162,7 @@
   metrics_provider_->set_received_memory_warning_before_last_shutdown(
       received_memory_warning);
   metrics_provider_->set_has_crash_logs(has_crash_logs);
+  metrics_provider_->set_was_last_shutdown_frozen(was_last_shutdown_frozen);
 
   // Create a histogram tester for verifying samples written to the shutdown
   // type histogram.
@@ -154,4 +177,4 @@
 
 INSTANTIATE_TEST_CASE_P(/* No InstantiationName */,
                         MobileSessionShutdownMetricsProviderTest,
-                        testing::Range(0, 16));
+                        testing::Range(0, 32));
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index 8443060..f1095dcb 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -217,7 +217,9 @@
                  providers:@[ [passwordController_ suggestionProvider] ]];
       accessoryMediator_ =
           [[FormInputAccessoryMediator alloc] initWithConsumer:nil
-                                                  webStateList:NULL];
+                                                  webStateList:NULL
+                                           personalDataManager:NULL
+                                                 passwordStore:NULL];
       [accessoryMediator_ injectWebState:web_state()];
       [accessoryMediator_ injectProviders:@[ suggestionController_ ]];
     }
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn
index f2024f5..a0686d1 100644
--- a/ios/chrome/browser/signin/BUILD.gn
+++ b/ios/chrome/browser/signin/BUILD.gn
@@ -41,6 +41,10 @@
     "profile_oauth2_token_service_factory.mm",
     "profile_oauth2_token_service_ios_provider_impl.h",
     "profile_oauth2_token_service_ios_provider_impl.mm",
+    "signin_browser_state_info_updater.h",
+    "signin_browser_state_info_updater.mm",
+    "signin_browser_state_info_updater_factory.h",
+    "signin_browser_state_info_updater_factory.mm",
     "signin_client_factory.cc",
     "signin_client_factory.h",
     "signin_error_controller_factory.cc",
diff --git a/ios/chrome/browser/signin/OWNERS b/ios/chrome/browser/signin/OWNERS
index a8f0801c..5ccf334 100644
--- a/ios/chrome/browser/signin/OWNERS
+++ b/ios/chrome/browser/signin/OWNERS
@@ -1,4 +1,3 @@
-bzanotti@chromium.org
 jlebel@chromium.org
 msarda@chromium.org
 
diff --git a/ios/chrome/browser/signin/account_reconcilor_factory.cc b/ios/chrome/browser/signin/account_reconcilor_factory.cc
index cc12c80..f586833 100644
--- a/ios/chrome/browser/signin/account_reconcilor_factory.cc
+++ b/ios/chrome/browser/signin/account_reconcilor_factory.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/memory/singleton.h"
+#include "build/build_config.h"
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/signin/core/browser/account_reconcilor.h"
 #include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
@@ -15,6 +16,7 @@
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "ios/chrome/browser/signin/signin_client_factory.h"
+#include "ios/web/public/features.h"
 #include "services/identity/public/cpp/identity_manager.h"
 
 namespace ios {
@@ -57,6 +59,10 @@
       GaiaCookieManagerServiceFactory::GetForBrowserState(chrome_browser_state),
       std::make_unique<signin::MirrorAccountReconcilorDelegate>(
           identity_manager)));
+#if defined(OS_IOS)
+  reconcilor->SetIsWKHTTPSystemCookieStoreEnabled(
+      base::FeatureList::IsEnabled(web::features::kWKHTTPSystemCookieStore));
+#endif  // defined(OS_IOS)
   reconcilor->Initialize(true /* start_reconcile_if_tokens_available */);
   return reconcilor;
 }
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm
index b57ab409..c8dac83a 100644
--- a/ios/chrome/browser/signin/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -66,7 +66,6 @@
       scoped_refptr<content_settings::CookieSettings> cookie_settings,
       scoped_refptr<HostContentSettingsMap> host_content_settings_map)
       : IOSChromeSigninClient(browser_state,
-                              signin_error_controller,
                               cookie_settings,
                               host_content_settings_map) {}
   ~FakeSigninClient() override {}
diff --git a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h
index 47f01b37..d054d55 100644
--- a/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h
+++ b/ios/chrome/browser/signin/gaia_auth_fetcher_ios.h
@@ -17,15 +17,15 @@
 
 namespace net {
 class URLRequestStatus;
-}
+}  // namespace net
 
 namespace network {
 class SharedURLLoaderFactory;
-}
+}  // namespace network
 
 namespace web {
 class BrowserState;
-}
+}  // namespace web
 
 // Specialization of GaiaAuthFetcher on iOS.
 //
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.h b/ios/chrome/browser/signin/ios_chrome_signin_client.h
index dce6cde..b19165df 100644
--- a/ios/chrome/browser/signin/ios_chrome_signin_client.h
+++ b/ios/chrome/browser/signin/ios_chrome_signin_client.h
@@ -11,7 +11,6 @@
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/ios/browser/wait_for_network_callback_helper.h"
 #include "net/cookies/cookie_change_dispatcher.h"
 
@@ -20,12 +19,10 @@
 }
 
 // Concrete implementation of SigninClient for //ios/chrome.
-class IOSChromeSigninClient : public SigninClient,
-                              public SigninErrorController::Observer {
+class IOSChromeSigninClient : public SigninClient {
  public:
   IOSChromeSigninClient(
       ios::ChromeBrowserState* browser_state,
-      SigninErrorController* signin_error_controller,
       scoped_refptr<content_settings::CookieSettings> cookie_settings,
       scoped_refptr<HostContentSettingsMap> host_content_settings_map);
   ~IOSChromeSigninClient() override;
@@ -36,10 +33,6 @@
   // SigninClient implementation.
   base::Time GetInstallDate() override;
   std::string GetProductVersion() override;
-  void OnSignedIn(const std::string& account_id,
-                  const std::string& gaia_id,
-                  const std::string& username,
-                  const std::string& password) override;
   std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher(
       GaiaAuthConsumer* consumer,
       gaia::GaiaSource source,
@@ -57,10 +50,6 @@
   void RemoveContentSettingsObserver(
       content_settings::Observer* observer) override;
   void DelayNetworkCall(const base::Closure& callback) override;
-  void OnSignedOut() override;
-
-  // SigninErrorController::Observer implementation.
-  void OnErrorChanged() override;
 
  private:
 
@@ -68,8 +57,6 @@
   std::unique_ptr<WaitForNetworkCallbackHelper> network_callback_helper_;
   // The browser state associated with this service.
   ios::ChromeBrowserState* browser_state_;
-  // Used to check for errors related to signing in.
-  SigninErrorController* signin_error_controller_;
   // Used to check if sign in cookies are allowed.
   scoped_refptr<content_settings::CookieSettings> cookie_settings_;
   // Used to add and remove content settings observers.
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
index 8bb28bf..1ea733a 100644
--- a/ios/chrome/browser/signin/ios_chrome_signin_client.mm
+++ b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
@@ -25,20 +25,16 @@
 
 IOSChromeSigninClient::IOSChromeSigninClient(
     ios::ChromeBrowserState* browser_state,
-    SigninErrorController* signin_error_controller,
     scoped_refptr<content_settings::CookieSettings> cookie_settings,
     scoped_refptr<HostContentSettingsMap> host_content_settings_map)
     : network_callback_helper_(
           std::make_unique<WaitForNetworkCallbackHelper>()),
       browser_state_(browser_state),
-      signin_error_controller_(signin_error_controller),
       cookie_settings_(cookie_settings),
       host_content_settings_map_(host_content_settings_map) {
-  signin_error_controller_->AddObserver(this);
 }
 
 IOSChromeSigninClient::~IOSChromeSigninClient() {
-  signin_error_controller_->RemoveObserver(this);
 }
 
 void IOSChromeSigninClient::Shutdown() {
@@ -57,38 +53,6 @@
   return GetVersionString();
 }
 
-void IOSChromeSigninClient::OnSignedIn(const std::string& account_id,
-                                       const std::string& gaia_id,
-                                       const std::string& username,
-                                       const std::string& password) {
-  ios::ChromeBrowserStateManager* browser_state_manager =
-      GetApplicationContext()->GetChromeBrowserStateManager();
-  BrowserStateInfoCache* cache =
-      browser_state_manager->GetBrowserStateInfoCache();
-  size_t index = cache->GetIndexOfBrowserStateWithPath(
-      browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
-  if (index != std::string::npos) {
-    cache->SetAuthInfoOfBrowserStateAtIndex(index, gaia_id,
-                                            base::UTF8ToUTF16(username));
-  }
-}
-
-void IOSChromeSigninClient::OnSignedOut() {
-  BrowserStateInfoCache* cache = GetApplicationContext()
-                                     ->GetChromeBrowserStateManager()
-                                     ->GetBrowserStateInfoCache();
-  size_t index = cache->GetIndexOfBrowserStateWithPath(
-      browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
-
-  // If sign out occurs because Sync setup was in progress and the browser state
-  // got deleted, then it is no longer in the cache.
-  if (index == std::string::npos)
-    return;
-
-  cache->SetAuthInfoOfBrowserStateAtIndex(index, std::string(),
-                                          base::string16());
-}
-
 PrefService* IOSChromeSigninClient::GetPrefs() {
   return browser_state_->GetPrefs();
 }
@@ -139,16 +103,3 @@
       ios::AccountConsistencyServiceFactory::GetForBrowserState(browser_state_);
   accountConsistencyService->RemoveChromeConnectedCookies(std::move(callback));
 }
-
-void IOSChromeSigninClient::OnErrorChanged() {
-  BrowserStateInfoCache* cache = GetApplicationContext()
-                                     ->GetChromeBrowserStateManager()
-                                     ->GetBrowserStateInfoCache();
-  size_t index = cache->GetIndexOfBrowserStateWithPath(
-      browser_state_->GetOriginalChromeBrowserState()->GetStatePath());
-  if (index == std::string::npos)
-    return;
-
-  cache->SetBrowserStateIsAuthErrorAtIndex(
-      index, signin_error_controller_->HasError());
-}
diff --git a/ios/chrome/browser/signin/signin_browser_state_info_updater.h b/ios/chrome/browser/signin/signin_browser_state_info_updater.h
new file mode 100644
index 0000000..dcba3219
--- /dev/null
+++ b/ios/chrome/browser/signin/signin_browser_state_info_updater.h
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_H_
+#define IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "build/build_config.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/signin/core/browser/signin_error_controller.h"
+#include "components/signin/core/browser/signin_manager_base.h"
+
+// This class listens to various signin events and updates the signin-related
+// fields of BrowserStateInfoCache.
+class SigninBrowserStateInfoUpdater : public KeyedService,
+                                      public SigninErrorController::Observer,
+                                      public SigninManagerBase::Observer {
+ public:
+  SigninBrowserStateInfoUpdater(SigninManagerBase* signin_manager,
+                                SigninErrorController* signin_error_controller,
+                                const base::FilePath& browser_state_path);
+
+  ~SigninBrowserStateInfoUpdater() override;
+
+ private:
+  // KeyedService:
+  void Shutdown() override;
+
+  // SigninErrorController::Observer:
+  void OnErrorChanged() override;
+
+  // SigninManagerBase::Observer:
+  void GoogleSigninSucceeded(const AccountInfo& account_info) override;
+  void GoogleSignedOut(const AccountInfo& account_info) override;
+
+  SigninErrorController* signin_error_controller_ = nullptr;
+  const base::FilePath browser_state_path_;
+  ScopedObserver<SigninErrorController, SigninBrowserStateInfoUpdater>
+      signin_error_controller_observer_;
+  ScopedObserver<SigninManagerBase, SigninBrowserStateInfoUpdater>
+      signin_manager_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(SigninBrowserStateInfoUpdater);
+};
+
+#endif  // IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_H_
diff --git a/ios/chrome/browser/signin/signin_browser_state_info_updater.mm b/ios/chrome/browser/signin/signin_browser_state_info_updater.mm
new file mode 100644
index 0000000..2145ff5
--- /dev/null
+++ b/ios/chrome/browser/signin/signin_browser_state_info_updater.mm
@@ -0,0 +1,82 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/chrome/browser/signin/signin_browser_state_info_updater.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/signin/core/browser/account_info.h"
+#include "ios/chrome/browser/application_context.h"
+#include "ios/chrome/browser/browser_state/browser_state_info_cache.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
+
+SigninBrowserStateInfoUpdater::SigninBrowserStateInfoUpdater(
+    SigninManagerBase* signin_manager,
+    SigninErrorController* signin_error_controller,
+    const base::FilePath& browser_state_path)
+    : signin_error_controller_(signin_error_controller),
+      browser_state_path_(browser_state_path),
+      signin_error_controller_observer_(this),
+      signin_manager_observer_(this) {
+  signin_error_controller_observer_.Add(signin_error_controller);
+  // TODO(crbug.com/908457): Call OnErrorChanged() here, to catch any change
+  // that happened since the construction of SigninErrorController. BrowserState
+  // metrics depend on this bug and must be fixed first.
+}
+
+SigninBrowserStateInfoUpdater::~SigninBrowserStateInfoUpdater() = default;
+
+void SigninBrowserStateInfoUpdater::Shutdown() {
+  signin_error_controller_observer_.RemoveAll();
+  signin_manager_observer_.RemoveAll();
+}
+
+void SigninBrowserStateInfoUpdater::OnErrorChanged() {
+  BrowserStateInfoCache* cache = GetApplicationContext()
+                                     ->GetChromeBrowserStateManager()
+                                     ->GetBrowserStateInfoCache();
+  size_t index = cache->GetIndexOfBrowserStateWithPath(browser_state_path_);
+  if (index == std::string::npos)
+    return;
+
+  cache->SetBrowserStateIsAuthErrorAtIndex(
+      index, signin_error_controller_->HasError());
+}
+
+void SigninBrowserStateInfoUpdater::GoogleSigninSucceeded(
+    const AccountInfo& account_info) {
+  ios::ChromeBrowserStateManager* browser_state_manager =
+      GetApplicationContext()->GetChromeBrowserStateManager();
+  BrowserStateInfoCache* cache =
+      browser_state_manager->GetBrowserStateInfoCache();
+  size_t index = cache->GetIndexOfBrowserStateWithPath(browser_state_path_);
+
+  if (index == std::string::npos)
+    return;
+
+  cache->SetAuthInfoOfBrowserStateAtIndex(
+      index, account_info.gaia, base::UTF8ToUTF16(account_info.email));
+}
+
+void SigninBrowserStateInfoUpdater::GoogleSignedOut(
+    const AccountInfo& account_info) {
+  BrowserStateInfoCache* cache = GetApplicationContext()
+                                     ->GetChromeBrowserStateManager()
+                                     ->GetBrowserStateInfoCache();
+  size_t index = cache->GetIndexOfBrowserStateWithPath(browser_state_path_);
+
+  // If sign out occurs because Sync setup was in progress and the browser state
+  // got deleted, then it is no longer in the cache.
+  if (index == std::string::npos)
+    return;
+
+  cache->SetAuthInfoOfBrowserStateAtIndex(index, /*gaia_id=*/std::string(),
+                                          /*user_name=*/base::string16());
+}
diff --git a/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.h b/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.h
new file mode 100644
index 0000000..852c3272
--- /dev/null
+++ b/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.h
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_FACTORY_H_
+#define IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+
+namespace ios {
+class ChromeBrowserState;
+}
+
+class SigninBrowserStateInfoUpdater;
+
+class SigninBrowserStateInfoUpdaterFactory
+    : public BrowserStateKeyedServiceFactory {
+ public:
+  // Returns nullptr if this browser state cannot have a
+  // SigninBrowserStateInfoUpdater (for example, if it is incognito).
+  static SigninBrowserStateInfoUpdater* GetForBrowserState(
+      ios::ChromeBrowserState* chrome_browser_state);
+
+  // Returns an instance of the factory singleton.
+  static SigninBrowserStateInfoUpdaterFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<
+      SigninBrowserStateInfoUpdaterFactory>;
+
+  SigninBrowserStateInfoUpdaterFactory();
+  ~SigninBrowserStateInfoUpdaterFactory() override;
+
+  // BrowserStateKeyedServiceFactory:
+  std::unique_ptr<KeyedService> BuildServiceInstanceFor(
+      web::BrowserState* state) const override;
+  bool ServiceIsCreatedWithBrowserState() const override;
+
+  DISALLOW_COPY_AND_ASSIGN(SigninBrowserStateInfoUpdaterFactory);
+};
+
+#endif  // IOS_CHROME_BROWSER_SIGNIN_SIGNIN_BROWSER_STATE_INFO_UPDATER_FACTORY_H_
diff --git a/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.mm b/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.mm
new file mode 100644
index 0000000..f7f6509
--- /dev/null
+++ b/ios/chrome/browser/signin/signin_browser_state_info_updater_factory.mm
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/signin/signin_browser_state_info_updater_factory.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/signin/signin_browser_state_info_updater.h"
+#include "ios/chrome/browser/signin/signin_error_controller_factory.h"
+#include "ios/chrome/browser/signin/signin_manager_factory.h"
+
+// static
+SigninBrowserStateInfoUpdater*
+SigninBrowserStateInfoUpdaterFactory::GetForBrowserState(
+    ios::ChromeBrowserState* chrome_browser_state) {
+  return static_cast<SigninBrowserStateInfoUpdater*>(
+      GetInstance()->GetServiceForBrowserState(chrome_browser_state, true));
+}
+
+// static
+SigninBrowserStateInfoUpdaterFactory*
+SigninBrowserStateInfoUpdaterFactory::GetInstance() {
+  return base::Singleton<SigninBrowserStateInfoUpdaterFactory>::get();
+}
+
+SigninBrowserStateInfoUpdaterFactory::SigninBrowserStateInfoUpdaterFactory()
+    : BrowserStateKeyedServiceFactory(
+          "SigninBrowserStateInfoUpdater",
+          BrowserStateDependencyManager::GetInstance()) {
+  DependsOn(ios::SigninErrorControllerFactory::GetInstance());
+  DependsOn(ios::SigninManagerFactory::GetInstance());
+}
+
+SigninBrowserStateInfoUpdaterFactory::~SigninBrowserStateInfoUpdaterFactory() {}
+
+std::unique_ptr<KeyedService>
+SigninBrowserStateInfoUpdaterFactory::BuildServiceInstanceFor(
+    web::BrowserState* state) const {
+  ios::ChromeBrowserState* chrome_browser_state =
+      ios::ChromeBrowserState::FromBrowserState(state);
+  return std::make_unique<SigninBrowserStateInfoUpdater>(
+      ios::SigninManagerFactory::GetForBrowserState(chrome_browser_state),
+      ios::SigninErrorControllerFactory::GetForBrowserState(
+          chrome_browser_state),
+      chrome_browser_state->GetStatePath());
+}
+
+bool SigninBrowserStateInfoUpdaterFactory::ServiceIsCreatedWithBrowserState()
+    const {
+  return true;
+}
diff --git a/ios/chrome/browser/signin/signin_client_factory.cc b/ios/chrome/browser/signin/signin_client_factory.cc
index 9376e19..97a6de6 100644
--- a/ios/chrome/browser/signin/signin_client_factory.cc
+++ b/ios/chrome/browser/signin/signin_client_factory.cc
@@ -11,7 +11,6 @@
 #include "ios/chrome/browser/content_settings/cookie_settings_factory.h"
 #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "ios/chrome/browser/signin/ios_chrome_signin_client.h"
-#include "ios/chrome/browser/signin/signin_error_controller_factory.h"
 
 // static
 SigninClient* SigninClientFactory::GetForBrowserState(
@@ -29,7 +28,6 @@
     : BrowserStateKeyedServiceFactory(
           "SigninClient",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ios::SigninErrorControllerFactory::GetInstance());
   DependsOn(ios::CookieSettingsFactory::GetInstance());
   DependsOn(ios::HostContentSettingsMapFactory::GetInstance());
 }
@@ -42,8 +40,6 @@
       ios::ChromeBrowserState::FromBrowserState(context);
   return std::make_unique<IOSChromeSigninClient>(
       chrome_browser_state,
-      ios::SigninErrorControllerFactory::GetForBrowserState(
-          chrome_browser_state),
       ios::CookieSettingsFactory::GetForBrowserState(chrome_browser_state),
       ios::HostContentSettingsMapFactory::GetForBrowserState(
           chrome_browser_state));
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn
index 2fa54838..b225d03 100644
--- a/ios/chrome/browser/sync/BUILD.gn
+++ b/ios/chrome/browser/sync/BUILD.gn
@@ -51,7 +51,6 @@
     "//components/sync",
     "//components/sync_preferences",
     "//components/sync_sessions",
-    "//components/unified_consent",
     "//components/version_info",
     "//google_apis",
     "//ios/chrome/browser",
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.cc b/ios/chrome/browser/sync/profile_sync_service_factory.cc
index 491708f..882b9d5 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/ios/chrome/browser/sync/profile_sync_service_factory.cc
@@ -17,7 +17,6 @@
 #include "components/signin/core/browser/device_id_helper.h"
 #include "components/sync/driver/startup_controller.h"
 #include "components/sync/driver/sync_util.h"
-#include "components/unified_consent/feature.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc
index fbaf6b9..e8d098d5 100644
--- a/ios/chrome/browser/sync/sync_setup_service.cc
+++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -11,16 +11,15 @@
 #include "components/sync/base/stop_source.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_user_settings.h"
-#include "components/unified_consent/feature.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 
 namespace {
 // The set of user-selectable datatypes. This must be in the same order as
 // |SyncSetupService::SyncableDatatype|.
 syncer::ModelType kDataTypes[] = {
-    syncer::BOOKMARKS,    syncer::TYPED_URLS,  syncer::PASSWORDS,
-    syncer::PROXY_TABS,   syncer::AUTOFILL,    syncer::PREFERENCES,
-    syncer::READING_LIST, syncer::USER_EVENTS,
+    syncer::BOOKMARKS,    syncer::TYPED_URLS, syncer::PASSWORDS,
+    syncer::PROXY_TABS,   syncer::AUTOFILL,   syncer::PREFERENCES,
+    syncer::READING_LIST,
 };
 }  // namespace
 
@@ -28,9 +27,6 @@
     : sync_service_(sync_service) {
   DCHECK(sync_service_);
   for (unsigned int i = 0; i < base::size(kDataTypes); ++i) {
-    if (kDataTypes[i] == syncer::USER_EVENTS &&
-        !unified_consent::IsUnifiedConsentFeatureEnabled())
-      continue;
     user_selectable_types_.Put(kDataTypes[i]);
   }
 }
diff --git a/ios/chrome/browser/sync/sync_setup_service.h b/ios/chrome/browser/sync/sync_setup_service.h
index b70b1ca..94fe2187 100644
--- a/ios/chrome/browser/sync/sync_setup_service.h
+++ b/ios/chrome/browser/sync/sync_setup_service.h
@@ -40,7 +40,6 @@
     kSyncAutofill,
     kSyncPreferences,
     kSyncReadingList,
-    kSyncUserEvent,
     kNumberOfSyncableDatatypes
   };
 
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index 790f8a7e..3b4a20f5 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -30,7 +30,7 @@
 #include "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
 #import "ios/chrome/browser/ui/authentication/authentication_ui_util.h"
 #import "ios/chrome/browser/ui/commands/browsing_data_commands.h"
-#import "ios/chrome/browser/ui/settings/import_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -396,7 +396,7 @@
 
 #pragma mark - ImportDataControllerDelegate
 
-- (void)didChooseClearDataPolicy:(ImportDataCollectionViewController*)controller
+- (void)didChooseClearDataPolicy:(ImportDataTableViewController*)controller
                  shouldClearData:(ShouldClearData)shouldClearData {
   DCHECK_NE(SHOULD_CLEAR_DATA_USER_CHOICE, shouldClearData);
   if (shouldClearData == SHOULD_CLEAR_DATA_CLEAR_DATA) {
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm
index aea3e31..41893b7 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm
@@ -10,11 +10,8 @@
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/common/autofill_features.h"
 #import "components/autofill/ios/browser/js_suggestion_manager.h"
-#import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h"
 #include "components/keyed_service/core/service_access_type.h"
-#include "components/password_manager/core/browser/password_store.h"
 #import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h"
-#import "ios/chrome/browser/autofill/manual_fill/passwords_fetcher.h"
 #include "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
 #import "ios/chrome/browser/ui/autofill/form_input_accessory_mediator.h"
@@ -31,21 +28,12 @@
 #error "This file requires ARC support."
 #endif
 
-@interface FormInputAccessoryCoordinator ()<
+@interface FormInputAccessoryCoordinator () <
     AutofillSecurityAlertPresenter,
     AddressCoordinatorDelegate,
     CardCoordinatorDelegate,
     ManualFillAccessoryViewControllerDelegate,
-    PasswordCoordinatorDelegate,
-    PasswordFetcherDelegate,
-    PersonalDataManagerObserver> {
-  // Personal data manager to be observed.
-  autofill::PersonalDataManager* _personalDataManager;
-
-  // C++ to ObjC bridge for PersonalDataManagerObserver.
-  std::unique_ptr<autofill::PersonalDataManagerObserverBridge>
-      _personalDataManagerObserver;
-}
+    PasswordCoordinatorDelegate>
 
 // The Mediator for the input accessory view controller.
 @property(nonatomic, strong)
@@ -55,18 +43,11 @@
 @property(nonatomic, strong)
     FormInputAccessoryViewController* formInputAccessoryViewController;
 
-// The manual fill accessory to show above the keyboard.
-@property(nonatomic, strong)
-    ManualFillAccessoryViewController* manualFillAccessoryViewController;
-
 // The object in charge of interacting with the web view. Used to fill the data
 // in the forms.
 @property(nonatomic, strong)
     ManualFillInjectionHandler* manualFillInjectionHandler;
 
-// The password fetcher used to inform if passwords are available.
-@property(nonatomic, strong) PasswordFetcher* passwordFetcher;
-
 // The WebStateList for this instance. Used to instantiate the child
 // coordinators lazily.
 @property(nonatomic, assign) WebStateList* webStateList;
@@ -91,64 +72,25 @@
                                           securityAlertPresenter:self];
 
     _formInputAccessoryViewController =
-        [[FormInputAccessoryViewController alloc] init];
-
-    if (autofill::features::IsPasswordManualFallbackEnabled()) {
-      _manualFillAccessoryViewController =
-          [[ManualFillAccessoryViewController alloc] initWithDelegate:self];
-      _formInputAccessoryViewController.manualFillAccessoryViewController =
-          _manualFillAccessoryViewController;
-    }
-
-    _formInputAccessoryMediator = [[FormInputAccessoryMediator alloc]
-        initWithConsumer:self.formInputAccessoryViewController
-            webStateList:webStateList];
+        [[FormInputAccessoryViewController alloc]
+            initWithManualFillAccessoryViewControllerDelegate:self];
 
     auto passwordStore = IOSChromePasswordStoreFactory::GetForBrowserState(
         browserState, ServiceAccessType::EXPLICIT_ACCESS);
-    // In BVC unit tests the password store doesn't exist. Skip creating the
-    // fetcher.
-    // TODO:(crbug.com/878388) Remove this workaround.
-    if (passwordStore) {
-      _passwordFetcher =
-          [[PasswordFetcher alloc] initWithPasswordStore:passwordStore
-                                                delegate:self];
-    }
     autofill::PersonalDataManager* personalDataManager =
         autofill::PersonalDataManagerFactory::GetForBrowserState(browserState);
-    // There is no personal data manager in OTR (incognito).
-    // TODO:(crbug.com/905720) Support Incognito.
-    if (personalDataManager) {
-      _personalDataManager = personalDataManager;
-      _personalDataManagerObserver.reset(
-          new autofill::PersonalDataManagerObserverBridge(self));
-      personalDataManager->AddObserver(_personalDataManagerObserver.get());
 
-      // TODO:(crbug.com/845472) Add earl grey test to verify the credit card
-      // button is hidden when local cards are saved and then
-      // kAutofillCreditCardEnabled is changed to disabled.
-      _manualFillAccessoryViewController.creditCardButtonHidden =
-          personalDataManager->GetCreditCards().empty();
-
-      _manualFillAccessoryViewController.addressButtonHidden =
-          personalDataManager->GetProfilesToSuggest().empty();
-    } else {
-      _manualFillAccessoryViewController.creditCardButtonHidden = YES;
-      _manualFillAccessoryViewController.addressButtonHidden = YES;
-    }
+    _formInputAccessoryMediator = [[FormInputAccessoryMediator alloc]
+           initWithConsumer:self.formInputAccessoryViewController
+               webStateList:webStateList
+        personalDataManager:personalDataManager
+              passwordStore:passwordStore];
   }
   return self;
 }
 
-- (void)dealloc {
-  if (_personalDataManager) {
-    _personalDataManager->RemoveObserver(_personalDataManagerObserver.get());
-  }
-}
-
 - (void)stop {
   [self stopChildren];
-  [self.manualFillAccessoryViewController reset];
   [self.formInputAccessoryViewController restoreOriginalKeyboardView];
 }
 
@@ -248,7 +190,7 @@
 }
 
 - (void)resetAccessoryView {
-  [self.manualFillAccessoryViewController reset];
+  [self.formInputAccessoryViewController resetManualFallbackIcons];
 }
 
 #pragma mark - CardCoordinatorDelegate
@@ -263,30 +205,6 @@
   [self.delegate openAddressSettings];
 }
 
-#pragma mark - PasswordFetcherDelegate
-
-- (void)passwordFetcher:(PasswordFetcher*)passwordFetcher
-      didFetchPasswords:
-          (std::vector<std::unique_ptr<autofill::PasswordForm>>&)passwords {
-  self.manualFillAccessoryViewController.passwordButtonHidden =
-      passwords.empty();
-}
-
-#pragma mark - PersonalDataManagerObserver
-
-- (void)onPersonalDataChanged {
-  autofill::PersonalDataManager* personalDataManager =
-      autofill::PersonalDataManagerFactory::GetForBrowserState(
-          self.browserState);
-  DCHECK(personalDataManager);
-
-  self.manualFillAccessoryViewController.creditCardButtonHidden =
-      personalDataManager->GetCreditCards().empty();
-
-  self.manualFillAccessoryViewController.addressButtonHidden =
-      personalDataManager->GetProfilesToSuggest().empty();
-}
-
 #pragma mark - AutofillSecurityAlertPresenter
 
 - (void)presentSecurityWarningAlertWithText:(NSString*)body {
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.h b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.h
index cb4247a..ab03936 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.h
@@ -7,6 +7,7 @@
 
 #import <Foundation/Foundation.h>
 
+#include "components/password_manager/core/browser/password_store.h"
 #import "ios/chrome/browser/autofill/form_input_navigator.h"
 #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
@@ -15,11 +16,17 @@
 @protocol FormInputAccessoryConsumer;
 @protocol FormInputSuggestionsProvider;
 @class JsSuggestionManager;
-class WebStateList;
+
+namespace autofill {
+class PersonalDataManager;
+}
+
 namespace web {
 class WebState;
 }
 
+class WebStateList;
+
 // This class contains all the logic to get and provide keyboard input accessory
 // views to its consumer. As well as telling the consumer when the default
 // accessory view shoeuld be restored to the system default.
@@ -27,8 +34,12 @@
 
 // Returns a mediator observing the passed `WebStateList` and associated with
 // the passed consumer. `webSateList` can be nullptr and `consumer` can be nil.
-- (instancetype)initWithConsumer:(id<FormInputAccessoryConsumer>)consumer
-                    webStateList:(WebStateList*)webStateList;
+- (instancetype)
+       initWithConsumer:(id<FormInputAccessoryConsumer>)consumer
+           webStateList:(WebStateList*)webStateList
+    personalDataManager:(autofill::PersonalDataManager*)personalDataManager
+          passwordStore:
+              (scoped_refptr<password_manager::PasswordStore>)passwordStore;
 
 // Unavailable, use initWithConsumer:webStateList: instead.
 - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
index e988e02..cbeaa47 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
@@ -8,9 +8,11 @@
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_block.h"
 #import "base/strings/sys_string_conversions.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/ios/browser/autofill_switches.h"
 #import "components/autofill/ios/browser/js_suggestion_manager.h"
+#import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h"
 #import "components/autofill/ios/form_util/form_activity_observer_bridge.h"
 #include "components/autofill/ios/form_util/form_activity_params.h"
 #import "ios/chrome/browser/autofill/form_input_accessory_consumer.h"
@@ -19,6 +21,7 @@
 #import "ios/chrome/browser/autofill/form_input_suggestions_provider.h"
 #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h"
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
+#import "ios/chrome/browser/autofill/manual_fill/passwords_fetcher.h"
 #import "ios/chrome/browser/passwords/password_generation_utils.h"
 #import "ios/chrome/browser/ui/autofill/manual_fill/keyboard_observer_helper.h"
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
@@ -38,11 +41,10 @@
                                           FormInputAccessoryViewDelegate,
                                           CRWWebStateObserver,
                                           KeyboardObserverHelperConsumer,
+                                          PasswordFetcherDelegate,
+                                          PersonalDataManagerObserver,
                                           WebStateListObserving>
 
-// The JS manager for interacting with the underlying form.
-@property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager;
-
 // The main consumer for this mediator.
 @property(nonatomic, weak) id<FormInputAccessoryConsumer> consumer;
 
@@ -53,6 +55,13 @@
 @property(nonatomic, strong)
     FormInputAccessoryViewHandler* formInputAccessoryHandler;
 
+// Track the use of hardware keyboard, when there's a notification of keyboard
+// use but no keyboard on the screen.
+@property(nonatomic, assign) BOOL hardwareKeyboard;
+
+// The JS manager for interacting with the underlying form.
+@property(nonatomic, weak) JsSuggestionManager* JSSuggestionManager;
+
 // The observer to determine when the keyboard dissapears and when it stays.
 @property(nonatomic, strong) KeyboardObserverHelper* keyboardObserver;
 
@@ -62,20 +71,20 @@
 // Last seen suggestions. Used to reenable suggestions.
 @property(nonatomic, strong) NSArray<FormSuggestion*>* lastSuggestions;
 
-// Whether suggestions are disabled.
-@property(nonatomic, assign) BOOL suggestionsDisabled;
-
 // The objects that can provide a custom input accessory view while filling
 // forms.
 @property(nonatomic, copy) NSArray<id<FormInputSuggestionsProvider>>* providers;
 
+// The password fetcher used to know if passwords are available and update the
+// consumer accordingly.
+@property(nonatomic, strong) PasswordFetcher* passwordFetcher;
+
+// Whether suggestions are disabled.
+@property(nonatomic, assign) BOOL suggestionsDisabled;
+
 // The WebState this instance is observing. Can be null.
 @property(nonatomic, assign) web::WebState* webState;
 
-// Track the use of hardware keyboard, when there's a notification of keyboard
-// use but no keyboard on the screen.
-@property(nonatomic, assign) BOOL hardwareKeyboard;
-
 @end
 
 @implementation FormInputAccessoryMediator {
@@ -83,6 +92,13 @@
   // active WebState.
   WebStateList* _webStateList;
 
+  // Personal data manager to be observed.
+  autofill::PersonalDataManager* _personalDataManager;
+
+  // C++ to ObjC bridge for PersonalDataManagerObserver.
+  std::unique_ptr<autofill::PersonalDataManagerObserverBridge>
+      _personalDataManagerObserver;
+
   // Bridge to observe the web state list from Objective-C.
   std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
 
@@ -97,12 +113,17 @@
   BOOL _suggestionsHaveBeenShown;
 }
 
-- (instancetype)initWithConsumer:(id<FormInputAccessoryConsumer>)consumer
-                    webStateList:(WebStateList*)webStateList {
+- (instancetype)
+       initWithConsumer:(id<FormInputAccessoryConsumer>)consumer
+           webStateList:(WebStateList*)webStateList
+    personalDataManager:(autofill::PersonalDataManager*)personalDataManager
+          passwordStore:
+              (scoped_refptr<password_manager::PasswordStore>)passwordStore {
   self = [super init];
   if (self) {
     _consumer = consumer;
     _consumer.navigationDelegate = self;
+
     if (webStateList) {
       _webStateList = webStateList;
       _webStateListObserver =
@@ -143,6 +164,35 @@
     _keyboardObserver = [[KeyboardObserverHelper alloc] init];
     _keyboardObserver.consumer = self;
   }
+  // In BVC unit tests the password store doesn't exist. Skip creating the
+  // fetcher.
+  // TODO:(crbug.com/878388) Remove this workaround.
+  if (passwordStore) {
+    _passwordFetcher =
+        [[PasswordFetcher alloc] initWithPasswordStore:passwordStore
+                                              delegate:self];
+  }
+  // There is no personal data manager in OTR (incognito).
+  // TODO:(crbug.com/905720) Support Incognito.
+  if (personalDataManager) {
+    _personalDataManager = personalDataManager;
+    _personalDataManagerObserver.reset(
+        new autofill::PersonalDataManagerObserverBridge(self));
+    personalDataManager->AddObserver(_personalDataManagerObserver.get());
+
+    // TODO:(crbug.com/845472) Add earl grey test to verify the credit card
+    // button is hidden when local cards are saved and then
+    // kAutofillCreditCardEnabled is changed to disabled.
+    consumer.creditCardButtonHidden =
+        personalDataManager->GetCreditCards().empty();
+
+    consumer.addressButtonHidden =
+        personalDataManager->GetProfilesToSuggest().empty();
+  } else {
+    consumer.creditCardButtonHidden = YES;
+    consumer.addressButtonHidden = YES;
+  }
+
   return self;
 }
 
@@ -158,6 +208,9 @@
     _webStateList = nullptr;
   }
   _formActivityObserverBridge.reset();
+  if (_personalDataManager) {
+    _personalDataManager->RemoveObserver(_personalDataManagerObserver.get());
+  }
 }
 
 - (void)detachFromWebState {
@@ -467,6 +520,26 @@
   [self.consumer continueCustomKeyboardView];
 }
 
+#pragma mark - PasswordFetcherDelegate
+
+- (void)passwordFetcher:(PasswordFetcher*)passwordFetcher
+      didFetchPasswords:
+          (std::vector<std::unique_ptr<autofill::PasswordForm>>&)passwords {
+  self.consumer.passwordButtonHidden = passwords.empty();
+}
+
+#pragma mark - PersonalDataManagerObserver
+
+- (void)onPersonalDataChanged {
+  DCHECK(_personalDataManager);
+
+  self.consumer.creditCardButtonHidden =
+      _personalDataManager->GetCreditCards().empty();
+
+  self.consumer.addressButtonHidden =
+      _personalDataManager->GetProfilesToSuggest().empty();
+}
+
 #pragma mark - Tests
 
 - (void)injectWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
index 4f18f08..de681aad 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -417,12 +417,13 @@
 
   // Show append button for search history/search suggestions as the right
   // control element (aka an accessory element of a table view cell).
-  row.trailingButton.hidden = !match.isAppendable && !match.isTabMatch;
+  BOOL hasVisibleTrailingButton = match.isAppendable || match.isTabMatch;
+  row.trailingButton.hidden = !hasVisibleTrailingButton;
   [row.trailingButton cancelTrackingWithEvent:nil];
 
   // If a right accessory element is present or the text alignment is right
   // aligned, adjust the width to align with the accessory element.
-  if (match.isAppendable || alignmentRight) {
+  if (hasVisibleTrailingButton || alignmentRight) {
     LayoutRect layout =
         LayoutRectForRectInBoundingRect(textLabel.frame, self.view.frame);
     layout.size.width -= kTrailingButtonWidth;
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 0e9ecdf..d1738b2 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -58,16 +58,16 @@
     "google_services_settings_view_controller_model_delegate.h",
     "handoff_table_view_controller.h",
     "handoff_table_view_controller.mm",
-    "import_data_collection_view_controller.h",
-    "import_data_collection_view_controller.mm",
+    "import_data_table_view_controller.h",
+    "import_data_table_view_controller.mm",
     "legacy_autofill_edit_collection_view_controller+protected.h",
     "legacy_autofill_edit_collection_view_controller.h",
     "legacy_autofill_edit_collection_view_controller.mm",
     "material_cell_catalog_view_controller.h",
     "material_cell_catalog_view_controller.mm",
-    "password_details_collection_view_controller.h",
-    "password_details_collection_view_controller.mm",
-    "password_details_collection_view_controller_delegate.h",
+    "password_details_table_view_controller.h",
+    "password_details_table_view_controller.mm",
+    "password_details_table_view_controller_delegate.h",
     "password_exporter.h",
     "password_exporter.mm",
     "privacy_table_view_controller.h",
@@ -92,10 +92,10 @@
     "settings_utils.mm",
     "sync_create_passphrase_collection_view_controller.h",
     "sync_create_passphrase_collection_view_controller.mm",
-    "sync_encryption_collection_view_controller.h",
-    "sync_encryption_collection_view_controller.mm",
     "sync_encryption_passphrase_collection_view_controller.h",
     "sync_encryption_passphrase_collection_view_controller.mm",
+    "sync_encryption_table_view_controller.h",
+    "sync_encryption_table_view_controller.mm",
     "sync_settings_collection_view_controller.h",
     "sync_settings_collection_view_controller.mm",
     "table_cell_catalog_view_controller.h",
@@ -234,7 +234,7 @@
   sources = [
     "passphrase_collection_view_controller_test.h",
     "passphrase_collection_view_controller_test.mm",
-    "password_details_collection_view_controller_for_testing.h",
+    "password_details_table_view_controller+testing.h",
     "password_exporter_for_testing.h",
     "personal_data_manager_data_changed_observer.cc",
     "personal_data_manager_data_changed_observer.h",
@@ -281,8 +281,8 @@
     "compose_email_handler_collection_view_controller_unittest.mm",
     "content_settings_table_view_controller_unittest.mm",
     "dataplan_usage_table_view_controller_unittest.mm",
-    "import_data_collection_view_controller_unittest.mm",
-    "password_details_collection_view_controller_unittest.mm",
+    "import_data_table_view_controller_unittest.mm",
+    "password_details_table_view_controller_unittest.mm",
     "password_exporter_unittest.mm",
     "privacy_table_view_controller_unittest.mm",
     "reauthentication_module_unittest.mm",
@@ -292,8 +292,8 @@
     "settings_root_collection_view_controller_unittest.mm",
     "settings_root_table_view_controller_unittest.mm",
     "sync_create_passphrase_collection_view_controller_unittest.mm",
-    "sync_encryption_collection_view_controller_unittest.mm",
     "sync_encryption_passphrase_collection_view_controller_unittest.mm",
+    "sync_encryption_table_view_controller_unittest.mm",
     "sync_settings_collection_view_controller_unittest.mm",
     "time_range_selector_collection_view_controller_unittest.mm",
     "translate_table_view_controller_unittest.mm",
@@ -419,6 +419,7 @@
     "//ios/chrome/browser/ui/authentication:authentication_ui",
     "//ios/chrome/browser/ui/authentication:eg_test_support",
     "//ios/chrome/browser/ui/settings:test_support",
+    "//ios/chrome/browser/ui/table_view/cells",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/ui/util:util",
     "//ios/chrome/test:test_support",
diff --git a/ios/chrome/browser/ui/settings/cells/clear_browsing_data_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/clear_browsing_data_item_unittest.mm
index fedd3319..da9572e 100644
--- a/ios/chrome/browser/ui/settings/cells/clear_browsing_data_item_unittest.mm
+++ b/ios/chrome/browser/ui/settings/cells/clear_browsing_data_item_unittest.mm
@@ -8,9 +8,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/sync_preferences/pref_service_mock_factory.h"
-#include "components/sync_preferences/pref_service_syncable.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h"
 #include "ios/chrome/browser/browsing_data/cache_counter.h"
@@ -29,17 +26,8 @@
   void SetUp() override {
     // Setup identity services.
     TestChromeBrowserState::Builder builder;
-    builder.SetPrefService(CreatePrefService());
     browser_state_ = builder.Build();
   }
-  std::unique_ptr<sync_preferences::PrefServiceSyncable> CreatePrefService() {
-    sync_preferences::PrefServiceMockFactory factory;
-    scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
-        new user_prefs::PrefRegistrySyncable);
-    std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs =
-        factory.CreateSyncable(registry.get());
-    return prefs;
-  }
 
   std::unique_ptr<TestChromeBrowserState> browser_state_;
   web::TestWebThreadBundle thread_bundle_;
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item.h b/ios/chrome/browser/ui/settings/cells/encryption_item.h
index 78e267e9..826f911e 100644
--- a/ios/chrome/browser/ui/settings/cells/encryption_item.h
+++ b/ios/chrome/browser/ui/settings/cells/encryption_item.h
@@ -7,14 +7,13 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
 
 // Item displaying possible options in the Sync Encryption screen.
-@interface EncryptionItem : CollectionViewItem
+@interface EncryptionItem : TableViewItem
 
 // The accessory type for the represented cell.
-@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
+@property(nonatomic) UITableViewCellAccessoryType accessoryType;
 
 // The text to display.
 @property(nonatomic, copy) NSString* text;
@@ -26,7 +25,7 @@
 @end
 
 // The cell associated to |EncryptionCell|.
-@interface EncryptionCell : MDCCollectionViewCell
+@interface EncryptionCell : UITableViewCell
 
 // UILabel corresponding to |text| from the item.
 @property(nonatomic, readonly, strong) UILabel* textLabel;
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item.mm b/ios/chrome/browser/ui/settings/cells/encryption_item.mm
index e9ed960..17d71449 100644
--- a/ios/chrome/browser/ui/settings/cells/encryption_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/encryption_item.mm
@@ -4,32 +4,14 @@
 
 #import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
 
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-namespace {
-// Padding used on the leading and trailing edges of the cell.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used on the top and bottom edges of the cell.
-const CGFloat kVerticalPadding = 16;
-}  // namespace
-
-@interface EncryptionCell ()
-
-// Returns the default text color used for the given |enabled| state.
-+ (UIColor*)defaultTextColorForEnabledState:(BOOL)enabled;
-
-@end
-
 @implementation EncryptionItem
 
 @synthesize accessoryType = _accessoryType;
@@ -46,12 +28,14 @@
   return self;
 }
 
-- (void)configureCell:(EncryptionCell*)cell {
-  [super configureCell:cell];
-  [cell cr_setAccessoryType:self.accessoryType];
+- (void)configureCell:(EncryptionCell*)cell
+           withStyler:(ChromeTableViewStyler*)styler {
+  [super configureCell:cell withStyler:styler];
+  cell.accessoryType = self.accessoryType;
   cell.textLabel.text = self.text;
   cell.textLabel.textColor =
-      [EncryptionCell defaultTextColorForEnabledState:self.enabled];
+      self.enabled ? [UIColor blackColor]
+                   : UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor);
 }
 
 @end
@@ -60,70 +44,38 @@
 
 @synthesize textLabel = _textLabel;
 
-+ (UIColor*)defaultTextColorForEnabledState:(BOOL)enabled {
-  MDCPalette* grey = [MDCPalette greyPalette];
-  return enabled ? grey.tint900 : grey.tint500;
-}
-
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
+- (instancetype)initWithStyle:(UITableViewCellStyle)style
+              reuseIdentifier:(NSString*)reuseIdentifier {
+  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) {
     self.isAccessibilityElement = YES;
 
     _textLabel = [[UILabel alloc] init];
     _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
     _textLabel.numberOfLines = 0;
-    _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
+    _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
+    _textLabel.adjustsFontForContentSizeCategory = YES;
     [self.contentView addSubview:_textLabel];
 
     // Set up the constraints.
     [NSLayoutConstraint activateConstraints:@[
       [_textLabel.leadingAnchor
           constraintEqualToAnchor:self.contentView.leadingAnchor
-                         constant:kHorizontalPadding],
+                         constant:kTableViewHorizontalSpacing],
       [_textLabel.trailingAnchor
           constraintEqualToAnchor:self.contentView.trailingAnchor
-                         constant:-kHorizontalPadding],
+                         constant:-kTableViewHorizontalSpacing],
     ]];
-    AddOptionalVerticalPadding(self.contentView, _textLabel, kVerticalPadding);
+    AddOptionalVerticalPadding(self.contentView, _textLabel,
+                               kTableViewLargeVerticalSpacing);
   }
   return self;
 }
 
-- (void)layoutSubviews {
-  // When the accessory type is None, the content view of the cell (and thus)
-  // the labels inside it span larger than when there is a Checkmark accessory
-  // type. That means that toggling the accessory type can induce a rewrapping
-  // of the detail text, which is not visually pleasing. To alleviate that
-  // issue, always lay out the cell as if there was a Checkmark accessory type.
-  //
-  // Force the accessory type to Checkmark for the duration of layout.
-  MDCCollectionViewCellAccessoryType realAccessoryType = self.accessoryType;
-  self.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-
-  // Implement -layoutSubviews as per instructions in documentation for
-  // +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
-  [super layoutSubviews];
-
-  // Adjust the text label preferredMaxLayoutWidth when the parent's width
-  // changes, for instance on screen rotation.
-  _textLabel.preferredMaxLayoutWidth =
-      CGRectGetWidth(self.contentView.frame) - 2 * kHorizontalPadding;
-
-  // Re-layout with the new preferred width to allow the label to adjust its
-  // height.
-  [super layoutSubviews];
-
-  // Restore the real accessory type at the end of the layout.
-  self.accessoryType = realAccessoryType;
-}
-
 - (void)prepareForReuse {
   [super prepareForReuse];
-  self.accessoryType = MDCCollectionViewCellAccessoryNone;
+  self.accessoryType = UITableViewCellAccessoryNone;
   self.textLabel.text = nil;
-  [EncryptionCell defaultTextColorForEnabledState:YES];
 }
 
 #pragma mark - UIAccessibility
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm
index 11d05d1..1e0dc9c 100644
--- a/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm
+++ b/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
 
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -28,12 +29,12 @@
 
   item.text = text;
   item.enabled = NO;
-  item.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-  [item configureCell:cell];
+  item.accessoryType = UITableViewCellAccessoryCheckmark;
+  [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]];
 
   EXPECT_NSEQ(text, cell.textLabel.text);
   EXPECT_NE(enabledColor, cell.textLabel.textColor);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, cell.accessoryType);
+  EXPECT_EQ(UITableViewCellAccessoryCheckmark, cell.accessoryType);
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
index 74f7a6ffb..35e8213 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
@@ -7,15 +7,14 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
 
 // ImportDataMultilineDetailItem is a model class that uses
 // ImportDataMultilineDetailCell.
-@interface ImportDataMultilineDetailItem : CollectionViewItem
+@interface ImportDataMultilineDetailItem : TableViewItem
 
 // The accessory type to display on the trailing edge of the cell.
-@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
+@property(nonatomic) UITableViewCellAccessoryType accessoryType;
 
 // The main text string.
 @property(nonatomic, copy) NSString* text;
@@ -25,12 +24,12 @@
 
 @end
 
-// ImportDataMultilineDetailCell implements an MDCCollectionViewCell
+// ImportDataMultilineDetailCell implements an UITableViewCell
 // subclass containing two text labels: a "main" label and a "detail" label.
 // The two labels are laid out on top of each other. The detail text can span
 // multiple lines.
 // This is to be used with a ImportDataMultilineDetailItem.
-@interface ImportDataMultilineDetailCell : MDCCollectionViewCell
+@interface ImportDataMultilineDetailCell : UITableViewCell
 
 // UILabels corresponding to |text| and |detailText| from the item.
 @property(nonatomic, readonly, strong) UILabel* textLabel;
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
index 02d2c4a6..61fe6c1c2 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
@@ -4,25 +4,15 @@
 
 #import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h"
+#import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui_util/constraints_ui_util.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
-#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-namespace {
-// Padding used on the leading and trailing edges of the cell.
-const CGFloat kHorizontalPadding = 16;
-
-// Padding used on the top and bottom edges of the cell.
-const CGFloat kVerticalPadding = 16;
-}  // namespace
-
 @implementation ImportDataMultilineDetailItem
 
 @synthesize accessoryType = _accessoryType;
@@ -39,9 +29,10 @@
 
 #pragma mark CollectionViewItem
 
-- (void)configureCell:(ImportDataMultilineDetailCell*)cell {
-  [super configureCell:cell];
-  [cell cr_setAccessoryType:self.accessoryType];
+- (void)configureCell:(ImportDataMultilineDetailCell*)cell
+           withStyler:(ChromeTableViewStyler*)styler {
+  [super configureCell:cell withStyler:styler];
+  cell.accessoryType = self.accessoryType;
   cell.textLabel.text = self.text;
   cell.detailTextLabel.text = self.detailText;
 }
@@ -53,34 +44,37 @@
 @synthesize textLabel = _textLabel;
 @synthesize detailTextLabel = _detailTextLabel;
 
-- (instancetype)initWithFrame:(CGRect)frame {
-  self = [super initWithFrame:frame];
+- (instancetype)initWithStyle:(UITableViewCellStyle)style
+              reuseIdentifier:(NSString*)reuseIdentifier {
+  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) {
     self.isAccessibilityElement = YES;
     UIView* contentView = self.contentView;
 
     _textLabel = [[UILabel alloc] init];
     _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
-    _textLabel.font = [UIFont systemFontOfSize:kUIKitMainFontSize];
-    _textLabel.textColor = UIColorFromRGB(kUIKitMainTextColor);
+    _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
+    _textLabel.adjustsFontForContentSizeCategory = YES;
+    _textLabel.textColor = UIColor.blackColor;
     [contentView addSubview:_textLabel];
 
     _detailTextLabel = [[UILabel alloc] init];
     _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
     _detailTextLabel.numberOfLines = 0;
     _detailTextLabel.font =
-        [UIFont systemFontOfSize:kUIKitMultilineDetailFontSize];
-    _detailTextLabel.textColor = UIColorFromRGB(kUIKitMultilineDetailTextColor);
+        [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
+    _detailTextLabel.adjustsFontForContentSizeCategory = YES;
+    _detailTextLabel.textColor = UIColorFromRGB(kSettingsCellsDetailTextColor);
     [contentView addSubview:_detailTextLabel];
 
     // Set up the constraints.
     [NSLayoutConstraint activateConstraints:@[
       [_textLabel.leadingAnchor
           constraintEqualToAnchor:contentView.leadingAnchor
-                         constant:kHorizontalPadding],
+                         constant:kTableViewHorizontalSpacing],
       [_textLabel.trailingAnchor
           constraintEqualToAnchor:contentView.trailingAnchor
-                         constant:-kHorizontalPadding],
+                         constant:-kTableViewHorizontalSpacing],
       [_detailTextLabel.leadingAnchor
           constraintEqualToAnchor:_textLabel.leadingAnchor],
       [_detailTextLabel.trailingAnchor
@@ -89,41 +83,11 @@
           constraintEqualToAnchor:_detailTextLabel.topAnchor],
     ]];
     AddOptionalVerticalPadding(contentView, _textLabel, _detailTextLabel,
-                               kVerticalPadding);
+                               kTableViewLargeVerticalSpacing);
   }
   return self;
 }
 
-- (void)layoutSubviews {
-  // When the accessory type is None, the content view of the cell (and thus)
-  // the labels inside it span larger than when there is a Checkmark accessory
-  // type. That means that toggling the accessory type can induce a rewrapping
-  // of the detail text, which is not visually pleasing. To alleviate that
-  // issue, always lay out the cell as if there was a Checkmark accessory type.
-  //
-  // Force the accessory type to Checkmark for the duration of layout.
-  MDCCollectionViewCellAccessoryType realAccessoryType = self.accessoryType;
-  self.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-
-  // Implement -layoutSubviews as per instructions in documentation for
-  // +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:].
-  [super layoutSubviews];
-
-  // Adjust the text label preferredMaxLayoutWidth when the parent's width
-  // changes, for instance on screen rotation.
-  CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
-  self.textLabel.preferredMaxLayoutWidth = parentWidth - 2 * kHorizontalPadding;
-  self.detailTextLabel.preferredMaxLayoutWidth =
-      parentWidth - 2 * kHorizontalPadding;
-
-  // Re-layout with the new preferred width to allow the label to adjust its
-  // height.
-  [super layoutSubviews];
-
-  // Restore the real accessory type at the end of the layout.
-  self.accessoryType = realAccessoryType;
-}
-
 #pragma mark Accessibility
 
 - (NSString*)accessibilityLabel {
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
index 68aab66..9abcd70 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -38,7 +39,7 @@
   EXPECT_FALSE(multilineDetailCell.textLabel.text);
   EXPECT_FALSE(multilineDetailCell.detailTextLabel.text);
 
-  [item configureCell:cell];
+  [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]];
   EXPECT_NSEQ(text, multilineDetailCell.textLabel.text);
   EXPECT_NSEQ(detailText, multilineDetailCell.detailTextLabel.text);
 }
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
index f9092982..5994b3a 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_coordinator.mm
@@ -24,8 +24,8 @@
 #import "ios/chrome/browser/ui/settings/google_services_settings_local_commands.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_mediator.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_view_controller.h"
-#import "ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h"
 #include "ios/chrome/browser/unified_consent/unified_consent_service_factory.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity_browser_opener.h"
@@ -168,14 +168,14 @@
 - (void)openEncryptionDialog {
   browser_sync::ProfileSyncService* syncService =
       ProfileSyncServiceFactory::GetForBrowserState(self.browserState);
-  SettingsRootCollectionViewController* controllerToPush;
+  UIViewController<SettingsRootViewControlling>* controllerToPush;
   // If there was a sync error, prompt the user to enter the passphrase.
   // Otherwise, show the full encryption options.
   if (syncService->IsPassphraseRequired()) {
     controllerToPush = [[SyncEncryptionPassphraseCollectionViewController alloc]
         initWithBrowserState:self.browserState];
   } else {
-    controllerToPush = [[SyncEncryptionCollectionViewController alloc]
+    controllerToPush = [[SyncEncryptionTableViewController alloc]
         initWithBrowserState:self.browserState];
   }
   controllerToPush.dispatcher = self.dispatcher;
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm
index 68d55e4..e1139a9e 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm
@@ -136,36 +136,6 @@
       assertWithMatcher:grey_nil()];
 }
 
-// Tests that "Activity and Interactions" switch should be disabled when the
-// "History" sync is off.
-- (void)testActivityAndInteractionsDisabledWithHistoryDisabled {
-  // TODO(crbug.com/906680): Re-enable this test when it's fixed.
-  EARL_GREY_TEST_DISABLED(@"Test disabled on devices and simulators.");
-
-  [SigninEarlGreyUI signinWithIdentity:[SigninEarlGreyUtils fakeIdentity1]];
-  [self openGoogleServicesSettings];
-  // "Activity and Interactions" is enabled.
-  [self
-      assertSwitchCellWithTitleID:
-          IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_TEXT
-                     detailTextID:
-                         IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_DETAIL
-                          enabled:YES];
-  [self scrollUp];
-  // Turn off "History".
-  [[self cellElementInteractionWithTitleID:
-             IDS_IOS_GOOGLE_SERVICES_SETTINGS_HISTORY_TEXT
-                              detailTextID:0] performAction:grey_tap()];
-  [self scrollUp];
-  // "Activity and Interactions" is disabled.
-  [self
-      assertSwitchCellWithTitleID:
-          IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_TEXT
-                     detailTextID:
-                         IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_DETAIL
-                          enabled:NO];
-}
-
 #pragma mark - Helpers
 
 // Opens the Google services settings.
@@ -299,11 +269,6 @@
                  detailTextID:0];
     [self
         assertCellWithTitleID:
-            IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_TEXT
-                 detailTextID:
-                     IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_DETAIL];
-    [self
-        assertCellWithTitleID:
             IDS_IOS_GOOGLE_SERVICES_SETTINGS_GOOGLE_ACTIVITY_CONTROL_TEXT
                  detailTextID:
                      IDS_IOS_GOOGLE_SERVICES_SETTINGS_GOOGLE_ACTIVITY_CONTROL_DETAIL];
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
index 44c967c..1fd3f8c 100644
--- a/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services_settings_mediator.mm
@@ -72,7 +72,6 @@
   SyncSettingsItemType,
   SyncReadingListItemType,
   AutocompleteWalletItemType,
-  SyncActivityAndInteractionsItemType,
   SyncGoogleActivityControlsItemType,
   EncryptionItemType,
   ManageSyncedDataItemType,
@@ -143,9 +142,6 @@
 @property(nonatomic, strong, readonly) ItemArray personalizedItems;
 // Item for the autocomplete wallet feature.
 @property(nonatomic, strong, readonly) SyncSwitchItem* autocompleteWalletItem;
-// Item for the activity and interactions feature.
-@property(nonatomic, strong, readonly)
-    SyncSwitchItem* syncActivityAndInteractionsItem;
 // Collapsible item for the non-personalized section.
 @property(nonatomic, strong, readonly)
     SettingsCollapsibleItem* nonPersonalizedServicesItem;
@@ -177,7 +173,6 @@
 @synthesize syncPersonalizationItem = _syncPersonalizationItem;
 @synthesize personalizedItems = _personalizedItems;
 @synthesize autocompleteWalletItem = _autocompleteWalletItem;
-@synthesize syncActivityAndInteractionsItem = _syncActivityAndInteractionsItem;
 @synthesize nonPersonalizedServicesItem = _nonPersonalizedServicesItem;
 @synthesize nonPersonalizedItems = _nonPersonalizedItems;
 
@@ -403,8 +398,8 @@
     _personalizedItems = @[
       syncBookmarksItem, syncHistoryItem, syncPasswordsItem, syncOpenTabsItem,
       syncAutofillItem, syncSettingsItem, syncReadingListItem,
-      self.autocompleteWalletItem, self.syncActivityAndInteractionsItem,
-      syncGoogleActivityControlsItem, encryptionItem, manageSyncedDataItem
+      self.autocompleteWalletItem, syncGoogleActivityControlsItem,
+      encryptionItem, manageSyncedDataItem
     ];
   }
   return _personalizedItems;
@@ -424,20 +419,6 @@
   return _autocompleteWalletItem;
 }
 
-- (SyncSwitchItem*)syncActivityAndInteractionsItem {
-  if (!_syncActivityAndInteractionsItem) {
-    _syncActivityAndInteractionsItem = [self
-        switchItemWithItemType:SyncActivityAndInteractionsItemType
-                  textStringID:
-                      IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_TEXT
-                detailStringID:
-                    IDS_IOS_GOOGLE_SERVICES_SETTINGS_ACTIVITY_AND_INTERACTIONS_DETAIL
-                     commandID:GoogleServicesSettingsCommandIDToggleDataTypeSync
-                      dataType:SyncSetupService::kSyncUserEvent];
-  }
-  return _syncActivityAndInteractionsItem;
-}
-
 - (SettingsCollapsibleItem*)nonPersonalizedServicesItem {
   if (!_nonPersonalizedServicesItem) {
     _nonPersonalizedServicesItem = [self
@@ -622,14 +603,6 @@
     // Autocomplete wallet item should be disabled when autofill is off.
     self.autocompleteWalletItem.on = false;
   }
-  syncer::ModelType historyModelType =
-      _syncSetupService->GetModelType(SyncSetupService::kSyncOmniboxHistory);
-  BOOL isHistoryOn = _syncSetupService->IsDataTypePreferred(historyModelType);
-  self.syncActivityAndInteractionsItem.enabled = enabled && isHistoryOn;
-  if (!isHistoryOn) {
-    // Activity and interactions item should be disabled when history is off.
-    self.syncActivityAndInteractionsItem.on = false;
-  }
 }
 
 // Updates the non-personalized section according to the user consent.
@@ -764,8 +737,7 @@
   // TODO(crbug.com/899791): Should reloads only the updated items (instead of
   // reload the full section), and get ride of
   // |self.personalizedSectionBeingAnimated|. This will get a smoother animation
-  // for "Autocomplete wall" switch and "Sync Activity and Interactions" switch
-  // when being tapped by the user.
+  // for "Autocomplete wall" switch switch when being tapped by the user.
   if (!self.personalizedSectionBeingAnimated) {
     CollectionViewModel* model = self.consumer.collectionViewModel;
     NSMutableIndexSet* sectionIndexToReload = [NSMutableIndexSet indexSet];
@@ -776,9 +748,6 @@
     // |self.autocompleteWalletItem| needs to be reloaded in case the autofill
     // data type changed state.
     [self.consumer reloadItem:self.autocompleteWalletItem];
-    // |self.syncActivityAndInteractionsItem| needs to be reloaded in case
-    // the history data type changed state.
-    [self.consumer reloadItem:self.syncActivityAndInteractionsItem];
   }
   [self updateSyncErrorSectionAndNotifyConsumer:YES];
 }
diff --git a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.h b/ios/chrome/browser/ui/settings/import_data_table_view_controller.h
similarity index 61%
rename from ios/chrome/browser/ui/settings/import_data_collection_view_controller.h
rename to ios/chrome/browser/ui/settings/import_data_table_view_controller.h
index 7343f2f..b274f0d 100644
--- a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.h
+++ b/ios/chrome/browser/ui/settings/import_data_table_view_controller.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_COLLECTION_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_COLLECTION_VIEW_CONTROLLER_H_
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_TABLE_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_TABLE_VIEW_CONTROLLER_H_
 
 #import "ios/chrome/browser/signin/constants.h"
-#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
 
-@class ImportDataCollectionViewController;
+@class ImportDataTableViewController;
 
 // The accessibility identifier of the Import Data cell.
 extern NSString* const kImportDataImportCellId;
@@ -17,19 +17,18 @@
 extern NSString* const kImportDataKeepSeparateCellId;
 
 // Notifies of the user action on the corresponding
-// ImportDataCollectionViewController.
+// ImportDataTableViewController.
 @protocol ImportDataControllerDelegate
 
 // Indicates that the user chose the clear data policy to be |shouldClearData|
 // when presented with |controller|.
-- (void)didChooseClearDataPolicy:(ImportDataCollectionViewController*)controller
+- (void)didChooseClearDataPolicy:(ImportDataTableViewController*)controller
                  shouldClearData:(ShouldClearData)shouldClearData;
 
 @end
 
-// Collection View that handles how to import data during account switching.
-@interface ImportDataCollectionViewController
-    : SettingsRootCollectionViewController
+// Table View that handles how to import data during account switching.
+@interface ImportDataTableViewController : SettingsRootTableViewController
 
 // |fromEmail| is the email of the previously signed in account.
 // |toIdentity| is the email of the account switched to.
@@ -41,10 +40,11 @@
                          toEmail:(NSString*)toEmail
                       isSignedIn:(BOOL)isSignedIn NS_DESIGNATED_INITIALIZER;
 
-- (instancetype)initWithLayout:(UICollectionViewLayout*)layout
-                         style:(CollectionViewControllerStyle)style
+- (instancetype)initWithTableViewStyle:(UITableViewStyle)style
+                           appBarStyle:
+                               (ChromeTableViewControllerStyle)appBarStyle
     NS_UNAVAILABLE;
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_COLLECTION_VIEW_CONTROLLER_H_
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_IMPORT_DATA_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm b/ios/chrome/browser/ui/settings/import_data_table_view_controller.mm
similarity index 62%
rename from ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm
rename to ios/chrome/browser/ui/settings/import_data_table_view_controller.mm
index 1c3c311..f21db7d0 100644
--- a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/import_data_table_view_controller.mm
@@ -2,20 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/import_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
 
 #include "base/logging.h"
 #import "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
-#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h"
 #import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
+#import "ios/chrome/browser/ui/table_view/table_view_model.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-#import "ios/third_party/material_components_ios/src/components/Collections/src/MaterialCollections.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -43,7 +39,7 @@
 
 }  // namespace
 
-@implementation ImportDataCollectionViewController {
+@implementation ImportDataTableViewController {
   __weak id<ImportDataControllerDelegate> _delegate;
   NSString* _fromEmail;
   NSString* _toEmail;
@@ -53,7 +49,7 @@
   ImportDataMultilineDetailItem* _keepDataSeparateItem;
 }
 
-#pragma mark Initialization
+#pragma mark - Initialization
 
 - (instancetype)initWithDelegate:(id<ImportDataControllerDelegate>)delegate
                        fromEmail:(NSString*)fromEmail
@@ -61,9 +57,9 @@
                       isSignedIn:(BOOL)isSignedIn {
   DCHECK(fromEmail);
   DCHECK(toEmail);
-  UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init];
   self =
-      [super initWithLayout:layout style:CollectionViewControllerStyleAppBar];
+      [super initWithTableViewStyle:UITableViewStyleGrouped
+                        appBarStyle:ChromeTableViewControllerStyleWithAppBar];
   if (self) {
     _delegate = delegate;
     _fromEmail = [fromEmail copy];
@@ -76,24 +72,29 @@
             ? l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_TITLE_SWITCH)
             : l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_TITLE_SIGNIN);
     [self setShouldHideDoneButton:YES];
-    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
-        initWithTitle:l10n_util::GetNSString(
-                          IDS_IOS_OPTIONS_IMPORT_DATA_CONTINUE_BUTTON)
-                style:UIBarButtonItemStyleDone
-               target:self
-               action:@selector(didTapContinue)];
-    // TODO(crbug.com/764578): -loadModel should not be called from
-    // initializer. A possible fix is to move this call to -viewDidLoad.
-    [self loadModel];
   }
   return self;
 }
 
-#pragma mark SettingsRootCollectionViewController
+- (void)viewDidLoad {
+  [super viewDidLoad];
+
+  [self setShouldHideDoneButton:YES];
+  self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
+      initWithTitle:l10n_util::GetNSString(
+                        IDS_IOS_OPTIONS_IMPORT_DATA_CONTINUE_BUTTON)
+              style:UIBarButtonItemStyleDone
+             target:self
+             action:@selector(didTapContinue)];
+
+  [self loadModel];
+}
+
+#pragma mark - SettingsRootTableViewController
 
 - (void)loadModel {
   [super loadModel];
-  CollectionViewModel* model = self.collectionViewModel;
+  TableViewModel* model = self.tableViewModel;
 
   [model addSectionWithIdentifier:SectionIdentifierDisclaimer];
   [model addItem:[self descriptionItem]
@@ -115,13 +116,14 @@
   }
 }
 
-#pragma mark Items
+#pragma mark - Items
 
-- (CollectionViewItem*)descriptionItem {
-  CardMultilineItem* item =
-      [[CardMultilineItem alloc] initWithType:ItemTypeFooter];
+- (TableViewItem*)descriptionItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeFooter];
   item.text = l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_HEADER,
                                       base::SysNSStringToUTF16(_fromEmail));
+  item.textColor = UIColor.blackColor;
   return item;
 }
 
@@ -132,8 +134,8 @@
   item.detailText =
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_SUBTITLE,
                               base::SysNSStringToUTF16(_toEmail));
-  item.accessoryType = _isSignedIn ? MDCCollectionViewCellAccessoryNone
-                                   : MDCCollectionViewCellAccessoryCheckmark;
+  item.accessoryType = _isSignedIn ? UITableViewCellAccessoryNone
+                                   : UITableViewCellAccessoryCheckmark;
   item.accessibilityIdentifier = kImportDataImportCellId;
   return item;
 }
@@ -150,54 +152,52 @@
     item.detailText = l10n_util::GetNSString(
         IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_SUBTITLE_SIGNIN);
   }
-  item.accessoryType = _isSignedIn ? MDCCollectionViewCellAccessoryCheckmark
-                                   : MDCCollectionViewCellAccessoryNone;
+  item.accessoryType = _isSignedIn ? UITableViewCellAccessoryCheckmark
+                                   : UITableViewCellAccessoryNone;
   item.accessibilityIdentifier = kImportDataKeepSeparateCellId;
   return item;
 }
 
-#pragma mark MDCCollectionViewStylingDelegate
+#pragma mark - UITableViewDelegate
 
-- (CGFloat)collectionView:(UICollectionView*)collectionView
-    cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
-  CGFloat cardWidth = CGRectGetWidth(collectionView.bounds) -
-                      2 * MDCCollectionViewCellStyleCardSectionInset;
-  return
-      [MDCCollectionViewCell cr_preferredHeightForWidth:cardWidth forItem:item];
+- (BOOL)tableView:(UITableView*)tableView
+    shouldHighlightRowAtIndexPath:(NSIndexPath*)indexPath {
+  NSInteger sectionIdentifier =
+      [self.tableViewModel sectionIdentifierForSection:indexPath.section];
+  if (sectionIdentifier != SectionIdentifierOptions)
+    return NO;
+  return YES;
 }
 
-#pragma mark UICollectionViewDelegate
-
-- (void)collectionView:(UICollectionView*)collectionView
-    didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
-  [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
+- (void)tableView:(UITableView*)tableView
+    didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+  [super tableView:tableView didSelectRowAtIndexPath:indexPath];
   NSInteger sectionIdentifier =
-      [self.collectionViewModel sectionIdentifierForSection:indexPath.section];
+      [self.tableViewModel sectionIdentifierForSection:indexPath.section];
 
   if (sectionIdentifier == SectionIdentifierOptions) {
     // Store the user choice.
-    NSInteger itemType =
-        [self.collectionViewModel itemTypeForIndexPath:indexPath];
+    NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath];
     _shouldClearData = (itemType == ItemTypeOptionImportData)
                            ? SHOULD_CLEAR_DATA_MERGE_DATA
                            : SHOULD_CLEAR_DATA_CLEAR_DATA;
     [self updateUI];
   }
+
+  [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }
 
-#pragma mark Private methods
+#pragma mark - Private
 
 // Updates the UI based on the value of |_shouldClearData|.
 - (void)updateUI {
   BOOL importDataSelected = _shouldClearData == SHOULD_CLEAR_DATA_MERGE_DATA;
   _importDataItem.accessoryType = importDataSelected
-                                      ? MDCCollectionViewCellAccessoryCheckmark
-                                      : MDCCollectionViewCellAccessoryNone;
-  _keepDataSeparateItem.accessoryType =
-      importDataSelected ? MDCCollectionViewCellAccessoryNone
-                         : MDCCollectionViewCellAccessoryCheckmark;
+                                      ? UITableViewCellAccessoryCheckmark
+                                      : UITableViewCellAccessoryNone;
+  _keepDataSeparateItem.accessoryType = importDataSelected
+                                            ? UITableViewCellAccessoryNone
+                                            : UITableViewCellAccessoryCheckmark;
   [self reconfigureCellsForItems:@[ _importDataItem, _keepDataSeparateItem ]];
 }
 
diff --git a/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm
similarity index 68%
rename from ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm
rename to ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm
index 4583446..70ba2e9 100644
--- a/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/import_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
 
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h"
 #import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
+#import "ios/chrome/browser/ui/table_view/table_view_model.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
@@ -21,7 +21,7 @@
 #endif
 
 @interface ImportDataControllerTestDelegate
-    : NSObject<ImportDataControllerDelegate>
+    : NSObject <ImportDataControllerDelegate>
 @property(nonatomic, readonly) BOOL didChooseClearDataPolicyCalled;
 @property(nonatomic, readonly) ShouldClearData shouldClearData;
 @end
@@ -31,7 +31,7 @@
 @synthesize didChooseClearDataPolicyCalled = _didChooseClearDataPolicyCalled;
 @synthesize shouldClearData = _shouldClearData;
 
-- (void)didChooseClearDataPolicy:(ImportDataCollectionViewController*)controller
+- (void)didChooseClearDataPolicy:(ImportDataTableViewController*)controller
                  shouldClearData:(ShouldClearData)shouldClearData {
   _didChooseClearDataPolicyCalled = YES;
   _shouldClearData = shouldClearData;
@@ -41,20 +41,19 @@
 
 namespace {
 
-class ImportDataCollectionViewControllerTest
-    : public CollectionViewControllerTest {
+class ImportDataTableViewControllerTest : public ChromeTableViewControllerTest {
  public:
   ImportDataControllerTestDelegate* delegate() { return delegate_; }
 
  protected:
   void SetUp() override {
-    CollectionViewControllerTest::SetUp();
+    ChromeTableViewControllerTest::SetUp();
     is_signed_in_ = true;
   }
 
-  CollectionViewController* InstantiateController() override {
+  ChromeTableViewController* InstantiateController() override {
     delegate_ = [[ImportDataControllerTestDelegate alloc] init];
-    return [[ImportDataCollectionViewController alloc]
+    return [[ImportDataTableViewController alloc]
         initWithDelegate:delegate_
                fromEmail:@"fromEmail@gmail.com"
                  toEmail:@"toEmail@gmail.com"
@@ -67,91 +66,89 @@
   ImportDataControllerTestDelegate* delegate_;
 };
 
-TEST_F(ImportDataCollectionViewControllerTest, TestModelSignedIn) {
+TEST_F(ImportDataTableViewControllerTest, TestModelSignedIn) {
   CreateController();
   CheckController();
   ASSERT_EQ(2, NumberOfSections());
   EXPECT_EQ(1, NumberOfItemsInSection(0));
-  CardMultilineItem* item = GetCollectionViewItem(0, 0);
+  CardMultilineItem* item = GetTableViewItem(0, 0);
   EXPECT_NSEQ(
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_HEADER,
                               base::SysNSStringToUTF16(@"fromEmail@gmail.com")),
       item.text);
   EXPECT_EQ(2, NumberOfItemsInSection(1));
-  CheckTextCellTitleAndSubtitle(
+  CheckTextCellTextAndDetailText(
       l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_TITLE),
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_SUBTITLE_SWITCH,
                               base::SysNSStringToUTF16(@"fromEmail@gmail.com")),
       1, 0);
-  CheckAccessoryType(MDCCollectionViewCellAccessoryCheckmark, 1, 0);
-  CheckTextCellTitleAndSubtitle(
+  CheckAccessoryType(UITableViewCellAccessoryCheckmark, 1, 0);
+  CheckTextCellTextAndDetailText(
       l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_TITLE),
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_SUBTITLE,
                               base::SysNSStringToUTF16(@"toEmail@gmail.com")),
       1, 1);
-  CheckAccessoryType(MDCCollectionViewCellAccessoryNone, 1, 1);
+  CheckAccessoryType(UITableViewCellAccessoryNone, 1, 1);
 }
 
-TEST_F(ImportDataCollectionViewControllerTest, TestModelSignedOut) {
+TEST_F(ImportDataTableViewControllerTest, TestModelSignedOut) {
   set_is_signed_in(false);
   CreateController();
   CheckController();
   ASSERT_EQ(2, NumberOfSections());
   EXPECT_EQ(1, NumberOfItemsInSection(0));
-  CardMultilineItem* item = GetCollectionViewItem(0, 0);
+  CardMultilineItem* item = GetTableViewItem(0, 0);
   EXPECT_NSEQ(
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_HEADER,
                               base::SysNSStringToUTF16(@"fromEmail@gmail.com")),
       item.text);
   EXPECT_EQ(2, NumberOfItemsInSection(1));
-  CheckTextCellTitleAndSubtitle(
+  CheckTextCellTextAndDetailText(
       l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_TITLE),
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_SUBTITLE,
                               base::SysNSStringToUTF16(@"toEmail@gmail.com")),
       1, 0);
-  CheckAccessoryType(MDCCollectionViewCellAccessoryCheckmark, 1, 0);
-  CheckTextCellTitleAndSubtitle(
+  CheckAccessoryType(UITableViewCellAccessoryCheckmark, 1, 0);
+  CheckTextCellTextAndDetailText(
       l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_TITLE),
       l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_SUBTITLE_SIGNIN),
       1, 1);
-  CheckAccessoryType(MDCCollectionViewCellAccessoryNone, 1, 1);
+  CheckAccessoryType(UITableViewCellAccessoryNone, 1, 1);
 }
 
 // Tests that checking a checkbox correctly uncheck the other one.
-TEST_F(ImportDataCollectionViewControllerTest, TestUniqueBoxChecked) {
+TEST_F(ImportDataTableViewControllerTest, TestUniqueBoxChecked) {
   CreateController();
 
-  ImportDataCollectionViewController* import_data_controller =
-      base::mac::ObjCCastStrict<ImportDataCollectionViewController>(
-          controller());
+  ImportDataTableViewController* import_data_controller =
+      base::mac::ObjCCastStrict<ImportDataTableViewController>(controller());
   NSIndexPath* importIndexPath = [NSIndexPath indexPathForItem:0 inSection:1];
-  NSIndexPath* keepSeparateIndexPath =
-      [NSIndexPath indexPathForItem:1 inSection:1];
+  NSIndexPath* keepSeparateIndexPath = [NSIndexPath indexPathForItem:1
+                                                           inSection:1];
   ImportDataMultilineDetailItem* importItem =
       base::mac::ObjCCastStrict<ImportDataMultilineDetailItem>(
-          [import_data_controller.collectionViewModel
+          [import_data_controller.tableViewModel
               itemAtIndexPath:importIndexPath]);
   ImportDataMultilineDetailItem* keepSeparateItem =
       base::mac::ObjCCastStrict<ImportDataMultilineDetailItem>(
-          [import_data_controller.collectionViewModel
+          [import_data_controller.tableViewModel
               itemAtIndexPath:keepSeparateIndexPath]);
 
-  [import_data_controller collectionView:[import_data_controller collectionView]
-                didSelectItemAtIndexPath:importIndexPath];
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark, importItem.accessoryType);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, keepSeparateItem.accessoryType);
+  [import_data_controller tableView:[import_data_controller tableView]
+            didSelectRowAtIndexPath:importIndexPath];
+  EXPECT_EQ(UITableViewCellAccessoryCheckmark, importItem.accessoryType);
+  EXPECT_EQ(UITableViewCellAccessoryNone, keepSeparateItem.accessoryType);
 
-  [import_data_controller collectionView:[import_data_controller collectionView]
-                didSelectItemAtIndexPath:keepSeparateIndexPath];
-  EXPECT_EQ(MDCCollectionViewCellAccessoryNone, importItem.accessoryType);
-  EXPECT_EQ(MDCCollectionViewCellAccessoryCheckmark,
-            keepSeparateItem.accessoryType);
+  [import_data_controller tableView:[import_data_controller tableView]
+            didSelectRowAtIndexPath:keepSeparateIndexPath];
+  EXPECT_EQ(UITableViewCellAccessoryNone, importItem.accessoryType);
+  EXPECT_EQ(UITableViewCellAccessoryCheckmark, keepSeparateItem.accessoryType);
 }
 
 // Tests that the default choice when the user is signed in is Clear Data and
 // that tapping continue will correctly select it. Regression test for
 // crbug.com/649533
-TEST_F(ImportDataCollectionViewControllerTest, TestDefaultChoiceSignedIn) {
+TEST_F(ImportDataTableViewControllerTest, TestDefaultChoiceSignedIn) {
   CreateController();
 
   EXPECT_FALSE(delegate().didChooseClearDataPolicyCalled);
@@ -169,7 +166,7 @@
 // Tests that the default choice when the user is signed out is Merge Data and
 // that tapping continue will correctly select it. Regression test for
 // crbug.com/649533
-TEST_F(ImportDataCollectionViewControllerTest, TestDefaultChoiceSignedOut) {
+TEST_F(ImportDataTableViewControllerTest, TestDefaultChoiceSignedOut) {
   set_is_signed_in(false);
   CreateController();
 
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index 9661894..64390ce 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -33,7 +33,6 @@
 #import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
-#import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
 #import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_autofill_data_item.h"
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h"
@@ -112,8 +111,6 @@
   ItemTypeAutofillStatus,
   ItemTypeAccountControlDynamicHeight,
   ItemTypeFooter,
-  ItemTypeSyncEncryption,
-  ItemTypeSyncEncryptionChecked,
   ItemTypeSyncPassphraseError,
   ItemTypeContentSuggestions,
   ItemTypeImageDetailTextItem,
@@ -407,10 +404,6 @@
 
   // Sync cells.
   [model addSectionWithIdentifier:SectionIdentifierSync];
-  [model addItem:[self syncEncryptionItem]
-      toSectionWithIdentifier:SectionIdentifierSync];
-  [model addItem:[self syncEncryptionCheckedItem]
-      toSectionWithIdentifier:SectionIdentifierSync];
   [model addItem:[self syncPassphraseErrorItem]
       toSectionWithIdentifier:SectionIdentifierSync];
 
@@ -469,8 +462,6 @@
     case ItemTypeAutofillDynamicHeight:
     case ItemTypeColdStateSigninPromo:
     case ItemTypeWarmStateSigninPromo:
-    case ItemTypeSyncEncryption:
-    case ItemTypeSyncEncryptionChecked:
       return [MDCCollectionViewCell
           cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
                              forItem:item];
@@ -846,27 +837,6 @@
   return footerItem;
 }
 
-- (EncryptionItem*)syncEncryptionItem {
-  EncryptionItem* item =
-      [[EncryptionItem alloc] initWithType:ItemTypeSyncEncryption];
-  item.text =
-      @"These two cells have exactly the same text, but one has a checkmark "
-      @"and the other does not.  They should lay out identically, and the "
-      @"presence of the checkmark should not cause the text to reflow.";
-  return item;
-}
-
-- (EncryptionItem*)syncEncryptionCheckedItem {
-  EncryptionItem* item =
-      [[EncryptionItem alloc] initWithType:ItemTypeSyncEncryptionChecked];
-  item.text =
-      @"These two cells have exactly the same text, but one has a checkmark "
-      @"and the other does not.  They should lay out identically, and the "
-      @"presence of the checkmark should not cause the text to reflow.";
-  item.accessoryType = MDCCollectionViewCellAccessoryCheckmark;
-  return item;
-}
-
 - (PassphraseErrorItem*)syncPassphraseErrorItem {
   PassphraseErrorItem* item =
       [[PassphraseErrorItem alloc] initWithType:ItemTypeSyncPassphraseError];
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.h b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.h
deleted file mode 100644
index 1b0d365a..0000000
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_H_
-
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h"
-#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
-
-namespace autofill {
-struct PasswordForm;
-}  // namespace autofill
-
-@protocol ReauthenticationProtocol;
-
-@interface PasswordDetailsCollectionViewController
-    : SettingsRootCollectionViewController
-
-// The designated initializer. |delegate| and |reauthenticaionModule| must not
-// be nil.
-- (instancetype)
-  initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
-              delegate:
-                  (id<PasswordDetailsCollectionViewControllerDelegate>)delegate
-reauthenticationModule:(id<ReauthenticationProtocol>)reauthenticationModule
-    NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)initWithLayout:(UICollectionViewLayout*)layout
-                         style:(CollectionViewControllerStyle)style
-    NS_UNAVAILABLE;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h
deleted file mode 100644
index 74b066a..0000000
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_DELEGATE_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_DELEGATE_H_
-
-#import <Foundation/Foundation.h>
-
-namespace autofill {
-struct PasswordForm;
-}  // namespace autofill
-
-@protocol PasswordDetailsCollectionViewControllerDelegate<NSObject>
-
-- (void)deletePassword:(const autofill::PasswordForm&)passwordForm;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_for_testing.h b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_for_testing.h
deleted file mode 100644
index 5a1dc38..0000000
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_for_testing.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_FOR_TESTING_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_FOR_TESTING_H_
-
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h"
-
-@interface PasswordDetailsCollectionViewController (ForTesting)
-
-// Allows to replace a |reauthenticationModule| for a fake one in integration
-// tests, where the testing code cannot control the creation of the
-// controller.
-- (void)setReauthenticationModule:
-    (id<ReauthenticationProtocol>)reauthenticationModule;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_COLLECTION_VIEW_CONTROLLER_FOR_TESTING_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
deleted file mode 100644
index 8d1ed952..0000000
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h"
-
-#include "base/mac/foundation_util.h"
-#include "base/strings/sys_string_conversions.h"
-#include "components/autofill/core/common/password_form.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
-#import "ios/chrome/browser/ui/settings/cells/password_details_item.h"
-#import "ios/chrome/browser/ui/settings/reauthentication_module.h"
-#import "ios/chrome/browser/web/chrome_web_test.h"
-#include "ios/chrome/grit/ios_strings.h"
-#include "ios/chrome/test/app/password_test_util.h"
-#include "ios/web/public/test/test_web_thread_bundle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-@interface MockSavePasswordsCollectionViewController
-    : NSObject<PasswordDetailsCollectionViewControllerDelegate>
-
-- (void)deletePassword:(const autofill::PasswordForm&)passwordForm;
-
-@end
-
-@implementation MockSavePasswordsCollectionViewController
-
-- (void)deletePassword:(const autofill::PasswordForm&)passwordForm {
-}
-
-@end
-
-namespace {
-
-NSString* const kSite = @"https://testorigin.com/";
-NSString* const kUsername = @"testusername";
-NSString* const kPassword = @"testpassword";
-
-// Indices related to the layout for a non-blacklisted, non-federated password.
-const int kSiteSection = 0;
-const int kSiteItem = 0;
-const int kCopySiteButtonItem = 1;
-
-const int kUsernameSection = 1;
-const int kUsernameItem = 0;
-const int kCopyUsernameButtonItem = 1;
-
-const int kPasswordSection = 2;
-const int kPasswordItem = 0;
-const int kCopyPasswordButtonItem = 1;
-const int kShowHideButtonItem = 2;
-
-const int kDeleteSection = 3;
-const int kDeleteButtonItem = 0;
-
-class PasswordDetailsCollectionViewControllerTest
-    : public CollectionViewControllerTest {
- protected:
-  PasswordDetailsCollectionViewControllerTest() {
-    origin_ = kSite;
-    form_.username_value = base::SysNSStringToUTF16(kUsername);
-    form_.password_value = base::SysNSStringToUTF16(kPassword);
-    form_.signon_realm = base::SysNSStringToUTF8(origin_);
-    form_.origin = GURL(form_.signon_realm);
-  }
-
-  void SetUp() override {
-    CollectionViewControllerTest::SetUp();
-    delegate_ = [[MockSavePasswordsCollectionViewController alloc] init];
-    reauthentication_module_ = [[MockReauthenticationModule alloc] init];
-    reauthentication_module_.shouldSucceed = YES;
-  }
-
-  CollectionViewController* InstantiateController() override {
-    return [[PasswordDetailsCollectionViewController alloc]
-          initWithPasswordForm:form_
-                      delegate:delegate_
-        reauthenticationModule:reauthentication_module_];
-  }
-
-  web::TestWebThreadBundle thread_bundle_;
-  MockSavePasswordsCollectionViewController* delegate_;
-  MockReauthenticationModule* reauthentication_module_;
-  NSString* origin_;
-  autofill::PasswordForm form_;
-};
-
-TEST_F(PasswordDetailsCollectionViewControllerTest,
-       TestInitialization_NormalPassword) {
-  CreateController();
-  CheckController();
-  EXPECT_EQ(4, NumberOfSections());
-  // Site section
-  EXPECT_EQ(2, NumberOfItemsInSection(kSiteSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE, kSiteSection);
-  PasswordDetailsItem* siteItem =
-      GetCollectionViewItem(kSiteSection, kSiteItem);
-  EXPECT_NSEQ(origin_, siteItem.text);
-  EXPECT_TRUE(siteItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON, kSiteSection,
-                           kCopySiteButtonItem);
-  // Username section
-  EXPECT_EQ(2, NumberOfItemsInSection(kUsernameSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME,
-                           kUsernameSection);
-  PasswordDetailsItem* usernameItem =
-      GetCollectionViewItem(kUsernameSection, kUsernameItem);
-  EXPECT_NSEQ(kUsername, usernameItem.text);
-  EXPECT_TRUE(usernameItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON,
-                           kUsernameSection, kCopyUsernameButtonItem);
-  // Password section
-  EXPECT_EQ(3, NumberOfItemsInSection(kPasswordSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD,
-                           kPasswordSection);
-  PasswordDetailsItem* passwordItem =
-      GetCollectionViewItem(kPasswordSection, kPasswordItem);
-  EXPECT_NSEQ(kPassword, passwordItem.text);
-  EXPECT_FALSE(passwordItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_COPY_BUTTON,
-                           kPasswordSection, kCopyPasswordButtonItem);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
-                           kPasswordSection, kShowHideButtonItem);
-  // Delete section
-  EXPECT_EQ(1, NumberOfItemsInSection(kDeleteSection));
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
-                           kDeleteSection, kDeleteButtonItem);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest,
-       TestInitialization_Blacklisted) {
-  constexpr int kBlacklistedSiteSection = 0;
-  constexpr int kBlacklistedSiteItem = 0;
-  constexpr int kBlacklistedCopySiteButtonItem = 1;
-
-  constexpr int kBlacklistedDeleteSection = 1;
-  constexpr int kBlacklistedDeleteButtonItem = 0;
-
-  form_.username_value.clear();
-  form_.password_value.clear();
-  form_.blacklisted_by_user = true;
-  CreateController();
-  CheckController();
-  EXPECT_EQ(2, NumberOfSections());
-  // Site section
-  EXPECT_EQ(2, NumberOfItemsInSection(kBlacklistedSiteSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE,
-                           kBlacklistedSiteSection);
-  PasswordDetailsItem* siteItem =
-      GetCollectionViewItem(kBlacklistedSiteSection, kBlacklistedSiteItem);
-  EXPECT_NSEQ(origin_, siteItem.text);
-  EXPECT_TRUE(siteItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON,
-                           kBlacklistedSiteSection,
-                           kBlacklistedCopySiteButtonItem);
-  // Delete section
-  EXPECT_EQ(1, NumberOfItemsInSection(kBlacklistedDeleteSection));
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
-                           kBlacklistedDeleteSection,
-                           kBlacklistedDeleteButtonItem);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest,
-       TestInitialization_Federated) {
-  constexpr int kFederatedSiteSection = 0;
-  constexpr int kFederatedSiteItem = 0;
-  constexpr int kFederatedCopySiteButtonItem = 1;
-
-  constexpr int kFederatedUsernameSection = 1;
-  constexpr int kFederatedUsernameItem = 0;
-  constexpr int kFederatedCopyUsernameButtonItem = 1;
-
-  constexpr int kFederatedFederationSection = 2;
-  constexpr int kFederatedFederationItem = 0;
-
-  constexpr int kFederatedDeleteSection = 3;
-  constexpr int kFederatedDeleteButtonItem = 0;
-
-  form_.password_value.clear();
-  form_.federation_origin =
-      url::Origin::Create(GURL("https://famous.provider.net"));
-  CreateController();
-  CheckController();
-  EXPECT_EQ(4, NumberOfSections());
-  // Site section
-  EXPECT_EQ(2, NumberOfItemsInSection(kFederatedSiteSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE,
-                           kFederatedSiteSection);
-  PasswordDetailsItem* siteItem =
-      GetCollectionViewItem(kFederatedSiteSection, kFederatedSiteItem);
-  EXPECT_NSEQ(origin_, siteItem.text);
-  EXPECT_TRUE(siteItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON,
-                           kFederatedSiteSection, kFederatedCopySiteButtonItem);
-  // Username section
-  EXPECT_EQ(2, NumberOfItemsInSection(kFederatedUsernameSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME,
-                           kFederatedUsernameSection);
-  PasswordDetailsItem* usernameItem =
-      GetCollectionViewItem(kFederatedUsernameSection, kFederatedUsernameItem);
-  EXPECT_NSEQ(kUsername, usernameItem.text);
-  EXPECT_TRUE(usernameItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON,
-                           kFederatedUsernameSection,
-                           kFederatedCopyUsernameButtonItem);
-  // Federated section
-  EXPECT_EQ(1, NumberOfItemsInSection(kFederatedFederationSection));
-  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_FEDERATION,
-                           kFederatedFederationSection);
-  PasswordDetailsItem* federationItem = GetCollectionViewItem(
-      kFederatedFederationSection, kFederatedFederationItem);
-  EXPECT_NSEQ(@"famous.provider.net", federationItem.text);
-  EXPECT_TRUE(federationItem.showingText);
-  // Delete section
-  EXPECT_EQ(1, NumberOfItemsInSection(kFederatedDeleteSection));
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
-                           kFederatedDeleteSection, kFederatedDeleteButtonItem);
-}
-
-struct SimplifyOriginTestData {
-  GURL origin;
-  NSString* expectedSimplifiedOrigin;
-};
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, SimplifyOrigin) {
-  SimplifyOriginTestData test_data[] = {
-      {GURL("http://test.com/index.php"), @"test.com"},
-      {GURL("https://example.com/index.php"), @"example.com"},
-      {GURL("android://"
-            "Qllt1FacrB0NYCeSFvmudHvssWBPFfC54EbtHTpFxukvw2wClI1rafcVB3kQOMxfJg"
-            "xbVAkGXvC_A52kbPL1EQ==@com.parkingpanda.mobile/"),
-       @"mobile.parkingpanda.com"}};
-
-  for (const auto& data : test_data) {
-    origin_ = base::SysUTF8ToNSString(data.origin.spec());
-    form_.signon_realm = base::SysNSStringToUTF8(origin_);
-    form_.origin = GURL(form_.signon_realm);
-    CreateController();
-    EXPECT_NSEQ(data.expectedSimplifiedOrigin, controller().title)
-        << " for origin " << data.origin;
-    ResetController();
-  }
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, CopySite) {
-  CreateController();
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kCopySiteButtonItem
-                                                  inSection:kSiteSection]];
-  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
-  EXPECT_NSEQ(origin_, generalPasteboard.string);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, CopyUsername) {
-  CreateController();
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath
-                                   indexPathForRow:kCopyUsernameButtonItem
-                                         inSection:kUsernameSection]];
-  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
-  EXPECT_NSEQ(kUsername, generalPasteboard.string);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, ShowPassword) {
-  CreateController();
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
-                                                  inSection:kPasswordSection]];
-  PasswordDetailsItem* passwordItem =
-      GetCollectionViewItem(kPasswordSection, kPasswordItem);
-  EXPECT_NSEQ(kPassword, passwordItem.text);
-  EXPECT_TRUE(passwordItem.showingText);
-  EXPECT_NSEQ(
-      l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW),
-      reauthentication_module_.localizedReasonForAuthentication);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON,
-                           kPasswordSection, kShowHideButtonItem);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, HidePassword) {
-  CreateController();
-  // First show the password.
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
-                                                  inSection:kPasswordSection]];
-  // Then hide it.
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
-                                                  inSection:kPasswordSection]];
-  PasswordDetailsItem* passwordItem =
-      GetCollectionViewItem(kPasswordSection, kPasswordItem);
-  EXPECT_NSEQ(kPassword, passwordItem.text);
-  EXPECT_FALSE(passwordItem.showingText);
-  CheckTextCellTitleWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
-                           kPasswordSection, kShowHideButtonItem);
-}
-
-TEST_F(PasswordDetailsCollectionViewControllerTest, CopyPassword) {
-  CreateController();
-  [controller() collectionView:[controller() collectionView]
-      didSelectItemAtIndexPath:[NSIndexPath
-                                   indexPathForRow:kCopyPasswordButtonItem
-                                         inSection:kPasswordSection]];
-  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
-  EXPECT_NSEQ(kPassword, generalPasteboard.string);
-  EXPECT_NSEQ(
-      l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_COPY),
-      reauthentication_module_.localizedReasonForAuthentication);
-}
-
-}  // namespace
diff --git a/ios/chrome/browser/ui/settings/password_details_table_view_controller+testing.h b/ios/chrome/browser/ui/settings/password_details_table_view_controller+testing.h
new file mode 100644
index 0000000..36ac1c5
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/password_details_table_view_controller+testing.h
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_TESTING_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_TESTING_H_
+
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
+
+// TODO(crbug.com/894791): Refactor the PasswordTableViewController and
+// PasswordsSettingsTestCase to remove this Category file.
+@interface PasswordDetailsTableViewController (Testing)
+
+// Allows to replace a |reauthenticationModule| for a fake one in integration
+// tests, where the testing code cannot control the creation of the
+// controller.
+- (void)setReauthenticationModule:
+    (id<ReauthenticationProtocol>)reauthenticationModule;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_TESTING_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_table_view_controller.h b/ios/chrome/browser/ui/settings/password_details_table_view_controller.h
new file mode 100644
index 0000000..2a35703
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/password_details_table_view_controller.h
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_H_
+
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h"
+#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
+
+namespace autofill {
+struct PasswordForm;
+}  // namespace autofill
+
+// The accessibility identifier of the password details table view.
+extern NSString* _Nonnull const kPasswordDetailsTableViewId;
+extern NSString* _Nonnull const kPasswordDetailsDeletionAlertViewId;
+
+@protocol ReauthenticationProtocol;
+
+// Displays details of a password item, including URL of the site, username and
+// password in masked state as default. User can copy the URL and username,
+// pass the iOS security check to see and copy the password , or delete the
+// password item.
+@interface PasswordDetailsTableViewController : SettingsRootTableViewController
+
+// The designated initializer.
+- (nullable instancetype)
+      initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
+                  delegate:
+                      (nonnull id<PasswordDetailsTableViewControllerDelegate>)
+                          delegate
+    reauthenticationModule:
+        (nonnull id<ReauthenticationProtocol>)reauthenticationModule
+    NS_DESIGNATED_INITIALIZER;
+
+- (nullable instancetype)initWithTableViewStyle:(UITableViewStyle)style
+                                    appBarStyle:(ChromeTableViewControllerStyle)
+                                                    appBarStyle NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm b/ios/chrome/browser/ui/settings/password_details_table_view_controller.mm
similarity index 72%
rename from ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
rename to ios/chrome/browser/ui/settings/password_details_table_view_controller.mm
index cdb4a4b58b..22cfe91c24 100644
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password_details_table_view_controller.mm
@@ -1,8 +1,8 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
 
 #import <UIKit/UIKit.h>
 
@@ -15,19 +15,15 @@
 #include "components/password_manager/core/browser/password_ui_utils.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
-#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
-#import "ios/chrome/browser/ui/settings/cells/password_details_item.h"
-#import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
 #import "ios/chrome/browser/ui/settings/reauthentication_module.h"
 #import "ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_utils.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
 #include "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
-#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
-#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
@@ -35,6 +31,10 @@
 #error "This file requires ARC support."
 #endif
 
+NSString* const kPasswordDetailsTableViewId = @"PasswordDetailsTableViewId";
+NSString* const kPasswordDetailsDeletionAlertViewId =
+    @"PasswordDetailsDeletionAlertViewId";
+
 namespace {
 
 typedef NS_ENUM(NSInteger, SectionIdentifier) {
@@ -60,18 +60,7 @@
 
 }  // namespace
 
-// This protocol declares the methods used by the context menus, so that
-// selectors can be created from those methods and passed to UIMenuItem.
-@protocol PasswordDetailsViewerProtocol<NSObject>
-- (void)copySite;
-- (void)copyUsername;
-- (void)copyPassword;
-- (void)showPassword;
-- (void)hidePassword;
-@end
-
-@interface PasswordDetailsCollectionViewController ()<
-    PasswordDetailsViewerProtocol> {
+@interface PasswordDetailsTableViewController () {
   // The username to which the saved password belongs.
   NSString* _username;
   // The saved password.
@@ -86,34 +75,35 @@
   autofill::PasswordForm _passwordForm;
   // Instance of the parent view controller needed in order to update the
   // password list when a password is deleted.
-  __weak id<PasswordDetailsCollectionViewControllerDelegate> _weakDelegate;
+  __weak id<PasswordDetailsTableViewControllerDelegate> _weakDelegate;
   // Module containing the reauthentication mechanism for viewing and copying
   // passwords.
   __weak id<ReauthenticationProtocol> _weakReauthenticationModule;
   // The password item.
-  PasswordDetailsItem* _passwordItem;
+  TableViewTextItem* _passwordItem;
 }
 
-// Alert dialogue to confirm deletion of passwords upon pressing the delete
+// Alert dialog to confirm deletion of passwords upon pressing the delete
 // button.
 @property(nonatomic, strong) UIAlertController* deleteConfirmation;
 
 @end
 
-@implementation PasswordDetailsCollectionViewController
+@implementation PasswordDetailsTableViewController
 
 @synthesize deleteConfirmation = _deleteConfirmation;
 
-- (instancetype)
-  initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
-              delegate:
-                  (id<PasswordDetailsCollectionViewControllerDelegate>)delegate
-reauthenticationModule:(id<ReauthenticationProtocol>)reauthenticationModule {
+- (instancetype)initWithPasswordForm:(const autofill::PasswordForm&)passwordForm
+                            delegate:
+                                (id<PasswordDetailsTableViewControllerDelegate>)
+                                    delegate
+              reauthenticationModule:
+                  (id<ReauthenticationProtocol>)reauthenticationModule {
   DCHECK(delegate);
   DCHECK(reauthenticationModule);
-  UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init];
   self =
-      [super initWithLayout:layout style:CollectionViewControllerStyleAppBar];
+      [super initWithTableViewStyle:UITableViewStyleGrouped
+                        appBarStyle:ChromeTableViewControllerStyleWithAppBar];
   if (self) {
     _weakDelegate = delegate;
     _weakReauthenticationModule = reauthenticationModule;
@@ -130,69 +120,55 @@
     }
     auto name_and_link =
         password_manager::GetShownOriginAndLinkUrl(_passwordForm);
+    self.title = base::SysUTF8ToNSString(name_and_link.first);
     _site = base::SysUTF8ToNSString(name_and_link.second.spec());
-    self.title = [PasswordDetailsCollectionViewController
-        simplifyOrigin:base::SysUTF8ToNSString(name_and_link.first)];
-    self.collectionViewAccessibilityIdentifier =
-        @"PasswordDetailsCollectionViewController";
     NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
     [defaultCenter addObserver:self
                       selector:@selector(hidePassword)
                           name:UIApplicationDidEnterBackgroundNotification
                         object:nil];
-
-    // TODO(crbug.com/764578): -loadModel should not be called from
-    // initializer. A possible fix is to move this call to -viewDidLoad.
-    [self loadModel];
   }
   return self;
 }
 
-+ (NSString*)simplifyOrigin:(NSString*)origin {
-  NSString* originWithoutScheme = nil;
-  if (![origin rangeOfString:@"://"].length) {
-    originWithoutScheme = origin;
-  } else {
-    originWithoutScheme =
-        [[origin componentsSeparatedByString:@"://"] objectAtIndex:1];
-  }
-  return
-      [[originWithoutScheme componentsSeparatedByString:@"/"] objectAtIndex:0];
+#pragma mark - UIViewController
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  self.tableView.accessibilityIdentifier = kPasswordDetailsTableViewId;
+
+  [self loadModel];
 }
 
-#pragma mark - SettingsRootCollectionViewController
+#pragma mark - ChromeTableViewController
 
 - (void)loadModel {
   [super loadModel];
-  CollectionViewModel* model = self.collectionViewModel;
+  TableViewModel* model = self.tableViewModel;
 
   [model addSectionWithIdentifier:SectionIdentifierSite];
-  SettingsTextItem* siteHeader =
-      [[SettingsTextItem alloc] initWithType:ItemTypeHeader];
+  TableViewTextHeaderFooterItem* siteHeader =
+      [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
   siteHeader.text = l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_SITE);
-  siteHeader.textColor = [[MDCPalette greyPalette] tint500];
   [model setHeader:siteHeader forSectionWithIdentifier:SectionIdentifierSite];
-  PasswordDetailsItem* siteItem =
-      [[PasswordDetailsItem alloc] initWithType:ItemTypeSite];
+  TableViewTextItem* siteItem =
+      [[TableViewTextItem alloc] initWithType:ItemTypeSite];
   siteItem.text = _site;
-  siteItem.showingText = YES;
   [model addItem:siteItem toSectionWithIdentifier:SectionIdentifierSite];
   [model addItem:[self siteCopyButtonItem]
       toSectionWithIdentifier:SectionIdentifierSite];
 
   if (!_passwordForm.blacklisted_by_user) {
     [model addSectionWithIdentifier:SectionIdentifierUsername];
-    SettingsTextItem* usernameHeader =
-        [[SettingsTextItem alloc] initWithType:ItemTypeHeader];
+    TableViewTextHeaderFooterItem* usernameHeader =
+        [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
     usernameHeader.text =
         l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME);
-    usernameHeader.textColor = [[MDCPalette greyPalette] tint500];
     [model setHeader:usernameHeader
         forSectionWithIdentifier:SectionIdentifierUsername];
-    PasswordDetailsItem* usernameItem =
-        [[PasswordDetailsItem alloc] initWithType:ItemTypeUsername];
+    TableViewTextItem* usernameItem =
+        [[TableViewTextItem alloc] initWithType:ItemTypeUsername];
     usernameItem.text = _username;
-    usernameItem.showingText = YES;
     [model addItem:usernameItem
         toSectionWithIdentifier:SectionIdentifierUsername];
     [model addItem:[self usernameCopyButtonItem]
@@ -200,17 +176,15 @@
 
     if (_passwordForm.federation_origin.opaque()) {
       [model addSectionWithIdentifier:SectionIdentifierPassword];
-      SettingsTextItem* passwordHeader =
-          [[SettingsTextItem alloc] initWithType:ItemTypeHeader];
+      TableViewTextHeaderFooterItem* passwordHeader =
+          [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
       passwordHeader.text =
           l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD);
-      passwordHeader.textColor = [[MDCPalette greyPalette] tint500];
       [model setHeader:passwordHeader
           forSectionWithIdentifier:SectionIdentifierPassword];
-      _passwordItem =
-          [[PasswordDetailsItem alloc] initWithType:ItemTypePassword];
+      _passwordItem = [[TableViewTextItem alloc] initWithType:ItemTypePassword];
       _passwordItem.text = _password;
-      _passwordItem.showingText = NO;
+      _passwordItem.masked = YES;
       [model addItem:_passwordItem
           toSectionWithIdentifier:SectionIdentifierPassword];
 
@@ -220,17 +194,15 @@
           toSectionWithIdentifier:SectionIdentifierPassword];
     } else {
       [model addSectionWithIdentifier:SectionIdentifierFederation];
-      SettingsTextItem* federationHeader =
-          [[SettingsTextItem alloc] initWithType:ItemTypeHeader];
+      TableViewTextHeaderFooterItem* federationHeader =
+          [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
       federationHeader.text =
           l10n_util::GetNSString(IDS_IOS_SHOW_PASSWORD_VIEW_FEDERATION);
-      federationHeader.textColor = [[MDCPalette greyPalette] tint500];
       [model setHeader:federationHeader
           forSectionWithIdentifier:SectionIdentifierFederation];
-      PasswordDetailsItem* federationItem =
-          [[PasswordDetailsItem alloc] initWithType:ItemTypeFederation];
+      TableViewTextItem* federationItem =
+          [[TableViewTextItem alloc] initWithType:ItemTypeFederation];
       federationItem.text = _federation;
-      federationItem.showingText = YES;
       [model addItem:federationItem
           toSectionWithIdentifier:SectionIdentifierFederation];
     }
@@ -243,11 +215,12 @@
 
 #pragma mark - Items
 
-- (CollectionViewItem*)siteCopyButtonItem {
-  SettingsTextItem* item =
-      [[SettingsTextItem alloc] initWithType:ItemTypeCopySite];
+// Returns the "Copy" button for site.
+- (TableViewItem*)siteCopyButtonItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeCopySite];
   item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_SITE_COPY_BUTTON);
-  item.textColor = [[MDCPalette cr_bluePalette] tint500];
+  item.textColor = UIColorFromRGB(kTableViewTextLabelColorBlue);
   // Accessibility label adds the header to the text, so that accessibility
   // users do not have to rely on the visual grouping to understand which part
   // of the credential is being copied.
@@ -260,11 +233,12 @@
   return item;
 }
 
-- (CollectionViewItem*)usernameCopyButtonItem {
-  SettingsTextItem* item =
-      [[SettingsTextItem alloc] initWithType:ItemTypeCopyUsername];
+// Returns the "Copy" button for user name.
+- (TableViewItem*)usernameCopyButtonItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeCopyUsername];
   item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON);
-  item.textColor = [[MDCPalette cr_bluePalette] tint500];
+  item.textColor = UIColorFromRGB(kTableViewTextLabelColorBlue);
   // Accessibility label adds the header to the text, so that accessibility
   // users do not have to rely on the visual grouping to understand which part
   // of the credential is being copied.
@@ -278,11 +252,12 @@
   return item;
 }
 
-- (CollectionViewItem*)passwordCopyButtonItem {
-  SettingsTextItem* item =
-      [[SettingsTextItem alloc] initWithType:ItemTypeCopyPassword];
+// Returns the "Copy" button for password.
+- (TableViewItem*)passwordCopyButtonItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeCopyPassword];
   item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_COPY_BUTTON);
-  item.textColor = [[MDCPalette cr_bluePalette] tint500];
+  item.textColor = UIColorFromRGB(kTableViewTextLabelColorBlue);
   // Accessibility label adds the header to the text, so that accessibility
   // users do not have to rely on the visual grouping to understand which part
   // of the credential is being copied.
@@ -296,26 +271,29 @@
   return item;
 }
 
-- (CollectionViewItem*)showHidePasswordButtonItem {
-  SettingsTextItem* item =
-      [[SettingsTextItem alloc] initWithType:ItemTypeShowHide];
+// Returns the "Show/Hide" toggle button for password.
+- (TableViewItem*)showHidePasswordButtonItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeShowHide];
   item.text = [self showHideButtonText];
-  item.textColor = [[MDCPalette cr_bluePalette] tint500];
+  item.textColor = UIColorFromRGB(kTableViewTextLabelColorBlue);
   item.accessibilityTraits |= UIAccessibilityTraitButton;
   return item;
 }
 
-- (CollectionViewItem*)deletePasswordButtonItem {
-  SettingsTextItem* item =
-      [[SettingsTextItem alloc] initWithType:ItemTypeDelete];
+// Returns the "Delete" button for password.
+- (TableViewItem*)deletePasswordButtonItem {
+  TableViewTextItem* item =
+      [[TableViewTextItem alloc] initWithType:ItemTypeDelete];
   item.text = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON);
-  item.textColor = [[MDCPalette cr_redPalette] tint500];
+  item.textColor = [UIColor redColor];
   item.accessibilityTraits |= UIAccessibilityTraitButton;
   return item;
 }
 
 #pragma mark - Actions
 
+// Copies the site to system pasteboard and shows a toast of success.
 - (void)copySite {
   UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
   generalPasteboard.string = _site;
@@ -324,6 +302,7 @@
        forSuccess:YES];
 }
 
+// Copies the user name to system pasteboard and shows a toast of success.
 - (void)copyUsername {
   UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
   generalPasteboard.string = _username;
@@ -332,6 +311,8 @@
        forSuccess:YES];
 }
 
+// Returns the title of "Show/Hide" toggle button for password based on current
+// state of |_plainTextPasswordShown|.
 - (NSString*)showHideButtonText {
   if (_plainTextPasswordShown) {
     return l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON);
@@ -342,32 +323,31 @@
 // Changes the text on the Show/Hide button appropriately according to
 // |_plainTextPasswordShown|.
 - (void)toggleShowHideButton {
-  CollectionViewModel* model = self.collectionViewModel;
+  TableViewModel* model = self.tableViewModel;
   NSIndexPath* path = [model indexPathForItemType:ItemTypeShowHide
                                 sectionIdentifier:SectionIdentifierPassword];
-  SettingsTextItem* item =
-      base::mac::ObjCCastStrict<SettingsTextItem>([model itemAtIndexPath:path]);
+  TableViewTextItem* item = base::mac::ObjCCastStrict<TableViewTextItem>(
+      [model itemAtIndexPath:path]);
   item.text = [self showHideButtonText];
-  item.textColor = [[MDCPalette cr_bluePalette] tint500];
   [self reconfigureCellsForItems:@[ item ]];
-  [self.collectionView.collectionViewLayout invalidateLayout];
 }
 
+// Shows the password and toggles the "Show/Hide" button if the user can
+// reauthenticate, otherwise shows the password dialog.
 - (void)showPassword {
   if (_plainTextPasswordShown) {
     return;
   }
 
   if ([_weakReauthenticationModule canAttemptReauth]) {
-    __weak PasswordDetailsCollectionViewController* weakSelf = self;
+    __weak PasswordDetailsTableViewController* weakSelf = self;
     void (^showPasswordHandler)(BOOL) = ^(BOOL success) {
-      PasswordDetailsCollectionViewController* strongSelf = weakSelf;
+      PasswordDetailsTableViewController* strongSelf = weakSelf;
       if (!strongSelf || !success)
         return;
-      PasswordDetailsItem* passwordItem = strongSelf->_passwordItem;
-      passwordItem.showingText = YES;
+      TableViewTextItem* passwordItem = strongSelf->_passwordItem;
+      passwordItem.masked = NO;
       [strongSelf reconfigureCellsForItems:@[ passwordItem ]];
-      [[strongSelf collectionView].collectionViewLayout invalidateLayout];
       strongSelf->_plainTextPasswordShown = YES;
       [strongSelf toggleShowHideButton];
       UMA_HISTOGRAM_ENUMERATION(
@@ -386,17 +366,19 @@
   }
 }
 
+// Hides the password and toggles the "Show/Hide" button.
 - (void)hidePassword {
   if (!_plainTextPasswordShown) {
     return;
   }
-  _passwordItem.showingText = NO;
+  _passwordItem.masked = YES;
   [self reconfigureCellsForItems:@[ _passwordItem ]];
-  [self.collectionView.collectionViewLayout invalidateLayout];
   _plainTextPasswordShown = NO;
   [self toggleShowHideButton];
 }
 
+// Copies the password to system pasteboard and shows a toast of success if the
+// user can reauthenticate, otherwise shows the password dialog.
 - (void)copyPassword {
   // If the password is displayed in plain text, there is no need to
   // re-authenticate the user when copying the password because they are already
@@ -416,9 +398,9 @@
         password_manager::metrics_util::REAUTH_SKIPPED,
         password_manager::metrics_util::REAUTH_COUNT);
   } else if ([_weakReauthenticationModule canAttemptReauth]) {
-    __weak PasswordDetailsCollectionViewController* weakSelf = self;
+    __weak PasswordDetailsTableViewController* weakSelf = self;
     void (^copyPasswordHandler)(BOOL) = ^(BOOL success) {
-      PasswordDetailsCollectionViewController* strongSelf = weakSelf;
+      PasswordDetailsTableViewController* strongSelf = weakSelf;
       if (!strongSelf)
         return;
       if (success) {
@@ -488,13 +470,16 @@
   [MDCSnackbarManager showMessage:copyPasswordResultMessage];
 }
 
+// Deletes the password with a deletion confirmation alert.
 - (void)deletePassword {
-  __weak PasswordDetailsCollectionViewController* weakSelf = self;
+  __weak PasswordDetailsTableViewController* weakSelf = self;
 
   self.deleteConfirmation = [UIAlertController
       alertControllerWithTitle:nil
                        message:nil
                 preferredStyle:UIAlertControllerStyleActionSheet];
+  _deleteConfirmation.view.accessibilityIdentifier =
+      kPasswordDetailsDeletionAlertViewId;
 
   UIAlertAction* cancelAction = [UIAlertAction
       actionWithTitle:l10n_util::GetNSString(IDS_IOS_CANCEL_PASSWORD_DELETION)
@@ -508,12 +493,14 @@
       actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)
                 style:UIAlertActionStyleDestructive
               handler:^(UIAlertAction* action) {
-                PasswordDetailsCollectionViewController* strongSelf = weakSelf;
+                PasswordDetailsTableViewController* strongSelf = weakSelf;
                 if (!strongSelf) {
                   return;
                 }
                 strongSelf.deleteConfirmation = nil;
-                [strongSelf->_weakDelegate deletePassword:_passwordForm];
+                [strongSelf->_weakDelegate
+                    passwordDetailsTableViewController:strongSelf
+                                        deletePassword:_passwordForm];
               }];
   [_deleteConfirmation addAction:deleteAction];
 
@@ -561,7 +548,7 @@
 // menu and shows it. This method should only be called for item types
 // representing the cells with the site, username and password.
 - (void)ensureContextMenuShownForItemType:(NSInteger)itemType
-                           collectionView:(UICollectionView*)collectionView
+                                tableView:(UITableView*)tableView
                               atIndexPath:(NSIndexPath*)indexPath {
   UIMenuController* menu = [UIMenuController sharedMenuController];
   if (![menu isMenuVisible]) {
@@ -580,27 +567,24 @@
         NOTREACHED();
     }
     [menu setMenuItems:options];
-    UICollectionViewLayoutAttributes* attributes =
-        [collectionView.collectionViewLayout
-            layoutAttributesForItemAtIndexPath:indexPath];
-    [menu setTargetRect:attributes.frame inView:collectionView];
+    [menu setTargetRect:[tableView rectForRowAtIndexPath:indexPath]
+                 inView:tableView];
     [menu setMenuVisible:YES animated:YES];
   }
 }
 
-#pragma mark - UICollectionViewDelegate
+#pragma mark - UITableViewDelegate
 
-- (void)collectionView:(UICollectionView*)collectionView
-    didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
-  [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
-  NSInteger itemType =
-      [self.collectionViewModel itemTypeForIndexPath:indexPath];
+- (void)tableView:(UITableView*)tableView
+    didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
+  [super tableView:tableView didSelectRowAtIndexPath:indexPath];
+  NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath];
   switch (itemType) {
     case ItemTypeSite:
     case ItemTypeUsername:
     case ItemTypePassword:
       [self ensureContextMenuShownForItemType:itemType
-                               collectionView:collectionView
+                                    tableView:tableView
                                   atIndexPath:indexPath];
       break;
     case ItemTypeCopySite:
@@ -625,24 +609,7 @@
     default:
       break;
   }
-}
-
-#pragma mark MDCCollectionViewStylingDelegate
-
-- (CGFloat)collectionView:(UICollectionView*)collectionView
-    cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
-  switch (item.type) {
-    case ItemTypeSite:
-    case ItemTypeUsername:
-    case ItemTypePassword:
-      return [MDCCollectionViewCell
-          cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
-                             forItem:item];
-    default:
-      return MDCCellDefaultOneLineHeight;
-  }
+  [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }
 
 #pragma mark - ForTesting
diff --git a/ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h b/ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h
new file mode 100644
index 0000000..e650ca3
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_DELEGATE_H_
+
+#import <Foundation/Foundation.h>
+
+namespace autofill {
+struct PasswordForm;
+}  // namespace autofill
+
+@class PasswordDetailsTableViewController;
+
+// PasswordDetailsTableViewController uses this protocal to interact with higher
+// level password controller.
+@protocol PasswordDetailsTableViewControllerDelegate
+
+- (void)passwordDetailsTableViewController:
+            (PasswordDetailsTableViewController*)controller
+                            deletePassword:
+                                (const autofill::PasswordForm&)passwordForm;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_DETAILS_TABLE_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password_details_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password_details_table_view_controller_unittest.mm
new file mode 100644
index 0000000..d6a4c545
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/password_details_table_view_controller_unittest.mm
@@ -0,0 +1,321 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
+
+#include "base/mac/foundation_util.h"
+#include "base/strings/sys_string_conversions.h"
+#include "components/autofill/core/common/password_form.h"
+#import "ios/chrome/browser/ui/settings/reauthentication_module.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
+#import "ios/chrome/browser/web/chrome_web_test.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ios/chrome/test/app/password_test_util.h"
+#include "ios/web/public/test/test_web_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#import "testing/gtest_mac.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface MockSavePasswordsTableViewController
+    : NSObject <PasswordDetailsTableViewControllerDelegate>
+
+- (void)passwordDetailsTableViewController:
+            (PasswordDetailsTableViewController*)constroller
+                            deletePassword:
+                                (const autofill::PasswordForm&)passwordForm;
+
+@end
+
+@implementation MockSavePasswordsTableViewController
+
+- (void)passwordDetailsTableViewController:
+            (PasswordDetailsTableViewController*)constroller
+                            deletePassword:
+                                (const autofill::PasswordForm&)passwordForm {
+}
+
+@end
+
+namespace {
+
+NSString* const kSite = @"https://testorigin.com/";
+NSString* const kUsername = @"testusername";
+NSString* const kPassword = @"testpassword";
+
+// Indices related to the layout for a non-blacklisted, non-federated password.
+const int kSiteSection = 0;
+const int kSiteItem = 0;
+const int kCopySiteButtonItem = 1;
+
+const int kUsernameSection = 1;
+const int kUsernameItem = 0;
+const int kCopyUsernameButtonItem = 1;
+
+const int kPasswordSection = 2;
+const int kPasswordItem = 0;
+const int kCopyPasswordButtonItem = 1;
+const int kShowHideButtonItem = 2;
+
+const int kDeleteSection = 3;
+const int kDeleteButtonItem = 0;
+
+class PasswordDetailsTableViewControllerTest
+    : public ChromeTableViewControllerTest {
+ protected:
+  PasswordDetailsTableViewControllerTest() {
+    origin_ = kSite;
+    form_.username_value = base::SysNSStringToUTF16(kUsername);
+    form_.password_value = base::SysNSStringToUTF16(kPassword);
+    form_.signon_realm = base::SysNSStringToUTF8(origin_);
+    form_.origin = GURL(form_.signon_realm);
+  }
+
+  void SetUp() override {
+    ChromeTableViewControllerTest::SetUp();
+    delegate_ = [[MockSavePasswordsTableViewController alloc] init];
+    reauthentication_module_ = [[MockReauthenticationModule alloc] init];
+    reauthentication_module_.shouldSucceed = YES;
+  }
+
+  ChromeTableViewController* InstantiateController() override {
+    return [[PasswordDetailsTableViewController alloc]
+          initWithPasswordForm:form_
+                      delegate:delegate_
+        reauthenticationModule:reauthentication_module_];
+  }
+
+  web::TestWebThreadBundle thread_bundle_;
+  MockSavePasswordsTableViewController* delegate_;
+  MockReauthenticationModule* reauthentication_module_;
+  NSString* origin_;
+  autofill::PasswordForm form_;
+};
+
+TEST_F(PasswordDetailsTableViewControllerTest,
+       TestInitialization_NormalPassword) {
+  CreateController();
+  CheckController();
+  EXPECT_EQ(4, NumberOfSections());
+  // Site section
+  EXPECT_EQ(2, NumberOfItemsInSection(kSiteSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE, kSiteSection);
+  TableViewTextItem* siteItem = GetTableViewItem(kSiteSection, kSiteItem);
+  EXPECT_NSEQ(origin_, siteItem.text);
+  EXPECT_FALSE(siteItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON, kSiteSection,
+                          kCopySiteButtonItem);
+  // Username section
+  EXPECT_EQ(2, NumberOfItemsInSection(kUsernameSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME,
+                           kUsernameSection);
+  TableViewTextItem* usernameItem =
+      GetTableViewItem(kUsernameSection, kUsernameItem);
+  EXPECT_NSEQ(kUsername, usernameItem.text);
+  EXPECT_FALSE(usernameItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON,
+                          kUsernameSection, kCopyUsernameButtonItem);
+  // Password section
+  EXPECT_EQ(3, NumberOfItemsInSection(kPasswordSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_PASSWORD,
+                           kPasswordSection);
+  TableViewTextItem* passwordItem =
+      GetTableViewItem(kPasswordSection, kPasswordItem);
+  EXPECT_NSEQ(kPassword, passwordItem.text);
+  EXPECT_TRUE(passwordItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_COPY_BUTTON,
+                          kPasswordSection, kCopyPasswordButtonItem);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
+                          kPasswordSection, kShowHideButtonItem);
+  // Delete section
+  EXPECT_EQ(1, NumberOfItemsInSection(kDeleteSection));
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
+                          kDeleteSection, kDeleteButtonItem);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, TestInitialization_Blacklisted) {
+  constexpr int kBlacklistedSiteSection = 0;
+  constexpr int kBlacklistedSiteItem = 0;
+  constexpr int kBlacklistedCopySiteButtonItem = 1;
+
+  constexpr int kBlacklistedDeleteSection = 1;
+  constexpr int kBlacklistedDeleteButtonItem = 0;
+
+  form_.username_value.clear();
+  form_.password_value.clear();
+  form_.blacklisted_by_user = true;
+  CreateController();
+  CheckController();
+  EXPECT_EQ(2, NumberOfSections());
+  // Site section
+  EXPECT_EQ(2, NumberOfItemsInSection(kBlacklistedSiteSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE,
+                           kBlacklistedSiteSection);
+  TableViewTextItem* siteItem =
+      GetTableViewItem(kBlacklistedSiteSection, kBlacklistedSiteItem);
+  EXPECT_NSEQ(origin_, siteItem.text);
+  EXPECT_FALSE(siteItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON,
+                          kBlacklistedSiteSection,
+                          kBlacklistedCopySiteButtonItem);
+  // Delete section
+  EXPECT_EQ(1, NumberOfItemsInSection(kBlacklistedDeleteSection));
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
+                          kBlacklistedDeleteSection,
+                          kBlacklistedDeleteButtonItem);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, TestInitialization_Federated) {
+  constexpr int kFederatedSiteSection = 0;
+  constexpr int kFederatedSiteItem = 0;
+  constexpr int kFederatedCopySiteButtonItem = 1;
+
+  constexpr int kFederatedUsernameSection = 1;
+  constexpr int kFederatedUsernameItem = 0;
+  constexpr int kFederatedCopyUsernameButtonItem = 1;
+
+  constexpr int kFederatedFederationSection = 2;
+  constexpr int kFederatedFederationItem = 0;
+
+  constexpr int kFederatedDeleteSection = 3;
+  constexpr int kFederatedDeleteButtonItem = 0;
+
+  form_.password_value.clear();
+  form_.federation_origin =
+      url::Origin::Create(GURL("https://famous.provider.net"));
+  CreateController();
+  CheckController();
+  EXPECT_EQ(4, NumberOfSections());
+  // Site section
+  EXPECT_EQ(2, NumberOfItemsInSection(kFederatedSiteSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_SITE,
+                           kFederatedSiteSection);
+  TableViewTextItem* siteItem =
+      GetTableViewItem(kFederatedSiteSection, kFederatedSiteItem);
+  EXPECT_NSEQ(origin_, siteItem.text);
+  EXPECT_FALSE(siteItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_SITE_COPY_BUTTON,
+                          kFederatedSiteSection, kFederatedCopySiteButtonItem);
+  // Username section
+  EXPECT_EQ(2, NumberOfItemsInSection(kFederatedUsernameSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_USERNAME,
+                           kFederatedUsernameSection);
+  TableViewTextItem* usernameItem =
+      GetTableViewItem(kFederatedUsernameSection, kFederatedUsernameItem);
+  EXPECT_NSEQ(kUsername, usernameItem.text);
+  EXPECT_FALSE(usernameItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_USERNAME_COPY_BUTTON,
+                          kFederatedUsernameSection,
+                          kFederatedCopyUsernameButtonItem);
+  // Federated section
+  EXPECT_EQ(1, NumberOfItemsInSection(kFederatedFederationSection));
+  CheckSectionHeaderWithId(IDS_IOS_SHOW_PASSWORD_VIEW_FEDERATION,
+                           kFederatedFederationSection);
+  TableViewTextItem* federationItem =
+      GetTableViewItem(kFederatedFederationSection, kFederatedFederationItem);
+  EXPECT_NSEQ(@"famous.provider.net", federationItem.text);
+  EXPECT_FALSE(federationItem.masked);
+  // Delete section
+  EXPECT_EQ(1, NumberOfItemsInSection(kFederatedDeleteSection));
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_DELETE_BUTTON,
+                          kFederatedDeleteSection, kFederatedDeleteButtonItem);
+}
+
+struct SimplifyOriginTestData {
+  GURL origin;
+  NSString* expectedSimplifiedOrigin;
+};
+
+TEST_F(PasswordDetailsTableViewControllerTest, SimplifyOrigin) {
+  SimplifyOriginTestData test_data[] = {
+      {GURL("http://test.com/index.php"), @"test.com"},
+      {GURL("https://example.com/index.php"), @"example.com"},
+      {GURL("android://"
+            "Qllt1FacrB0NYCeSFvmudHvssWBPFfC54EbtHTpFxukvw2wClI1rafcVB3kQOMxfJg"
+            "xbVAkGXvC_A52kbPL1EQ==@com.parkingpanda.mobile/"),
+       @"mobile.parkingpanda.com"}};
+
+  for (const auto& data : test_data) {
+    origin_ = base::SysUTF8ToNSString(data.origin.spec());
+    form_.signon_realm = base::SysNSStringToUTF8(origin_);
+    form_.origin = GURL(form_.signon_realm);
+    CreateController();
+    EXPECT_NSEQ(data.expectedSimplifiedOrigin, controller().title)
+        << " for origin " << data.origin;
+    ResetController();
+  }
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, CopySite) {
+  CreateController();
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:kCopySiteButtonItem
+                                                 inSection:kSiteSection]];
+  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
+  EXPECT_NSEQ(origin_, generalPasteboard.string);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, CopyUsername) {
+  CreateController();
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath
+                                  indexPathForRow:kCopyUsernameButtonItem
+                                        inSection:kUsernameSection]];
+  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
+  EXPECT_NSEQ(kUsername, generalPasteboard.string);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, ShowPassword) {
+  CreateController();
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
+                                                 inSection:kPasswordSection]];
+  TableViewTextItem* passwordItem =
+      GetTableViewItem(kPasswordSection, kPasswordItem);
+  EXPECT_NSEQ(kPassword, passwordItem.text);
+  EXPECT_FALSE(passwordItem.masked);
+  EXPECT_NSEQ(
+      l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW),
+      reauthentication_module_.localizedReasonForAuthentication);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON,
+                          kPasswordSection, kShowHideButtonItem);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, HidePassword) {
+  CreateController();
+  // First show the password.
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
+                                                 inSection:kPasswordSection]];
+  // Then hide it.
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:kShowHideButtonItem
+                                                 inSection:kPasswordSection]];
+  TableViewTextItem* passwordItem =
+      GetTableViewItem(kPasswordSection, kPasswordItem);
+  EXPECT_NSEQ(kPassword, passwordItem.text);
+  EXPECT_TRUE(passwordItem.masked);
+  CheckTextCellTextWithId(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON,
+                          kPasswordSection, kShowHideButtonItem);
+}
+
+TEST_F(PasswordDetailsTableViewControllerTest, CopyPassword) {
+  CreateController();
+  [controller() tableView:[controller() tableView]
+      didSelectRowAtIndexPath:[NSIndexPath
+                                  indexPathForRow:kCopyPasswordButtonItem
+                                        inSection:kPasswordSection]];
+  UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
+  EXPECT_NSEQ(kPassword, generalPasteboard.string);
+  EXPECT_NSEQ(
+      l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_COPY),
+      reauthentication_module_.localizedReasonForAuthentication);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
index a8ebafa..5f160d1 100644
--- a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
@@ -22,7 +22,9 @@
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/reauthentication_module.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
@@ -71,8 +73,7 @@
 
 // Returns the GREYElementInteraction* for the item on the password list with
 // the given |matcher|. It scrolls in |direction| if necessary to ensure that
-// the matched item is interactable. The result can be used to perform user
-// actions or checks.
+// the matched item is interactable.
 GREYElementInteraction* GetInteractionForListItem(id<GREYMatcher> matcher,
                                                   GREYDirection direction) {
   return [[EarlGrey
@@ -84,8 +85,7 @@
 
 // Returns the GREYElementInteraction* for the cell on the password list with
 // the given |username|. It scrolls down if necessary to ensure that the matched
-// cell is interactable. The result can be used to perform user actions or
-// checks.
+// cell is interactable.
 GREYElementInteraction* GetInteractionForPasswordEntry(NSString* username) {
   return GetInteractionForListItem(ButtonWithAccessibilityLabel(username),
                                    kGREYDirectionDown);
@@ -93,16 +93,23 @@
 
 // Returns the GREYElementInteraction* for the item on the detail view
 // identified with the given |matcher|. It scrolls down if necessary to ensure
-// that the matched cell is interactable. The result can be used to perform
-// user actions or checks.
+// that the matched cell is interactable.
 GREYElementInteraction* GetInteractionForPasswordDetailItem(
     id<GREYMatcher> matcher) {
   return [[EarlGrey
       selectElementWithMatcher:grey_allOf(matcher, grey_interactable(), nil)]
          usingSearchAction:grey_scrollInDirection(kGREYDirectionDown,
                                                   kScrollAmount)
-      onElementWithMatcher:grey_accessibilityID(
-                               @"PasswordDetailsCollectionViewController")];
+      onElementWithMatcher:grey_accessibilityID(kPasswordDetailsTableViewId)];
+}
+
+// Returns the GREYElementInteraction* for the item on the deletion alert
+// identified with the given |matcher|.
+GREYElementInteraction* GetInteractionForPasswordDetailDeletionAlert(
+    id<GREYMatcher> matcher) {
+  return [[EarlGrey
+      selectElementWithMatcher:grey_allOf(matcher, grey_interactable(), nil)]
+      inRoot:grey_accessibilityID(kPasswordDetailsDeletionAlertViewId)];
 }
 
 // Matcher for a UITextField inside a SettingsSearchCell.
@@ -643,16 +650,8 @@
   [GetInteractionForPasswordDetailItem(DeleteButton())
       performAction:grey_tap()];
 
-  // Tap the alert's Delete button to confirm. Check accessibilityTrait to
-  // differentiate against the above DeleteButton()-matching element, which is
-  // has UIAccessibilityTraitSelected.
-  // TODO(crbug.com/751311): Revisit and check if there is a better solution to
-  // match the Delete button.
-  id<GREYMatcher> deleteConfirmationButton = grey_allOf(
-      ButtonWithAccessibilityLabel(
-          l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)),
-      grey_not(grey_accessibilityTrait(UIAccessibilityTraitSelected)), nil);
-  [[EarlGrey selectElementWithMatcher:deleteConfirmationButton]
+  [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel(
+      l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)))
       performAction:grey_tap()];
 
   // Wait until the alert and the detail view are dismissed.
@@ -713,16 +712,8 @@
   [GetInteractionForPasswordDetailItem(DeleteButton())
       performAction:grey_tap()];
 
-  // Tap the alert's Delete button to confirm. Check accessibilityTrait to
-  // differentiate against the above DeleteButton()-matching element, which is
-  // has UIAccessibilityTraitSelected.
-  // TODO(crbug.com/751311): Revisit and check if there is a better solution to
-  // match the Delete button.
-  id<GREYMatcher> deleteConfirmationButton = grey_allOf(
-      ButtonWithAccessibilityLabel(
-          l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)),
-      grey_not(grey_accessibilityTrait(UIAccessibilityTraitSelected)), nil);
-  [[EarlGrey selectElementWithMatcher:deleteConfirmationButton]
+  [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel(
+      l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)))
       performAction:grey_tap()];
 
   // Wait until the alert and the detail view are dismissed.
@@ -776,16 +767,8 @@
   [GetInteractionForPasswordDetailItem(DeleteButton())
       performAction:grey_tap()];
 
-  // Tap the alert's Delete button to confirm. Check accessibilityTrait to
-  // differentiate against the above DeleteButton()-matching element, which is
-  // has UIAccessibilityTraitSelected.
-  // TODO(crbug.com/751311): Revisit and check if there is a better solution to
-  // match the Delete button.
-  id<GREYMatcher> deleteConfirmationButton = grey_allOf(
-      ButtonWithAccessibilityLabel(
-          l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)),
-      grey_not(grey_accessibilityTrait(UIAccessibilityTraitSelected)), nil);
-  [[EarlGrey selectElementWithMatcher:deleteConfirmationButton]
+  [GetInteractionForPasswordDetailDeletionAlert(ButtonWithAccessibilityLabel(
+      l10n_util::GetNSString(IDS_IOS_CONFIRM_PASSWORD_DELETION)))
       performAction:grey_tap()];
 
   // Wait until the alert and the detail view are dismissed.
@@ -981,7 +964,7 @@
       performAction:grey_tap()];
 
   // Tap the password cell to display the context menu.
-  [GetInteractionForPasswordDetailItem(grey_text(@"•••••••••••••••••"))
+  [GetInteractionForPasswordDetailItem(grey_text(kMaskedPassword))
       performAction:grey_tap()];
 
   // Make sure to capture the reauthentication module in a variable until the
@@ -1024,7 +1007,7 @@
       performAction:grey_tap()];
 
   // Tap the password cell to display the context menu.
-  [GetInteractionForPasswordDetailItem(grey_text(@"•••••••••••••••••"))
+  [GetInteractionForPasswordDetailItem(grey_text(kMaskedPassword))
       performAction:grey_tap()];
 
   // Make sure to capture the reauthentication module in a variable until the
@@ -1052,8 +1035,8 @@
       performAction:grey_tap()];
 
   // Check that the password is masked again.
-  [GetInteractionForPasswordDetailItem(grey_text(@"•••••••••••••••••"))
-      assertWithMatcher:grey_notNil()];
+  [GetInteractionForPasswordDetailItem(grey_text(kMaskedPassword))
+      performAction:grey_tap()];
 
   [[EarlGrey selectElementWithMatcher:SettingsMenuBackButton()]
       performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h
index edf7e7d3..1987e6d 100644
--- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h
+++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SAVE_PASSWORDS_COLLECTION_VIEW_CONTROLLER_H_
 #define IOS_CHROME_BROWSER_UI_SETTINGS_SAVE_PASSWORDS_COLLECTION_VIEW_CONTROLLER_H_
 
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h"
 #import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
 
 #include <memory>
@@ -31,8 +31,8 @@
 
 @end
 
-@interface SavePasswordsCollectionViewController (
-    Testing)<PasswordDetailsCollectionViewControllerDelegate>
+@interface SavePasswordsCollectionViewController (Testing) <
+    PasswordDetailsTableViewControllerDelegate>
 
 // Initializes the password exporter with a (fake) |reauthenticationModule|.
 - (void)setReauthenticationModuleForExporter:
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
index e022112..71c260a0 100644
--- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
@@ -39,8 +39,8 @@
 #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_switch_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_search_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h"
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller_delegate.h"
 #import "ios/chrome/browser/ui/settings/password_exporter.h"
 #import "ios/chrome/browser/ui/settings/reauthentication_module.h"
 #import "ios/chrome/browser/ui/settings/settings_utils.h"
@@ -108,7 +108,7 @@
 @implementation BlacklistedFormContentItem
 @end
 
-@protocol PasswordExportActivityViewControllerDelegate<NSObject>
+@protocol PasswordExportActivityViewControllerDelegate <NSObject>
 
 // Used to reset the export state when the activity view disappears.
 - (void)resetExport;
@@ -118,9 +118,9 @@
 @interface PasswordExportActivityViewController : UIActivityViewController
 
 - (PasswordExportActivityViewController*)
-initWithActivityItems:(NSArray*)activityItems
-             delegate:
-                 (id<PasswordExportActivityViewControllerDelegate>)delegate;
+    initWithActivityItems:(NSArray*)activityItems
+                 delegate:
+                     (id<PasswordExportActivityViewControllerDelegate>)delegate;
 
 @end
 
@@ -129,9 +129,9 @@
 }
 
 - (PasswordExportActivityViewController*)
-initWithActivityItems:(NSArray*)activityItems
-             delegate:
-                 (id<PasswordExportActivityViewControllerDelegate>)delegate {
+    initWithActivityItems:(NSArray*)activityItems
+                 delegate:(id<PasswordExportActivityViewControllerDelegate>)
+                              delegate {
   self = [super initWithActivityItems:activityItems applicationActivities:nil];
   if (self) {
     _weakDelegate = delegate;
@@ -147,9 +147,9 @@
 
 @end
 
-@interface SavePasswordsCollectionViewController ()<
+@interface SavePasswordsCollectionViewController () <
     BooleanObserver,
-    PasswordDetailsCollectionViewControllerDelegate,
+    PasswordDetailsTableViewControllerDelegate,
     PasswordExporterDelegate,
     PasswordExportActivityViewControllerDelegate,
     SavePasswordsConsumerDelegate,
@@ -219,8 +219,8 @@
   DCHECK(browserState);
   MDCCollectionViewFlowLayout* layout =
       [[AlphaAnimatedCollectionViewFlowLayout alloc] init];
-  self =
-      [super initWithLayout:layout style:CollectionViewControllerStyleAppBar];
+  self = [super initWithLayout:layout
+                         style:CollectionViewControllerStyleAppBar];
   if (self) {
     browserState_ = browserState;
     reauthenticationModule_ = [[ReauthenticationModule alloc]
@@ -386,8 +386,8 @@
 }
 
 - (BlacklistedFormContentItem*)
-blacklistedFormItemWithText:(NSString*)text
-                    forForm:(autofill::PasswordForm*)form {
+    blacklistedFormItemWithText:(NSString*)text
+                        forForm:(autofill::PasswordForm*)form {
   BlacklistedFormContentItem* passwordItem =
       [[BlacklistedFormContentItem alloc] initWithType:ItemTypeBlacklisted];
   passwordItem.text = text;
@@ -468,8 +468,8 @@
 
 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
                  cellForItemAtIndexPath:(NSIndexPath*)indexPath {
-  UICollectionViewCell* cell =
-      [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
+  UICollectionViewCell* cell = [super collectionView:collectionView
+                              cellForItemAtIndexPath:indexPath];
 
   if ([self.collectionViewModel itemTypeForIndexPath:indexPath] ==
       ItemTypeSavePasswordsSwitch) {
@@ -684,8 +684,8 @@
 #pragma mark UICollectionViewDelegate
 
 - (void)openDetailedViewForForm:(const autofill::PasswordForm&)form {
-  PasswordDetailsCollectionViewController* controller =
-      [[PasswordDetailsCollectionViewController alloc]
+  PasswordDetailsTableViewController* controller =
+      [[PasswordDetailsTableViewController alloc]
             initWithPasswordForm:form
                         delegate:self
           reauthenticationModule:reauthenticationModule_];
@@ -829,23 +829,24 @@
     didDeleteItemsAtIndexPaths:(NSArray*)indexPaths {
   // Remove empty sections.
   __weak SavePasswordsCollectionViewController* weakSelf = self;
-  [self.collectionView performBatchUpdates:^{
-    SavePasswordsCollectionViewController* strongSelf = weakSelf;
-    if (!strongSelf)
-      return;
-    // Delete in reverse order of section indexes (bottom up of section
-    // displayed), so that indexes in model matches those in the view.  if we
-    // don't we'll cause a crash.
-    [strongSelf
-        clearSectionWithIdentifier:SectionIdentifierBlacklist
-                           ifEmpty:strongSelf->blacklistedForms_.empty()];
-    [strongSelf clearSectionWithIdentifier:SectionIdentifierSavedPasswords
-                                   ifEmpty:strongSelf->savedForms_.empty()];
-    [strongSelf
-        clearSectionWithIdentifier:SectionIdentifierSearchPasswordsBox
-                           ifEmpty:strongSelf->savedForms_.empty() &&
-                                   strongSelf->blacklistedForms_.empty()];
-  }
+  [self.collectionView
+      performBatchUpdates:^{
+        SavePasswordsCollectionViewController* strongSelf = weakSelf;
+        if (!strongSelf)
+          return;
+        // Delete in reverse order of section indexes (bottom up of section
+        // displayed), so that indexes in model matches those in the view.  if
+        // we don't we'll cause a crash.
+        [strongSelf
+            clearSectionWithIdentifier:SectionIdentifierBlacklist
+                               ifEmpty:strongSelf->blacklistedForms_.empty()];
+        [strongSelf clearSectionWithIdentifier:SectionIdentifierSavedPasswords
+                                       ifEmpty:strongSelf->savedForms_.empty()];
+        [strongSelf
+            clearSectionWithIdentifier:SectionIdentifierSearchPasswordsBox
+                               ifEmpty:strongSelf->savedForms_.empty() &&
+                                       strongSelf->blacklistedForms_.empty()];
+      }
       completion:^(BOOL finished) {
         SavePasswordsCollectionViewController* strongSelf = weakSelf;
         if (!strongSelf)
@@ -858,9 +859,11 @@
       }];
 }
 
-#pragma mark PasswordDetailsCollectionViewControllerDelegate
+#pragma mark PasswordDetailsTableViewControllerDelegate
 
-- (void)deletePassword:(const autofill::PasswordForm&)form {
+- (void)passwordDetailsTableViewController:
+            (PasswordDetailsTableViewController*)controller
+                            deletePassword:(const autofill::PasswordForm&)form {
   passwordStore_->RemoveLogin(form);
 
   std::vector<std::unique_ptr<autofill::PasswordForm>>& forms =
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller_unittest.mm
index 3aff7bc..6785b78 100644
--- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller_unittest.mm
@@ -21,7 +21,7 @@
 #import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_search_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
@@ -405,7 +405,8 @@
   AddPasswordForm(std::make_unique<autofill::PasswordForm>(form));
 
   EXPECT_CALL(GetMockStore(), RemoveLogin(form));
-  [save_password_controller deletePassword:form];
+  [save_password_controller passwordDetailsTableViewController:nil
+                                                deletePassword:form];
 }
 
 // Tests filtering of items.
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.h b/ios/chrome/browser/ui/settings/settings_navigation_controller.h
index 6d476b2..c767737 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.h
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.h
@@ -94,7 +94,7 @@
                  delegate:(id<SettingsNavigationControllerDelegate>)delegate
        feedbackDataSource:(id<UserFeedbackDataSource>)dataSource;
 
-// Creates and displays a new ImportDataCollectionViewController. |browserState|
+// Creates and displays a new ImportDataTableViewController. |browserState|
 // should not be nil.
 + (SettingsNavigationController*)
 newImportDataController:(ios::ChromeBrowserState*)browserState
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
index 1273533..4cedc067 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -18,7 +18,7 @@
 #import "ios/chrome/browser/ui/settings/autofill_profile_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_coordinator.h"
 #import "ios/chrome/browser/ui/settings/google_services_settings_view_controller.h"
-#import "ios/chrome/browser/ui/settings/import_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
@@ -221,11 +221,11 @@
               fromEmail:(NSString*)fromEmail
                 toEmail:(NSString*)toEmail
              isSignedIn:(BOOL)isSignedIn {
-  UIViewController* controller = [[ImportDataCollectionViewController alloc]
-      initWithDelegate:importDataDelegate
-             fromEmail:fromEmail
-               toEmail:toEmail
-            isSignedIn:isSignedIn];
+  UIViewController* controller =
+      [[ImportDataTableViewController alloc] initWithDelegate:importDataDelegate
+                                                    fromEmail:fromEmail
+                                                      toEmail:toEmail
+                                                   isSignedIn:isSignedIn];
 
   SettingsNavigationController* nc = [[SettingsNavigationController alloc]
       initWithRootViewController:controller
diff --git a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h b/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h
deleted file mode 100644
index f352c4a..0000000
--- a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_COLLECTION_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_COLLECTION_VIEW_CONTROLLER_H_
-
-#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h"
-
-namespace ios {
-class ChromeBrowserState;
-}  // namespace ios
-
-// Controller to allow user to specify encryption passphrase for Sync.
-@interface SyncEncryptionCollectionViewController
-    : SettingsRootCollectionViewController
-
-// Designated initializer. |browserState| must not be nil.
-- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
-    NS_DESIGNATED_INITIALIZER;
-- (instancetype)initWithLayout:(UICollectionViewLayout*)layout
-                         style:(CollectionViewControllerStyle)style
-    NS_UNAVAILABLE;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_COLLECTION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h
new file mode 100644
index 0000000..4787f22
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_TABLE_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_TABLE_VIEW_CONTROLLER_H_
+
+#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
+
+namespace ios {
+class ChromeBrowserState;
+}  // namespace ios
+
+// Controller to allow user to specify encryption passphrase for Sync.
+@interface SyncEncryptionTableViewController : SettingsRootTableViewController
+
+// Designated initializer. |browserState| must not be nil.
+- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
+    NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithTableViewStyle:(UITableViewStyle)style
+                           appBarStyle:
+                               (ChromeTableViewControllerStyle)appBarStyle
+    NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_SYNC_ENCRYPTION_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.mm b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.mm
similarity index 60%
rename from ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.mm
rename to ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.mm
index 8607e5b..b9f62eb 100644
--- a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.mm
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h"
 
 #include <memory>
 
+#include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/browser_sync/profile_sync_service.h"
 #include "components/google/core/common/google_util.h"
@@ -16,14 +17,14 @@
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_observer_bridge.h"
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h"
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
 #import "ios/chrome/browser/ui/settings/settings_utils.h"
 #import "ios/chrome/browser/ui/settings/sync_create_passphrase_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_view_controller.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
+#import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h"
+#import "ios/chrome/browser/ui/table_view/table_view_model.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "url/gurl.h"
@@ -36,7 +37,6 @@
 
 typedef NS_ENUM(NSInteger, SectionIdentifier) {
   SectionIdentifierEncryption = kSectionIdentifierEnumZero,
-  SectionIdentifierFooter,
 };
 
 typedef NS_ENUM(NSInteger, ItemType) {
@@ -47,28 +47,20 @@
 
 }  // namespace
 
-@interface SyncEncryptionCollectionViewController ()<SyncObserverModelBridge> {
+@interface SyncEncryptionTableViewController () <SyncObserverModelBridge> {
   ios::ChromeBrowserState* _browserState;
   std::unique_ptr<SyncObserverBridge> _syncObserver;
   BOOL _isUsingSecondaryPassphrase;
 }
-// Returns an account item.
-- (CollectionViewItem*)accountItem;
-
-// Returns a passphrase item.
-- (CollectionViewItem*)passphraseItem;
-
-// Returns a footer item with a link.
-- (CollectionViewItem*)footerItem;
 @end
 
-@implementation SyncEncryptionCollectionViewController
+@implementation SyncEncryptionTableViewController
 
 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState {
   DCHECK(browserState);
-  UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init];
   self =
-      [super initWithLayout:layout style:CollectionViewControllerStyleAppBar];
+      [super initWithTableViewStyle:UITableViewStyleGrouped
+                        appBarStyle:ChromeTableViewControllerStyleWithAppBar];
   if (self) {
     self.title = l10n_util::GetNSString(IDS_IOS_SYNC_ENCRYPTION_TITLE);
     _browserState = browserState;
@@ -77,18 +69,22 @@
     _isUsingSecondaryPassphrase = syncService->IsEngineInitialized() &&
                                   syncService->IsUsingSecondaryPassphrase();
     _syncObserver = std::make_unique<SyncObserverBridge>(self, syncService);
-    // TODO(crbug.com/764578): -loadModel should not be called from
-    // initializer. A possible fix is to move this call to -viewDidLoad.
-    [self loadModel];
   }
   return self;
 }
 
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  self.tableView.estimatedSectionFooterHeight =
+      kTableViewHeaderFooterViewHeight;
+  [self loadModel];
+}
+
 #pragma mark - SettingsRootCollectionViewController
 
 - (void)loadModel {
   [super loadModel];
-  CollectionViewModel* model = self.collectionViewModel;
+  TableViewModel* model = self.tableViewModel;
 
   [model addSectionWithIdentifier:SectionIdentifierEncryption];
   [model addItem:[self accountItem]
@@ -97,15 +93,15 @@
       toSectionWithIdentifier:SectionIdentifierEncryption];
 
   if (_isUsingSecondaryPassphrase) {
-    [model addSectionWithIdentifier:SectionIdentifierFooter];
-    [model addItem:[self footerItem]
-        toSectionWithIdentifier:SectionIdentifierFooter];
+    [model setFooter:[self footerItem]
+        forSectionWithIdentifier:SectionIdentifierEncryption];
   }
 }
 
 #pragma mark - Items
 
-- (CollectionViewItem*)accountItem {
+// Returns an account item.
+- (TableViewItem*)accountItem {
   DCHECK(browser_sync::ProfileSyncService::IsSyncAllowedByFlag());
   NSString* text = l10n_util::GetNSString(IDS_SYNC_BASIC_ENCRYPTION_DATA);
   return [self itemWithType:ItemTypeAccount
@@ -114,7 +110,8 @@
                     enabled:!_isUsingSecondaryPassphrase];
 }
 
-- (CollectionViewItem*)passphraseItem {
+// Returns a passphrase item.
+- (TableViewItem*)passphraseItem {
   DCHECK(browser_sync::ProfileSyncService::IsSyncAllowedByFlag());
   NSString* text = l10n_util::GetNSString(IDS_SYNC_FULL_ENCRYPTION_DATA);
   return [self itemWithType:ItemTypePassphrase
@@ -123,69 +120,53 @@
                     enabled:!_isUsingSecondaryPassphrase];
 }
 
-- (CollectionViewItem*)footerItem {
-  CollectionViewFooterItem* footerItem =
-      [[CollectionViewFooterItem alloc] initWithType:ItemTypeFooter];
-  footerItem.cellStyle = CollectionViewCellStyle::kUIKit;
+// Returns a footer item with a link.
+- (TableViewHeaderFooterItem*)footerItem {
+  TableViewLinkHeaderFooterItem* footerItem =
+      [[TableViewLinkHeaderFooterItem alloc] initWithType:ItemTypeFooter];
   footerItem.text =
       l10n_util::GetNSString(IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT);
   footerItem.linkURL = google_util::AppendGoogleLocaleParam(
       GURL(kSyncGoogleDashboardURL),
       GetApplicationContext()->GetApplicationLocale());
-  footerItem.linkDelegate = self;
   return footerItem;
 }
 
-#pragma mark - MDCCollectionViewStylingDelegate
+#pragma mark - UITableViewDelegate
 
-- (MDCCollectionViewCellStyle)collectionView:(UICollectionView*)collectionView
-                         cellStyleForSection:(NSInteger)section {
-  NSInteger sectionIdentifier =
-      [self.collectionViewModel sectionIdentifierForSection:section];
-  switch (sectionIdentifier) {
-    case SectionIdentifierFooter:
-      // Display the Learn More footer in the default style with no "card" UI
-      // and no section padding.
-      return MDCCollectionViewCellStyleDefault;
-    default:
-      return self.styler.cellStyle;
+- (UIView*)tableView:(UITableView*)tableView
+    viewForFooterInSection:(NSInteger)section {
+  UIView* footerView = [super tableView:tableView
+                 viewForFooterInSection:section];
+  if (SectionIdentifierEncryption ==
+          [self.tableViewModel sectionIdentifierForSection:section] &&
+      [self.tableViewModel footerForSection:section]) {
+    TableViewLinkHeaderFooterView* footer =
+        base::mac::ObjCCastStrict<TableViewLinkHeaderFooterView>(footerView);
+    footer.delegate = self;
   }
+  return footerView;
 }
 
-- (BOOL)collectionView:(UICollectionView*)collectionView
-    shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath {
-  NSInteger sectionIdentifier =
-      [self.collectionViewModel sectionIdentifierForSection:indexPath.section];
-  switch (sectionIdentifier) {
-    case SectionIdentifierFooter:
-      // Display the Learn More footer without any background image or
-      // shadowing.
-      return YES;
-    default:
-      return NO;
+- (BOOL)tableView:(UITableView*)tableView
+    shouldHighlightRowAtIndexPath:(NSIndexPath*)indexPath {
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
+  if (item.type == ItemTypePassphrase || item.type == ItemTypeAccount) {
+    EncryptionItem* encryptionItem =
+        base::mac::ObjCCastStrict<EncryptionItem>(item);
+    // Don't perform any action if the cell isn't enabled.
+    return encryptionItem.isEnabled;
   }
+  return YES;
 }
 
-- (CGFloat)collectionView:(UICollectionView*)collectionView
-    cellHeightAtIndexPath:(NSIndexPath*)indexPath {
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
-  return [MDCCollectionViewCell
-      cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds)
-                         forItem:item];
-}
-
-#pragma mark - UICollectionViewDelegate
-
-- (void)collectionView:(UICollectionView*)collectionView
-    didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
-  [super collectionView:collectionView didSelectItemAtIndexPath:indexPath];
+- (void)tableView:(UITableView*)tableView
+    didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
   DCHECK_EQ(indexPath.section,
-            [self.collectionViewModel
+            [self.tableViewModel
                 sectionForSectionIdentifier:SectionIdentifierEncryption]);
 
-  CollectionViewItem* item =
-      [self.collectionViewModel itemAtIndexPath:indexPath];
+  TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath];
   if ([item respondsToSelector:@selector(isEnabled)] &&
       ![item performSelector:@selector(isEnabled)]) {
     // Don't perform any action if the cell isn't enabled.
@@ -211,6 +192,8 @@
     default:
       break;
   }
+
+  [tableView deselectRowAtIndexPath:indexPath animated:NO];
 }
 
 #pragma mark SyncObserverModelBridge
@@ -228,14 +211,14 @@
 
 #pragma mark - Private methods
 
-- (CollectionViewItem*)itemWithType:(NSInteger)type
-                               text:(NSString*)text
-                            checked:(BOOL)checked
-                            enabled:(BOOL)enabled {
+- (TableViewItem*)itemWithType:(NSInteger)type
+                          text:(NSString*)text
+                       checked:(BOOL)checked
+                       enabled:(BOOL)enabled {
   EncryptionItem* item = [[EncryptionItem alloc] initWithType:type];
   item.text = text;
-  item.accessoryType = checked ? MDCCollectionViewCellAccessoryCheckmark
-                               : MDCCollectionViewCellAccessoryNone;
+  item.accessoryType = checked ? UITableViewCellAccessoryCheckmark
+                               : UITableViewCellAccessoryNone;
   item.enabled = enabled;
   return item;
 }
diff --git a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller_unittest.mm
similarity index 81%
rename from ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller_unittest.mm
rename to ios/chrome/browser/ui/settings/sync_encryption_table_view_controller_unittest.mm
index 5127de6..d3874bd8 100644
--- a/ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/sync_encryption_table_view_controller_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h"
 
 #include <memory>
 
@@ -12,8 +12,8 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.h"
 #include "ios/chrome/browser/sync/profile_sync_service_factory.h"
-#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h"
 #import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -39,8 +39,8 @@
       &init_params);
 }
 
-class SyncEncryptionCollectionViewControllerTest
-    : public CollectionViewControllerTest {
+class SyncEncryptionTableViewControllerTest
+    : public ChromeTableViewControllerTest {
  protected:
   void SetUp() override {
     TestChromeBrowserState::Builder test_cbs_builder;
@@ -48,7 +48,7 @@
         ProfileSyncServiceFactory::GetInstance(),
         base::BindRepeating(&CreateNiceProfileSyncServiceMock));
     chrome_browser_state_ = test_cbs_builder.Build();
-    CollectionViewControllerTest::SetUp();
+    ChromeTableViewControllerTest::SetUp();
 
     mock_profile_sync_service_ =
         static_cast<browser_sync::ProfileSyncServiceMock*>(
@@ -62,8 +62,8 @@
     CreateController();
   }
 
-  CollectionViewController* InstantiateController() override {
-    return [[SyncEncryptionCollectionViewController alloc]
+  ChromeTableViewController* InstantiateController() override {
+    return [[SyncEncryptionTableViewController alloc]
         initWithBrowserState:chrome_browser_state_.get()];
   }
 
@@ -73,20 +73,20 @@
   browser_sync::ProfileSyncServiceMock* mock_profile_sync_service_;
 };
 
-TEST_F(SyncEncryptionCollectionViewControllerTest, TestModel) {
+TEST_F(SyncEncryptionTableViewControllerTest, TestModel) {
   CheckController();
   CheckTitleWithId(IDS_IOS_SYNC_ENCRYPTION_TITLE);
 
-  EXPECT_EQ(2, NumberOfSections());
+  EXPECT_EQ(1, NumberOfSections());
 
   NSInteger const kSection = 0;
   EXPECT_EQ(2, NumberOfItemsInSection(kSection));
 
-  EncryptionItem* accountItem = GetCollectionViewItem(kSection, 0);
+  EncryptionItem* accountItem = GetTableViewItem(kSection, 0);
   EXPECT_NSEQ(l10n_util::GetNSString(IDS_SYNC_BASIC_ENCRYPTION_DATA),
               accountItem.text);
 
-  EncryptionItem* passphraseItem = GetCollectionViewItem(kSection, 1);
+  EncryptionItem* passphraseItem = GetTableViewItem(kSection, 1);
   EXPECT_NSEQ(l10n_util::GetNSString(IDS_SYNC_FULL_ENCRYPTION_DATA),
               passphraseItem.text);
 }
diff --git a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
index a14f10d..d030a2e 100644
--- a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.mm
@@ -43,8 +43,8 @@
 #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
-#import "ios/chrome/browser/ui/settings/sync_encryption_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_encryption_passphrase_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/sync_encryption_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -332,10 +332,6 @@
   for (int i = 0; i < SyncSetupService::kNumberOfSyncableDatatypes; ++i) {
     SyncSetupService::SyncableDatatype dataType =
         static_cast<SyncSetupService::SyncableDatatype>(i);
-    if (dataType == SyncSetupService::kSyncUserEvent) {
-      // This data type should only be used with the unified consent UI.
-      continue;
-    }
     [model addItem:[self switchItemForDataType:dataType]
         toSectionWithIdentifier:SectionIdentifierSyncServices];
   }
@@ -766,14 +762,14 @@
       [self shouldDisableSettingsOnSyncError])
     return;
 
-  SettingsRootCollectionViewController* controllerToPush;
+  UIViewController<SettingsRootViewControlling>* controllerToPush;
   // If there was a sync error, prompt the user to enter the passphrase.
   // Otherwise, show the full encryption options.
   if (syncService->IsPassphraseRequired()) {
     controllerToPush = [[SyncEncryptionPassphraseCollectionViewController alloc]
         initWithBrowserState:_browserState];
   } else {
-    controllerToPush = [[SyncEncryptionCollectionViewController alloc]
+    controllerToPush = [[SyncEncryptionTableViewController alloc]
         initWithBrowserState:_browserState];
   }
   controllerToPush.dispatcher = self.dispatcher;
@@ -838,10 +834,6 @@
        index < SyncSetupService::kNumberOfSyncableDatatypes; ++index) {
     SyncSetupService::SyncableDatatype dataType =
         static_cast<SyncSetupService::SyncableDatatype>(index);
-    if (dataType == SyncSetupService::kSyncUserEvent) {
-      // This data type should only be used with the unified consent UI.
-      continue;
-    }
     NSIndexPath* indexPath = [self.collectionViewModel
         indexPathForItemType:ItemTypeSyncableDataType
            sectionIdentifier:SectionIdentifierSyncServices
@@ -977,8 +969,6 @@
       return IDS_SYNC_DATATYPE_PREFERENCES;
     case SyncSetupService::kSyncReadingList:
       return IDS_SYNC_DATATYPE_READING_LIST;
-    case SyncSetupService::kSyncUserEvent:
-    // Not supported for the code before the unified consent.
     case SyncSetupService::kNumberOfSyncableDatatypes:
       NOTREACHED();
   }
diff --git a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm
index b468784..e1ac4c0 100644
--- a/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/sync_settings_collection_view_controller_unittest.mm
@@ -241,11 +241,10 @@
   EXPECT_EQ(3, NumberOfSections());
 
   EXPECT_EQ(1, NumberOfItemsInSection(0));
-  // There is one item per data type, except for unified consent that is
-  // unsupported by the old UI. In addition, there are two extra items, one
-  // for "Sync Everything" and another for Autofill wallet import.
+  // There are two extra items, one for "Sync Everything" and another for
+  // Autofill wallet import.
   constexpr int expected_number_of_items =
-      SyncSetupService::kNumberOfSyncableDatatypes - 1 + 2;
+      SyncSetupService::kNumberOfSyncableDatatypes + 2;
   EXPECT_EQ(expected_number_of_items, NumberOfItemsInSection(1));
   EXPECT_EQ(2, NumberOfItemsInSection(2));
 
@@ -266,10 +265,6 @@
   for (int i = 0; i < SyncSetupService::kNumberOfSyncableDatatypes; i++) {
     SyncSetupService::SyncableDatatype dataType =
         static_cast<SyncSetupService::SyncableDatatype>(i);
-    if (dataType == SyncSetupService::kSyncUserEvent) {
-      // Old UI without unified consent doesn't support user event data type.
-      continue;
-    }
     SyncSwitchItem* syncDataTypeItem = GetCollectionViewItem(1, item++);
     EXPECT_NSEQ(syncDataTypeItem.text,
                 l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
index 89768d3..e6375c4 100644
--- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -6,6 +6,7 @@
 
 #import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h"
+#import "ios/chrome/browser/ui/settings/cells/encryption_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h"
 #import "ios/chrome/browser/ui/table_view/cells/table_view_accessory_item.h"
@@ -45,6 +46,7 @@
   ItemTypeURLWithSupplementalText,
   ItemTypeURLWithBadgeImage,
   ItemTypeTextSettingsDetail,
+  ItemTypeEncryption,
   ItemTypeLinkFooter,
   ItemTypeDetailText,
   ItemTypeSettingsSwitch,
@@ -173,6 +175,25 @@
   [model addItem:settingsSwitchItem
       toSectionWithIdentifier:SectionIdentifierSettings];
 
+  EncryptionItem* encryptionChecked =
+      [[EncryptionItem alloc] initWithType:ItemTypeEncryption];
+  encryptionChecked.text =
+      @"These two cells have exactly the same text, but one has a checkmark "
+      @"and the other does not.  They should lay out identically, and the "
+      @"presence of the checkmark should not cause the text to reflow.";
+  encryptionChecked.accessoryType = UITableViewCellAccessoryCheckmark;
+  [model addItem:encryptionChecked
+      toSectionWithIdentifier:SectionIdentifierSettings];
+
+  EncryptionItem* encryptionUnchecked =
+      [[EncryptionItem alloc] initWithType:ItemTypeEncryption];
+  encryptionUnchecked.text =
+      @"These two cells have exactly the same text, but one has a checkmark "
+      @"and the other does not.  They should lay out identically, and the "
+      @"presence of the checkmark should not cause the text to reflow.";
+  [model addItem:encryptionUnchecked
+      toSectionWithIdentifier:SectionIdentifierSettings];
+
   TableViewLinkHeaderFooterItem* linkFooter =
       [[TableViewLinkHeaderFooterItem alloc] initWithType:ItemTypeLinkFooter];
   linkFooter.text =
diff --git a/ios/chrome/browser/ui/side_swipe/BUILD.gn b/ios/chrome/browser/ui/side_swipe/BUILD.gn
index 4b102cb..240926fa 100644
--- a/ios/chrome/browser/ui/side_swipe/BUILD.gn
+++ b/ios/chrome/browser/ui/side_swipe/BUILD.gn
@@ -33,7 +33,6 @@
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/ntp",
-    "//ios/chrome/browser/ui/ntp:util",
     "//ios/chrome/browser/ui/tab_grid/grid:grid_ui",
     "//ios/chrome/browser/ui/tabs/requirements",
     "//ios/chrome/browser/ui/toolbar/public",
@@ -55,8 +54,6 @@
   deps = [
     ":side_swipe",
     "//base",
-    "//base/test:test_support",
-    "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state:test_support",
     "//ios/web/public/test",
     "//testing/gtest",
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
index 03dc118..198f035 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -31,7 +31,6 @@
 #import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
-#import "ios/web/public/navigation_item.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
 
@@ -115,11 +114,6 @@
   ios::ChromeBrowserState* browserState_;
 }
 
-// Whether to allow navigating from the leading edge.
-@property(nonatomic, assign) BOOL leadingEdgeNavigationEnabled;
-// Whether to allow navigating from the trailing edge.
-@property(nonatomic, assign) BOOL trailingEdgeNavigationEnabled;
-
 // Load grey snapshots for the next |kIpadGreySwipeTabCount| tabs in
 // |direction|.
 - (void)createGreyCache:(UISwipeGestureRecognizerDirection)direction;
@@ -225,17 +219,11 @@
 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
     shouldBeRequiredToFailByGestureRecognizer:
         (UIGestureRecognizer*)otherGestureRecognizer {
-  // Take precedence over a pan gesture recognizer so that moving up and
+  // Only take precedence over a pan gesture recognizer so that moving up and
   // down while swiping doesn't trigger overscroll actions.
   if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
     return YES;
   }
-  // Take precedence over a WKWebView side swipe gesture.
-  if ([otherGestureRecognizer
-          isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
-    return YES;
-  }
-
   return NO;
 }
 
@@ -271,16 +259,6 @@
     if (![gesture isEqual:swipeGestureRecognizer_]) {
       return NO;
     }
-
-    if (gesture.direction == UISwipeGestureRecognizerDirectionRight &&
-        !self.leadingEdgeNavigationEnabled) {
-      return NO;
-    }
-
-    if (gesture.direction == UISwipeGestureRecognizerDirectionLeft &&
-        !self.trailingEdgeNavigationEnabled) {
-      return NO;
-    }
     swipeType_ = SwipeType::CHANGE_PAGE;
     return YES;
   }
@@ -608,39 +586,6 @@
   completionHandler();
 }
 
-- (void)updateNavigationEdgeSwipeForWebState:(web::WebState*)webState {
-  // With slim nav disabled, always use SideSwipeController's edge swipe for
-  // navigation.
-  if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    self.leadingEdgeNavigationEnabled = YES;
-    self.trailingEdgeNavigationEnabled = YES;
-    return;
-  }
-
-  // With slim nav enabled, disable SideSwipeController's edge swipe for a
-  // typical navigation.  Continue to use SideSwipeController when on, before,
-  // or after a native page.
-  self.leadingEdgeNavigationEnabled = NO;
-  self.trailingEdgeNavigationEnabled = NO;
-
-  if (UseNativeSwipe(webState->GetNavigationManager()->GetVisibleItem())) {
-    self.leadingEdgeNavigationEnabled = YES;
-    self.trailingEdgeNavigationEnabled = YES;
-  }
-
-  // If the previous page is an NTP, enable leading edge swipe.
-  web::NavigationItemList backItems =
-      webState->GetNavigationManager()->GetBackwardItems();
-  if (backItems.size() > 0 && UseNativeSwipe(backItems[0]))
-    self.leadingEdgeNavigationEnabled = YES;
-
-  // If the next page is an NTP, enable trailing edge swipe.
-  web::NavigationItemList fordwardItems =
-      webState->GetNavigationManager()->GetForwardItems();
-  if (fordwardItems.size() > 0 && UseNativeSwipe(fordwardItems[0]))
-    self.trailingEdgeNavigationEnabled = YES;
-}
-
 #pragma mark - CRWWebStateObserver Methods
 
 // Checking -webStateDidStopLoading is likely incorrect, but to narrow the scope
@@ -676,12 +621,6 @@
   // the gesture recognizer.
   [swipeGestureRecognizer_ setEnabled:NO];
   [swipeGestureRecognizer_ setEnabled:YES];
-
-  [self updateNavigationEdgeSwipeForWebState:newTab.webState];
-}
-
-- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab {
-  [self updateNavigationEdgeSwipeForWebState:tab.webState];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller_unittest.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller_unittest.mm
index 3f0d12e..a98d8bfb 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller_unittest.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller_unittest.mm
@@ -2,14 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
-#include "base/test/scoped_feature_list.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
-#include "ios/chrome/browser/chrome_url_constants.h"
-#include "ios/web/public/features.h"
-#import "ios/web/public/navigation_item.h"
-#import "ios/web/public/test/fakes/test_navigation_manager.h"
-#import "ios/web/public/test/fakes/test_web_state.h"
+#import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
 #include "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
@@ -20,12 +14,6 @@
 #error "This file requires ARC support."
 #endif
 
-@interface SideSwipeController (ExposedForTesting)
-@property(nonatomic, assign) BOOL leadingEdgeNavigationEnabled;
-@property(nonatomic, assign) BOOL trailingEdgeNavigationEnabled;
-- (void)updateNavigationEdgeSwipeForWebState:(web::WebState*)webState;
-@end
-
 namespace {
 
 class SideSwipeControllerTest : public PlatformTest {
@@ -51,7 +39,6 @@
   UIView* view_;
   TabModel* tab_model_;
   SideSwipeController* side_swipe_controller_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_F(SideSwipeControllerTest, TestConstructor) {
@@ -68,46 +55,4 @@
   EXPECT_TRUE(hasRecognizer);
 }
 
-// Tests that pages that need to use Chromium native swipe
-TEST_F(SideSwipeControllerTest, TestEdgeNavigationEnabled) {
-  feature_list_.InitAndEnableFeature(web::features::kSlimNavigationManager);
-
-  auto testWebState = std::make_unique<web::TestWebState>();
-  auto testNavigationManager = std::make_unique<web::TestNavigationManager>();
-  std::unique_ptr<web::NavigationItem> item = web::NavigationItem::Create();
-  testNavigationManager->SetVisibleItem(item.get());
-  testWebState->SetNavigationManager(std::move(testNavigationManager));
-
-  // The NTP and chrome://crash should use native swipe.
-  item->SetURL(GURL(kChromeUINewTabURL));
-  [side_swipe_controller_
-      updateNavigationEdgeSwipeForWebState:testWebState.get()];
-  EXPECT_TRUE(side_swipe_controller_.leadingEdgeNavigationEnabled);
-  EXPECT_TRUE(side_swipe_controller_.trailingEdgeNavigationEnabled);
-
-  item->SetURL(GURL("chrome://crash"));
-  [side_swipe_controller_
-      updateNavigationEdgeSwipeForWebState:testWebState.get()];
-  EXPECT_TRUE(side_swipe_controller_.leadingEdgeNavigationEnabled);
-  EXPECT_TRUE(side_swipe_controller_.trailingEdgeNavigationEnabled);
-
-  item->SetURL(GURL("http://wwww.test.com"));
-  [side_swipe_controller_
-      updateNavigationEdgeSwipeForWebState:testWebState.get()];
-  EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
-  EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
-
-  item->SetURL(GURL("chrome://foo"));
-  [side_swipe_controller_
-      updateNavigationEdgeSwipeForWebState:testWebState.get()];
-  EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
-  EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
-
-  item->SetURL(GURL("chrome://version"));
-  [side_swipe_controller_
-      updateNavigationEdgeSwipeForWebState:testWebState.get()];
-  EXPECT_FALSE(side_swipe_controller_.leadingEdgeNavigationEnabled);
-  EXPECT_FALSE(side_swipe_controller_.trailingEdgeNavigationEnabled);
-}
-
 }  // anonymous namespace
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_util.h b/ios/chrome/browser/ui/side_swipe/side_swipe_util.h
index 715c145..27f28ac 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_util.h
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_util.h
@@ -7,18 +7,10 @@
 
 #import <UIKit/UIKit.h>
 
-namespace web {
-class NavigationItem;
-}
-
 // If swiping to the right (or left in RTL).
 BOOL IsSwipingBack(UISwipeGestureRecognizerDirection direction);
 
 // If swiping to the left (or right in RTL).
 BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction);
 
-// Returns |YES| if the item should use Chromium native swipe.  This is true for
-// the NTP and chrome://crash.
-BOOL UseNativeSwipe(web::NavigationItem* item);
-
 #endif  // IOS_CHROME_BROWSER_UI_SIDE_SWIPE_SIDE_SWIPE_UTIL_H_
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_util.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_util.mm
index bdcd3faf..9b0e44c 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_util.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_util.mm
@@ -6,11 +6,7 @@
 
 #import <UIKit/UIKit.h>
 
-#include "ios/chrome/browser/chrome_url_constants.h"
-#import "ios/chrome/browser/chrome_url_util.h"
-#import "ios/chrome/browser/ui/ntp/ntp_util.h"
 #include "ios/chrome/browser/ui/util/rtl_geometry.h"
-#import "ios/web/public/navigation_item.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -29,14 +25,3 @@
   else
     return direction == UISwipeGestureRecognizerDirectionLeft;
 }
-
-BOOL UseNativeSwipe(web::NavigationItem* item) {
-  if (IsURLNewTabPage(item->GetVirtualURL()))
-    return YES;
-
-  GURL url(item->GetURL());
-  if (UrlHasChromeScheme(url) && url.host_piece() == kChromeUICrashHost)
-    return YES;
-
-  return NO;
-}
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h
index 3241ab1..63311426 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h
@@ -38,6 +38,9 @@
 // Hex Value for light gray label text color.
 extern const int kTableViewTextLabelColorLightGrey;
 
+// Hex Value for blue label text color.
+extern const int kTableViewTextLabelColorBlue;
+
 // Hex Value for the text color of the secondary labels (e.g. details, URL,
 // metadata...).
 extern const int kTableViewSecondaryLabelLightGrayTextColor;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm
index 2b89608..fca15ab 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.mm
@@ -36,6 +36,7 @@
   header.textLabel.text = self.text;
   header.subtitleLabel.text = self.subtitleText;
   header.accessibilityLabel = self.text;
+  header.isAccessibilityElement = YES;
   if (styler.cellHighlightColor)
     header.highlightColor = styler.cellHighlightColor;
 }
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
index 3ca1871..d0e7537 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
@@ -8,6 +8,8 @@
 #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ui/base/l10n/l10n_util_mac.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -35,13 +37,26 @@
   [super configureCell:tableCell withStyler:styler];
   TableViewTextCell* cell =
       base::mac::ObjCCastStrict<TableViewTextCell>(tableCell);
-  cell.textLabel.text = self.masked ? kMaskedPassword : self.text;
+  // TODO(crbug.com/894791): set isAccessibilityElement = YES in TableViewItem.
+  cell.isAccessibilityElement = YES;
+
+  if (self.masked) {
+    cell.textLabel.text = kMaskedPassword;
+    cell.accessibilityLabel =
+        l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDDEN_LABEL);
+  } else {
+    cell.textLabel.text = self.text;
+    cell.accessibilityLabel =
+        self.accessibilityLabel ? self.accessibilityLabel : self.text;
+  }
+
   // Decide cell.textLabel.backgroundColor in order:
   //   1. styler.cellBackgroundColor;
   //   2. styler.tableViewBackgroundColor.
   cell.textLabel.backgroundColor = styler.cellBackgroundColor
                                        ? styler.cellBackgroundColor
                                        : styler.tableViewBackgroundColor;
+
   // Decide cell.textLabel.textColor in order:
   //   1. this.textColor;
   //   2. styler.cellTitleColor;
@@ -76,6 +91,7 @@
     _textLabel.numberOfLines = 0;
     _textLabel.lineBreakMode = NSLineBreakByWordWrapping;
     _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
+    _textLabel.isAccessibilityElement = NO;
 
     // Add subviews to View Hierarchy.
     [self.contentView addSubview:_textLabel];
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm
index 3c88a96..bc05219 100644
--- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm
+++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm
@@ -69,8 +69,8 @@
 
 id ChromeTableViewControllerTest::GetTableViewItem(int section, int item) {
   TableViewModel* model = [controller_ tableViewModel];
-  NSIndexPath* index_path =
-      [NSIndexPath indexPathForItem:item inSection:section];
+  NSIndexPath* index_path = [NSIndexPath indexPathForItem:item
+                                                inSection:section];
   TableViewItem* collection_view_item = [model hasItemAtIndexPath:index_path]
                                             ? [model itemAtIndexPath:index_path]
                                             : nil;
@@ -114,14 +114,15 @@
   CheckSectionFooter(l10n_util::GetNSString(expected_text_id), section);
 }
 
+// TODO(crbug.com/894791): There are some unittests that are using
+// CheckTextCellText to check Item with both "text" and "detailText". Change all
+// of them to CheckTextCellTextAndDetailText when the migration is finished.
 void ChromeTableViewControllerTest::CheckTextCellText(NSString* expected_text,
                                                       int section,
                                                       int item) {
   id cell = GetTableViewItem(section, item);
   ASSERT_TRUE([cell respondsToSelector:@selector(text)]);
-  ASSERT_TRUE([cell respondsToSelector:@selector(detailText)]);
   EXPECT_NSEQ(expected_text, [cell text]);
-  EXPECT_FALSE([cell detailText]);
 }
 
 void ChromeTableViewControllerTest::CheckTextCellTextWithId(
@@ -190,8 +191,8 @@
     int section,
     int item,
     ProceduralBlock completion_block) {
-  NSIndexPath* index_path =
-      [NSIndexPath indexPathForItem:item inSection:section];
+  NSIndexPath* index_path = [NSIndexPath indexPathForItem:item
+                                                inSection:section];
   __weak ChromeTableViewController* weak_controller = controller_;
   void (^batch_updates)() = ^{
     ChromeTableViewController* strong_controller = weak_controller;
diff --git a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
index 8f02bbd..536c402a 100644
--- a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
+++ b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -8,6 +8,7 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/unified_consent/feature.h"
+#include "components/unified_consent/unified_consent_metrics.h"
 #include "components/unified_consent/unified_consent_service.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
@@ -62,6 +63,10 @@
   syncer::SyncService* sync_service =
       ProfileSyncServiceFactory::GetForBrowserState(browser_state);
 
+  // Record settings for pre- and post-UnifiedConsent users.
+  unified_consent::metrics::RecordSettingsHistogram(service_client.get(),
+                                                    user_pref_service);
+
   if (!unified_consent::IsUnifiedConsentFeatureEnabled()) {
     unified_consent::UnifiedConsentService::RollbackIfNeeded(
         user_pref_service, sync_service, service_client.get());
diff --git a/ios/chrome/test/app/password_test_util.mm b/ios/chrome/test/app/password_test_util.mm
index bea449b..af7d1c99 100644
--- a/ios/chrome/test/app/password_test_util.mm
+++ b/ios/chrome/test/app/password_test_util.mm
@@ -5,7 +5,7 @@
 #include "ios/chrome/test/app/password_test_util.h"
 
 #include "base/mac/foundation_util.h"
-#import "ios/chrome/browser/ui/settings/password_details_collection_view_controller_for_testing.h"
+#import "ios/chrome/browser/ui/settings/password_details_table_view_controller+testing.h"
 #import "ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #import "ios/chrome/browser/ui/util/top_view_controller.h"
@@ -52,11 +52,10 @@
   SettingsNavigationController* settings_navigation_controller =
       base::mac::ObjCCastStrict<SettingsNavigationController>(
           top_view_controller::TopPresentedViewController());
-  PasswordDetailsCollectionViewController*
-      password_details_collection_view_controller =
-          base::mac::ObjCCastStrict<PasswordDetailsCollectionViewController>(
-              settings_navigation_controller.topViewController);
-  [password_details_collection_view_controller
+  PasswordDetailsTableViewController* password_details_table_view_controller =
+      base::mac::ObjCCastStrict<PasswordDetailsTableViewController>(
+          settings_navigation_controller.topViewController);
+  [password_details_table_view_controller
       setReauthenticationModule:mock_reauthentication_module];
   return mock_reauthentication_module;
 }
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm
index 2f3904f..985d11f 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -30,7 +30,7 @@
 #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data_ui_constants.h"
-#import "ios/chrome/browser/ui/settings/import_data_collection_view_controller.h"
+#import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync_settings_collection_view_controller.h"
 #import "ios/chrome/browser/ui/static_content/static_html_view_controller.h"
diff --git a/ios/web/public/test/fakes/test_navigation_manager.mm b/ios/web/public/test/fakes/test_navigation_manager.mm
index cecff9c..1f3485c 100644
--- a/ios/web/public/test/fakes/test_navigation_manager.mm
+++ b/ios/web/public/test/fakes/test_navigation_manager.mm
@@ -154,10 +154,12 @@
 }
 
 NavigationItemList TestNavigationManager::GetBackwardItems() const {
+  NOTREACHED();
   return NavigationItemList();
 }
 
 NavigationItemList TestNavigationManager::GetForwardItems() const {
+  NOTREACHED();
   return NavigationItemList();
 }
 
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 3c1e05c..0cbf1daa 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -954,10 +954,6 @@
   if (self) {
     _webStateImpl = webState;
     _webUsageEnabled = YES;
-
-    if (web::GetWebClient()->IsSlimNavigationManagerEnabled())
-      _allowsBackForwardNavigationGestures = YES;
-
     DCHECK(_webStateImpl);
     // Load phase when no WebView present is 'loaded' because this represents
     // the idle state.
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index bfd994b..d7c6f5c 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -212,7 +212,7 @@
                        context:nullptr];
     [[result stub] removeObserver:web_controller() forKeyPath:OCMOCK_ANY];
     [[result stub] evaluateJavaScript:OCMOCK_ANY completionHandler:OCMOCK_ANY];
-    [[result stub] setAllowsBackForwardNavigationGestures:YES];
+    // CRWWebController sets this property to NO by default.
     [[result stub] setAllowsBackForwardNavigationGestures:NO];
 
     return result;
@@ -310,18 +310,13 @@
   EXPECT_FALSE(observer.did_finish_navigation_info());
 }
 
-// Tests allowsBackForwardNavigationGestures default value and negating this
-// property.
+// Tests allowsBackForwardNavigationGestures default value and setting this
+// property to YES.
 TEST_P(CRWWebControllerTest, SetAllowsBackForwardNavigationGestures) {
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
-    web_controller().allowsBackForwardNavigationGestures = NO;
-    EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
-  } else {
-    EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
-    web_controller().allowsBackForwardNavigationGestures = YES;
-    EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
-  }
+  OCMExpect([mock_web_view_ setAllowsBackForwardNavigationGestures:YES]);
+  EXPECT_FALSE(web_controller().allowsBackForwardNavigationGestures);
+  web_controller().allowsBackForwardNavigationGestures = YES;
+  EXPECT_TRUE(web_controller().allowsBackForwardNavigationGestures);
 }
 
 INSTANTIATE_TEST_CASES(CRWWebControllerTest);
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.h b/ios/web_view/internal/signin/ios_web_view_signin_client.h
index 7c8caac..7d3e63c7 100644
--- a/ios/web_view/internal/signin/ios_web_view_signin_client.h
+++ b/ios/web_view/internal/signin/ios_web_view_signin_client.h
@@ -54,7 +54,6 @@
       gaia::GaiaSource source,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
       override;
-  void OnSignedOut() override;
 
   // CWVSyncController setter/getter.
   void SetSyncController(CWVSyncController* sync_controller);
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
index 47b2173..6c4200d 100644
--- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm
+++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -36,8 +36,6 @@
   network_callback_helper_.reset();
 }
 
-void IOSWebViewSigninClient::OnSignedOut() {}
-
 std::string IOSWebViewSigninClient::GetProductVersion() {
   // TODO(crbug.com/768689): Implement this method with appropriate values.
   return "";
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 1ecb3f2..9cf68b3 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -599,8 +599,10 @@
   // Copy all metadata to the wrapped frame.
   wrapping_frame->metadata()->MergeMetadataFrom(frame->metadata());
 
-  for (size_t i = 0; i < NumPlanes(format); ++i) {
-    wrapping_frame->data_[i] = frame->data(i);
+  if (frame->IsMappable()) {
+    for (size_t i = 0; i < NumPlanes(format); ++i) {
+      wrapping_frame->data_[i] = frame->data(i);
+    }
   }
 
 #if defined(OS_LINUX)
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index fbf3c8b..38352803 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -357,6 +357,7 @@
     "//base",
     "//media",
     "//ui/gfx:buffer_types",
+    "//ui/gfx:memory_buffer",
     "//ui/gfx/geometry",
   ]
 }
diff --git a/media/gpu/format_utils.cc b/media/gpu/format_utils.cc
index 72d5d626..fc4029e 100644
--- a/media/gpu/format_utils.cc
+++ b/media/gpu/format_utils.cc
@@ -4,6 +4,7 @@
 
 #include "media/gpu/format_utils.h"
 #include "base/logging.h"
+#include "ui/gfx/buffer_format_util.h"
 
 namespace media {
 
@@ -30,7 +31,8 @@
       return PIXEL_FORMAT_NV12;
 
     default:
-      LOG(FATAL) << "Add more cases as needed";
+      LOG(FATAL) << "Unsupported BufferFormat: "
+                 << gfx::BufferFormatToString(format);
       return PIXEL_FORMAT_UNKNOWN;
   }
 }
@@ -51,7 +53,7 @@
       return gfx::BufferFormat::YUV_420_BIPLANAR;
 
     default:
-      LOG(FATAL) << "Add more cases as needed";
+      LOG(FATAL) << "Unsupported VideoPixelFormat: " << pixel_format;
       return gfx::BufferFormat::BGRX_8888;
   }
 }
diff --git a/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
index 0467727..e12f045c 100644
--- a/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_decode_accelerator.cc
@@ -453,13 +453,13 @@
                            parse_result.frame_header.coded_height);
   if (new_coded_size != coded_size_ || va_surface_id_ == VA_INVALID_SURFACE ||
       picture_va_rt_format != va_rt_format_) {
-    vaapi_wrapper_->DestroySurfaces();
+    vaapi_wrapper_->DestroyContextAndSurfaces();
     va_surface_id_ = VA_INVALID_SURFACE;
     va_rt_format_ = picture_va_rt_format;
 
     std::vector<VASurfaceID> va_surfaces;
-    if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1,
-                                        &va_surfaces)) {
+    if (!vaapi_wrapper_->CreateContextAndSurfaces(va_rt_format_, new_coded_size,
+                                                  1, &va_surfaces)) {
       VLOGF(1) << "Create VA surface failed";
       NotifyError(bitstream_buffer_id, PLATFORM_FAILURE);
       return;
diff --git a/media/gpu/vaapi/vaapi_jpeg_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_jpeg_decode_accelerator_unittest.cc
index 17311a9..a65b7a70 100644
--- a/media/gpu/vaapi/vaapi_jpeg_decode_accelerator_unittest.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_decode_accelerator_unittest.cc
@@ -145,8 +145,10 @@
   }
 
   std::vector<VASurfaceID> va_surfaces;
-  if (!wrapper_->CreateSurfaces(va_surface_format, size, 1, &va_surfaces))
+  if (!wrapper_->CreateContextAndSurfaces(va_surface_format, size, 1,
+                                          &va_surfaces)) {
     return false;
+  }
 
   EXPECT_EQ(va_surfaces.size(), 1u);
   if (va_surfaces.size() == 0 ||
@@ -201,8 +203,8 @@
                  parse_result.frame_header.coded_height);
 
   std::vector<VASurfaceID> va_surfaces;
-  ASSERT_TRUE(
-      wrapper_->CreateSurfaces(GetVASurfaceFormat(), size, 1, &va_surfaces));
+  ASSERT_TRUE(wrapper_->CreateContextAndSurfaces(GetVASurfaceFormat(), size, 1,
+                                                 &va_surfaces));
 
   EXPECT_FALSE(Decode(wrapper_.get(), parse_result, va_surfaces[0]));
 }
@@ -211,8 +213,8 @@
 TEST_F(VaapiJpegDecodeAcceleratorTest, ScopedVAImage) {
   std::vector<VASurfaceID> va_surfaces;
   const gfx::Size coded_size(64, 64);
-  ASSERT_TRUE(wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, coded_size, 1,
-                                       &va_surfaces));
+  ASSERT_TRUE(wrapper_->CreateContextAndSurfaces(VA_RT_FORMAT_YUV420,
+                                                 coded_size, 1, &va_surfaces));
   ASSERT_EQ(va_surfaces.size(), 1u);
 
   std::unique_ptr<ScopedVAImage> scoped_image;
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
index 75b9577..7b1794f 100644
--- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -117,13 +117,13 @@
 
   // Recreate VASurface if the video frame's size changed.
   if (input_size != surface_size_ || va_surface_id_ == VA_INVALID_SURFACE) {
-    vaapi_wrapper_->DestroySurfaces();
+    vaapi_wrapper_->DestroyContextAndSurfaces();
     va_surface_id_ = VA_INVALID_SURFACE;
     surface_size_ = gfx::Size();
 
     std::vector<VASurfaceID> va_surfaces;
-    if (!vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420, input_size, 1,
-                                        &va_surfaces)) {
+    if (!vaapi_wrapper_->CreateContextAndSurfaces(
+            VA_RT_FORMAT_YUV420, input_size, 1, &va_surfaces)) {
       VLOGF(1) << "Failed to create VA surface";
       notify_error_cb_.Run(buffer_id, PLATFORM_FAILURE);
       return;
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
index 9e06015..d4f7c07d 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -530,7 +530,7 @@
   // All surfaces released, destroy them and dismiss all PictureBuffers.
   awaiting_va_surfaces_recycle_ = false;
   available_va_surfaces_.clear();
-  vaapi_wrapper_->DestroySurfaces();
+  vaapi_wrapper_->DestroyContextAndSurfaces();
 
   for (auto iter = pictures_.begin(); iter != pictures_.end(); ++iter) {
     VLOGF(2) << "Dismissing picture id: " << iter->first;
@@ -644,8 +644,8 @@
   } else {
     va_surface_ids.clear();
     RETURN_AND_NOTIFY_ON_FAILURE(
-        vaapi_wrapper_->CreateSurfaces(va_format, requested_pic_size_,
-                                       buffers.size(), &va_surface_ids),
+        vaapi_wrapper_->CreateContextAndSurfaces(
+            va_format, requested_pic_size_, buffers.size(), &va_surface_ids),
         "Failed creating VA Surfaces", PLATFORM_FAILURE, );
   }
   DCHECK_EQ(va_surface_ids.size(), buffers.size());
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
index 2d4821e..0a2311dd 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -64,9 +64,9 @@
  public:
   MockVaapiWrapper() = default;
   MOCK_METHOD4(
-      CreateSurfaces,
+      CreateContextAndSurfaces,
       bool(unsigned int, const gfx::Size&, size_t, std::vector<VASurfaceID>*));
-  MOCK_METHOD0(DestroySurfaces, void());
+  MOCK_METHOD0(DestroyContextAndSurfaces, void());
 
  private:
   ~MockVaapiWrapper() override = default;
@@ -205,7 +205,7 @@
     EXPECT_CALL(*mock_decoder_, GetRequiredNumOfPictures())
         .WillOnce(Return(num_pictures));
     EXPECT_CALL(*mock_decoder_, GetPicSize()).WillOnce(Return(picture_size));
-    EXPECT_CALL(*mock_vaapi_wrapper_, DestroySurfaces());
+    EXPECT_CALL(*mock_vaapi_wrapper_, DestroyContextAndSurfaces());
 
     if (expect_dismiss_picture_buffers) {
       EXPECT_CALL(*this, DismissPictureBuffer(_))
@@ -238,13 +238,13 @@
     base::Closure quit_closure = run_loop.QuitClosure();
 
     EXPECT_CALL(*mock_vaapi_wrapper_,
-                CreateSurfaces(_, picture_size, num_pictures, _))
-        .WillOnce(DoAll(
-            WithArg<3>(Invoke(
-                [num_pictures](std::vector<VASurfaceID>* va_surface_ids) {
-                  va_surface_ids->resize(num_pictures);
-                })),
-            Return(true)));
+                CreateContextAndSurfaces(_, picture_size, num_pictures, _))
+        .WillOnce(
+            DoAll(WithArg<3>(Invoke(
+                      [num_pictures](std::vector<VASurfaceID>* va_surface_ids) {
+                        va_surface_ids->resize(num_pictures);
+                      })),
+                  Return(true)));
     EXPECT_CALL(*mock_vaapi_picture_factory_,
                 MockCreateVaapiPicture(mock_vaapi_wrapper_.get(), picture_size))
         .Times(num_pictures);
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index 7389e67..284736f 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -345,7 +345,7 @@
       kNumSurfacesForOutputPicture +
       (native_input_mode_ ? 0 : kNumSurfacesPerInputVideoFrame);
 
-  if (!vaapi_wrapper_->CreateSurfaces(
+  if (!vaapi_wrapper_->CreateContextAndSurfaces(
           VA_RT_FORMAT_YUV420, coded_size_,
           (num_frames_in_flight + 1) * va_surfaces_per_video_frame_,
           &available_va_surface_ids_)) {
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index 00d46da..b4156423 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -892,29 +892,32 @@
   return VASupportedImageFormats::Get().IsImageFormatSupported(format);
 }
 
-bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
-                                  const gfx::Size& size,
-                                  size_t num_surfaces,
-                                  std::vector<VASurfaceID>* va_surfaces) {
-  base::AutoLock auto_lock(*va_lock_);
-  DVLOG(2) << "Creating " << num_surfaces << " surfaces";
-  DCHECK(va_surfaces->empty());
+bool VaapiWrapper::CreateContextAndSurfaces(
+    unsigned int va_format,
+    const gfx::Size& size,
+    size_t num_surfaces,
+    std::vector<VASurfaceID>* va_surfaces) {
+  {
+    base::AutoLock auto_lock(*va_lock_);
+    DVLOG(2) << "Creating " << num_surfaces << " surfaces";
+    DCHECK(va_surfaces->empty());
 
-  if (!va_surface_ids_.empty() || va_surface_format_ != 0u) {
-    LOG(ERROR) << "Surfaces should be destroyed before creating new surfaces";
-    return false;
-  }
+    if (!va_surface_ids_.empty() || va_surface_format_ != 0u) {
+      LOG(ERROR) << "Surfaces should be destroyed before creating new surfaces";
+      return false;
+    }
 
-  // Allocate surfaces in driver.
-  va_surface_ids_.resize(num_surfaces);
-  VAStatus va_res =
-      vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
-                       &va_surface_ids_[0], va_surface_ids_.size(), NULL, 0);
+    // Allocate surfaces in driver.
+    va_surface_ids_.resize(num_surfaces);
+    VAStatus va_res =
+        vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
+                         &va_surface_ids_[0], va_surface_ids_.size(), NULL, 0);
 
-  VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed");
-  if (va_res != VA_STATUS_SUCCESS) {
-    va_surface_ids_.clear();
-    return false;
+    VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed");
+    if (va_res != VA_STATUS_SUCCESS) {
+      va_surface_ids_.clear();
+      return false;
+    }
   }
 
   // And create a context associated with them.
@@ -922,12 +925,15 @@
   if (success)
     *va_surfaces = va_surface_ids_;
   else
-    DestroySurfaces_Locked();
+    DestroyContextAndSurfaces();
+
   return success;
 }
 
 bool VaapiWrapper::CreateContext(unsigned int va_format,
                                  const gfx::Size& size) {
+  base::AutoLock auto_lock(*va_lock_);
+
   // vaCreateContext() doesn't really need an array of VASurfaceIDs (see
   // https://lists.01.org/pipermail/intel-vaapi-media/2017-July/000052.html and
   // https://github.com/intel/libva/issues/251); pass a dummy list of valid
@@ -945,11 +951,24 @@
   return va_res == VA_STATUS_SUCCESS;
 }
 
-void VaapiWrapper::DestroySurfaces() {
+void VaapiWrapper::DestroyContextAndSurfaces() {
   base::AutoLock auto_lock(*va_lock_);
   DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces";
 
-  DestroySurfaces_Locked();
+  if (va_context_id_ != VA_INVALID_ID) {
+    VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
+    VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
+  }
+
+  if (!va_surface_ids_.empty()) {
+    VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
+                                        va_surface_ids_.size());
+    VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
+  }
+
+  va_surface_ids_.clear();
+  va_context_id_ = VA_INVALID_ID;
+  va_surface_format_ = 0;
 }
 
 scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
@@ -1398,7 +1417,7 @@
 VaapiWrapper::~VaapiWrapper() {
   DestroyPendingBuffers();
   DestroyCodedBuffers();
-  DestroySurfaces();
+  DestroyContextAndSurfaces();
   DeinitializeVpp();
   Deinitialize();
 }
@@ -1447,25 +1466,6 @@
   return true;
 }
 
-void VaapiWrapper::DestroySurfaces_Locked() {
-  va_lock_->AssertAcquired();
-
-  if (va_context_id_ != VA_INVALID_ID) {
-    VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
-    VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
-  }
-
-  if (!va_surface_ids_.empty()) {
-    VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
-                                        va_surface_ids_.size());
-    VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
-  }
-
-  va_surface_ids_.clear();
-  va_context_id_ = VA_INVALID_ID;
-  va_surface_format_ = 0;
-}
-
 void VaapiWrapper::DestroySurface(VASurfaceID va_surface_id) {
   base::AutoLock auto_lock(*va_lock_);
 
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h
index a6eebd12..dc1fdef 100644
--- a/media/gpu/vaapi/vaapi_wrapper.h
+++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -53,6 +53,7 @@
 // It is also responsible for managing and freeing VABuffers (not VASurfaces),
 // which are used to queue parameters and slice data to the HW codec,
 // as well as underlying memory for VASurfaces themselves.
+// TODO(crbug.com/909547): Use GUARDED_BY in VaapiWrapper.
 class MEDIA_GPU_EXPORT VaapiWrapper
     : public base::RefCountedThreadSafe<VaapiWrapper> {
  public:
@@ -95,27 +96,29 @@
   static bool IsImageFormatSupported(const VAImageFormat& format);
 
   // Creates |num_surfaces| backing surfaces in driver for VASurfaces of
-  // |va_format|, each of size |size|. Returns true when successful, with the
-  // created IDs in |va_surfaces| to be managed and later wrapped in
-  // VASurfaces.
-  // The client must DestroySurfaces() each time before calling this method
-  // again to free the allocated surfaces first, but is not required to do so
-  // at destruction time, as this will be done automatically from
-  // the destructor.
-  virtual bool CreateSurfaces(unsigned int va_format,
-                              const gfx::Size& size,
-                              size_t num_surfaces,
-                              std::vector<VASurfaceID>* va_surfaces);
-
-  // Creates a VA Context associated with |format| and |size|.
+  // |va_format|, each of size |size| and initializes |va_context_id_| with
+  // |format| and |size|. Returns true when successful, with the created IDs in
+  // |va_surfaces| to be managed and later wrapped in VASurfaces. The client
+  // must DestroyContextAndSurfaces() each time before calling this method again
+  // to free the allocated surfaces first, but is not required to do so at
+  // destruction time, as this will be done automatically from the destructor.
+  virtual bool CreateContextAndSurfaces(unsigned int va_format,
+                                        const gfx::Size& size,
+                                        size_t num_surfaces,
+                                        std::vector<VASurfaceID>* va_surfaces);
+  // Creates a VA Context associated with |format| and |size|, and sets
+  // |va_context_id_|. The |va_context_id_| will be destroyed by
+  // DestroyContextAndSurfaces().
   bool CreateContext(unsigned int va_format, const gfx::Size& size);
 
-  // Frees all memory allocated in CreateSurfaces.
-  virtual void DestroySurfaces();
+  // Frees all memory allocated in CreateContextAndSurfaces() and destroys
+  // |va_context_id_|.
+  virtual void DestroyContextAndSurfaces();
 
   // Create a VASurface for |pixmap|. The ownership of the surface is
   // transferred to the caller. It differs from surfaces created using
-  // CreateSurfaces(), where VaapiWrapper is the owner of the surfaces.
+  // CreateContextAndSurfaces(), where VaapiWrapper is the owner of the
+  // surfaces.
   scoped_refptr<VASurface> CreateVASurfaceForPixmap(
       const scoped_refptr<gfx::NativePixmap>& pixmap);
 
@@ -225,9 +228,6 @@
   void Deinitialize();
   bool VaInitialize(const base::Closure& report_error_to_uma_cb);
 
-  // Free all memory allocated in CreateSurfaces.
-  void DestroySurfaces_Locked();
-
   // Destroys a |va_surface_id|.
   void DestroySurface(VASurfaceID va_surface_id);
 
@@ -260,8 +260,8 @@
   // All valid after successful Initialize() and until Deinitialize().
   VADisplay va_display_;
   VAConfigID va_config_id_;
-  // Created for the current set of va_surface_ids_ in CreateSurfaces() and
-  // valid until DestroySurfaces().
+  // Created in CreateContext() or CreateContextAndSurfaces() and valid until
+  // DestroyContextAndSurfaces().
   VAContextID va_context_id_;
 
   // Data queued up for HW codec, to be committed on next execution.
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc
index 6889c19..5641304c 100644
--- a/net/dns/host_cache.cc
+++ b/net/dns/host_cache.cc
@@ -6,16 +6,15 @@
 
 #include <algorithm>
 
+#include "base/bind.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/default_tick_clock.h"
 #include "base/trace_event/trace_event.h"
-#include "base/values.h"
 #include "net/base/net_errors.h"
 #include "net/base/trace_constants.h"
-#include "net/dns/dns_util.h"
 #include "net/dns/host_resolver.h"
 #include "net/log/net_log.h"
 
@@ -67,6 +66,16 @@
   return true;
 }
 
+template <typename T>
+void MergeLists(base::Optional<T>* target, const base::Optional<T>& source) {
+  if (target->has_value() && source) {
+    target->value().insert(target->value().end(), source.value().begin(),
+                           source.value().end());
+  } else if (source) {
+    *target = source;
+  }
+}
+
 }  // namespace
 
 // Used in histograms; do not modify existing values.
@@ -114,9 +123,78 @@
 HostCache::Key::Key()
     : Key("", DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY) {}
 
+HostCache::Entry::Entry(int error, Source source, base::TimeDelta ttl)
+    : error_(error), source_(source), ttl_(ttl) {
+  DCHECK_GE(ttl_, base::TimeDelta());
+  DCHECK_NE(OK, error_);
+}
+
+HostCache::Entry::Entry(int error, Source source)
+    : error_(error), source_(source), ttl_(base::TimeDelta::FromSeconds(-1)) {
+  DCHECK_NE(OK, error_);
+}
+
+HostCache::Entry::Entry(const Entry& entry) = default;
+
+HostCache::Entry::Entry(Entry&& entry) = default;
+
 HostCache::Entry::~Entry() = default;
 
-HostCache::Entry::Entry(HostCache::Entry&& entry) = default;
+base::Optional<base::TimeDelta> HostCache::Entry::GetOptionalTtl() const {
+  if (has_ttl())
+    return ttl();
+  else
+    return base::nullopt;
+}
+
+// static
+HostCache::Entry HostCache::Entry::MergeEntries(Entry front, Entry back) {
+  // Only expected to merge OK or ERR_NAME_NOT_RESOLVED results.
+  DCHECK(front.error() == OK || front.error() == ERR_NAME_NOT_RESOLVED);
+  DCHECK(back.error() == OK || back.error() == ERR_NAME_NOT_RESOLVED);
+
+  // Build results in |front| to preserve unmerged fields.
+
+  front.error_ =
+      front.error() == OK || back.error() == OK ? OK : ERR_NAME_NOT_RESOLVED;
+
+  MergeLists(&front.addresses_, back.addresses());
+  MergeLists(&front.text_records_, back.text_records());
+  MergeLists(&front.hostnames_, back.hostnames());
+
+  // Use canonical name from |back| iff empty in |front|.
+  if (front.addresses() && front.addresses().value().canonical_name().empty() &&
+      back.addresses()) {
+    front.addresses_.value().set_canonical_name(
+        back.addresses().value().canonical_name());
+  }
+
+  // Only expected to merge entries from same source.
+  DCHECK_EQ(front.source(), back.source());
+
+  if (front.has_ttl() && back.has_ttl()) {
+    front.ttl_ = std::min(front.ttl(), back.ttl());
+  } else if (back.has_ttl()) {
+    front.ttl_ = back.ttl();
+  }
+
+  front.expires_ = std::min(front.expires(), back.expires());
+  front.network_changes_ =
+      std::max(front.network_changes(), back.network_changes());
+  front.total_hits_ = front.total_hits() + back.total_hits();
+  front.stale_hits_ = front.stale_hits() + back.stale_hits();
+
+  return front;
+}
+
+NetLogParametersCallback HostCache::Entry::CreateNetLogCallback() const {
+  return base::BindRepeating(&HostCache::Entry::NetLogCallback,
+                             base::Unretained(this));
+}
+
+HostCache::Entry& HostCache::Entry::operator=(const Entry& entry) = default;
+
+HostCache::Entry& HostCache::Entry::operator=(Entry&& entry) = default;
 
 HostCache::Entry::Entry(const HostCache::Entry& entry,
                         base::TimeTicks now,
@@ -174,6 +252,69 @@
   out->stale_hits = stale_hits_;
 }
 
+std::unique_ptr<base::Value> HostCache::Entry::NetLogCallback(
+    NetLogCaptureMode capture_mode) const {
+  return std::make_unique<base::Value>(
+      GetAsValue(false /* include_staleness */));
+}
+
+base::DictionaryValue HostCache::Entry::GetAsValue(
+    bool include_staleness) const {
+  base::DictionaryValue entry_dict;
+
+  if (include_staleness) {
+    // The kExpirationKey value is using TimeTicks instead of Time used if
+    // |include_staleness| is false, so it cannot be used to deserialize.
+    // This is ok as it is used only for netlog.
+    entry_dict.SetString(kExpirationKey, NetLog::TickCountToString(expires()));
+    entry_dict.SetInteger(kTtlKey, ttl().InMilliseconds());
+    entry_dict.SetInteger(kNetworkChangesKey, network_changes());
+  } else {
+    // Convert expiration time in TimeTicks to Time for serialization, using a
+    // string because base::Value doesn't handle 64-bit integers.
+    base::Time expiration_time =
+        base::Time::Now() - (base::TimeTicks::Now() - expires());
+    entry_dict.SetString(
+        kExpirationKey, base::Int64ToString(expiration_time.ToInternalValue()));
+  }
+
+  if (error() != OK) {
+    entry_dict.SetInteger(kErrorKey, error());
+  } else {
+    if (addresses()) {
+      // Append all of the resolved addresses.
+      base::ListValue addresses_value;
+      for (const IPEndPoint& address : addresses().value()) {
+        addresses_value.GetList().emplace_back(address.ToStringWithoutPort());
+      }
+      entry_dict.SetKey(kAddressesKey, std::move(addresses_value));
+    }
+
+    if (text_records()) {
+      // Append all resolved text records.
+      base::ListValue text_list_value;
+      for (const std::string& text_record : text_records().value()) {
+        text_list_value.GetList().emplace_back(text_record);
+      }
+      entry_dict.SetKey(kTextRecordsKey, std::move(text_list_value));
+    }
+
+    if (hostnames()) {
+      // Append all the resolved hostnames.
+      base::ListValue hostnames_value;
+      base::ListValue host_ports_value;
+      for (const HostPortPair& hostname : hostnames().value()) {
+        hostnames_value.GetList().emplace_back(hostname.host());
+        host_ports_value.GetList().emplace_back(hostname.port());
+      }
+      entry_dict.SetKey(kHostnameResultsKey, std::move(hostnames_value));
+      entry_dict.SetKey(kHostPortsKey, std::move(host_ports_value));
+    }
+  }
+
+  return entry_dict;
+}
+
 HostCache::HostCache(size_t max_entries)
     : max_entries_(max_entries),
       network_changes_(0),
@@ -368,8 +509,8 @@
     const Key& key = pair.first;
     const Entry& entry = pair.second;
 
-    std::unique_ptr<base::DictionaryValue> entry_dict(
-        new base::DictionaryValue());
+    auto entry_dict = std::make_unique<base::DictionaryValue>(
+        entry.GetAsValue(include_staleness));
 
     entry_dict->SetString(kHostnameKey, key.hostname);
     entry_dict->SetInteger(kDnsQueryTypeKey,
@@ -378,58 +519,6 @@
     entry_dict->SetInteger(kHostResolverSourceKey,
                            static_cast<int>(key.host_resolver_source));
 
-    if (include_staleness) {
-      // The kExpirationKey value is using TimeTicks instead of Time used if
-      // |include_staleness| is false, so it cannot be used to deserialize.
-      // This is ok as it is used only for netlog.
-      entry_dict->SetString(kExpirationKey,
-                            NetLog::TickCountToString(entry.expires()));
-      entry_dict->SetInteger(kTtlKey, entry.ttl().InMilliseconds());
-      entry_dict->SetInteger(kNetworkChangesKey, entry.network_changes());
-    } else {
-      // Convert expiration time in TimeTicks to Time for serialization, using a
-      // string because base::Value doesn't handle 64-bit integers.
-      base::Time expiration_time =
-          base::Time::Now() - (tick_clock_->NowTicks() - entry.expires());
-      entry_dict->SetString(
-          kExpirationKey,
-          base::Int64ToString(expiration_time.ToInternalValue()));
-    }
-
-    if (entry.error() != OK) {
-      entry_dict->SetInteger(kErrorKey, entry.error());
-    } else {
-      if (entry.addresses()) {
-        // Append all of the resolved addresses.
-        base::ListValue addresses_value;
-        for (const IPEndPoint& address : entry.addresses().value()) {
-          addresses_value.GetList().emplace_back(address.ToStringWithoutPort());
-        }
-        entry_dict->SetKey(kAddressesKey, std::move(addresses_value));
-      }
-
-      if (entry.text_records()) {
-        // Append all resolved text records.
-        base::ListValue text_list_value;
-        for (const std::string& text_record : entry.text_records().value()) {
-          text_list_value.GetList().emplace_back(text_record);
-        }
-        entry_dict->SetKey(kTextRecordsKey, std::move(text_list_value));
-      }
-
-      if (entry.hostnames()) {
-        // Append all the resolved hostnames.
-        base::ListValue hostnames_value;
-        base::ListValue host_ports_value;
-        for (const HostPortPair& hostname : entry.hostnames().value()) {
-          hostnames_value.GetList().emplace_back(hostname.host());
-          host_ports_value.GetList().emplace_back(hostname.port());
-        }
-        entry_dict->SetKey(kHostnameResultsKey, std::move(hostnames_value));
-        entry_dict->SetKey(kHostPortsKey, std::move(host_ports_value));
-      }
-    }
-
     entry_list->Append(std::move(entry_dict));
   }
 }
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h
index 6dda3aa9..f81062bb 100644
--- a/net/dns/host_cache.h
+++ b/net/dns/host_cache.h
@@ -21,6 +21,7 @@
 #include "base/optional.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "net/base/address_family.h"
 #include "net/base/address_list.h"
 #include "net/base/expiring_cache.h"
@@ -29,6 +30,8 @@
 #include "net/dns/dns_util.h"
 #include "net/dns/host_resolver_source.h"
 #include "net/dns/public/dns_query_type.h"
+#include "net/log/net_log_capture_mode.h"
+#include "net/log/net_log_parameters_callback.h"
 
 namespace base {
 class ListValue;
@@ -110,26 +113,58 @@
       SetResult(std::forward<T>(results));
     }
 
+    // For errors with no |results|.
+    Entry(int error, Source source, base::TimeDelta ttl);
+    Entry(int error, Source source);
+
+    Entry(const Entry& entry);
     Entry(Entry&& entry);
     ~Entry();
 
+    Entry& operator=(const Entry& entry);
+    Entry& operator=(Entry&& entry);
+
     int error() const { return error_; }
+    void set_error(int error) { error_ = error; }
     const base::Optional<AddressList>& addresses() const { return addresses_; }
+    void set_addresses(const base::Optional<AddressList>& addresses) {
+      addresses_ = addresses;
+    }
     const base::Optional<std::vector<std::string>>& text_records() const {
       return text_records_;
     }
+    void set_text_records(
+        base::Optional<std::vector<std::string>> text_records) {
+      text_records_ = std::move(text_records);
+    }
     const base::Optional<std::vector<HostPortPair>>& hostnames() const {
       return hostnames_;
     }
+    void set_hostnames(base::Optional<std::vector<HostPortPair>> hostnames) {
+      hostnames_ = std::move(hostnames);
+    }
     Source source() const { return source_; }
     bool has_ttl() const { return ttl_ >= base::TimeDelta(); }
     base::TimeDelta ttl() const { return ttl_; }
+    base::Optional<base::TimeDelta> GetOptionalTtl() const;
+    void set_ttl(base::TimeDelta ttl) { ttl_ = ttl; }
 
     base::TimeTicks expires() const { return expires_; }
 
     // Public for the net-internals UI.
     int network_changes() const { return network_changes_; }
 
+    // Merge |front| and |back|, representing results from multiple
+    // transactions for the same overal host resolution query. On merging result
+    // lists, result elements from |front| will be merged in front of elements
+    // from |back|. Fields that cannot be merged take precedence from |front|.
+    static Entry MergeEntries(Entry front, Entry back);
+
+    // Creates a callback for use with the NetLog that returns a Value
+    // representation of the entry.  The callback must be destroyed before
+    // |this| is.
+    NetLogParametersCallback CreateNetLogCallback() const;
+
    private:
     friend class HostCache;
 
@@ -163,6 +198,10 @@
                       int network_changes,
                       EntryStaleness* out) const;
 
+    std::unique_ptr<base::Value> NetLogCallback(
+        NetLogCaptureMode capture_mode) const;
+    base::DictionaryValue GetAsValue(bool include_staleness) const;
+
     // The resolve results for this entry.
     int error_;
     base::Optional<AddressList> addresses_;
diff --git a/net/dns/host_cache_unittest.cc b/net/dns/host_cache_unittest.cc
index 38932d2..acf7fbc 100644
--- a/net/dns/host_cache_unittest.cc
+++ b/net/dns/host_cache_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "net/base/net_errors.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
@@ -868,4 +869,162 @@
   EXPECT_EQ(4, delegate.num_changes());
 }
 
+TEST(HostCacheTest, MergeEntries) {
+  const IPAddress kAddressFront(1, 2, 3, 4);
+  const IPEndPoint kEndpointFront(kAddressFront, 0);
+  HostCache::Entry front(OK, AddressList(kEndpointFront),
+                         HostCache::Entry::SOURCE_DNS);
+  front.set_text_records(std::vector<std::string>{"text1"});
+  const HostPortPair kHostnameFront("host", 1);
+  front.set_hostnames(std::vector<HostPortPair>{kHostnameFront});
+
+  const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                               0);
+  const IPEndPoint kEndpointBack(kAddressBack, 0);
+  HostCache::Entry back(OK, AddressList(kEndpointBack),
+                        HostCache::Entry::SOURCE_DNS);
+  back.set_text_records(std::vector<std::string>{"text2"});
+  const HostPortPair kHostnameBack("host", 2);
+  back.set_hostnames(std::vector<HostPortPair>{kHostnameBack});
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  EXPECT_EQ(OK, result.error());
+  EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
+
+  ASSERT_TRUE(result.addresses());
+  EXPECT_THAT(result.addresses().value().endpoints(),
+              testing::ElementsAre(kEndpointFront, kEndpointBack));
+  EXPECT_THAT(result.text_records(),
+              testing::Optional(testing::ElementsAre("text1", "text2")));
+  EXPECT_THAT(result.hostnames(), testing::Optional(testing::ElementsAre(
+                                      kHostnameFront, kHostnameBack)));
+}
+
+TEST(HostCacheTest, MergeEntries_frontEmpty) {
+  HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
+
+  const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                               0);
+  const IPEndPoint kEndpointBack(kAddressBack, 0);
+  HostCache::Entry back(OK, AddressList(kEndpointBack),
+                        HostCache::Entry::SOURCE_DNS,
+                        base::TimeDelta::FromHours(4));
+  back.set_text_records(std::vector<std::string>{"text2"});
+  const HostPortPair kHostnameBack("host", 2);
+  back.set_hostnames(std::vector<HostPortPair>{kHostnameBack});
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  EXPECT_EQ(OK, result.error());
+  EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
+
+  ASSERT_TRUE(result.addresses());
+  EXPECT_THAT(result.addresses().value().endpoints(),
+              testing::ElementsAre(kEndpointBack));
+  EXPECT_THAT(result.text_records(),
+              testing::Optional(testing::ElementsAre("text2")));
+  EXPECT_THAT(result.hostnames(),
+              testing::Optional(testing::ElementsAre(kHostnameBack)));
+
+  EXPECT_EQ(base::TimeDelta::FromHours(4), result.ttl());
+}
+
+TEST(HostCacheTest, MergeEntries_backEmpty) {
+  const IPAddress kAddressFront(1, 2, 3, 4);
+  const IPEndPoint kEndpointFront(kAddressFront, 0);
+  HostCache::Entry front(OK, AddressList(kEndpointFront),
+                         HostCache::Entry::SOURCE_DNS,
+                         base::TimeDelta::FromMinutes(5));
+  front.set_text_records(std::vector<std::string>{"text1"});
+  const HostPortPair kHostnameFront("host", 1);
+  front.set_hostnames(std::vector<HostPortPair>{kHostnameFront});
+
+  HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  EXPECT_EQ(OK, result.error());
+  EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
+
+  ASSERT_TRUE(result.addresses());
+  EXPECT_THAT(result.addresses().value().endpoints(),
+              testing::ElementsAre(kEndpointFront));
+  EXPECT_THAT(result.text_records(),
+              testing::Optional(testing::ElementsAre("text1")));
+  EXPECT_THAT(result.hostnames(),
+              testing::Optional(testing::ElementsAre(kHostnameFront)));
+
+  EXPECT_EQ(base::TimeDelta::FromMinutes(5), result.ttl());
+}
+
+TEST(HostCacheTest, MergeEntries_bothEmpty) {
+  HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
+  HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, result.error());
+  EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
+
+  EXPECT_FALSE(result.addresses());
+  EXPECT_FALSE(result.text_records());
+  EXPECT_FALSE(result.hostnames());
+
+  EXPECT_FALSE(result.has_ttl());
+}
+
+TEST(HostCacheTest, MergeEntries_differentTtl) {
+  HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS,
+                         base::TimeDelta::FromDays(12));
+  HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS,
+                        base::TimeDelta::FromSeconds(42));
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  EXPECT_EQ(base::TimeDelta::FromSeconds(42), result.ttl());
+}
+
+TEST(HostCacheTest, MergeEntries_FrontCannonnamePreserved) {
+  AddressList addresses_front;
+  const std::string kCanonicalNameFront = "name1";
+  addresses_front.set_canonical_name(kCanonicalNameFront);
+  HostCache::Entry front(OK, addresses_front, HostCache::Entry::SOURCE_DNS);
+
+  AddressList addresses_back;
+  const std::string kCanonicalNameBack = "name2";
+  addresses_back.set_canonical_name(kCanonicalNameBack);
+  HostCache::Entry back(OK, addresses_back, HostCache::Entry::SOURCE_DNS);
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  ASSERT_TRUE(result.addresses());
+  EXPECT_EQ(kCanonicalNameFront, result.addresses().value().canonical_name());
+}
+
+// Test that the back canonname can be used if there is no front cannonname.
+TEST(HostCacheTest, MergeEntries_BackCannonnameUsable) {
+  AddressList addresses_front;
+  const std::string kCanonicalNameFront = "";
+  addresses_front.set_canonical_name(kCanonicalNameFront);
+  HostCache::Entry front(OK, addresses_front, HostCache::Entry::SOURCE_DNS);
+
+  AddressList addresses_back;
+  const std::string kCanonicalNameBack = "name2";
+  addresses_back.set_canonical_name(kCanonicalNameBack);
+  HostCache::Entry back(OK, addresses_back, HostCache::Entry::SOURCE_DNS);
+
+  HostCache::Entry result =
+      HostCache::Entry::MergeEntries(std::move(front), std::move(back));
+
+  ASSERT_TRUE(result.addresses());
+  EXPECT_EQ(kCanonicalNameBack, result.addresses().value().canonical_name());
+}
+
 }  // namespace net
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h
index bae1fc7..a985f68 100644
--- a/net/dns/host_resolver.h
+++ b/net/dns/host_resolver.h
@@ -92,10 +92,23 @@
     // Address record (A or AAAA) results of the request. Should only be called
     // after Start() signals completion, either by invoking the callback or by
     // returning a result other than |ERR_IO_PENDING|.
-    //
-    // TODO(crbug.com/821021): Implement other GetResults() methods for requests
-    // that return other data (eg DNS TXT requests).
     virtual const base::Optional<AddressList>& GetAddressResults() const = 0;
+
+    // Text record (TXT) results of the request. Should only be called after
+    // Start() signals completion, either by invoking the callback or by
+    // returning a result other than |ERR_IO_PENDING|.
+    virtual const base::Optional<std::vector<std::string>>& GetTextResults()
+        const = 0;
+
+    // Hostname record (SRV or PTR) results of the request. For SRV results,
+    // hostnames are ordered acording to their priorities and weights. See RFC
+    // 2782.
+    //
+    // Should only be called after Start() signals completion, either by
+    // invoking the callback or by returning a result other than
+    // |ERR_IO_PENDING|.
+    virtual const base::Optional<std::vector<HostPortPair>>&
+    GetHostnameResults() const = 0;
   };
 
   // |max_concurrent_resolves| is how many resolve requests will be allowed to
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index 70ea152..77febd3 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -236,10 +236,40 @@
 
 //-----------------------------------------------------------------------------
 
-AddressList EnsurePortOnAddressList(const AddressList& list, uint16_t port) {
-  if (list.empty() || list.front().port() == port)
-    return list;
-  return AddressList::CopyWithPort(list, port);
+// Creates a copy of |results| with the port of all address and hostname values
+// set to |port| if the current port is 0. Preserves any non-zero ports.
+HostCache::Entry SetPortOnResults(HostCache::Entry results, uint16_t port) {
+  if (results.addresses() &&
+      std::any_of(results.addresses().value().begin(),
+                  results.addresses().value().end(),
+                  [](const IPEndPoint& e) { return e.port() == 0; })) {
+    AddressList addresses_with_port;
+    addresses_with_port.set_canonical_name(
+        results.addresses().value().canonical_name());
+    for (const IPEndPoint& endpoint : results.addresses().value()) {
+      if (endpoint.port() == 0)
+        addresses_with_port.push_back(IPEndPoint(endpoint.address(), port));
+      else
+        addresses_with_port.push_back(endpoint);
+    }
+    results.set_addresses(addresses_with_port);
+  }
+
+  if (results.hostnames() &&
+      std::any_of(results.hostnames().value().begin(),
+                  results.hostnames().value().end(),
+                  [](const HostPortPair& h) { return h.port() == 0; })) {
+    std::vector<HostPortPair> hostnames_with_port;
+    for (const HostPortPair& hostname : results.hostnames().value()) {
+      if (hostname.port() == 0)
+        hostnames_with_port.push_back(HostPortPair(hostname.host(), port));
+      else
+        hostnames_with_port.push_back(hostname);
+    }
+    results.set_hostnames(std::move(hostnames_with_port));
+  }
+
+  return results;
 }
 
 // Returns true if |addresses| contains only IPv4 loopback addresses.
@@ -351,11 +381,14 @@
 std::unique_ptr<base::Value> NetLogDnsTaskFailedCallback(
     int net_error,
     int dns_error,
-    NetLogCaptureMode /* capture_mode */) {
+    NetLogParametersCallback results_callback,
+    NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
   dict->SetInteger("net_error", net_error);
   if (dns_error)
     dict->SetInteger("dns_error", dns_error);
+  if (results_callback)
+    dict->Set("resolve_results", results_callback.Run(capture_mode));
   return std::move(dict);
 }
 
@@ -540,18 +573,16 @@
 
 //-----------------------------------------------------------------------------
 
-bool ResolveLocalHostname(base::StringPiece host,
-                          uint16_t port,
-                          AddressList* address_list) {
+bool ResolveLocalHostname(base::StringPiece host, AddressList* address_list) {
   address_list->clear();
 
   bool is_local6;
   if (!IsLocalHostname(host, &is_local6))
     return false;
 
-  address_list->push_back(IPEndPoint(IPAddress::IPv6Localhost(), port));
+  address_list->push_back(IPEndPoint(IPAddress::IPv6Localhost(), 0));
   if (!is_local6) {
-    address_list->push_back(IPEndPoint(IPAddress::IPv4Localhost(), port));
+    address_list->push_back(IPEndPoint(IPAddress::IPv4Localhost(), 0));
   }
 
   return true;
@@ -614,17 +645,34 @@
 
   const base::Optional<AddressList>& GetAddressResults() const override {
     DCHECK(complete_);
-    return address_results_;
+    static const base::NoDestructor<base::Optional<AddressList>> nullopt_result;
+    return results_ ? results_.value().addresses() : *nullopt_result;
   }
 
-  void set_address_results(const AddressList& address_results) {
+  const base::Optional<std::vector<std::string>>& GetTextResults()
+      const override {
+    DCHECK(complete_);
+    static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+        nullopt_result;
+    return results_ ? results_.value().text_records() : *nullopt_result;
+  }
+
+  const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
+      const override {
+    DCHECK(complete_);
+    static const base::NoDestructor<base::Optional<std::vector<HostPortPair>>>
+        nullopt_result;
+    return results_ ? results_.value().hostnames() : *nullopt_result;
+  }
+
+  void set_results(HostCache::Entry results) {
     // Should only be called at most once and before request is marked
     // completed.
     DCHECK(!complete_);
-    DCHECK(!address_results_);
+    DCHECK(!results_);
     DCHECK(!parameters_.is_speculative);
 
-    address_results_ = address_results;
+    results_ = std::move(results);
   }
 
   void ChangeRequestPriority(RequestPriority priority);
@@ -645,7 +693,7 @@
     callback_.Reset();
 
     // No results should be set.
-    DCHECK(!address_results_);
+    DCHECK(!results_);
   }
 
   // Cleans up Job assignment, marks request completed, and calls the completion
@@ -704,7 +752,7 @@
   CompletionOnceCallback callback_;
 
   bool complete_;
-  base::Optional<AddressList> address_results_;
+  base::Optional<HostCache::Entry> results_;
 
   base::TimeTicks request_time_;
 
@@ -1014,9 +1062,7 @@
   class Delegate {
    public:
     virtual void OnDnsTaskComplete(base::TimeTicks start_time,
-                                   int net_error,
-                                   const AddressList& addr_list,
-                                   base::TimeDelta ttl) = 0;
+                                   const HostCache::Entry& results) = 0;
 
     // Called when the first of two jobs succeeds.  If the first completed
     // transaction fails, this is not called.  Also not called when the DnsTask
@@ -1078,8 +1124,6 @@
     transaction2_->Start();
   }
 
-  base::TimeDelta ttl() { return ttl_; }
-
  private:
   std::unique_ptr<DnsTransaction> CreateTransaction(
       DnsQueryType dns_query_type) {
@@ -1088,7 +1132,8 @@
         client_->GetTransactionFactory()->CreateTransaction(
             key_.hostname, DnsQueryTypeToQtype(dns_query_type),
             base::BindOnce(&DnsTask::OnTransactionComplete,
-                           base::Unretained(this), tick_clock_->NowTicks()),
+                           base::Unretained(this), tick_clock_->NowTicks(),
+                           dns_query_type),
             net_log_);
     trans->SetRequestContext(delegate_->url_request_context());
     trans->SetRequestPriority(delegate_->priority());
@@ -1096,6 +1141,7 @@
   }
 
   void OnTransactionComplete(const base::TimeTicks& start_time,
+                             DnsQueryType dns_query_type,
                              DnsTransaction* transaction,
                              int net_error,
                              const DnsResponse* response) {
@@ -1104,7 +1150,7 @@
     if (net_error != OK && !(net_error == ERR_NAME_NOT_RESOLVED && response &&
                              response->IsValid())) {
       UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.TransactionFailure", duration);
-      OnFailure(net_error, DnsResponse::DNS_PARSE_OK);
+      OnFailure(net_error, DnsResponse::DNS_PARSE_OK, base::nullopt);
       return;
     }
 
@@ -1119,115 +1165,161 @@
         break;
     }
 
-    AddressList addr_list;
-    base::TimeDelta ttl;
-    DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
-    UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList",
-                              result,
-                              DnsResponse::DNS_PARSE_RESULT_MAX);
-    if (result != DnsResponse::DNS_PARSE_OK) {
-      // Fail even if the other query succeeds.
-      OnFailure(ERR_DNS_MALFORMED_RESPONSE, result);
+    DnsResponse::Result parse_result = DnsResponse::DNS_PARSE_RESULT_MAX;
+    HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
+    switch (dns_query_type) {
+      case DnsQueryType::UNSPECIFIED:
+        // Should create two separate transactions with specified type.
+        NOTREACHED();
+        break;
+      case DnsQueryType::A:
+      case DnsQueryType::AAAA:
+        parse_result = ParseAddressDnsResponse(response, &results);
+        break;
+    }
+    DCHECK_LT(parse_result, DnsResponse::DNS_PARSE_RESULT_MAX);
+
+    if (results.error() != OK && results.error() != ERR_NAME_NOT_RESOLVED) {
+      OnFailure(results.error(), parse_result, results.GetOptionalTtl());
       return;
     }
 
+    // Merge results with saved results from previous transactions.
+    if (saved_results_) {
+      DCHECK(needs_two_transactions());
+      DCHECK_GE(1u, num_completed_transactions_);
+
+      switch (dns_query_type) {
+        case DnsQueryType::A:
+          // A results in |results| go after other results in |saved_results_|,
+          // so merge |saved_results_| to the front.
+          results = HostCache::Entry::MergeEntries(
+              std::move(saved_results_).value(), std::move(results));
+          break;
+        case DnsQueryType::AAAA:
+          // AAAA results in |results| go before other results in
+          // |saved_results_|, so merge |saved_results_| to the back.
+          results = HostCache::Entry::MergeEntries(
+              std::move(results), std::move(saved_results_).value());
+          break;
+        default:
+          // Only expect address query types with multiple transactions.
+          NOTREACHED();
+      }
+    }
+
+    // If not all transactions are complete, the task cannot yet be completed
+    // and the results so far must be saved to merge with additional results.
     ++num_completed_transactions_;
-    if (num_completed_transactions_ == 1) {
-      ttl_ = ttl;
-    } else {
-      ttl_ = std::min(ttl_, ttl);
-    }
-
-    if (transaction->GetType() == dns_protocol::kTypeA) {
-      DCHECK_EQ(transaction1_.get(), transaction);
-      // Place IPv4 addresses after IPv6.
-      addr_list_.insert(addr_list_.end(), addr_list.begin(), addr_list.end());
-    } else if (transaction->GetType() == dns_protocol::kTypeAAAA) {
-      // Place IPv6 addresses before IPv4.
-      addr_list_.insert(addr_list_.begin(), addr_list.begin(), addr_list.end());
-    } else {
-      // TODO(crbug.com/846423): Add result parsing for non-address types.
-      NOTIMPLEMENTED();
-    }
-
-    // If requested via HOST_RESOLVER_CANONNAME, store the canonical name from
-    // the response. Prefer the name from the AAAA response. Only look at name
-    // if there is at least one address record.
-    if ((key_.host_resolver_flags & HOST_RESOLVER_CANONNAME) != 0 &&
-        !addr_list.empty() &&
-        (transaction->GetType() == dns_protocol::kTypeAAAA ||
-         addr_list_.canonical_name().empty())) {
-      addr_list_.set_canonical_name(addr_list.canonical_name());
-    }
-
     if (needs_two_transactions() && num_completed_transactions_ == 1) {
+      saved_results_ = std::move(results);
       // No need to repeat the suffix search.
       key_.hostname = transaction->GetHostname();
       delegate_->OnFirstDnsTransactionComplete();
       return;
     }
 
-    if (addr_list_.empty()) {
-      // TODO(szym): Don't fallback to ProcTask in this case.
-      OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
-      return;
-    }
-
     // If there are multiple addresses, and at least one is IPv6, need to sort
     // them.  Note that IPv6 addresses are always put before IPv4 ones, so it's
     // sufficient to just check the family of the first address.
-    if (addr_list_.size() > 1 &&
-        addr_list_[0].GetFamily() == ADDRESS_FAMILY_IPV6) {
+    if (results.addresses() && results.addresses().value().size() > 1 &&
+        results.addresses().value()[0].GetFamily() == ADDRESS_FAMILY_IPV6) {
       // Sort addresses if needed.  Sort could complete synchronously.
       client_->GetAddressSorter()->Sort(
-          addr_list_, base::BindOnce(&DnsTask::OnSortComplete, AsWeakPtr(),
-                                     tick_clock_->NowTicks()));
-    } else {
-      OnSuccess(addr_list_);
+          results.addresses().value(),
+          base::BindOnce(&DnsTask::OnSortComplete, AsWeakPtr(),
+                         tick_clock_->NowTicks(), std::move(results)));
+      return;
     }
+
+    OnSuccess(results);
   }
 
-  void OnSortComplete(base::TimeTicks start_time,
+  DnsResponse::Result ParseAddressDnsResponse(const DnsResponse* response,
+                                              HostCache::Entry* out_results) {
+    AddressList addresses;
+    base::TimeDelta ttl;
+    DnsResponse::Result parse_result =
+        response->ParseToAddressList(&addresses, &ttl);
+    UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList", parse_result,
+                              DnsResponse::DNS_PARSE_RESULT_MAX);
+
+    if (parse_result != DnsResponse::DNS_PARSE_OK) {
+      *out_results = HostCache::Entry(ERR_DNS_MALFORMED_RESPONSE, AddressList(),
+                                      HostCache::Entry::SOURCE_DNS);
+    } else if (addresses.empty()) {
+      *out_results = HostCache::Entry(ERR_NAME_NOT_RESOLVED, AddressList(),
+                                      HostCache::Entry::SOURCE_DNS, ttl);
+    } else {
+      *out_results = HostCache::Entry(OK, std::move(addresses),
+                                      HostCache::Entry::SOURCE_DNS, ttl);
+    }
+    return parse_result;
+  }
+
+  void OnSortComplete(base::TimeTicks sort_start_time,
+                      HostCache::Entry results,
                       bool success,
                       const AddressList& addr_list) {
+    results.set_addresses(addr_list);
+
     if (!success) {
       UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.SortFailure",
-                                   tick_clock_->NowTicks() - start_time);
-      OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK);
+                                   tick_clock_->NowTicks() - sort_start_time);
+      OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK,
+                results.GetOptionalTtl());
       return;
     }
 
     UMA_HISTOGRAM_LONG_TIMES_100("AsyncDNS.SortSuccess",
-                                 tick_clock_->NowTicks() - start_time);
+                                 tick_clock_->NowTicks() - sort_start_time);
 
     // AddressSorter prunes unusable destinations.
-    if (addr_list.empty()) {
+    if (addr_list.empty() &&
+        results.text_records().value_or(std::vector<std::string>()).empty() &&
+        results.hostnames().value_or(std::vector<HostPortPair>()).empty()) {
       LOG(WARNING) << "Address list empty after RFC3484 sort";
-      OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
+      OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK,
+                results.GetOptionalTtl());
       return;
     }
 
-    OnSuccess(addr_list);
+    OnSuccess(results);
   }
 
-  void OnFailure(int net_error, DnsResponse::Result result) {
+  void OnFailure(int net_error,
+                 DnsResponse::Result parse_result,
+                 base::Optional<base::TimeDelta> ttl) {
     DCHECK_NE(OK, net_error);
-    net_log_.EndEvent(
-        NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
-        base::Bind(&NetLogDnsTaskFailedCallback, net_error, result));
-    base::TimeDelta ttl = ttl_ < base::TimeDelta::FromSeconds(
-                                     std::numeric_limits<uint32_t>::max()) &&
-                                  num_completed_transactions_ > 0
-                              ? ttl_
-                              : base::TimeDelta::FromSeconds(0);
-    delegate_->OnDnsTaskComplete(task_start_time_, net_error, AddressList(),
-                                 ttl);
+
+    HostCache::Entry results(net_error, HostCache::Entry::SOURCE_UNKNOWN);
+
+    net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
+                      base::Bind(&NetLogDnsTaskFailedCallback, results.error(),
+                                 parse_result, results.CreateNetLogCallback()));
+
+    // If we have a TTL from a previously completed transaction, use it.
+    base::TimeDelta previous_transaction_ttl;
+    if (saved_results_ && saved_results_.value().has_ttl() &&
+        saved_results_.value().ttl() <
+            base::TimeDelta::FromSeconds(
+                std::numeric_limits<uint32_t>::max())) {
+      previous_transaction_ttl = saved_results_.value().ttl();
+      if (ttl)
+        results.set_ttl(std::min(ttl.value(), previous_transaction_ttl));
+      else
+        results.set_ttl(previous_transaction_ttl);
+    } else if (ttl) {
+      results.set_ttl(ttl.value());
+    }
+
+    delegate_->OnDnsTaskComplete(task_start_time_, results);
   }
 
-  void OnSuccess(const AddressList& addr_list) {
+  void OnSuccess(const HostCache::Entry& results) {
     net_log_.EndEvent(NetLogEventType::HOST_RESOLVER_IMPL_DNS_TASK,
-                      addr_list.CreateNetLogCallback());
-    delegate_->OnDnsTaskComplete(task_start_time_, OK, addr_list, ttl_);
+                      results.CreateNetLogCallback());
+    delegate_->OnDnsTaskComplete(task_start_time_, results);
   }
 
   DnsClient* client_;
@@ -1246,10 +1338,9 @@
 
   unsigned num_completed_transactions_;
 
-  // These are updated as each transaction completes.
-  base::TimeDelta ttl_;
-  // IPv6 addresses must appear first in the list.
-  AddressList addr_list_;
+  // Result from previously completed transactions. Only set if a transaction
+  // has completed while others are still in progress.
+  base::Optional<HostCache::Entry> saved_results_;
 
   const base::TickClock* tick_clock_;
   base::TimeTicks task_start_time_;
@@ -1389,7 +1480,7 @@
       // If we were called from a Request's callback within CompleteRequests,
       // that Request could not have been cancelled, so num_active_requests()
       // could not be 0. Therefore, we are not in CompleteRequests().
-      CompleteRequestsWithError(OK /* cancelled */);
+      CompleteRequestsWithError(ERR_FAILED /* cancelled */);
     }
   }
 
@@ -1445,14 +1536,11 @@
   // this Job was destroyed.
   bool ServeFromHosts() {
     DCHECK_GT(num_active_requests(), 0u);
-    AddressList addr_list;
-    if (resolver_->ServeFromHosts(
-            key(), requests_.head()->value()->request_host().port(),
-            &addr_list)) {
+    base::Optional<HostCache::Entry> results = resolver_->ServeFromHosts(key());
+    if (results) {
       // This will destroy the Job.
-      CompleteRequests(
-          MakeCacheEntry(OK, addr_list, HostCache::Entry::SOURCE_HOSTS),
-          base::TimeDelta(), true /* allow_cache */);
+      CompleteRequests(results.value(), base::TimeDelta(),
+                       true /* allow_cache */);
       return true;
     }
     return false;
@@ -1492,35 +1580,6 @@
     DCHECK_EQ(1u, num_occupied_job_slots_);
   }
 
-  // MakeCacheEntry() and MakeCacheEntryWithTTL() are helpers to build a
-  // HostCache::Entry(). The address list is omited from the cache entry
-  // for errors.
-  HostCache::Entry MakeCacheEntry(int net_error,
-                                  const AddressList& addr_list,
-                                  HostCache::Entry::Source source) const {
-    return HostCache::Entry(
-        net_error,
-        net_error == OK ? MakeAddressListForRequest(addr_list) : AddressList(),
-        source);
-  }
-
-  HostCache::Entry MakeCacheEntryWithTTL(int net_error,
-                                         const AddressList& addr_list,
-                                         HostCache::Entry::Source source,
-                                         base::TimeDelta ttl) const {
-    return HostCache::Entry(
-        net_error,
-        net_error == OK ? MakeAddressListForRequest(addr_list) : AddressList(),
-        source, ttl);
-  }
-
-  AddressList MakeAddressListForRequest(const AddressList& list) const {
-    if (requests_.empty())
-      return list;
-    return AddressList::CopyWithPort(
-        list, requests_.head()->value()->request_host().port());
-  }
-
   void UpdatePriority() {
     if (is_queued())
       handle_ = resolver_->dispatcher_->ChangePriority(handle_, priority());
@@ -1621,7 +1680,11 @@
     // hosts file, its own cache, a DNS lookup or somewhere else.
     // Don't store the |ttl| in cache since it's not obtained from the server.
     CompleteRequests(
-        MakeCacheEntry(net_error, addr_list, HostCache::Entry::SOURCE_UNKNOWN),
+        HostCache::Entry(net_error,
+                         net_error == OK
+                             ? AddressList::CopyWithPort(addr_list, 0)
+                             : AddressList(),
+                         HostCache::Entry::SOURCE_UNKNOWN),
         ttl, true /* allow_cache */);
   }
 
@@ -1650,9 +1713,10 @@
       // Since we cannot complete synchronously from here, post a failure.
       base::SequencedTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
-          base::BindOnce(&Job::OnDnsTaskFailure, weak_ptr_factory_.GetWeakPtr(),
-                         dns_task_->AsWeakPtr(), base::TimeDelta(),
-                         ERR_FAILED));
+          base::BindOnce(
+              &Job::OnDnsTaskFailure, weak_ptr_factory_.GetWeakPtr(),
+              dns_task_->AsWeakPtr(), base::TimeDelta(),
+              HostCache::Entry(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN)));
     }
   }
 
@@ -1666,7 +1730,9 @@
   // so we use it as indicator whether Job is still valid.
   void OnDnsTaskFailure(const base::WeakPtr<DnsTask>& dns_task,
                         base::TimeDelta duration,
-                        int net_error) {
+                        const HostCache::Entry& failure_results) {
+    DCHECK_NE(OK, failure_results.error());
+
     UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.DnsTask.FailureTime", duration);
 
     if (!dns_task)
@@ -1674,12 +1740,12 @@
 
     if (duration < base::TimeDelta::FromMilliseconds(10)) {
       base::UmaHistogramSparse("Net.DNS.DnsTask.ErrorBeforeFallback.Fast",
-                               std::abs(net_error));
+                               std::abs(failure_results.error()));
     } else {
       base::UmaHistogramSparse("Net.DNS.DnsTask.ErrorBeforeFallback.Slow",
-                               std::abs(net_error));
+                               std::abs(failure_results.error()));
     }
-    dns_task_error_ = net_error;
+    dns_task_error_ = failure_results.error();
 
     // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so.
     // http://crbug.com/117655
@@ -1692,50 +1758,42 @@
       StartProcTask();
     } else {
       UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL);
-      // If the ttl is max, we didn't get one from the record, so set it to 0
-      base::TimeDelta ttl =
-          dns_task->ttl() < base::TimeDelta::FromSeconds(
-                                std::numeric_limits<uint32_t>::max())
-              ? dns_task->ttl()
-              : base::TimeDelta::FromSeconds(0);
-      CompleteRequests(
-          HostCache::Entry(net_error, AddressList(),
-                           HostCache::Entry::Source::SOURCE_UNKNOWN, ttl),
-          ttl, true /* allow_cache */);
+      base::TimeDelta ttl = failure_results.has_ttl()
+                                ? failure_results.ttl()
+                                : base::TimeDelta::FromSeconds(0);
+      CompleteRequests(failure_results, ttl, true /* allow_cache */);
     }
   }
 
   // HostResolverImpl::DnsTask::Delegate implementation:
 
   void OnDnsTaskComplete(base::TimeTicks start_time,
-                         int net_error,
-                         const AddressList& addr_list,
-                         base::TimeDelta ttl) override {
+                         const HostCache::Entry& results) override {
     DCHECK(is_dns_running());
 
     base::TimeDelta duration = tick_clock_->NowTicks() - start_time;
-    if (net_error != OK) {
-      OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, net_error);
+    if (results.error() != OK) {
+      OnDnsTaskFailure(dns_task_->AsWeakPtr(), duration, results);
       return;
     }
 
     UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.DnsTask.SuccessTime", duration);
 
     UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS);
-    RecordTTL(ttl);
+    RecordTTL(results.ttl());
 
     resolver_->OnDnsTaskResolve();
 
-    base::TimeDelta bounded_ttl =
-        std::max(ttl, base::TimeDelta::FromSeconds(kMinimumTTLSeconds));
+    base::TimeDelta bounded_ttl = std::max(
+        results.ttl(), base::TimeDelta::FromSeconds(kMinimumTTLSeconds));
 
-    if (ContainsIcannNameCollisionIp(addr_list)) {
+    if (results.addresses() &&
+        ContainsIcannNameCollisionIp(results.addresses().value())) {
       CompleteRequestsWithError(ERR_ICANN_NAME_COLLISION);
-    } else {
-      CompleteRequests(MakeCacheEntryWithTTL(net_error, addr_list,
-                                             HostCache::Entry::SOURCE_DNS, ttl),
-                       bounded_ttl, true /* allow_cache */);
+      return;
     }
+
+    CompleteRequests(results, bounded_ttl, true /* allow_cache */);
   }
 
   void OnFirstDnsTransactionComplete() override {
@@ -1774,18 +1832,18 @@
         base::BindOnce(&Job::OnMdnsTaskComplete, base::Unretained(this)));
   }
 
-  void OnMdnsTaskComplete(int error) {
+  void OnMdnsTaskComplete() {
     DCHECK(is_mdns_running());
     // TODO(crbug.com/846423): Consider adding MDNS-specific logging.
 
-    if (error != OK) {
-      CompleteRequestsWithError(error);
-    } else if (ContainsIcannNameCollisionIp(mdns_task_->result_addresses())) {
+    HostCache::Entry results = mdns_task_->GetResults();
+    if (results.addresses() &&
+        ContainsIcannNameCollisionIp(results.addresses().value())) {
       CompleteRequestsWithError(ERR_ICANN_NAME_COLLISION);
     } else {
       // MDNS uses a separate cache, so skip saving result to cache.
       // TODO(crbug.com/846423): Consider merging caches.
-      CompleteRequestsWithoutCache(error, mdns_task_->result_addresses());
+      CompleteRequestsWithoutCache(results);
     }
   }
 
@@ -1877,7 +1935,7 @@
   //
   // If not |allow_cache|, result will not be stored in the host cache, even if
   // result would otherwise allow doing so.
-  void CompleteRequests(const HostCache::Entry& entry,
+  void CompleteRequests(const HostCache::Entry& results,
                         base::TimeDelta ttl,
                         bool allow_cache) {
     CHECK(resolver_.get());
@@ -1908,23 +1966,23 @@
     }
 
     net_log_.EndEventWithNetErrorCode(NetLogEventType::HOST_RESOLVER_IMPL_JOB,
-                                      entry.error());
+                                      results.error());
 
     DCHECK(!requests_.empty());
 
-    if (entry.error() == OK || entry.error() == ERR_ICANN_NAME_COLLISION) {
+    if (results.error() == OK || results.error() == ERR_ICANN_NAME_COLLISION) {
       // Record this histogram here, when we know the system has a valid DNS
       // configuration.
       UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig",
                             resolver_->received_dns_config_);
     }
 
-    bool did_complete = (entry.error() != ERR_NETWORK_CHANGED) &&
-                        (entry.error() != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
+    bool did_complete = (results.error() != ERR_NETWORK_CHANGED) &&
+                        (results.error() != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
     if (did_complete && allow_cache)
-      resolver_->CacheResult(key_, entry, ttl);
+      resolver_->CacheResult(key_, results, ttl);
 
-    RecordJobHistograms(entry.error());
+    RecordJobHistograms(results.error());
 
     // Complete all of the requests that were attached to the job and
     // detach them.
@@ -1933,18 +1991,17 @@
       req->RemoveFromList();
       DCHECK_EQ(this, req->job());
       // Update the net log and notify registered observers.
-      LogFinishRequest(req->source_net_log(), entry.error());
+      LogFinishRequest(req->source_net_log(), results.error());
       if (did_complete) {
         // Record effective total time from creation to completion.
         resolver_->RecordTotalTime(
             req->parameters().is_speculative, false /* from_cache */,
             tick_clock_->NowTicks() - req->request_time());
       }
-      if (entry.error() == OK && !req->parameters().is_speculative) {
-        req->set_address_results(EnsurePortOnAddressList(
-            entry.addresses().value(), req->request_host().port()));
+      if (results.error() == OK && !req->parameters().is_speculative) {
+        req->set_results(SetPortOnResults(results, req->request_host().port()));
       }
-      req->OnJobCompleted(this, entry.error());
+      req->OnJobCompleted(this, results.error());
 
       // Check if the resolver was destroyed as a result of running the
       // callback. If it was, we could continue, but we choose to bail.
@@ -1953,17 +2010,16 @@
     }
   }
 
-  void CompleteRequestsWithoutCache(int error, const AddressList& addresses) {
-    CompleteRequests(
-        MakeCacheEntry(error, addresses, HostCache::Entry::SOURCE_UNKNOWN),
-        base::TimeDelta(), false /* allow_cache */);
+  void CompleteRequestsWithoutCache(const HostCache::Entry& results) {
+    CompleteRequests(results, base::TimeDelta(), false /* allow_cache */);
   }
 
   // Convenience wrapper for CompleteRequests in case of failure.
   void CompleteRequestsWithError(int net_error) {
-    CompleteRequests(HostCache::Entry(net_error, AddressList(),
-                                      HostCache::Entry::SOURCE_UNKNOWN),
-                     base::TimeDelta(), true /* allow_cache */);
+    DCHECK_NE(OK, net_error);
+    CompleteRequests(
+        HostCache::Entry(net_error, HostCache::Entry::SOURCE_UNKNOWN),
+        base::TimeDelta(), true /* allow_cache */);
   }
 
   RequestPriority priority() const override {
@@ -2184,14 +2240,20 @@
   LogStartRequest(source_net_log, info);
 
   Key key;
-  int rv = ResolveLocally(
-      info.host_port_pair(), AddressFamilyToDnsQueryType(info.address_family()),
+  HostCache::Entry results = ResolveLocally(
+      info.host_port_pair().host(),
+      AddressFamilyToDnsQueryType(info.address_family()),
       FlagsToSource(info.host_resolver_flags()), info.host_resolver_flags(),
       info.allow_cached_response(), false /* allow_stale */,
-      nullptr /* stale_info */, source_net_log, addresses, &key);
+      nullptr /* stale_info */, source_net_log, &key);
 
-  LogFinishRequest(source_net_log, rv);
-  return rv;
+  if (results.addresses()) {
+    *addresses = AddressList::CopyWithPort(results.addresses().value(),
+                                           info.host_port_pair().port());
+  }
+
+  LogFinishRequest(source_net_log, results.error());
+  return results.error();
 }
 
 int HostResolverImpl::ResolveStaleFromCache(
@@ -2207,13 +2269,20 @@
   LogStartRequest(source_net_log, info);
 
   Key key;
-  int rv = ResolveLocally(
-      info.host_port_pair(), AddressFamilyToDnsQueryType(info.address_family()),
-      FlagsToSource(info.host_resolver_flags()), info.host_resolver_flags(),
-      info.allow_cached_response(), true /* allow_stale */, stale_info,
-      source_net_log, addresses, &key);
-  LogFinishRequest(source_net_log, rv);
-  return rv;
+  HostCache::Entry results =
+      ResolveLocally(info.host_port_pair().host(),
+                     AddressFamilyToDnsQueryType(info.address_family()),
+                     FlagsToSource(info.host_resolver_flags()),
+                     info.host_resolver_flags(), info.allow_cached_response(),
+                     true /* allow_stale */, stale_info, source_net_log, &key);
+
+  if (results.addresses()) {
+    *addresses = AddressList::CopyWithPort(results.addresses().value(),
+                                           info.host_port_pair().port());
+  }
+
+  LogFinishRequest(source_net_log, results.error());
+  return results.error();
 }
 
 void HostResolverImpl::SetDnsClientEnabled(bool enabled) {
@@ -2357,96 +2426,103 @@
 
   LogStartRequest(request->source_net_log(), request->request_host());
 
-  AddressList addresses;
   Key key;
-  int rv = ResolveLocally(
-      request->request_host(), request->parameters().dns_query_type,
+  HostCache::Entry results = ResolveLocally(
+      request->request_host().host(), request->parameters().dns_query_type,
       request->parameters().source, request->host_resolver_flags(),
       request->parameters().allow_cached_response, false /* allow_stale */,
-      nullptr /* stale_info */, request->source_net_log(), &addresses, &key);
-  if (rv == OK && !request->parameters().is_speculative) {
-    request->set_address_results(
-        EnsurePortOnAddressList(addresses, request->request_host().port()));
+      nullptr /* stale_info */, request->source_net_log(), &key);
+  if (results.error() == OK && !request->parameters().is_speculative) {
+    request->set_results(
+        SetPortOnResults(results, request->request_host().port()));
   }
-  if (rv != ERR_DNS_CACHE_MISS) {
-    LogFinishRequest(request->source_net_log(), rv);
+  if (results.error() != ERR_DNS_CACHE_MISS) {
+    LogFinishRequest(request->source_net_log(), results.error());
     RecordTotalTime(request->parameters().is_speculative, true /* from_cache */,
                     base::TimeDelta());
-    return rv;
+    return results.error();
   }
 
-  rv = CreateAndStartJob(key, request);
+  int rv = CreateAndStartJob(key, request);
   // At this point, expect only async or errors.
   DCHECK_NE(OK, rv);
 
   return rv;
 }
 
-int HostResolverImpl::ResolveLocally(const HostPortPair& host,
-                                     DnsQueryType dns_query_type,
-                                     HostResolverSource source,
-                                     HostResolverFlags flags,
-                                     bool allow_cache,
-                                     bool allow_stale,
-                                     HostCache::EntryStaleness* stale_info,
-                                     const NetLogWithSource& source_net_log,
-                                     AddressList* addresses,
-                                     Key* key) {
+HostCache::Entry HostResolverImpl::ResolveLocally(
+    const std::string& hostname,
+    DnsQueryType dns_query_type,
+    HostResolverSource source,
+    HostResolverFlags flags,
+    bool allow_cache,
+    bool allow_stale,
+    HostCache::EntryStaleness* stale_info,
+    const NetLogWithSource& source_net_log,
+    Key* out_key) {
   IPAddress ip_address;
   IPAddress* ip_address_ptr = nullptr;
-  if (ip_address.AssignFromIPLiteral(host.host())) {
+  if (ip_address.AssignFromIPLiteral(hostname)) {
     ip_address_ptr = &ip_address;
   } else {
     // Check that the caller supplied a valid hostname to resolve.
-    if (!IsValidDNSDomain(host.host()))
-      return ERR_NAME_NOT_RESOLVED;
+    if (!IsValidDNSDomain(hostname)) {
+      return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
+                              HostCache::Entry::SOURCE_UNKNOWN);
+    }
   }
 
   // Build a key that identifies the request in the cache and in the
   // outstanding jobs map.
-  *key = GetEffectiveKeyForRequest(host.host(), dns_query_type, source, flags,
-                                   ip_address_ptr, source_net_log);
+  *out_key = GetEffectiveKeyForRequest(hostname, dns_query_type, source, flags,
+                                       ip_address_ptr, source_net_log);
 
   DCHECK(allow_stale == !!stale_info);
   // The result of |getaddrinfo| for empty hosts is inconsistent across systems.
   // On Windows it gives the default interface's address, whereas on Linux it
   // gives an error. We will make it fail on all platforms for consistency.
-  if (host.host().empty() || host.host().size() > kMaxHostLength) {
+  if (hostname.empty() || hostname.size() > kMaxHostLength) {
     MakeNotStale(stale_info);
-    return ERR_NAME_NOT_RESOLVED;
+    return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
+                            HostCache::Entry::SOURCE_UNKNOWN);
   }
 
-  int net_error = ERR_UNEXPECTED;
-  if (ResolveAsIP(*key, host.port(), ip_address_ptr, &net_error, addresses)) {
+  base::Optional<HostCache::Entry> resolved =
+      ResolveAsIP(*out_key, ip_address_ptr);
+  if (resolved) {
     MakeNotStale(stale_info);
-    return net_error;
+    return resolved.value();
   }
 
   // Special-case localhost names, as per the recommendations in
   // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost.
-  if (ServeLocalhost(*key, host.port(), addresses)) {
+  resolved = ServeLocalhost(*out_key);
+  if (resolved) {
     MakeNotStale(stale_info);
-    return OK;
+    return resolved.value();
   }
 
-  if (allow_cache && ServeFromCache(*key, host.port(), &net_error, addresses,
-                                    allow_stale, stale_info)) {
-    source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
-                            addresses->CreateNetLogCallback());
-    // |ServeFromCache()| will set |*stale_info| as needed.
-    return net_error;
+  if (allow_cache) {
+    resolved = ServeFromCache(*out_key, allow_stale, stale_info);
+    if (resolved) {
+      source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_CACHE_HIT,
+                              resolved.value().CreateNetLogCallback());
+      // |ServeFromCache()| will update |*stale_info| as needed.
+      return resolved.value();
+    }
   }
 
   // TODO(szym): Do not do this if nsswitch.conf instructs not to.
   // http://crbug.com/117655
-  if (ServeFromHosts(*key, host.port(), addresses)) {
+  resolved = ServeFromHosts(*out_key);
+  if (resolved) {
     source_net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_HOSTS_HIT,
-                            addresses->CreateNetLogCallback());
+                            resolved.value().CreateNetLogCallback());
     MakeNotStale(stale_info);
-    return OK;
+    return resolved.value();
   }
 
-  return ERR_DNS_CACHE_MISS;
+  return HostCache::Entry(ERR_DNS_CACHE_MISS, HostCache::Entry::SOURCE_UNKNOWN);
 }
 
 int HostResolverImpl::CreateAndStartJob(const Key& key, RequestImpl* request) {
@@ -2480,41 +2556,34 @@
   return ERR_IO_PENDING;
 }
 
-bool HostResolverImpl::ResolveAsIP(const Key& key,
-                                   uint16_t host_port,
-                                   const IPAddress* ip_address,
-                                   int* net_error,
-                                   AddressList* addresses) {
-  DCHECK(addresses);
-  DCHECK(net_error);
+base::Optional<HostCache::Entry> HostResolverImpl::ResolveAsIP(
+    const Key& key,
+    const IPAddress* ip_address) {
   if (ip_address == nullptr || !IsAddressType(key.dns_query_type))
-    return false;
+    return base::nullopt;
 
-  *net_error = OK;
   AddressFamily family = GetAddressFamily(*ip_address);
   if (key.dns_query_type != DnsQueryType::UNSPECIFIED &&
       key.dns_query_type != AddressFamilyToDnsQueryType(family)) {
     // Don't return IPv6 addresses for IPv4 queries, and vice versa.
-    *net_error = ERR_NAME_NOT_RESOLVED;
-  } else {
-    *addresses = AddressList::CreateFromIPAddress(*ip_address, host_port);
-    if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)
-      addresses->SetDefaultCanonicalName();
+    return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
+                            HostCache::Entry::SOURCE_UNKNOWN);
   }
-  return true;
+
+  AddressList addresses = AddressList::CreateFromIPAddress(*ip_address, 0);
+  if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)
+    addresses.SetDefaultCanonicalName();
+  return HostCache::Entry(OK, std::move(addresses),
+                          HostCache::Entry::SOURCE_UNKNOWN);
 }
 
-bool HostResolverImpl::ServeFromCache(const Key& key,
-                                      uint16_t host_port,
-                                      int* net_error,
-                                      AddressList* addresses,
-                                      bool allow_stale,
-                                      HostCache::EntryStaleness* stale_info) {
-  DCHECK(addresses);
-  DCHECK(net_error);
+base::Optional<HostCache::Entry> HostResolverImpl::ServeFromCache(
+    const Key& key,
+    bool allow_stale,
+    HostCache::EntryStaleness* stale_info) {
   DCHECK(allow_stale == !!stale_info);
   if (!cache_.get())
-    return false;
+    return base::nullopt;
 
   const HostCache::Entry* cache_entry;
   if (allow_stale)
@@ -2522,25 +2591,20 @@
   else
     cache_entry = cache_->Lookup(key, tick_clock_->NowTicks());
   if (!cache_entry)
-    return false;
+    return base::nullopt;
 
-  *net_error = cache_entry->error();
-  if (*net_error == OK) {
+  if (cache_entry->error() == OK) {
     if (cache_entry->has_ttl())
       RecordTTL(cache_entry->ttl());
-    *addresses =
-        EnsurePortOnAddressList(cache_entry->addresses().value(), host_port);
   }
-  return true;
+
+  return *cache_entry;
 }
 
-bool HostResolverImpl::ServeFromHosts(const Key& key,
-                                      uint16_t host_port,
-                                      AddressList* addresses) {
-  DCHECK(addresses);
-  if (!HaveDnsConfig())
-    return false;
-  addresses->clear();
+base::Optional<HostCache::Entry> HostResolverImpl::ServeFromHosts(
+    const Key& key) {
+  if (!HaveDnsConfig() || !IsAddressType(key.dns_query_type))
+    return base::nullopt;
 
   // HOSTS lookups are case-insensitive.
   std::string hostname = base::ToLowerASCII(key.hostname);
@@ -2552,64 +2616,70 @@
   // flexibility, but lose implicit ordering.
   // We prefer IPv6 because "happy eyeballs" will fall back to IPv4 if
   // necessary.
+  AddressList addresses;
   if (key.dns_query_type == DnsQueryType::AAAA ||
       key.dns_query_type == DnsQueryType::UNSPECIFIED) {
     auto it = hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6));
     if (it != hosts.end())
-      addresses->push_back(IPEndPoint(it->second, host_port));
+      addresses.push_back(IPEndPoint(it->second, 0));
   }
 
   if (key.dns_query_type == DnsQueryType::A ||
       key.dns_query_type == DnsQueryType::UNSPECIFIED) {
     auto it = hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV4));
     if (it != hosts.end())
-      addresses->push_back(IPEndPoint(it->second, host_port));
+      addresses.push_back(IPEndPoint(it->second, 0));
   }
 
   // If got only loopback addresses and the family was restricted, resolve
   // again, without restrictions. See SystemHostResolverCall for rationale.
   if ((key.host_resolver_flags &
-          HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) &&
-      IsAllIPv4Loopback(*addresses)) {
+       HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) &&
+      IsAllIPv4Loopback(addresses)) {
     Key new_key(key);
     new_key.dns_query_type = DnsQueryType::UNSPECIFIED;
     new_key.host_resolver_flags &=
         ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
-    return ServeFromHosts(new_key, host_port, addresses);
+    return ServeFromHosts(new_key);
   }
-  return !addresses->empty();
+
+  if (!addresses.empty()) {
+    return HostCache::Entry(OK, std::move(addresses),
+                            HostCache::Entry::SOURCE_HOSTS);
+  }
+
+  return base::nullopt;
 }
 
-bool HostResolverImpl::ServeLocalhost(const Key& key,
-                                      uint16_t host_port,
-                                      AddressList* addresses) {
+base::Optional<HostCache::Entry> HostResolverImpl::ServeLocalhost(
+    const Key& key) {
   AddressList resolved_addresses;
-  if (!ResolveLocalHostname(key.hostname, host_port, &resolved_addresses))
-    return false;
+  if (!IsAddressType(key.dns_query_type) ||
+      !ResolveLocalHostname(key.hostname, &resolved_addresses)) {
+    return base::nullopt;
+  }
 
-  addresses->clear();
-
-  if (IsAddressType(key.dns_query_type)) {
-    for (const auto& address : resolved_addresses) {
-      // Include the address if:
-      // - caller didn't specify an address family, or
-      // - caller specifically asked for the address family of this address, or
-      // - this is an IPv6 address and caller specifically asked for IPv4 due
-      //   to lack of detected IPv6 support. (See SystemHostResolverCall for
-      //   rationale).
-      if (key.dns_query_type == DnsQueryType::UNSPECIFIED ||
-          DnsQueryTypeToAddressFamily(key.dns_query_type) ==
-              address.GetFamily() ||
-          (address.GetFamily() == ADDRESS_FAMILY_IPV6 &&
-           key.dns_query_type == DnsQueryType::A &&
-           (key.host_resolver_flags &
-            HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6))) {
-        addresses->push_back(address);
-      }
+  AddressList filtered_addresses;
+  for (const auto& address : resolved_addresses) {
+    // Include the address if:
+    // - caller didn't specify an address family, or
+    // - caller specifically asked for the address family of this address, or
+    // - this is an IPv6 address and caller specifically asked for IPv4 due
+    //   to lack of detected IPv6 support. (See SystemHostResolverCall for
+    //   rationale).
+    if (key.dns_query_type == DnsQueryType::UNSPECIFIED ||
+        DnsQueryTypeToAddressFamily(key.dns_query_type) ==
+            address.GetFamily() ||
+        (address.GetFamily() == ADDRESS_FAMILY_IPV6 &&
+         key.dns_query_type == DnsQueryType::A &&
+         (key.host_resolver_flags &
+          HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6))) {
+      filtered_addresses.push_back(address);
     }
   }
 
-  return true;
+  return HostCache::Entry(OK, std::move(filtered_addresses),
+                          HostCache::Entry::SOURCE_UNKNOWN);
 }
 
 void HostResolverImpl::CacheResult(const Key& key,
diff --git a/net/dns/host_resolver_impl.h b/net/dns/host_resolver_impl.h
index ff2c0a2..3d12082 100644
--- a/net/dns/host_resolver_impl.h
+++ b/net/dns/host_resolver_impl.h
@@ -241,11 +241,10 @@
   int Resolve(RequestImpl* request);
 
   // Attempts host resolution using fast local sources: IP literal resolution,
-  // cache lookup, HOSTS lookup (if enabled), and localhost. Returns OK if
-  // successful, ERR_NAME_NOT_RESOLVED if input is invalid, or
-  // ERR_DNS_CACHE_MISS if the host could not be resolved using local sources.
-  //
-  // On success, the resulting addresses are written to |addresses|.
+  // cache lookup, HOSTS lookup (if enabled), and localhost. Returns results
+  // with error() OK if successful, ERR_NAME_NOT_RESOLVED if input is invalid,
+  // or ERR_DNS_CACHE_MISS if the host could not be resolved using local
+  // sources.
   //
   // On ERR_DNS_CACHE_MISS and OK, the cache key for the request is written to
   // |key|. On other errors, it may not be.
@@ -256,33 +255,27 @@
   //
   // If |allow_stale| is false, then stale cache entries will not be returned,
   // and |stale_info| must be null.
-  int ResolveLocally(const HostPortPair& host,
-                     DnsQueryType requested_address_family,
-                     HostResolverSource source,
-                     HostResolverFlags flags,
-                     bool allow_cache,
-                     bool allow_stale,
-                     HostCache::EntryStaleness* stale_info,
-                     const NetLogWithSource& request_net_log,
-                     AddressList* addresses,
-                     Key* key);
+  HostCache::Entry ResolveLocally(const std::string& hostname,
+                                  DnsQueryType requested_address_family,
+                                  HostResolverSource source,
+                                  HostResolverFlags flags,
+                                  bool allow_cache,
+                                  bool allow_stale,
+                                  HostCache::EntryStaleness* stale_info,
+                                  const NetLogWithSource& request_net_log,
+                                  Key* out_key);
 
   // Attempts to create and start a Job to asynchronously attempt to resolve
   // |key|. On success, returns ERR_IO_PENDING and attaches the Job to
   // |request|. On error, marks |request| completed and returns the error.
   int CreateAndStartJob(const Key& key, RequestImpl* request);
 
-  // Tries to resolve |key| as an IP, returns true and sets |net_error| if
-  // succeeds, returns false otherwise.
-  bool ResolveAsIP(const Key& key,
-                   uint16_t host_port,
-                   const IPAddress* ip_address,
-                   int* net_error,
-                   AddressList* addresses);
+  // Tries to resolve |key| and its possible IP address representation,
+  // |ip_address|. Returns a results entry iff the input can be resolved.
+  base::Optional<HostCache::Entry> ResolveAsIP(const Key& key,
+                                               const IPAddress* ip_address);
 
-  // If |key| is not found in cache returns false, otherwise returns
-  // true, sets |net_error| to the cached error code and fills |addresses|
-  // if it is a positive entry.
+  // Returns the result iff a positive match is found for |key| in the cache.
   //
   // If |allow_stale| is true, then stale cache entries can be returned.
   // |stale_info| must be non-null, and will be filled in with details of the
@@ -290,24 +283,18 @@
   //
   // If |allow_stale| is false, then stale cache entries will not be returned,
   // and |stale_info| must be null.
-  bool ServeFromCache(const Key& key,
-                      uint16_t host_port,
-                      int* net_error,
-                      AddressList* addresses,
-                      bool allow_stale,
-                      HostCache::EntryStaleness* stale_info);
+  base::Optional<HostCache::Entry> ServeFromCache(
+      const Key& key,
+      bool allow_stale,
+      HostCache::EntryStaleness* stale_info);
 
-  // If we have a DnsClient with a valid DnsConfig, and |key| is found in the
-  // HOSTS file, returns true and fills |addresses|. Otherwise returns false.
-  bool ServeFromHosts(const Key& key,
-                      uint16_t host_port,
-                      AddressList* addresses);
+  // Iff we have a DnsClient with a valid DnsConfig, and |key| can be resolved
+  // from the HOSTS file, return the results.
+  base::Optional<HostCache::Entry> ServeFromHosts(const Key& key);
 
-  // If |key| is for a localhost name (RFC 6761), returns true and fills
-  // |addresses| with the loopback IP. Otherwise returns false.
-  bool ServeLocalhost(const Key& key,
-                      uint16_t host_port,
-                      AddressList* addresses);
+  // Iff |key| is for a localhost name (RFC 6761) and address DNS query type,
+  // returns a results entry with the loopback IP.
+  base::Optional<HostCache::Entry> ServeLocalhost(const Key& key);
 
   // Returns the (hostname, address_family) key to use for |info|, choosing an
   // "effective" address family by inheriting the resolver's default address
@@ -480,7 +467,7 @@
 };
 
 // Resolves a local hostname (such as "localhost" or "localhost6") into
-// IP endpoints with the given port. Returns true if |host| is a local
+// IP endpoints (with port 0). Returns true if |host| is a local
 // hostname and false otherwise. Special IPv6 names (e.g. "localhost6")
 // will resolve to an IPv6 address only, whereas other names will
 // resolve to both IPv4 and IPv6.
@@ -488,7 +475,6 @@
 // TODO(tfarina): It would be better to change the tests so this function
 // gets exercised indirectly through HostResolverImpl.
 NET_EXPORT_PRIVATE bool ResolveLocalHostname(base::StringPiece host,
-                                             uint16_t port,
                                              AddressList* address_list);
 
 }  // namespace net
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_impl_unittest.cc
index 1c65e37d..b7aa517 100644
--- a/net/dns/host_resolver_impl_unittest.cc
+++ b/net/dns/host_resolver_impl_unittest.cc
@@ -568,34 +568,27 @@
   }
 };
 
-const uint16_t kLocalhostLookupPort = 80;
-
-bool HasEndpoint(const IPEndPoint& endpoint, const AddressList& addresses) {
+bool HasAddress(const IPAddress& search_address, const AddressList& addresses) {
   for (const auto& address : addresses) {
-    if (endpoint == address)
+    if (search_address == address.address())
       return true;
   }
   return false;
 }
 
 void TestBothLoopbackIPs(const std::string& host) {
-  IPEndPoint localhost_ipv4(IPAddress::IPv4Localhost(), kLocalhostLookupPort);
-  IPEndPoint localhost_ipv6(IPAddress::IPv6Localhost(), kLocalhostLookupPort);
-
   AddressList addresses;
-  EXPECT_TRUE(ResolveLocalHostname(host, kLocalhostLookupPort, &addresses));
+  EXPECT_TRUE(ResolveLocalHostname(host, &addresses));
   EXPECT_EQ(2u, addresses.size());
-  EXPECT_TRUE(HasEndpoint(localhost_ipv4, addresses));
-  EXPECT_TRUE(HasEndpoint(localhost_ipv6, addresses));
+  EXPECT_TRUE(HasAddress(IPAddress::IPv4Localhost(), addresses));
+  EXPECT_TRUE(HasAddress(IPAddress::IPv6Localhost(), addresses));
 }
 
 void TestIPv6LoopbackOnly(const std::string& host) {
-  IPEndPoint localhost_ipv6(IPAddress::IPv6Localhost(), kLocalhostLookupPort);
-
   AddressList addresses;
-  EXPECT_TRUE(ResolveLocalHostname(host, kLocalhostLookupPort, &addresses));
+  EXPECT_TRUE(ResolveLocalHostname(host, &addresses));
   EXPECT_EQ(1u, addresses.size());
-  EXPECT_TRUE(HasEndpoint(localhost_ipv6, addresses));
+  EXPECT_TRUE(HasAddress(IPAddress::IPv6Localhost(), addresses));
 }
 
 // Used to bind the unique_ptr<Request>* into callbacks.
@@ -5628,7 +5621,9 @@
   EXPECT_THAT(request->Resolve(), IsError(ERR_IO_PENDING));
   ASSERT_THAT(request->WaitForResult(), IsOk());
 
-  EXPECT_TRUE(request->list().canonical_name().empty());
+  // HostResolver may still give name, but if so, it must be correct.
+  std::string result_name = request->list().canonical_name();
+  EXPECT_TRUE(result_name.empty() || result_name == "canonical");
 }
 
 TEST_F(HostResolverImplDnsTest, NoCanonicalName_CreateRequest) {
@@ -5645,8 +5640,10 @@
       HostPortPair("alias", 80), NetLogWithSource(), base::nullopt));
   ASSERT_THAT(response.result_error(), IsOk());
 
-  EXPECT_TRUE(
-      response.request()->GetAddressResults().value().canonical_name().empty());
+  // HostResolver may still give name, but if so, it must be correct.
+  std::string result_name =
+      response.request()->GetAddressResults().value().canonical_name();
+  EXPECT_TRUE(result_name.empty() || result_name == "canonical");
 }
 
 TEST_F(HostResolverImplDnsTest, CanonicalName_CreateRequest) {
@@ -5730,40 +5727,25 @@
   TestIPv6LoopbackOnly("localhost6.localdomain6");
   TestIPv6LoopbackOnly("localhost6.localdomain6.");
 
-  EXPECT_FALSE(
-      ResolveLocalHostname("127.0.0.1", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("::1", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:1", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname("localhostx", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname("localhost.x", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("foo.localdomain", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("foo.localdomain.x", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname("localhost6x", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("localhost.localdomain6",
-                                    kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("localhost6.localdomain",
-                                    kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname("127.0.0.1.1", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname(".127.0.0.255", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("::2", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("::1:1", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:1:0:0:1", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("::1:1", kLocalhostLookupPort, &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:0:1", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(ResolveLocalHostname("foo.localhost.com", kLocalhostLookupPort,
-                                    &addresses));
-  EXPECT_FALSE(
-      ResolveLocalHostname("foo.localhoste", kLocalhostLookupPort, &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("127.0.0.1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("::1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("localhostx", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("localhost.x", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("foo.localdomain", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("foo.localdomain.x", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("localhost6x", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("localhost.localdomain6", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("localhost6.localdomain", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("127.0.0.1.1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname(".127.0.0.255", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("::2", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("::1:1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:1:0:0:1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("::1:1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("0:0:0:0:0:0:0:0:1", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("foo.localhost.com", &addresses));
+  EXPECT_FALSE(ResolveLocalHostname("foo.localhoste", &addresses));
 }
 
 TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAfterConfig) {
diff --git a/net/dns/host_resolver_mdns_task.cc b/net/dns/host_resolver_mdns_task.cc
index 5f7d82f..6e0f2f6 100644
--- a/net/dns/host_resolver_mdns_task.cc
+++ b/net/dns/host_resolver_mdns_task.cc
@@ -19,13 +19,15 @@
 class HostResolverMdnsTask::Transaction {
  public:
   Transaction(DnsQueryType query_type, HostResolverMdnsTask* task)
-      : query_type_(query_type), result_(ERR_IO_PENDING), task_(task) {}
+      : query_type_(query_type),
+        results_(ERR_IO_PENDING, HostCache::Entry::SOURCE_UNKNOWN),
+        task_(task) {}
 
   void Start() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);
 
     // Should not be completed or running yet.
-    DCHECK_EQ(ERR_IO_PENDING, result_);
+    DCHECK_EQ(ERR_IO_PENDING, results_.error());
     DCHECK(!async_transaction_);
 
     // TODO(crbug.com/846423): Use |allow_cached_response| to set the
@@ -44,57 +46,67 @@
     bool start_result = inner_transaction->Start();
 
     if (!start_result)
-      task_->CompleteWithResult(ERR_FAILED, true /* post_needed */);
-    else if (result_ == ERR_IO_PENDING)
+      task_->Complete(true /* post_needed */);
+    else if (results_.error() == ERR_IO_PENDING)
       async_transaction_ = std::move(inner_transaction);
   }
 
-  bool IsDone() const { return result_ != ERR_IO_PENDING; }
+  bool IsDone() const { return results_.error() != ERR_IO_PENDING; }
   bool IsError() const {
-    return IsDone() && result_ != OK && result_ != ERR_NAME_NOT_RESOLVED;
+    return IsDone() && results_.error() != OK &&
+           results_.error() != ERR_NAME_NOT_RESOLVED;
   }
-  int result() const { return result_; }
+  const HostCache::Entry& results() const { return results_; }
 
   void Cancel() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);
-    DCHECK_EQ(ERR_IO_PENDING, result_);
+    DCHECK_EQ(ERR_IO_PENDING, results_.error());
 
-    result_ = ERR_FAILED;
+    results_ = HostCache::Entry(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
     async_transaction_ = nullptr;
   }
 
  private:
   void OnComplete(MDnsTransaction::Result result, const RecordParsed* parsed) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);
-    DCHECK_EQ(ERR_IO_PENDING, result_);
+    DCHECK_EQ(ERR_IO_PENDING, results_.error());
 
+    int error = ERR_UNEXPECTED;
     switch (result) {
       case MDnsTransaction::RESULT_RECORD:
-        result_ = OK;
+        error = OK;
         break;
       case MDnsTransaction::RESULT_NO_RESULTS:
       case MDnsTransaction::RESULT_NSEC:
-        result_ = ERR_NAME_NOT_RESOLVED;
+        error = ERR_NAME_NOT_RESOLVED;
         break;
       default:
         // No other results should be possible with the request flags used.
         NOTREACHED();
     }
 
-    if (result_ == net::OK) {
+    if (error == net::OK) {
       switch (query_type_) {
         case DnsQueryType::A:
-          task_->result_addresses_.push_back(
-              IPEndPoint(parsed->rdata<net::ARecordRdata>()->address(), 0));
+          results_ = HostCache::Entry(
+              OK,
+              AddressList(
+                  IPEndPoint(parsed->rdata<net::ARecordRdata>()->address(), 0)),
+              HostCache::Entry::SOURCE_UNKNOWN);
           break;
         case DnsQueryType::AAAA:
-          task_->result_addresses_.push_back(
-              IPEndPoint(parsed->rdata<net::AAAARecordRdata>()->address(), 0));
+          results_ = HostCache::Entry(
+              OK,
+              AddressList(IPEndPoint(
+                  parsed->rdata<net::AAAARecordRdata>()->address(), 0)),
+              HostCache::Entry::SOURCE_UNKNOWN);
           break;
         default:
           // TODO(crbug.com/846423): Add result parsing for non-address types.
           NOTIMPLEMENTED();
       }
+    } else {
+      results_ = HostCache::Entry(error, HostCache::Entry::SOURCE_UNKNOWN);
     }
 
     // If we don't have a saved async_transaction, it means OnComplete was
@@ -106,7 +118,7 @@
   const DnsQueryType query_type_;
 
   // ERR_IO_PENDING until transaction completes (or is cancelled).
-  int result_;
+  HostCache::Entry results_;
 
   // Not saved until MDnsTransaction::Start completes to differentiate inline
   // completion.
@@ -132,11 +144,11 @@
   transactions_.clear();
 }
 
-void HostResolverMdnsTask::Start(CompletionOnceCallback completion_callback) {
+void HostResolverMdnsTask::Start(base::OnceClosure completion_closure) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!completion_callback_);
+  DCHECK(!completion_closure_);
 
-  completion_callback_ = std::move(completion_callback);
+  completion_closure_ = std::move(completion_closure);
 
   for (auto& transaction : transactions_) {
     // Only start transaction if it is not already marked done. A transaction
@@ -147,29 +159,47 @@
   }
 }
 
-void HostResolverMdnsTask::CheckCompletion(bool post_needed) {
+HostCache::Entry HostResolverMdnsTask::GetResults() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!transactions_.empty());
+  DCHECK(!completion_closure_);
+  DCHECK(std::all_of(transactions_.begin(), transactions_.end(),
+                     [](const Transaction& t) { return t.IsDone(); }));
 
-  // Finish immediately if any transactions completed with an error.
   auto found_error =
       std::find_if(transactions_.begin(), transactions_.end(),
                    [](const Transaction& t) { return t.IsError(); });
   if (found_error != transactions_.end()) {
-    CompleteWithResult(found_error->result(), post_needed);
+    return found_error->results();
+  }
+
+  HostCache::Entry combined_results = transactions_.front().results();
+  for (auto it = ++transactions_.begin(); it != transactions_.end(); ++it) {
+    combined_results = HostCache::Entry::MergeEntries(
+        std::move(combined_results), it->results());
+  }
+
+  return combined_results;
+}
+
+void HostResolverMdnsTask::CheckCompletion(bool post_needed) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // Finish immediately if any transactions completed with an error.
+  if (std::any_of(transactions_.begin(), transactions_.end(),
+                  [](const Transaction& t) { return t.IsError(); })) {
+    Complete(post_needed);
     return;
   }
 
   if (std::all_of(transactions_.begin(), transactions_.end(),
                   [](const Transaction& t) { return t.IsDone(); })) {
-    // Task is overall successful if any of the transactions found results.
-    int result = result_addresses_.empty() ? ERR_NAME_NOT_RESOLVED : OK;
-
-    CompleteWithResult(result, post_needed);
+    Complete(post_needed);
     return;
   }
 }
 
-void HostResolverMdnsTask::CompleteWithResult(int result, bool post_needed) {
+void HostResolverMdnsTask::Complete(bool post_needed) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Cancel any incomplete async transactions.
@@ -180,15 +210,14 @@
 
   if (post_needed) {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            [](base::WeakPtr<HostResolverMdnsTask> task, int result) {
-              if (task)
-                std::move(task->completion_callback_).Run(result);
-            },
-            weak_ptr_factory_.GetWeakPtr(), result));
+        FROM_HERE, base::BindOnce(
+                       [](base::WeakPtr<HostResolverMdnsTask> task) {
+                         if (task)
+                           std::move(task->completion_closure_).Run();
+                       },
+                       weak_ptr_factory_.GetWeakPtr()));
   } else {
-    std::move(completion_callback_).Run(result);
+    std::move(completion_closure_).Run();
   }
 }
 
diff --git a/net/dns/host_resolver_mdns_task.h b/net/dns/host_resolver_mdns_task.h
index 90d3a7c..c4f9058 100644
--- a/net/dns/host_resolver_mdns_task.h
+++ b/net/dns/host_resolver_mdns_task.h
@@ -9,11 +9,12 @@
 #include <string>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
-#include "net/base/completion_once_callback.h"
+#include "net/dns/host_cache.h"
 #include "net/dns/host_resolver.h"
 #include "net/dns/mdns_client.h"
 #include "net/dns/public/dns_query_type.h"
@@ -31,28 +32,27 @@
                        const std::vector<DnsQueryType>& query_types);
   ~HostResolverMdnsTask();
 
-  // Starts the task. |completion_callback| will be called asynchronously with
-  // results.
+  // Starts the task. |completion_closure| will be called asynchronously.
   //
   // Should only be called once.
-  void Start(CompletionOnceCallback completion_callback);
+  void Start(base::OnceClosure completion_closure);
 
-  const AddressList& result_addresses() { return result_addresses_; }
+  // Results only available after invocation of the completion closure.
+  HostCache::Entry GetResults() const;
 
  private:
   class Transaction;
 
   void CheckCompletion(bool post_needed);
-  void CompleteWithResult(int result, bool post_needed);
+  void Complete(bool post_needed);
 
   MDnsClient* const mdns_client_;
 
   const std::string hostname_;
 
-  AddressList result_addresses_;
   std::vector<Transaction> transactions_;
 
-  CompletionOnceCallback completion_callback_;
+  base::OnceClosure completion_closure_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/net/dns/mapped_host_resolver.cc b/net/dns/mapped_host_resolver.cc
index 24cfb5d..64ef729 100644
--- a/net/dns/mapped_host_resolver.cc
+++ b/net/dns/mapped_host_resolver.cc
@@ -22,8 +22,22 @@
   int Start(CompletionOnceCallback callback) override { return error_; }
 
   const base::Optional<AddressList>& GetAddressResults() const override {
-    static base::NoDestructor<base::Optional<AddressList>> nullopt_address_list;
-    return *nullopt_address_list;
+    static base::NoDestructor<base::Optional<AddressList>> nullopt_result;
+    return *nullopt_result;
+  }
+
+  const base::Optional<std::vector<std::string>>& GetTextResults()
+      const override {
+    static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+        nullopt_result;
+    return *nullopt_result;
+  }
+
+  const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
+      const override {
+    static const base::NoDestructor<base::Optional<std::vector<HostPortPair>>>
+        nullopt_result;
+    return *nullopt_result;
   }
 
  private:
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index 9a292fe..073109f2 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -12,6 +12,7 @@
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
+#include "base/no_destructor.h"
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/pattern.h"
@@ -110,6 +111,22 @@
     return address_results_;
   }
 
+  const base::Optional<std::vector<std::string>>& GetTextResults()
+      const override {
+    DCHECK(complete_);
+    static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+        nullopt_result;
+    return *nullopt_result;
+  }
+
+  const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
+      const override {
+    DCHECK(complete_);
+    static const base::NoDestructor<base::Optional<std::vector<HostPortPair>>>
+        nullopt_result;
+    return *nullopt_result;
+  }
+
   void set_address_results(const AddressList& address_results) {
     // Should only be called at most once and before request is marked
     // completed.
@@ -741,6 +758,16 @@
     IMMEDIATE_CRASH();
   }
 
+  const base::Optional<std::vector<std::string>>& GetTextResults()
+      const override {
+    IMMEDIATE_CRASH();
+  }
+
+  const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
+      const override {
+    IMMEDIATE_CRASH();
+  }
+
   void ChangeRequestPriority(RequestPriority priority) override {}
 
  private:
diff --git a/net/http/transport_security_persister.cc b/net/http/transport_security_persister.cc
index efbbcf3..74c7c93 100644
--- a/net/http/transport_security_persister.cc
+++ b/net/http/transport_security_persister.cc
@@ -246,6 +246,25 @@
   writer_.ScheduleWrite(this);
 }
 
+void TransportSecurityPersister::WriteNow(TransportSecurityState* state,
+                                          base::OnceClosure callback) {
+  DCHECK(foreground_runner_->RunsTasksInCurrentSequence());
+  DCHECK_EQ(transport_security_state_, state);
+
+  writer_.RegisterOnNextWriteCallbacks(
+      base::OnceClosure(),
+      base::BindOnce(&TransportSecurityPersister::OnWriteFinished,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  auto data = std::make_unique<std::string>();
+  SerializeData(data.get());
+  writer_.WriteNow(std::move(data));
+}
+
+void TransportSecurityPersister::OnWriteFinished(base::OnceClosure callback,
+                                                 bool result) {
+  foreground_runner_->PostTask(FROM_HERE, std::move(callback));
+}
+
 bool TransportSecurityPersister::SerializeData(std::string* output) {
   DCHECK(foreground_runner_->RunsTasksInCurrentSequence());
 
diff --git a/net/http/transport_security_persister.h b/net/http/transport_security_persister.h
index 56e1c37..bfc85cb3 100644
--- a/net/http/transport_security_persister.h
+++ b/net/http/transport_security_persister.h
@@ -66,6 +66,9 @@
 
   // Called by the TransportSecurityState when it changes its state.
   void StateIsDirty(TransportSecurityState*) override;
+  // Called when the TransportSecurityState should be written immediately.
+  void WriteNow(TransportSecurityState* state,
+                base::OnceClosure callback) override;
 
   // ImportantFileWriter::DataSerializer:
   //
@@ -118,6 +121,7 @@
                           TransportSecurityState* state);
 
   void CompleteLoad(const std::string& state);
+  void OnWriteFinished(base::OnceClosure callback, bool result);
 
   TransportSecurityState* transport_security_state_;
 
diff --git a/net/http/transport_security_persister_unittest.cc b/net/http/transport_security_persister_unittest.cc
index 5dc5bc6..b5392b9 100644
--- a/net/http/transport_security_persister_unittest.cc
+++ b/net/http/transport_security_persister_unittest.cc
@@ -153,16 +153,13 @@
   std::string serialized;
   EXPECT_TRUE(persister_->SerializeData(&serialized));
 
-  // Persist the data to the file. For the test to be fast and not flaky, we
-  // just do it directly rather than call persister_->StateIsDirty. (That uses
-  // ImportantFileWriter, which has an asynchronous commit interval rather
-  // than block.) Use a different basename just for cleanliness.
-  base::FilePath path =
-      temp_dir_.GetPath().AppendASCII("TransportSecurityPersisterTest");
-  EXPECT_EQ(static_cast<int>(serialized.size()),
-            base::WriteFile(path, serialized.c_str(), serialized.size()));
+  // Persist the data to the file.
+  base::RunLoop run_loop;
+  persister_->WriteNow(&state_, run_loop.QuitClosure());
+  run_loop.Run();
 
   // Read the data back.
+  base::FilePath path = temp_dir_.GetPath().AppendASCII("TransportSecurity");
   std::string persisted;
   EXPECT_TRUE(base::ReadFileToString(path, &persisted));
   EXPECT_EQ(persisted, serialized);
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index f2b3b76..fe43390 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -897,7 +897,9 @@
   enabled_expect_ct_hosts_.clear();
 }
 
-void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
+void TransportSecurityState::DeleteAllDynamicDataSince(
+    const base::Time& time,
+    base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   bool dirtied = false;
@@ -934,8 +936,10 @@
     ++expect_ct_iterator;
   }
 
-  if (dirtied)
-    DirtyNotify();
+  if (dirtied && delegate_)
+    delegate_->WriteNow(this, std::move(callback));
+  else
+    std::move(callback).Run();
 }
 
 TransportSecurityState::~TransportSecurityState() {
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index 5617c50..5e772fd 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -52,6 +52,10 @@
     // This function may not block and may be called with internal locks held.
     // Thus it must not reenter the TransportSecurityState object.
     virtual void StateIsDirty(TransportSecurityState* state) = 0;
+    // Same as StateIsDirty but instructs the Delegate to persist the data
+    // immediately and call |callback| when done.
+    virtual void WriteNow(TransportSecurityState* state,
+                          base::OnceClosure callback) = 0;
 
    protected:
     virtual ~Delegate() {}
@@ -417,8 +421,9 @@
   // time.
   //
   // If any entries are deleted, the new state will be persisted through
-  // the Delegate (if any).
-  void DeleteAllDynamicDataSince(const base::Time& time);
+  // the Delegate (if any). Calls |callback| when data is persisted to disk.
+  void DeleteAllDynamicDataSince(const base::Time& time,
+                                 base::OnceClosure callback);
 
   // Deletes any dynamic data stored for |host| (e.g. HSTS or HPKP data).
   // If |host| doesn't have an exact entry then no action is taken. Does
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index d789aaa57..8822b6c 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "base/base64.h"
+#include "base/bind_helpers.h"
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/field_trial.h"
@@ -731,11 +732,11 @@
                 GetSampleSPKIHashes(), GURL());
   state.AddExpectCT("example.com", expiry, true, GURL());
 
-  state.DeleteAllDynamicDataSince(expiry);
+  state.DeleteAllDynamicDataSince(expiry, base::DoNothing());
   EXPECT_TRUE(state.ShouldUpgradeToSSL("example.com"));
   EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
   EXPECT_TRUE(state.GetDynamicExpectCTState("example.com", &expect_ct_state));
-  state.DeleteAllDynamicDataSince(older);
+  state.DeleteAllDynamicDataSince(older, base::DoNothing());
   EXPECT_FALSE(state.ShouldUpgradeToSSL("example.com"));
   EXPECT_FALSE(state.HasPublicKeyPins("example.com"));
   EXPECT_FALSE(state.GetDynamicExpectCTState("example.com", &expect_ct_state));
diff --git a/services/BUILD.gn b/services/BUILD.gn
index d8bb6a48..238f76e 100644
--- a/services/BUILD.gn
+++ b/services/BUILD.gn
@@ -3,8 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/ui.gni")
-import("//services/catalog/public/tools/catalog.gni")
-import("//services/service_manager/public/tools/test/service_test.gni")
 import("//testing/test.gni")
 import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
 
@@ -12,18 +10,8 @@
 # to avoid having to maintain a separate test binary for every service.
 #
 # To add tests for a new service, please define a "tests" source_set in the
-# service subdirectory and add it as a dependency here. If your unit tests
-# use the ServiceTest framework, you must also include corresponding catalog
-# entries in the "services_unittests_catalog" target below.
-#
-# TODO(https://crbug.com/906239): Move all platforms off of service_test.
-if (is_ios) {
-  services_unittests_target_type = "test"
-} else {
-  services_unittests_target_type = "service_test"
-}
-
-target(services_unittests_target_type, "services_unittests") {
+# service subdirectory and add it as a dependency here.
+test("services_unittests") {
   # If your service does not run on iOS, its tests should go in the !iOS
   # section below. If you are unsure, contact blundell@chromium.org.
   deps = [
@@ -32,6 +20,7 @@
     "//services/metrics/public/cpp:tests",
     "//services/network:tests",
     "//services/network/public/cpp:tests",
+    "//services/test:run_all_unittests",
   ]
 
   if (!is_ios) {
@@ -85,41 +74,14 @@
     # standalone services must be added here.
     deps += [ "//services/video_capture:tests" ]
   }
-
-  if (is_ios) {
-    deps += [ "//mojo/core/test:run_all_unittests" ]
-  } else {
-    test_runner = "//services/test:run_all_service_tests"
-    catalog = ":services_unittests_catalog"
-  }
 }
 
 if (!is_ios) {
-  catalog("services_unittests_catalog") {
-    testonly = true
-
-    catalog_deps = [
-      "//services/video_capture:tests_catalog",
-      "//services/viz:tests_catalog",
-    ]
-
-    if (use_aura) {
-      catalog_deps += [
-        "//services/ws/ime:tests_catalog",
-        "//services/ws:tests_catalog",
-      ]
-    }
-  }
-
-  service_test("services_perftests") {
+  test("services_perftests") {
     deps = [
+      "//services/test:run_all_unittests",
       "//services/viz/public/cpp/compositing:perftests",
     ]
-    catalog = ":services_perftests_catalog"
-  }
-
-  catalog("services_perftests_catalog") {
-    testonly = true
   }
 }
 
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc
index 8c2a95e..f3f91b4 100644
--- a/services/identity/public/cpp/identity_test_environment.cc
+++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -24,7 +24,8 @@
 class IdentityManagerDependenciesOwner {
  public:
   IdentityManagerDependenciesOwner(
-      bool use_fake_url_loader_for_gaia_cookie_manager);
+      bool use_fake_url_loader_for_gaia_cookie_manager,
+      sync_preferences::TestingPrefServiceSyncable* pref_service);
   ~IdentityManagerDependenciesOwner();
 
   AccountTrackerService* account_tracker_service();
@@ -35,8 +36,15 @@
 
   FakeGaiaCookieManagerService* gaia_cookie_manager_service();
 
+  sync_preferences::TestingPrefServiceSyncable* pref_service();
+
  private:
-  sync_preferences::TestingPrefServiceSyncable pref_service_;
+  // Depending on whether a |pref_service| instance is passed in
+  // the constructor, exactly one of these will be non-null.
+  std::unique_ptr<sync_preferences::TestingPrefServiceSyncable>
+      owned_pref_service_;
+  sync_preferences::TestingPrefServiceSyncable* raw_pref_service_ = nullptr;
+
   AccountTrackerService account_tracker_;
   TestSigninClient signin_client_;
   FakeProfileOAuth2TokenService token_service_;
@@ -47,9 +55,16 @@
 };
 
 IdentityManagerDependenciesOwner::IdentityManagerDependenciesOwner(
-    bool use_fake_url_loader_for_gaia_cookie_manager)
-    : signin_client_(&pref_service_),
-      token_service_(&pref_service_),
+    bool use_fake_url_loader_for_gaia_cookie_manager,
+    sync_preferences::TestingPrefServiceSyncable* pref_service_param)
+    : owned_pref_service_(
+          pref_service_param
+              ? nullptr
+              : std::make_unique<
+                    sync_preferences::TestingPrefServiceSyncable>()),
+      raw_pref_service_(pref_service_param),
+      signin_client_(pref_service()),
+      token_service_(pref_service()),
 #if defined(OS_CHROMEOS)
       signin_manager_(&signin_client_, &account_tracker_),
 #else
@@ -71,13 +86,13 @@
           &token_service_,
           &signin_client_,
           use_fake_url_loader_for_gaia_cookie_manager) {
-  AccountTrackerService::RegisterPrefs(pref_service_.registry());
-  ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
-  SigninManagerBase::RegisterProfilePrefs(pref_service_.registry());
-  SigninManagerBase::RegisterPrefs(pref_service_.registry());
+  AccountTrackerService::RegisterPrefs(pref_service()->registry());
+  ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service()->registry());
+  SigninManagerBase::RegisterProfilePrefs(pref_service()->registry());
+  SigninManagerBase::RegisterPrefs(pref_service()->registry());
 
-  account_tracker_.Initialize(&pref_service_, base::FilePath());
-  signin_manager_.Initialize(&pref_service_);
+  account_tracker_.Initialize(pref_service(), base::FilePath());
+  signin_manager_.Initialize(pref_service());
 }
 
 IdentityManagerDependenciesOwner::~IdentityManagerDependenciesOwner() {}
@@ -101,15 +116,25 @@
   return &gaia_cookie_manager_service_;
 }
 
+sync_preferences::TestingPrefServiceSyncable*
+IdentityManagerDependenciesOwner::pref_service() {
+  DCHECK(raw_pref_service_ || owned_pref_service_);
+  DCHECK(!(raw_pref_service_ && owned_pref_service_));
+
+  return raw_pref_service_ ? raw_pref_service_ : owned_pref_service_.get();
+}
+
 IdentityTestEnvironment::IdentityTestEnvironment(
-    bool use_fake_url_loader_for_gaia_cookie_manager)
+    bool use_fake_url_loader_for_gaia_cookie_manager,
+    sync_preferences::TestingPrefServiceSyncable* pref_service)
     : IdentityTestEnvironment(
           /*account_tracker_service=*/nullptr,
           /*token_service=*/nullptr,
           /*signin_manager=*/nullptr,
           /*gaia_cookie_manager_service=*/nullptr,
           std::make_unique<IdentityManagerDependenciesOwner>(
-              use_fake_url_loader_for_gaia_cookie_manager),
+              use_fake_url_loader_for_gaia_cookie_manager,
+              pref_service),
           /*identity_manager=*/nullptr) {}
 
 IdentityTestEnvironment::IdentityTestEnvironment(
diff --git a/services/identity/public/cpp/identity_test_environment.h b/services/identity/public/cpp/identity_test_environment.h
index ac4e0fe..c8bd5a55 100644
--- a/services/identity/public/cpp/identity_test_environment.h
+++ b/services/identity/public/cpp/identity_test_environment.h
@@ -16,6 +16,10 @@
 class IdentityTestEnvironmentChromeBrowserStateAdaptor;
 class IdentityTestEnvironmentProfileAdaptor;
 
+namespace sync_preferences {
+class TestingPrefServiceSyncable;
+}
+
 namespace identity {
 
 namespace {
@@ -46,8 +50,15 @@
   // IdentityTestEnvironment is being introduced to incrementally convert
   // a test). In that case, use the below constructor and switch to this
   // constructor once the conversion is complete.
+  //
+  // Additionally, this constructor also takes an optional PrefService
+  // instance as parameter, which allows tests to move away from referencing
+  // IdentityManager's dependencies directly (namely AccountTrackerService,
+  // PO2TS, SigninManager and GaiaCookieManagerService), but still be able
+  // to tweak preferences on demand.
   IdentityTestEnvironment(
-      bool use_fake_url_loader_for_gaia_cookie_manager = false);
+      bool use_fake_url_loader_for_gaia_cookie_manager = false,
+      sync_preferences::TestingPrefServiceSyncable* pref_service = nullptr);
 
   // Constructor that takes in instances of the dependencies of
   // IdentityManager and constructs an IdentityManager instance from those
diff --git a/services/identity/public/cpp/primary_account_mutator_impl.cc b/services/identity/public/cpp/primary_account_mutator_impl.cc
index 78316b30..cc9d3d3 100644
--- a/services/identity/public/cpp/primary_account_mutator_impl.cc
+++ b/services/identity/public/cpp/primary_account_mutator_impl.cc
@@ -41,6 +41,12 @@
     ClearAccountsAction action,
     signin_metrics::ProfileSignout source_metric,
     signin_metrics::SignoutDelete delete_metric) {
+  // Check if and auth process is ongoing before reporting failure to support
+  // the legacy workflow of cancelling it by clearing the primary account.
+  if (!signin_manager_->IsAuthenticated() &&
+      !LegacyIsPrimaryAccountAuthInProgress())
+    return false;
+
   // TODO: report failure if SignOut is not allowed.
 
   switch (action) {
@@ -88,11 +94,12 @@
         const std::string& username,
         const std::string& password,
         base::OnceCallback<void(const std::string&)> callback) {
-  NOTIMPLEMENTED();
+  signin_manager_->StartSignInWithRefreshToken(refresh_token, gaia_id, username,
+                                               password, std::move(callback));
 }
 
 void PrimaryAccountMutatorImpl::LegacyCompletePendingPrimaryAccountSignin() {
-  NOTIMPLEMENTED();
+  signin_manager_->CompletePendingSignin();
 }
 
 void PrimaryAccountMutatorImpl::LegacyMergeSigninCredentialIntoCookieJar() {
@@ -100,14 +107,20 @@
 }
 
 bool PrimaryAccountMutatorImpl::LegacyIsPrimaryAccountAuthInProgress() const {
-  NOTIMPLEMENTED();
-  return false;
+  return signin_manager_->AuthInProgress();
 }
 
 AccountInfo PrimaryAccountMutatorImpl::LegacyPrimaryAccountForAuthInProgress()
     const {
-  NOTIMPLEMENTED();
-  return AccountInfo{};
+  if (!LegacyIsPrimaryAccountAuthInProgress())
+    return AccountInfo{};
+
+  AccountInfo account_info;
+  account_info.account_id = signin_manager_->GetAccountIdForAuthInProgress();
+  account_info.gaia = signin_manager_->GetGaiaIdForAuthInProgress();
+  account_info.email = signin_manager_->GetUsernameForAuthInProgress();
+
+  return account_info;
 }
 
 void PrimaryAccountMutatorImpl::LegacyCopyCredentialsFrom(
diff --git a/services/identity/public/cpp/primary_account_mutator_unittest.cc b/services/identity/public/cpp/primary_account_mutator_unittest.cc
index 34dbdc9..581a4ea 100644
--- a/services/identity/public/cpp/primary_account_mutator_unittest.cc
+++ b/services/identity/public/cpp/primary_account_mutator_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "services/identity/public/cpp/primary_account_mutator.h"
 
+#include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
 #include "components/signin/core/browser/signin_metrics.h"
 #include "services/identity/public/cpp/identity_test_environment.h"
@@ -13,6 +14,8 @@
 const char kUnknownAccountId[] = "{unknown account id}";
 const char kPrimaryAccountEmail[] = "primary.account@example.com";
 const char kAnotherAccountEmail[] = "another.account@example.com";
+const char kRefreshToken[] = "refresh_token";
+const char kPassword[] = "password";
 }  // namespace
 
 class PrimaryAccountMutatorTest : public PlatformTest {
@@ -136,6 +139,30 @@
       primary_account_info.account_id));
 }
 
+TEST_F(PrimaryAccountMutatorTest, ClearPrimaryAccount_NotSignedIn) {
+  // Abort the test if the current platform does not support mutation of the
+  // primary account (the returned PrimaryAccountMutator* will be null).
+  if (!primary_account_mutator())
+    return;
+
+  // Trying to signout an account that hasn't signed in first should fail.
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(primary_account_mutator()->ClearPrimaryAccount(
+      identity::PrimaryAccountMutator::ClearAccountsAction::kDefault,
+      signin_metrics::SIGNOUT_TEST,
+      signin_metrics::SignoutDelete::IGNORE_METRIC));
+
+  // Adding an account without signing in should yield similar a result.
+  AccountInfo primary_account_info =
+      environment()->MakeAccountAvailable(kPrimaryAccountEmail);
+
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(primary_account_mutator()->ClearPrimaryAccount(
+      identity::PrimaryAccountMutator::ClearAccountsAction::kDefault,
+      signin_metrics::SIGNOUT_TEST,
+      signin_metrics::SignoutDelete::IGNORE_METRIC));
+}
+
 TEST_F(PrimaryAccountMutatorTest, ClearPrimaryAccount_Default) {
   if (!primary_account_mutator())
     return;
@@ -242,4 +269,216 @@
       primary_account_info.account_id));
   EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
       other_account_info.account_id));
-}
\ No newline at end of file
+}
+
+// Checks that checking whether an authentication process is in progress reports
+// true before starting and after successfully completing the signin process.
+TEST_F(PrimaryAccountMutatorTest, SigninWithRefreshToken) {
+  // Abort the test if the current platform does not support mutation of the
+  // primary account (the returned PrimaryAccountMutator* will be null).
+  if (!primary_account_mutator())
+    return;
+
+  // We'll sign in the same account twice, using SetPrimaryAccount() and
+  // LegacyStartSigninWithRefreshTokenForPrimaryAccount(), and check that
+  // in both cases the end result is the same.
+  AccountInfo account_info =
+      environment()->MakeAccountAvailable(kPrimaryAccountEmail);
+
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_TRUE(
+      primary_account_mutator()->SetPrimaryAccount(account_info.account_id));
+
+  const std::string primary_account_id_1 =
+      identity_manager()->GetPrimaryAccountId();
+
+  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(primary_account_id_1.empty());
+  EXPECT_EQ(primary_account_id_1, account_info.account_id);
+
+  EXPECT_TRUE(
+      identity_manager()->HasAccountWithRefreshToken(primary_account_id_1));
+  EXPECT_FALSE(identity_manager()->GetPrimaryAccountInfo().email.empty());
+
+  // Sign out the account to try to sign in again with the other mechanism, but
+  // using kKeepAll so we can use the same account we made available before.
+  EXPECT_TRUE(primary_account_mutator()->ClearPrimaryAccount(
+      identity::PrimaryAccountMutator::ClearAccountsAction::kKeepAll,
+      signin_metrics::SIGNOUT_TEST,
+      signin_metrics::SignoutDelete::IGNORE_METRIC));
+
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_TRUE(identity_manager()->GetPrimaryAccountId().empty());
+  EXPECT_TRUE(identity_manager()->GetPrimaryAccountInfo().email.empty());
+
+  // Start a signin process for the account and complete it right away to check
+  // whether we end up with a similar result than with SetPrimaryAccount().
+  std::string signed_account_refresh_token;
+  primary_account_mutator()->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
+      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      base::BindOnce(
+          [](std::string* out_refresh_token, const std::string& refresh_token) {
+            *out_refresh_token = refresh_token;
+          },
+          base::Unretained(&signed_account_refresh_token)));
+
+  primary_account_mutator()->LegacyCompletePendingPrimaryAccountSignin();
+
+  // The refresh token assigned to the account should match the one passed.
+  EXPECT_EQ(signed_account_refresh_token, kRefreshToken);
+
+  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(primary_account_id_1.empty());
+  EXPECT_EQ(primary_account_id_1, account_info.account_id);
+
+  EXPECT_TRUE(
+      identity_manager()->HasAccountWithRefreshToken(primary_account_id_1));
+  EXPECT_FALSE(identity_manager()->GetPrimaryAccountInfo().email.empty());
+
+  const std::string primary_account_id_2 =
+      identity_manager()->GetPrimaryAccountId();
+
+  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(primary_account_id_2.empty());
+  EXPECT_EQ(primary_account_id_2, account_info.account_id);
+
+  EXPECT_TRUE(
+      identity_manager()->HasAccountWithRefreshToken(primary_account_id_2));
+  EXPECT_FALSE(identity_manager()->GetPrimaryAccountInfo().email.empty());
+
+  // Information retrieved via the IdentityManager now for the current primary
+  // account should match the data of the account we signed in before.
+  EXPECT_EQ(primary_account_id_1, primary_account_id_2);
+}
+
+// Checks that checking whether an authentication process is in progress reports
+// true before starting and after successfully completing the signin process.
+TEST_F(PrimaryAccountMutatorTest, AuthInProgress_SigninCompleted) {
+  // Abort the test if the current platform does not support mutation of the
+  // primary account (the returned PrimaryAccountMutator* will be null).
+  if (!primary_account_mutator())
+    return;
+
+  AccountInfo account_info =
+      environment()->MakeAccountAvailable(kPrimaryAccountEmail);
+
+  // Account available in the tracker service but still not authenticated means
+  // there's neither a primary account nor an authentication process ongoing.
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  // Start a signin process for the account we just made available and check
+  // that it's reported to be in progress before the process is completed.
+  base::RunLoop run_loop;
+  std::string signed_account_refresh_token;
+  primary_account_mutator()->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
+      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      base::BindOnce(
+          [](std::string* out_refresh_token, const std::string& refresh_token) {
+            *out_refresh_token = refresh_token;
+          },
+          base::Unretained(&signed_account_refresh_token)));
+
+  EXPECT_TRUE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  AccountInfo auth_in_progress_account_info =
+      primary_account_mutator()->LegacyPrimaryAccountForAuthInProgress();
+
+  // The data from the AccountInfo related to the authentication process still
+  // in progress should match the data of the account being signed in.
+  EXPECT_EQ(auth_in_progress_account_info.account_id, account_info.account_id);
+  EXPECT_EQ(auth_in_progress_account_info.gaia, account_info.gaia);
+  EXPECT_EQ(auth_in_progress_account_info.email, account_info.email);
+
+  // Finally, complete the signin process so that we can do further checks.
+  primary_account_mutator()->LegacyCompletePendingPrimaryAccountSignin();
+  run_loop.RunUntilIdle();
+
+  // The refresh token assigned to the account should match the one passed.
+  EXPECT_EQ(signed_account_refresh_token, kRefreshToken);
+
+  // An account has been authenticated now, so there should be a primary account
+  // authenticated and no authentication process reported as in progress now.
+  EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  // Information retrieved via the IdentityManager now for the current primary
+  // account should match the data of the account being signed in.
+  EXPECT_EQ(identity_manager()->GetPrimaryAccountId(), account_info.account_id);
+  AccountInfo identity_manager_account_info =
+      identity_manager()->GetPrimaryAccountInfo();
+  EXPECT_EQ(identity_manager_account_info.account_id, account_info.account_id);
+  EXPECT_EQ(identity_manager_account_info.gaia, account_info.gaia);
+  EXPECT_EQ(identity_manager_account_info.email, account_info.email);
+}
+
+// Checks that checking whether an authentication process is in progress reports
+// true before starting and after cancelling and ongoing signin process.
+TEST_F(PrimaryAccountMutatorTest, AuthInProgress_SigninCancelled) {
+  // Abort the test if the current platform does not support mutation of the
+  // primary account (the returned PrimaryAccountMutator* will be null).
+  if (!primary_account_mutator())
+    return;
+
+  AccountInfo account_info =
+      environment()->MakeAccountAvailable(kPrimaryAccountEmail);
+
+  // Account available in the tracker service but still not authenticated means
+  // there's neither a primary account nor an authentication process ongoing.
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  // Start a signin process for the account we just made available and check
+  // that it's reported to be in progress before the process is completed.
+  base::RunLoop run_loop;
+  std::string signed_account_refresh_token;
+  primary_account_mutator()->LegacyStartSigninWithRefreshTokenForPrimaryAccount(
+      kRefreshToken, account_info.gaia, account_info.email, kPassword,
+      base::BindOnce(
+          [](std::string* out_refresh_token, const std::string& refresh_token) {
+            *out_refresh_token = refresh_token;
+          },
+          base::Unretained(&signed_account_refresh_token)));
+
+  EXPECT_TRUE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  AccountInfo auth_in_progress_account_info =
+      primary_account_mutator()->LegacyPrimaryAccountForAuthInProgress();
+
+  // The data from the AccountInfo related to the authentication process still
+  // in progress should match the data of the account being signed in.
+  EXPECT_EQ(auth_in_progress_account_info.account_id, account_info.account_id);
+  EXPECT_EQ(auth_in_progress_account_info.gaia, account_info.gaia);
+  EXPECT_EQ(auth_in_progress_account_info.email, account_info.email);
+
+  // Now cancel the signin process (by attempting to clear the primary account
+  // we were trying to sign in so far), so that we can do further checks.
+  EXPECT_TRUE(primary_account_mutator()->ClearPrimaryAccount(
+      identity::PrimaryAccountMutator::ClearAccountsAction::kRemoveAll,
+      signin_metrics::SIGNOUT_TEST,
+      signin_metrics::SignoutDelete::IGNORE_METRIC));
+  run_loop.RunUntilIdle();
+
+  // The refresh token assigned to the account should match the one passed.
+  EXPECT_EQ(signed_account_refresh_token, kRefreshToken);
+
+  // The request has been cancelled, so there should not be a primary account
+  // signed in, the refresh we just received should not be valid for the primary
+  // account (even if it's been fetched and stored for the account already) and
+  // no authentication process reported as in progress now.
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
+  EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
+  EXPECT_TRUE(
+      identity_manager()->HasAccountWithRefreshToken(account_info.account_id));
+  EXPECT_FALSE(
+      primary_account_mutator()->LegacyIsPrimaryAccountAuthInProgress());
+
+  // Information retrieved via the IdentityManager confirms the cancelation.
+  EXPECT_EQ(identity_manager()->GetPrimaryAccountId(), std::string());
+  EXPECT_TRUE(identity_manager()->GetPrimaryAccountInfo().IsEmpty());
+}
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.h b/services/identity/public/objc/identity_manager_observer_bridge.h
index 85d9543a..32c5ae65 100644
--- a/services/identity/public/objc/identity_manager_observer_bridge.h
+++ b/services/identity/public/objc/identity_manager_observer_bridge.h
@@ -27,7 +27,10 @@
 - (void)onRefreshTokenUpdatedForAccount:(const AccountInfo&)accountInfo
                                   valid:(BOOL)isValid;
 - (void)onRefreshTokenRemovedForAccount:(const std::string&)accountId;
+- (void)onRefreshTokensLoaded;
 - (void)onAccountsInCookieUpdated:(const std::vector<AccountInfo>&)accounts;
+- (void)onStartBatchOfRefreshTokenStateChanges;
+- (void)onEndBatchOfRefreshTokenStateChanges;
 
 @end
 
@@ -49,8 +52,11 @@
   void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info,
                                        bool is_valid) override;
   void OnRefreshTokenRemovedForAccount(const std::string& account_id) override;
+  void OnRefreshTokensLoaded() override;
   void OnAccountsInCookieUpdated(
       const std::vector<AccountInfo>& accounts) override;
+  void OnStartBatchOfRefreshTokenStateChanges() override;
+  void OnEndBatchOfRefreshTokenStateChanges() override;
 
  private:
   // Identity manager to observe.
diff --git a/services/identity/public/objc/identity_manager_observer_bridge.mm b/services/identity/public/objc/identity_manager_observer_bridge.mm
index f2def54..0f4d265 100644
--- a/services/identity/public/objc/identity_manager_observer_bridge.mm
+++ b/services/identity/public/objc/identity_manager_observer_bridge.mm
@@ -52,6 +52,12 @@
   }
 }
 
+void IdentityManagerObserverBridge::OnRefreshTokensLoaded() {
+  if ([delegate_ respondsToSelector:@selector(onRefreshTokensLoaded)]) {
+    [delegate_ onRefreshTokensLoaded];
+  }
+}
+
 void IdentityManagerObserverBridge::OnAccountsInCookieUpdated(
     const std::vector<AccountInfo>& accounts) {
   if ([delegate_ respondsToSelector:@selector(onAccountsInCookieUpdated:)]) {
@@ -59,4 +65,18 @@
   }
 }
 
+void IdentityManagerObserverBridge::OnStartBatchOfRefreshTokenStateChanges() {
+  if ([delegate_ respondsToSelector:@selector
+                 (onStartBatchOfRefreshTokenStateChanges)]) {
+    [delegate_ onStartBatchOfRefreshTokenStateChanges];
+  }
+}
+
+void IdentityManagerObserverBridge::OnEndBatchOfRefreshTokenStateChanges() {
+  if ([delegate_
+          respondsToSelector:@selector(onEndBatchOfRefreshTokenStateChanges)]) {
+    [delegate_ onEndBatchOfRefreshTokenStateChanges];
+  }
+}
+
 }  // namespace identity
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 1b38d05..3eef70c 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/barrier_closure.h"
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/containers/unique_ptr_adapters.h"
@@ -731,20 +732,19 @@
 void NetworkContext::ClearNetworkingHistorySince(
     base::Time time,
     base::OnceClosure completion_callback) {
+  auto barrier = base::BarrierClosure(2, std::move(completion_callback));
+
+  url_request_context_->transport_security_state()->DeleteAllDynamicDataSince(
+      time, barrier);
+
   // TODO(mmenke): Neither of these methods waits until the changes have been
   // commited to disk. They probably should, as most similar methods net/
   // exposes do.
-
-  // Completes synchronously.
-  url_request_context_->transport_security_state()->DeleteAllDynamicDataSince(
-      time);
-
   // May not be set in all tests.
   if (network_qualities_pref_delegate_)
     network_qualities_pref_delegate_->ClearPrefs();
 
-  url_request_context_->http_server_properties()->Clear(
-      std::move(completion_callback));
+  url_request_context_->http_server_properties()->Clear(barrier);
 }
 
 void NetworkContext::ClearHttpCache(base::Time start_time,
diff --git a/services/service_manager/public/cpp/service.cc b/services/service_manager/public/cpp/service.cc
index 2b49e25..4adfb73 100644
--- a/services/service_manager/public/cpp/service.cc
+++ b/services/service_manager/public/cpp/service.cc
@@ -14,7 +14,7 @@
 Service::~Service() = default;
 
 // static
-void Service::RunUntilTermination(std::unique_ptr<Service> service) {
+void Service::RunAsyncUntilTermination(std::unique_ptr<Service> service) {
   auto* raw_service = service.get();
   raw_service->set_termination_closure(base::BindOnce(
       [](std::unique_ptr<Service> service) {}, std::move(service)));
diff --git a/services/service_manager/public/cpp/service.h b/services/service_manager/public/cpp/service.h
index f316a404..60726b5c 100644
--- a/services/service_manager/public/cpp/service.h
+++ b/services/service_manager/public/cpp/service.h
@@ -32,7 +32,7 @@
   // This should really only be called on a Service instance that has a bound
   // connection to the Service Manager, e.g. a functioning ServiceBinding. If
   // the service never calls |Terminate()|, it will effectively leak.
-  static void RunUntilTermination(std::unique_ptr<Service> service);
+  static void RunAsyncUntilTermination(std::unique_ptr<Service> service);
 
   // Sets a closure to run when the service wants to self-terminate. This may be
   // used by whomever created the Service instance in order to clean up
diff --git a/services/test/BUILD.gn b/services/test/BUILD.gn
index 907bc3a..76aa1a4c 100644
--- a/services/test/BUILD.gn
+++ b/services/test/BUILD.gn
@@ -4,7 +4,7 @@
 
 import("//build/config/ui.gni")
 
-source_set("run_all_service_tests") {
+source_set("run_all_unittests") {
   # This target is in a separate directory because we want to expand DEPS so
   # that it not all of //services can access //ui.
   visibility = [ "//services:*" ]
@@ -12,13 +12,13 @@
   testonly = true
 
   sources = [
-    "run_all_service_tests.cc",
+    "run_all_unittests.cc",
   ]
 
   deps = [
     "//base",
     "//base/test:test_support",
-    "//services/service_manager/public/cpp/test:common_initialization",
+    "//mojo/core/embedder",
     "//ui/base",
   ]
 
@@ -41,7 +41,7 @@
 }
 
 bundle_data("tests_bundle_data") {
-  visibility = [ ":run_all_service_tests" ]
+  visibility = [ ":run_all_unittests" ]
   testonly = true
   sources = [
     "//services/test/data/content-sniffer-test0.html",
diff --git a/services/test/run_all_service_tests.cc b/services/test/run_all_unittests.cc
similarity index 64%
rename from services/test/run_all_service_tests.cc
rename to services/test/run_all_unittests.cc
index ca6d59a..7e14ead 100644
--- a/services/test/run_all_service_tests.cc
+++ b/services/test/run_all_unittests.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,15 +6,26 @@
 #include "base/files/file.h"
 #include "base/i18n/icu_util.h"
 #include "base/macros.h"
+#include "base/message_loop/message_loop.h"
 #include "base/path_service.h"
 #include "base/test/launcher/unit_test_launcher.h"
 #include "base/test/test_suite.h"
+#include "base/threading/thread.h"
 #include "build/build_config.h"
-#include "services/service_manager/public/cpp/test/common_initialization.h"
+#include "mojo/core/embedder/embedder.h"
+#include "mojo/core/embedder/scoped_ipc_support.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/resource/scale_factor.h"
 #include "ui/base/ui_base_paths.h"
 
+#if defined(OS_ANDROID)
+#include "base/android/jni_android.h"
+#endif
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "mojo/core/embedder/default_mach_broker.h"
+#endif
+
 namespace {
 
 class ServiceTestSuite : public base::TestSuite {
@@ -25,6 +36,8 @@
  protected:
   void Initialize() override {
     base::TestSuite::Initialize();
+
+#if !defined(OS_IOS)
     ui::RegisterPathProvider();
 
     base::FilePath ui_test_pak_path;
@@ -41,13 +54,17 @@
         path.Append(FILE_PATH_LITERAL("bluetooth_test_strings.pak"));
     ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
         bluetooth_test_strings, ui::SCALE_FACTOR_NONE);
+#endif  // !defined(OS_IOS)
 
     // base::TestSuite and ViewsInit both try to load icu. That's ok for tests.
     base::i18n::AllowMultipleInitializeCallsForTesting();
   }
 
   void Shutdown() override {
+#if !defined(OS_IOS)
     ui::ResourceBundle::CleanupSharedInstance();
+#endif
+
     base::TestSuite::Shutdown();
   }
 
@@ -60,7 +77,21 @@
 int main(int argc, char** argv) {
   ServiceTestSuite test_suite(argc, argv);
 
-  return service_manager::InitializeAndLaunchUnitTests(
+  mojo::core::Init();
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  mojo::core::SetMachPortProvider(
+      mojo::core::DefaultMachBroker::Get()->port_provider());
+#endif
+
+  base::Thread ipc_thread("IPC thread");
+  ipc_thread.StartWithOptions(
+      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
+  mojo::core::ScopedIPCSupport ipc_support(
+      ipc_thread.task_runner(),
+      mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
+
+  return base::LaunchUnitTests(
       argc, argv,
-      base::Bind(&ServiceTestSuite::Run, base::Unretained(&test_suite)));
+      base::BindOnce(&ServiceTestSuite::Run, base::Unretained(&test_suite)));
 }
diff --git a/services/video_capture/BUILD.gn b/services/video_capture/BUILD.gn
index 836a1a685..1651485 100644
--- a/services/video_capture/BUILD.gn
+++ b/services/video_capture/BUILD.gn
@@ -2,9 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//services/catalog/public/tools/catalog.gni")
 import("//services/service_manager/public/cpp/service.gni")
 import("//services/service_manager/public/service_manifest.gni")
-import("//services/service_manager/public/tools/test/service_test.gni")
 import("//testing/test.gni")
 
 service("video_capture") {
@@ -93,12 +93,12 @@
 
   deps = [
     ":lib",
+    ":tests_catalog_source",
     ":video_capture",
     "//base/test:test_support",
     "//media/capture:test_support",
     "//media/capture/mojom:video_capture",
     "//services/service_manager/public/cpp",
-    "//services/service_manager/public/cpp:service_test_support",
     "//services/service_manager/public/cpp/test:test_support",
     "//services/video_capture/public/cpp:mocks",
     "//testing/gmock",
@@ -117,6 +117,13 @@
 }
 
 catalog("tests_catalog") {
+  testonly = true
   embedded_services = [ ":unittest_manifest" ]
   standalone_services = [ ":manifest" ]
 }
+
+catalog_cpp_source("tests_catalog_source") {
+  testonly = true
+  catalog = ":tests_catalog"
+  generated_function_name = "video_capture::CreateTestCatalog"
+}
diff --git a/services/video_capture/test/device_factory_provider_test.cc b/services/video_capture/test/device_factory_provider_test.cc
index dc210830..c7d611e 100644
--- a/services/video_capture/test/device_factory_provider_test.cc
+++ b/services/video_capture/test/device_factory_provider_test.cc
@@ -10,6 +10,7 @@
 #include "services/service_manager/public/mojom/service_manager.mojom.h"
 #include "services/video_capture/public/cpp/mock_producer.h"
 #include "services/video_capture/public/mojom/constants.mojom.h"
+#include "services/video_capture/tests_catalog_source.h"
 
 namespace video_capture {
 
@@ -22,7 +23,10 @@
     ~SharedMemoryVirtualDeviceContext() = default;
 
 DeviceFactoryProviderTest::DeviceFactoryProviderTest()
-    : service_manager::test::ServiceTest("video_capture_unittests") {}
+    : test_service_manager_(CreateTestCatalog()),
+      test_service_binding_(&test_service_,
+                            test_service_manager_.RegisterTestInstance(
+                                "video_capture_unittests")) {}
 
 DeviceFactoryProviderTest::~DeviceFactoryProviderTest() = default;
 
@@ -32,8 +36,6 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kUseFakeDeviceForMediaStream, "device-count=3");
 
-  service_manager::test::ServiceTest::SetUp();
-
   connector()->BindInterface(mojom::kServiceName, &factory_provider_);
   // Note, that we explicitly do *not* call
   // |factory_provider_->InjectGpuDependencies()| here. Test case
diff --git a/services/video_capture/test/device_factory_provider_test.h b/services/video_capture/test/device_factory_provider_test.h
index 4874e6e0..fe3262ba 100644
--- a/services/video_capture/test/device_factory_provider_test.h
+++ b/services/video_capture/test/device_factory_provider_test.h
@@ -5,16 +5,22 @@
 #ifndef SERVICES_VIDEO_CAPTURE_VIDEO_CAPTURE_TEST_DEVICE_FACTORY_PROVIDER_TEST_H_
 #define SERVICES_VIDEO_CAPTURE_VIDEO_CAPTURE_TEST_DEVICE_FACTORY_PROVIDER_TEST_H_
 
+#include "base/macros.h"
 #include "base/test/mock_callback.h"
-#include "services/service_manager/public/cpp/service_test.h"
+#include "base/test/scoped_task_environment.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
+#include "services/service_manager/public/cpp/test/test_service_manager.h"
 #include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace video_capture {
 
 class MockProducer;
 
 // Basic test fixture that sets up a connection to the fake device factory.
-class DeviceFactoryProviderTest : public service_manager::test::ServiceTest {
+class DeviceFactoryProviderTest : public testing::Test {
  public:
   DeviceFactoryProviderTest();
   ~DeviceFactoryProviderTest() override;
@@ -36,10 +42,21 @@
   mojom::TextureVirtualDevicePtr AddTextureVirtualDevice(
       const std::string& device_id);
 
+  service_manager::Connector* connector() {
+    return test_service_binding_.GetConnector();
+  }
+
+  base::test::ScopedTaskEnvironment task_environment_;
+  service_manager::TestServiceManager test_service_manager_;
+  service_manager::Service test_service_;
+  service_manager::ServiceBinding test_service_binding_;
+
   mojom::DeviceFactoryProviderPtr factory_provider_;
   mojom::DeviceFactoryPtr factory_;
   base::MockCallback<mojom::DeviceFactory::GetDeviceInfosCallback>
       device_info_receiver_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceFactoryProviderTest);
 };
 
 }  // namespace video_capture
diff --git a/services/ws/BUILD.gn b/services/ws/BUILD.gn
index ef33a27..489d0bcc 100644
--- a/services/ws/BUILD.gn
+++ b/services/ws/BUILD.gn
@@ -4,11 +4,11 @@
 
 import("//build/config/ui.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
-import("//testing/test.gni")
 import("//services/catalog/public/tools/catalog.gni")
 import("//services/service_manager/public/cpp/service.gni")
 import("//services/service_manager/public/service_manifest.gni")
 import("//services/service_manager/public/tools/test/service_test.gni")
+import("//testing/test.gni")
 
 component("lib") {
   friend = [
@@ -158,12 +158,13 @@
 
   deps = [
     ":lib",
+    ":tests_catalog_source",
     "//base",
     "//base/test:test_support",
     "//components/viz/test:test_support",
     "//mojo/public/cpp/bindings:bindings",
     "//services/service_manager/public/cpp",
-    "//services/service_manager/public/cpp:service_test_support",
+    "//services/service_manager/public/cpp/test:test_support",
     "//services/ws/common",
     "//services/ws/public/cpp",
     "//services/ws/public/cpp/host",
@@ -196,6 +197,12 @@
   standalone_services = [ "//services/ws/test_ws:manifest" ]
 }
 
+catalog_cpp_source("tests_catalog_source") {
+  testonly = true
+  catalog = ":tests_catalog"
+  generated_function_name = "ws::test::CreateTestCatalog"
+}
+
 source_set("tests") {
   testonly = true
 
diff --git a/services/ws/ime/BUILD.gn b/services/ws/ime/BUILD.gn
index 7b16499..53fe131 100644
--- a/services/ws/ime/BUILD.gn
+++ b/services/ws/ime/BUILD.gn
@@ -5,7 +5,6 @@
 import("//services/catalog/public/tools/catalog.gni")
 import("//services/service_manager/public/cpp/service.gni")
 import("//services/service_manager/public/service_manifest.gni")
-import("//services/service_manager/public/tools/test/service_test.gni")
 import("//testing/test.gni")
 
 source_set("lib") {
@@ -32,11 +31,14 @@
   ]
 
   deps = [
+    ":tests_catalog_source",
     "//base",
+    "//base/test:test_support",
     "//services/service_manager/public/cpp",
-    "//services/service_manager/public/cpp:service_test_support",
+    "//services/service_manager/public/cpp/test:test_support",
     "//services/ws/ime/test_ime_driver/public/mojom",
     "//services/ws/public/mojom",
+    "//testing/gtest",
   ]
 
   data_deps = [
@@ -53,5 +55,14 @@
 catalog("tests_catalog") {
   testonly = true
   embedded_services = [ ":unittest_manifest" ]
-  standalone_services = [ "//services/ws/ime/test_ime_driver:manifest" ]
+  standalone_services = [
+    "//services/ws/ime/test_ime_driver:manifest",
+    "//services/ws/test_ws:manifest",
+  ]
+}
+
+catalog_cpp_source("tests_catalog_source") {
+  testonly = true
+  catalog = ":tests_catalog"
+  generated_function_name = "ws::test::CreateImeTestCatalog"
 }
diff --git a/services/ws/ime/ime_unittest.cc b/services/ws/ime/ime_unittest.cc
index 5c168ba..828c00e 100644
--- a/services/ws/ime/ime_unittest.cc
+++ b/services/ws/ime/ime_unittest.cc
@@ -7,12 +7,16 @@
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/service_manager/public/cpp/service_context.h"
-#include "services/service_manager/public/cpp/service_test.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
+#include "services/service_manager/public/cpp/test/test_service_manager.h"
 #include "services/ws/ime/test_ime_driver/public/mojom/constants.mojom.h"
+#include "services/ws/ime/tests_catalog_source.h"
 #include "services/ws/public/mojom/constants.mojom.h"
 #include "services/ws/public/mojom/ime/ime.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 
@@ -54,14 +58,13 @@
   DISALLOW_COPY_AND_ASSIGN(TestTextInputClient);
 };
 
-class IMEAppTest : public service_manager::test::ServiceTest {
+class IMEAppTest : public testing::Test {
  public:
-  IMEAppTest() : ServiceTest("ime_unittests") {}
-  ~IMEAppTest() override {}
-
-  // service_manager::test::ServiceTest:
-  void SetUp() override {
-    ServiceTest::SetUp();
+  IMEAppTest()
+      : test_service_manager_(ws::test::CreateImeTestCatalog()),
+        test_service_binding_(
+            &test_service_,
+            test_service_manager_.RegisterTestInstance("ime_unittests")) {
     // test_ime_driver will register itself as the current IMEDriver.
     // TODO(https://crbug.com/904148): This should not use |WarmService()|.
     connector()->WarmService(service_manager::ServiceFilter::ByName(
@@ -69,6 +72,12 @@
     connector()->BindInterface(ws::mojom::kServiceName, &ime_driver_);
   }
 
+  ~IMEAppTest() override {}
+
+  service_manager::Connector* connector() {
+    return test_service_binding_.GetConnector();
+  }
+
   bool ProcessKeyEvent(ws::mojom::InputMethodPtr* input_method,
                        std::unique_ptr<ui::Event> event) {
     (*input_method)
@@ -89,6 +98,11 @@
     run_loop_->Quit();
   }
 
+  base::test::ScopedTaskEnvironment task_environment_;
+  service_manager::TestServiceManager test_service_manager_;
+  service_manager::Service test_service_;
+  service_manager::ServiceBinding test_service_binding_;
+
   ws::mojom::IMEDriverPtr ime_driver_;
   std::unique_ptr<base::RunLoop> run_loop_;
   bool handled_;
diff --git a/services/ws/ime/test_ime_driver/main.cc b/services/ws/ime/test_ime_driver/main.cc
index a23932d..1e125de 100644
--- a/services/ws/ime/test_ime_driver/main.cc
+++ b/services/ws/ime/test_ime_driver/main.cc
@@ -3,10 +3,18 @@
 // found in the LICENSE file.
 
 #include "services/service_manager/public/c/main.h"
-#include "services/service_manager/public/cpp/service_runner.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 #include "services/ws/ime/test_ime_driver/test_ime_application.h"
 
 MojoResult ServiceMain(MojoHandle service_request_handle) {
-  service_manager::ServiceRunner runner(new ws::test::TestIMEApplication);
-  return runner.Run(service_request_handle);
+  base::MessageLoop message_loop;
+  base::RunLoop run_loop;
+  ws::test::TestIMEApplication app{service_manager::mojom::ServiceRequest(
+      mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_request_handle)))};
+  app.set_termination_closure(run_loop.QuitClosure());
+  run_loop.Run();
+  return MOJO_RESULT_OK;
 }
diff --git a/services/ws/ime/test_ime_driver/test_ime_application.cc b/services/ws/ime/test_ime_driver/test_ime_application.cc
index 9a5d8af..33067a0d 100644
--- a/services/ws/ime/test_ime_driver/test_ime_application.cc
+++ b/services/ws/ime/test_ime_driver/test_ime_application.cc
@@ -6,7 +6,6 @@
 
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "services/service_manager/public/cpp/connector.h"
-#include "services/service_manager/public/cpp/service_context.h"
 #include "services/ws/ime/test_ime_driver/test_ime_driver.h"
 #include "services/ws/public/mojom/constants.mojom.h"
 #include "services/ws/public/mojom/ime/ime.mojom.h"
@@ -14,9 +13,11 @@
 namespace ws {
 namespace test {
 
-TestIMEApplication::TestIMEApplication() {}
+TestIMEApplication::TestIMEApplication(
+    service_manager::mojom::ServiceRequest request)
+    : service_binding_(this, std::move(request)) {}
 
-TestIMEApplication::~TestIMEApplication() {}
+TestIMEApplication::~TestIMEApplication() = default;
 
 void TestIMEApplication::OnStart() {
   mojom::IMEDriverPtr ime_driver_ptr;
@@ -24,7 +25,8 @@
                           MakeRequest(&ime_driver_ptr));
 
   mojom::IMERegistrarPtr ime_registrar;
-  context()->connector()->BindInterface(mojom::kServiceName, &ime_registrar);
+  service_binding_.GetConnector()->BindInterface(mojom::kServiceName,
+                                                 &ime_registrar);
   ime_registrar->RegisterDriver(std::move(ime_driver_ptr));
 }
 
diff --git a/services/ws/ime/test_ime_driver/test_ime_application.h b/services/ws/ime/test_ime_driver/test_ime_application.h
index 408d328..f61f041 100644
--- a/services/ws/ime/test_ime_driver/test_ime_application.h
+++ b/services/ws/ime/test_ime_driver/test_ime_application.h
@@ -7,19 +7,23 @@
 
 #include "base/macros.h"
 #include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 
 namespace ws {
 namespace test {
 
 class TestIMEApplication : public service_manager::Service {
  public:
-  TestIMEApplication();
+  explicit TestIMEApplication(service_manager::mojom::ServiceRequest request);
   ~TestIMEApplication() override;
 
  private:
   // service_manager::Service:
   void OnStart() override;
 
+  service_manager::ServiceBinding service_binding_;
+
   DISALLOW_COPY_AND_ASSIGN(TestIMEApplication);
 };
 
diff --git a/services/ws/window_server_service_test_base.cc b/services/ws/window_server_service_test_base.cc
index 44d73a6..3209b1a 100644
--- a/services/ws/window_server_service_test_base.cc
+++ b/services/ws/window_server_service_test_base.cc
@@ -7,11 +7,9 @@
 #include <memory>
 
 #include "base/command_line.h"
-#include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/public/cpp/service_test.h"
 #include "services/ws/common/switches.h"
+#include "services/ws/tests_catalog_source.h"
 #include "ui/gl/gl_switches.h"
 
 namespace ws {
@@ -20,27 +18,6 @@
 
 const char kTestAppName[] = "ui_ws2_service_unittests";
 
-class WindowServerServiceTestClient
-    : public service_manager::test::ServiceTestClient {
- public:
-  explicit WindowServerServiceTestClient(WindowServerServiceTestBase* test)
-      : ServiceTestClient(test), test_(test) {}
-  ~WindowServerServiceTestClient() override {}
-
- private:
-  // service_manager::test::ServiceTestClient:
-  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
-                       const std::string& interface_name,
-                       mojo::ScopedMessagePipeHandle interface_pipe) override {
-    test_->OnBindInterface(source_info, interface_name,
-                           std::move(interface_pipe));
-  }
-
-  WindowServerServiceTestBase* test_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowServerServiceTestClient);
-};
-
 void EnsureCommandLineSwitch(const std::string& name) {
   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
   if (!cmd_line->HasSwitch(name))
@@ -50,16 +27,18 @@
 }  // namespace
 
 WindowServerServiceTestBase::WindowServerServiceTestBase()
-    : ServiceTest(kTestAppName) {
+    : test_service_manager_(test::CreateTestCatalog()),
+      test_service_binding_(
+          this,
+          test_service_manager_.RegisterTestInstance(kTestAppName)) {
   EnsureCommandLineSwitch(switches::kUseTestConfig);
   EnsureCommandLineSwitch(::switches::kOverrideUseSoftwareGLForTests);
 }
 
-WindowServerServiceTestBase::~WindowServerServiceTestBase() {}
+WindowServerServiceTestBase::~WindowServerServiceTestBase() = default;
 
-std::unique_ptr<service_manager::Service>
-WindowServerServiceTestBase::CreateService() {
-  return std::make_unique<WindowServerServiceTestClient>(this);
+const char* WindowServerServiceTestBase::test_name() const {
+  return kTestAppName;
 }
 
 }  // namespace ws
diff --git a/services/ws/window_server_service_test_base.h b/services/ws/window_server_service_test_base.h
index 117e619..17a2a14 100644
--- a/services/ws/window_server_service_test_base.h
+++ b/services/ws/window_server_service_test_base.h
@@ -6,24 +6,36 @@
 #define SERVICES_WS_WINDOW_SERVER_SERVICE_TEST_BASE_H_
 
 #include "base/macros.h"
-#include "services/service_manager/public/cpp/service_test.h"
+#include "base/test/scoped_task_environment.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/service.h"
+#include "services/service_manager/public/cpp/service_binding.h"
+#include "services/service_manager/public/cpp/test/test_service_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace ws {
 
-// Base class for all window manager ServiceTests to perform some common setup.
-class WindowServerServiceTestBase : public service_manager::test::ServiceTest {
+// Base class for all window manager service tests to perform some common setup.
+// This fixture brings up a test Service Manager and acts as a service instance
+// which identifies as the service named "ui_ws2_service_unittests". Subclasses
+// can implement |OnBindInterface()| to handle interface requests targeting that
+// instance in tests.
+class WindowServerServiceTestBase : public testing::Test,
+                                    public service_manager::Service {
  public:
   WindowServerServiceTestBase();
   ~WindowServerServiceTestBase() override;
 
-  virtual void OnBindInterface(
-      const service_manager::BindSourceInfo& source_info,
-      const std::string& interface_name,
-      mojo::ScopedMessagePipeHandle interface_pipe) = 0;
+  service_manager::Connector* connector() {
+    return test_service_binding_.GetConnector();
+  }
+
+  const char* test_name() const;
 
  private:
-  // service_manager::test::ServiceTest:
-  std::unique_ptr<service_manager::Service> CreateService() override;
+  base::test::ScopedTaskEnvironment task_environment_;
+  service_manager::TestServiceManager test_service_manager_;
+  service_manager::ServiceBinding test_service_binding_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowServerServiceTestBase);
 };
diff --git a/services/ws/window_tree_client_unittest.cc b/services/ws/window_tree_client_unittest.cc
index 3559a70..aaad599 100644
--- a/services/ws/window_tree_client_unittest.cc
+++ b/services/ws/window_tree_client_unittest.cc
@@ -13,7 +13,6 @@
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
-#include "services/service_manager/public/cpp/service_test.h"
 #include "services/ws/common/util.h"
 #include "services/ws/ids.h"
 #include "services/ws/public/mojom/constants.mojom.h"
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 90eafa2..8ba9734e 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -140,10 +140,6 @@
 #   define SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE
 #endif
 
-#ifndef SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT
-#define SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT
-#endif
-
 // Remove this after we fixed all the issues related to the new SDF algorithm
 // (https://codereview.chromium.org/1643143002)
 #ifndef SK_USE_LEGACY_DISTANCE_FIELDS
diff --git a/styleguide/python/python.md b/styleguide/python/python.md
index d73d8ea..0f30b544 100644
--- a/styleguide/python/python.md
+++ b/styleguide/python/python.md
@@ -30,5 +30,27 @@
 
 ## Tools
 
+### pylint
 [Depot tools](http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools.html)
 contains a local copy of pylint, appropriately configured.
+ * Directories need to opt into pylint presumbit checks via:
+   `input_api.canned_checks.RunPylint()`.
+
+### YAPF
+[YAPF](https://github.com/google/yapf) is a Python formatter that can be used via:
+
+```sh
+git cl format --python
+```
+
+Directories can opt into enforcing YAPF styling by adding `.style.yapf` file
+with the following contents:
+```
+[style]
+based_on_style = chromium
+```
+
+Entire files can be formatted (rather than just touched lines) via:
+```sh
+git cl format --python --full
+```
\ No newline at end of file
diff --git a/testing/buildbot/chromium.webrtc.json b/testing/buildbot/chromium.webrtc.json
index b13dadb4..27e271c 100644
--- a/testing/buildbot/chromium.webrtc.json
+++ b/testing/buildbot/chromium.webrtc.json
@@ -1,8 +1,8 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
-  "Android Builder": {},
-  "Android Tester": {
+  "WebRTC Chromium Android Builder": {},
+  "WebRTC Chromium Android Tester": {
     "gtest_tests": [
       {
         "args": [
@@ -27,111 +27,6 @@
       }
     ]
   },
-  "Mac Builder": {
-    "additional_compile_targets": [
-      "frame_analyzer",
-      "jingle_unittests",
-      "remoting_unittests"
-    ]
-  },
-  "Mac Tester": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--gtest_filter=WebRtcApprtcBrowserTest.*",
-          "--run-manual",
-          "--test-launcher-jobs=1"
-        ],
-        "name": "browser_tests_apprtc",
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "browser_tests"
-      },
-      {
-        "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter",
-          "--run-manual",
-          "--test-launcher-jobs=1"
-        ],
-        "name": "browser_tests_functional",
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "browser_tests"
-      },
-      {
-        "args": [
-          "--enable-logging",
-          "--v=1",
-          "--test-launcher-jobs=1",
-          "--test-launcher-print-test-stdio=always"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": false
-        },
-        "test": "capture_unittests"
-      },
-      {
-        "args": [
-          "--gtest_filter=WebRtc*"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
-          "--gtest_filter=UsingRealWebcam*",
-          "--run-manual",
-          "--test-launcher-jobs=1"
-        ],
-        "name": "content_browsertests_sequential",
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
-          "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*",
-          "--run-manual",
-          "--ui-test-action-max-timeout=120000"
-        ],
-        "name": "content_browsertests_stress",
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "jingle_unittests"
-      },
-      {
-        "args": [
-          "--gtest_filter=Webrtc*"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "remoting_unittests"
-      }
-    ]
-  },
-  "Mac Tester (long-running)": {},
   "WebRTC Chromium Linux Builder": {
     "additional_compile_targets": [
       "frame_analyzer",
@@ -236,14 +131,14 @@
       }
     ]
   },
-  "Win Builder": {
+  "WebRTC Chromium Mac Builder": {
     "additional_compile_targets": [
       "frame_analyzer",
       "jingle_unittests",
       "remoting_unittests"
     ]
   },
-  "Win10 Tester": {
+  "WebRTC Chromium Mac Tester": {
     "gtest_tests": [
       {
         "args": [
@@ -340,7 +235,14 @@
       }
     ]
   },
-  "Win7 Tester": {
+  "WebRTC Chromium Win Builder": {
+    "additional_compile_targets": [
+      "frame_analyzer",
+      "jingle_unittests",
+      "remoting_unittests"
+    ]
+  },
+  "WebRTC Chromium Win10 Tester": {
     "gtest_tests": [
       {
         "args": [
@@ -437,8 +339,104 @@
       }
     ]
   },
-  "Win7 Tester (long-running)": {},
-  "Win8 Tester": {
+  "WebRTC Chromium Win7 Tester": {
+    "gtest_tests": [
+      {
+        "args": [
+          "--gtest_filter=WebRtcApprtcBrowserTest.*",
+          "--run-manual",
+          "--test-launcher-jobs=1"
+        ],
+        "name": "browser_tests_apprtc",
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "browser_tests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc_functional.browser_tests.filter",
+          "--run-manual",
+          "--test-launcher-jobs=1"
+        ],
+        "name": "browser_tests_functional",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "browser_tests"
+      },
+      {
+        "args": [
+          "--enable-logging",
+          "--v=1",
+          "--test-launcher-jobs=1",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
+        "test": "capture_unittests"
+      },
+      {
+        "args": [
+          "--gtest_filter=WebRtc*"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--gtest_filter=UsingRealWebcam*",
+          "--run-manual",
+          "--test-launcher-jobs=1"
+        ],
+        "name": "content_browsertests_sequential",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--gtest_filter=WebRtc*MANUAL*:-UsingRealWebcam*",
+          "--run-manual",
+          "--ui-test-action-max-timeout=120000"
+        ],
+        "name": "content_browsertests_stress",
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "content_browsertests"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/webrtc.content_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "content_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "jingle_unittests"
+      },
+      {
+        "args": [
+          "--gtest_filter=Webrtc*"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "remoting_unittests"
+      }
+    ]
+  },
+  "WebRTC Chromium Win8 Tester": {
     "gtest_tests": [
       {
         "args": [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 0c1cbece..4f7aa34 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -3326,25 +3326,12 @@
   {
     'name': 'chromium.webrtc',
     'machines': {
-      'Android Builder': {},
-      'Android Tester': {
+      'WebRTC Chromium Android Builder': {},
+      'WebRTC Chromium Android Tester': {
         'test_suites': {
           'gtest_tests': 'webrtc_android_tests_with_baremetal_tests',
         },
       },
-      'Mac Builder': {
-        'additional_compile_targets': [
-          'frame_analyzer',
-          'jingle_unittests',
-          'remoting_unittests',
-        ],
-      },
-      'Mac Tester': {
-        'test_suites': {
-          'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
-        },
-      },
-      'Mac Tester (long-running)': {},
       'WebRTC Chromium Linux Builder': {
         'additional_compile_targets': [
           'frame_analyzer',
@@ -3357,26 +3344,36 @@
           'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
         },
       },
-      'Win Builder': {
+      'WebRTC Chromium Mac Builder': {
         'additional_compile_targets': [
           'frame_analyzer',
           'jingle_unittests',
           'remoting_unittests',
         ],
       },
-      'Win10 Tester': {
+      'WebRTC Chromium Mac Tester': {
         'test_suites': {
           'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
         },
       },
-      'Win7 Tester': {
+      'WebRTC Chromium Win Builder': {
+        'additional_compile_targets': [
+          'frame_analyzer',
+          'jingle_unittests',
+          'remoting_unittests',
+        ],
+      },
+      'WebRTC Chromium Win10 Tester': {
         'test_suites': {
           'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
         },
       },
-      # TODO(crbug.com/877018): delete long-running bots.
-      'Win7 Tester (long-running)': {},
-      'Win8 Tester': {
+      'WebRTC Chromium Win7 Tester': {
+        'test_suites': {
+          'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
+        },
+      },
+      'WebRTC Chromium Win8 Tester': {
         'test_suites': {
           'gtest_tests': 'webrtc_chromium_tests_with_baremetal_tests',
         },
diff --git a/third_party/blink/public/README.md b/third_party/blink/public/README.md
index b9c21cd1..fa00f0f 100644
--- a/third_party/blink/public/README.md
+++ b/third_party/blink/public/README.md
@@ -31,13 +31,13 @@
 Blink is designed to run in a sandbox and interacts with the operating system
 via the platform API. The central interface in this part of the API is
 Platform, which is a pure virtual interface from which Blink obtains many other
-interfaces. public/platform/ is implemented by WebKit/Source/platform/exported/.
+interfaces. public/platform/ is implemented by blink/renderer/platform/exported.
 
 The public/web directory defines an interface to Blink's implementation of the
 web platform, including the Document Object Model (DOM). The central interface
 in this part of the API is WebView, which is a good starting point for
 exploring the API. public/web/ is implemented by
-WebKit/Source/{core,modules,controller}/exported/.
+blink/renderer/{core,modules}/exported/.
 
 Note that public/platform should not depend on public/web.
 
diff --git a/third_party/blink/public/blink_resources.grd b/third_party/blink/public/blink_resources.grd
index ec9af0a..42047241c 100644
--- a/third_party/blink/public/blink_resources.grd
+++ b/third_party/blink/public/blink_resources.grd
@@ -8,19 +8,19 @@
   </outputs>
   <release seq="1">
     <includes>
-      <!-- Source/core/css/html.css processed through minimize_css.py -->
+      <!-- renderer/core/html/resources/html.css processed through minimize_css.py -->
       <include name="IDR_UASTYLE_HTML_CSS" file="${cwd}/${html_min_css}" type="BINDATA" compress="gzip"/>
-      <include name="IDR_UASTYLE_QUIRKS_CSS" file="../renderer/core/css/quirks.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_QUIRKS_CSS" file="../renderer/core/html/resources/quirks.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_VIEW_SOURCE_CSS" file="../renderer/core/css/view-source.css" type="BINDATA" compress="gzip"/>
-      <include name="IDR_UASTYLE_THEME_CHROMIUM_ANDROID_CSS" file="../renderer/core/css/themeChromiumAndroid.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_THEME_CHROMIUM_ANDROID_CSS" file="../renderer/core/html/resources/android.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_FULLSCREEN_ANDROID_CSS" file="../renderer/core/css/fullscreenAndroid.css" type="BINDATA" compress="gzip"/>
-      <include name="IDR_UASTYLE_THEME_CHROMIUM_LINUX_CSS" file="../renderer/core/css/themeChromiumLinux.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_THEME_CHROMIUM_LINUX_CSS" file="../renderer/core/html/resources/linux.css" type="BINDATA" compress="gzip"/>
       <if expr="is_macosx">
-        <include name="IDR_UASTYLE_THEME_MAC_CSS" file="../renderer/core/css/themeMac.css" type="BINDATA" compress="gzip"/>
+        <include name="IDR_UASTYLE_THEME_MAC_CSS" file="../renderer/core/html/resources/mac.css" type="BINDATA" compress="gzip"/>
       </if>
-      <include name="IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS" file="../renderer/core/css/themeInputMultipleFields.css" type="BINDATA" compress="gzip"/>
-      <include name="IDR_UASTYLE_THEME_WIN_CSS" file="../renderer/core/css/themeWin.css" type="BINDATA" compress="gzip"/>
-      <include name="IDR_UASTYLE_THEME_WIN_QUIRKS_CSS" file="../renderer/core/css/themeWinQuirks.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS" file="../renderer/core/html/resources/input_multiple_fields.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_THEME_WIN_CSS" file="../renderer/core/html/resources/win.css" type="BINDATA" compress="gzip"/>
+      <include name="IDR_UASTYLE_THEME_WIN_QUIRKS_CSS" file="../renderer/core/html/resources/win_quirks.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_SVG_CSS" file="../renderer/core/css/svg.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_MATHML_CSS" file="../renderer/core/css/mathml.css" type="BINDATA" compress="gzip"/>
       <include name="IDR_UASTYLE_FULLSCREEN_CSS" file="../renderer/core/css/fullscreen.css" type="BINDATA" compress="gzip"/>
diff --git a/third_party/blink/public/platform/modules/indexeddb/web_idb_value.h b/third_party/blink/public/platform/modules/indexeddb/web_idb_value.h
index ab318f08..e090e63 100644
--- a/third_party/blink/public/platform/modules/indexeddb/web_idb_value.h
+++ b/third_party/blink/public/platform/modules/indexeddb/web_idb_value.h
@@ -42,12 +42,7 @@
   // TODO(pwnall): When Onion Soup-ing IndexedDB, ReleaseIDBValue() should
   //               take a v8::Isolate, and all the ownership tracking logic
   //               can be deleted.
-  std::unique_ptr<IDBValue> ReleaseIdbValue() noexcept {
-#if DCHECK_IS_ON()
-    ReleaseIdbValueOwnership();
-#endif  // DCHECK_IS_ON()
-    return std::move(private_);
-  }
+  BLINK_EXPORT std::unique_ptr<IDBValue> ReleaseIdbValue() noexcept;
 #endif  // INSIDE_BLINK
 
  private:
diff --git a/third_party/blink/public/platform/scheduler/DEPS b/third_party/blink/public/platform/scheduler/DEPS
index be14c6e..e4bbc96 100644
--- a/third_party/blink/public/platform/scheduler/DEPS
+++ b/third_party/blink/public/platform/scheduler/DEPS
@@ -6,6 +6,7 @@
     "+base/memory/ptr_util.h",
     "+base/memory/ref_counted.h",
     "+base/message_loop/message_loop.h",
+    "+base/message_loop/message_pump.h",
     "+base/optional.h",
     "+base/single_thread_task_runner.h",
     "+base/threading/thread.h",
diff --git a/third_party/blink/public/platform/scheduler/web_thread_scheduler.h b/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
index 4f26ac1e..c1485f8c 100644
--- a/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
+++ b/third_party/blink/public/platform/scheduler/web_thread_scheduler.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include "base/macros.h"
+#include "base/message_loop/message_pump.h"
 #include "base/optional.h"
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
@@ -21,7 +22,7 @@
 namespace base {
 namespace trace_event {
 class BlameContext;
-}
+}  // namespace trace_event
 }  // namespace base
 
 namespace blink {
@@ -31,7 +32,7 @@
 
 namespace viz {
 struct BeginFrameArgs;
-}
+}  // namespace viz
 
 namespace blink {
 namespace scheduler {
@@ -57,10 +58,13 @@
   // the main thread. They have default implementation that only does
   // NOTREACHED(), and are overridden only by the main thread scheduler.
 
-  // If |initial_virtual_time| is specified then the scheduler will be created
-  // with virtual time enabled and paused, and base::Time will be overridden to
-  // start at |initial_virtual_time|.
+  // If |message_pump| is null caller must have registered one using
+  // base::MessageLoop.
+  // If |initial_virtual_time| is specified then the
+  // scheduler will be created with virtual time enabled and paused, and
+  // base::Time will be overridden to start at |initial_virtual_time|.
   static std::unique_ptr<WebThreadScheduler> CreateMainThreadScheduler(
+      std::unique_ptr<base::MessagePump> message_pump = nullptr,
       base::Optional<base::Time> initial_virtual_time = base::nullopt);
 
   // Returns compositor thread scheduler for the compositor thread
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index bea7d347..a192b48 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -2094,6 +2094,9 @@
   kFlexboxSingleLineAlignContent = 2642,
   kSignedExchangeInnerResponseInMainFrame = 2643,
   kSignedExchangeInnerResponseInSubFrame = 2644,
+  kCSSSelectorNotWithValidList = 2645,
+  kCSSSelectorNotWithInvalidList = 2646,
+  kCSSSelectorNotWithPartiallyValidList = 2647,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
index 2a4efb8..d667ffa 100644
--- a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
+++ b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
@@ -39,6 +39,22 @@
                                         sanitize_script_errors));
   }
 
+  Message(ScriptState* script_state,
+          v8::Local<v8::Promise> promise,
+          v8::Local<v8::Value> exception,
+          const String& error_message,
+          std::unique_ptr<SourceLocation> location,
+          SanitizeScriptErrors sanitize_script_errors)
+      : script_state_(script_state),
+        promise_(script_state->GetIsolate(), promise),
+        exception_(script_state->GetIsolate(), exception),
+        error_message_(error_message),
+        location_(std::move(location)),
+        promise_rejection_id_(0),
+        collected_(false),
+        should_log_to_console_(true),
+        sanitize_script_errors_(sanitize_script_errors) {}
+
   bool IsCollected() { return collected_ || !script_state_->ContextIsValid(); }
 
   bool HasPromise(v8::Local<v8::Value> promise) {
@@ -152,22 +168,6 @@
   }
 
  private:
-  Message(ScriptState* script_state,
-          v8::Local<v8::Promise> promise,
-          v8::Local<v8::Value> exception,
-          const String& error_message,
-          std::unique_ptr<SourceLocation> location,
-          SanitizeScriptErrors sanitize_script_errors)
-      : script_state_(script_state),
-        promise_(script_state->GetIsolate(), promise),
-        exception_(script_state->GetIsolate(), exception),
-        error_message_(error_message),
-        location_(std::move(location)),
-        promise_rejection_id_(0),
-        collected_(false),
-        should_log_to_console_(true),
-        sanitize_script_errors_(sanitize_script_errors) {}
-
   static void DidCollectPromise(const v8::WeakCallbackInfo<Message>& data) {
     data.GetParameter()->collected_ = true;
     data.GetParameter()->promise_.Clear();
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index c38d56de..f6df6136 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -15,7 +15,7 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "v8/include/v8.h"
 
 #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
index 1a602b4..5aaee51 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "third_party/blink/renderer/platform/wtf/deque.h"
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
index 3433c20..bcedd546 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc
@@ -11,8 +11,8 @@
 #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
index a1360cd..3cbeb15 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -68,6 +68,7 @@
                                       // OffscreenCanvas. For OffscreenCanvas
                                       // transfer
   kReadableStreamTransferTag = 'r',   // index:uint32_t
+  kWritableStreamTransferTag = 'w',   // index:uint32_t
   kDOMPointTag = 'Q',                 // x:Double, y:Double, z:Double, w:Double
   kDOMPointReadOnlyTag = 'W',         // x:Double, y:Double, z:Double, w:Double
   kDOMRectTag = 'E',          // x:Double, y:Double, width:Double, height:Double
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
index 12a567a..0fbf601 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -49,10 +49,12 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/messaging/message_port.h"
 #include "third_party/blink/renderer/core/streams/readable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
 #include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
@@ -394,6 +396,22 @@
   }
 }
 
+void SerializedScriptValue::TransferWritableStreams(
+    ScriptState* script_state,
+    const WritableStreamArray& writable_streams,
+    ExceptionState& exception_state) {
+  auto* execution_context = ExecutionContext::From(script_state);
+  for (WritableStream* writable_stream : writable_streams) {
+    mojo::MessagePipe pipe;
+    MessagePort* local_port = MessagePort::Create(*execution_context);
+    local_port->Entangle(std::move(pipe.handle0));
+    writable_stream->Serialize(script_state, local_port, exception_state);
+    if (exception_state.HadException())
+      return;
+    stream_channels_.push_back(MessagePortChannel(std::move(pipe.handle1)));
+  }
+}
+
 void SerializedScriptValue::TransferArrayBuffers(
     v8::Isolate* isolate,
     const ArrayBufferArray& array_buffers,
@@ -562,6 +580,18 @@
         return false;
       }
       transferables.readable_streams.push_back(stream);
+    } else if (RuntimeEnabledFeatures::TransferableStreamsEnabled() &&
+               V8WritableStream::HasInstance(transferable_object, isolate)) {
+      WritableStream* stream = V8WritableStream::ToImpl(
+          v8::Local<v8::Object>::Cast(transferable_object));
+      if (transferables.writable_streams.Contains(stream)) {
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kDataCloneError,
+            "WritableStream at index " + String::Number(i) +
+                " is a duplicate of an earlier WritableStream.");
+        return false;
+      }
+      transferables.writable_streams.push_back(stream);
     } else {
       exception_state.ThrowTypeError("Value at index " + String::Number(i) +
                                      " does not have a transferable type.");
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
index 17ea019..eea42505 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -295,6 +295,9 @@
   void TransferReadableStreams(ScriptState*,
                                const ReadableStreamArray&,
                                ExceptionState&);
+  void TransferWritableStreams(ScriptState*,
+                               const WritableStreamArray&,
+                               ExceptionState&);
   void CloneSharedArrayBuffers(SharedArrayBufferArray&);
   DataBufferPtr data_buffer_;
   size_t data_buffer_size_ = 0;
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h b/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
index d50e3ae8..2408ccf 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
@@ -18,6 +18,7 @@
 class MessagePort;
 class MojoHandle;
 class ReadableStream;
+class WritableStream;
 
 using ArrayBufferArray = HeapVector<Member<DOMArrayBufferBase>>;
 using ImageBitmapArray = HeapVector<Member<ImageBitmap>>;
@@ -25,6 +26,7 @@
 using MessagePortArray = HeapVector<Member<MessagePort>>;
 using MojoHandleArray = HeapVector<Member<blink::MojoHandle>>;
 using ReadableStreamArray = HeapVector<Member<ReadableStream>>;
+using WritableStreamArray = HeapVector<Member<WritableStream>>;
 
 class CORE_EXPORT Transferables final {
   STACK_ALLOCATED();
@@ -39,6 +41,7 @@
   MessagePortArray message_ports;
   MojoHandleArray mojo_handles;
   ReadableStreamArray readable_streams;
+  WritableStreamArray writable_streams;
 };
 
 // Along with extending |Transferables| to hold a new kind of transferable
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index 331fba6..bf2da93 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/core/mojo/mojo_handle.h"
 #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
 #include "third_party/blink/renderer/core/streams/readable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -523,6 +524,18 @@
           script_state_, (*transferred_stream_ports_)[index].Get(),
           exception_state);
     }
+    case kWritableStreamTransferTag: {
+      if (!RuntimeEnabledFeatures::TransferableStreamsEnabled())
+        return nullptr;
+      uint32_t index = 0;
+      if (!ReadUint32(&index) || !transferred_stream_ports_ ||
+          index >= transferred_stream_ports_->size()) {
+        return nullptr;
+      }
+      return WritableStream::Deserialize(
+          script_state_, (*transferred_stream_ports_)[index].Get(),
+          exception_state);
+    }
     default:
       break;
   }
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
index 8fa66100..c37928d 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
 #include "third_party/blink/renderer/core/geometry/dom_point.h"
@@ -35,6 +36,7 @@
 #include "third_party/blink/renderer/core/html/canvas/image_data.h"
 #include "third_party/blink/renderer/core/mojo/mojo_handle.h"
 #include "third_party/blink/renderer/core/streams/readable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
 #include "third_party/blink/renderer/platform/file_metadata.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -172,6 +174,10 @@
           script_state_, transferables_->readable_streams, exception_state);
       if (exception_state.HadException())
         return;
+      serialized_script_value_->TransferWritableStreams(
+          script_state_, transferables_->writable_streams, exception_state);
+      if (exception_state.HadException())
+        return;
     }
   }
 }
@@ -486,6 +492,35 @@
     WriteUint32(static_cast<uint32_t>(index));
     return true;
   }
+  if (wrapper_type_info == &V8WritableStream::wrapper_type_info &&
+      RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+    WritableStream* stream = wrappable->ToImpl<WritableStream>();
+    size_t index = kNotFound;
+    if (transferables_)
+      index = transferables_->writable_streams.Find(stream);
+    if (index == kNotFound) {
+      exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
+                                        "A WritableStream could not be cloned "
+                                        "because it was not transferred.");
+      return false;
+    }
+    if (stream->IsLocked(script_state_, exception_state).value_or(true)) {
+      if (exception_state.HadException())
+        return false;
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kDataCloneError,
+          "A WritableStream could not be cloned because it was locked");
+      return false;
+    }
+    WriteTag(kWritableStreamTransferTag);
+    DCHECK(transferables_);
+    // The index calculation depends on the order that TransferReadableStreams
+    // and TransferWritableStreams are called in
+    // V8ScriptValueSerializer::FinalizeTransfer.
+    WriteUint32(
+        static_cast<uint32_t>(index + transferables_->readable_streams.size()));
+    return true;
+  }
   return false;
 }
 
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
index 8b1231c90..8cbe4da 100644
--- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
+++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h
@@ -113,10 +113,9 @@
     : public WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy> {
  public:
   static RemoteWindowProxyManager* Create(RemoteFrame& frame) {
-    return new RemoteWindowProxyManager(frame);
+    return MakeGarbageCollected<RemoteWindowProxyManager>(frame);
   }
 
- private:
   explicit RemoteWindowProxyManager(RemoteFrame& frame)
       : WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy>(
             frame,
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
index 8840687..88e2a40f 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -59,7 +59,7 @@
           certificate_generator->FromPEM(pem_private_key, pem_certificate);
       if (!certificate)
         return nullptr;
-      return new RTCCertificate(std::move(certificate));
+      return MakeGarbageCollected<RTCCertificate>(std::move(certificate));
     }
     case kDetectedBarcodeTag: {
       String raw_value;
diff --git a/third_party/blink/renderer/bindings/scripts/utilities.py b/third_party/blink/renderer/bindings/scripts/utilities.py
index e582cbfe..4b9573f 100644
--- a/third_party/blink/renderer/bindings/scripts/utilities.py
+++ b/third_party/blink/renderer/bindings/scripts/utilities.py
@@ -441,7 +441,7 @@
         'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContextOrXRPresentationContext': 'RenderingContext',
         # modules/canvas/htmlcanvas/html_canvas_element_module.idl
         'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContextOrXRPresentationContext': 'RenderingContext',
-        # core/imagebitmap/ImageBitmapFactories.idl
+        # core/frame/window_or_worker_global_scope.idl
         'HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas': 'ImageBitmapSource',
         # bindings/tests/idls/core/TestTypedefs.idl
         'NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord': 'NestedUnionType',
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl.cc b/third_party/blink/renderer/controller/oom_intervention_impl.cc
index e004975..24b601f 100644
--- a/third_party/blink/renderer/controller/oom_intervention_impl.cc
+++ b/third_party/blink/renderer/controller/oom_intervention_impl.cc
@@ -12,7 +12,6 @@
 #include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index b7cc2fd..0eacbb5 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1382,7 +1382,7 @@
   script = "../build/scripts/minimize_css.py"
 
   inputs = [
-    "css/html.css",
+    "html/resources/html.css",
   ]
   outputs = [
     "$blink_core_output_dir/html.css",
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
index 0f3441f..228aa27c 100644
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -545,7 +545,6 @@
                     "fullscreen/document_fullscreen.idl",
                     "fullscreen/element_fullscreen.idl",
                     "html/html_hyperlink_element_utils.idl",
-                    "imagebitmap/image_bitmap_factories.idl",
                     "layout/custom/css_layout_worklet.idl",
                     "svg/svg_document.idl",
                     "svg/svg_filter_primitive_standard_attributes.idl",
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn
index a987ac8..fe7c36a 100644
--- a/third_party/blink/renderer/core/css/BUILD.gn
+++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -264,8 +264,9 @@
     "cssom/prepopulated_computed_style_property_map.h",
     "cssom/style_property_map.cc",
     "cssom/style_property_map.h",
-    "cssom/style_property_map_read_only.cc",
     "cssom/style_property_map_read_only.h",
+    "cssom/style_property_map_read_only_main_thread.cc",
+    "cssom/style_property_map_read_only_main_thread.h",
     "cssom/style_value_factory.cc",
     "cssom/style_value_factory.h",
     "document_style_environment_variables.cc",
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index 2e68a95..97ca29e6 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -611,7 +611,7 @@
     DCHECK(!cssom_wrapper_->ParentElement());
     return cssom_wrapper_.Get();
   }
-  cssom_wrapper_ = new PropertySetCSSStyleDeclaration(*this);
+  cssom_wrapper_ = MakeGarbageCollected<PropertySetCSSStyleDeclaration>(*this);
   return cssom_wrapper_.Get();
 }
 
diff --git a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
index 4c517e14..9fa239ba 100644
--- a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
+++ b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h
@@ -8,7 +8,7 @@
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
 #include "third_party/blink/renderer/core/css/css_selector.h"
-#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h"
+#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 
 namespace blink {
@@ -17,11 +17,13 @@
 // API. The specification is here:
 // https://drafts.css-houdini.org/css-typed-om/#computed-StylePropertyMapReadOnly-objects
 //
-// The computed StylePropertyMapReadOnly retrieves computed styles and returns
-// them as CSSStyleValues. The IDL for this class is in StylePropertyMap.idl.
-// The computed StylePropertyMapReadOnly for an element is accessed via
-// element.computedStyleMap() (see ElementComputedStyleMap.idl/h)
-class CORE_EXPORT ComputedStylePropertyMap : public StylePropertyMapReadOnly {
+// The computed StylePropertyMapReadOnlyMainThread retrieves computed styles and
+// returns them as CSSStyleValues. The IDL for this class is in
+// StylePropertyMap.idl. The computed StylePropertyMapReadOnlyMainThread for an
+// element is accessed via element.computedStyleMap() (see
+// ElementComputedStyleMap.idl/h)
+class CORE_EXPORT ComputedStylePropertyMap
+    : public StylePropertyMapReadOnlyMainThread {
  public:
   static ComputedStylePropertyMap* Create(Node* node) {
     return new ComputedStylePropertyMap(node);
@@ -29,7 +31,7 @@
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(node_);
-    StylePropertyMapReadOnly::Trace(visitor);
+    StylePropertyMapReadOnlyMainThread::Trace(visitor);
   }
 
   unsigned int size() override;
@@ -41,7 +43,7 @@
 
  protected:
   ComputedStylePropertyMap(Node* node, const String& pseudo_element = String())
-      : StylePropertyMapReadOnly(),
+      : StylePropertyMapReadOnlyMainThread(),
         pseudo_id_(CSSSelector::ParsePseudoId(pseudo_element)),
         node_(node) {}
 
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
index 7a3deba..310444d99 100644
--- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
@@ -21,7 +21,7 @@
     Node* styled_node,
     const Vector<CSSPropertyID>& native_properties,
     const Vector<AtomicString>& custom_properties)
-    : StylePropertyMapReadOnly(), styled_node_(styled_node) {
+    : StylePropertyMapReadOnlyMainThread(), styled_node_(styled_node) {
   // NOTE: This may over-reserve as shorthand properties will get dropped from
   // being in the map.
   native_values_.ReserveCapacityForSize(native_properties.size());
@@ -128,7 +128,7 @@
   visitor->Trace(styled_node_);
   visitor->Trace(native_values_);
   visitor->Trace(custom_values_);
-  StylePropertyMapReadOnly::Trace(visitor);
+  StylePropertyMapReadOnlyMainThread::Trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
index f691eaf..7d346e5f 100644
--- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
+++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/css/css_property_id_templates.h"
-#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h"
+#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h"
 
 namespace blink {
 
@@ -24,7 +24,7 @@
 // result when the ComputedStyle changes UpdateStyle needs to be called to
 // re-populate the internal maps.
 class CORE_EXPORT PrepopulatedComputedStylePropertyMap
-    : public StylePropertyMapReadOnly {
+    : public StylePropertyMapReadOnlyMainThread {
  public:
   // NOTE: styled_node may be null, in the case where this map is for an
   // anonymous box.
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
index 3ba2bc2..30e93f2 100644
--- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
+++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
@@ -43,7 +43,7 @@
   Node* node = PageNode();
 
   PrepopulatedComputedStylePropertyMap* map =
-      new PrepopulatedComputedStylePropertyMap(
+      MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
           GetDocument(), node->ComputedStyleRef(), node, native_properties,
           empty_custom_properties);
 
@@ -79,7 +79,7 @@
   Node* node = PageNode();
 
   PrepopulatedComputedStylePropertyMap* map =
-      new PrepopulatedComputedStylePropertyMap(
+      MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
           GetDocument(), node->ComputedStyleRef(), node,
           empty_native_properties, custom_properties);
 
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.h b/third_party/blink/renderer/core/css/cssom/style_property_map.h
index 37b32d5..6bbc19b 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map.h
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/bindings/core/v8/css_style_value_or_string.h"
-#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h"
+#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 
 namespace blink {
@@ -15,7 +15,7 @@
 class ExceptionState;
 class ExecutionContext;
 
-class CORE_EXPORT StylePropertyMap : public StylePropertyMapReadOnly {
+class CORE_EXPORT StylePropertyMap : public StylePropertyMapReadOnlyMainThread {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h
index d3eda52..bdb8445 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h
@@ -14,52 +14,23 @@
 
 namespace blink {
 
-class CSSProperty;
-
 class CORE_EXPORT StylePropertyMapReadOnly
     : public ScriptWrappable,
       public PairIterable<String, CSSStyleValueVector> {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  using StylePropertyMapEntry = std::pair<String, CSSStyleValueVector>;
-
-  ~StylePropertyMapReadOnly() override = default;
-
-  CSSStyleValue* get(const ExecutionContext*,
-                     const String& property_name,
-                     ExceptionState&);
-  CSSStyleValueVector getAll(const ExecutionContext*,
+  virtual CSSStyleValue* get(const ExecutionContext*,
                              const String& property_name,
-                             ExceptionState&);
-  bool has(const ExecutionContext*,
-           const String& property_name,
-           ExceptionState&);
+                             ExceptionState&) = 0;
+  virtual CSSStyleValueVector getAll(const ExecutionContext*,
+                                     const String& property_name,
+                                     ExceptionState&) = 0;
+  virtual bool has(const ExecutionContext*,
+                   const String& property_name,
+                   ExceptionState&) = 0;
 
   virtual unsigned int size() = 0;
-
- protected:
-  StylePropertyMapReadOnly() = default;
-
-  virtual const CSSValue* GetProperty(CSSPropertyID) = 0;
-  virtual const CSSValue* GetCustomProperty(AtomicString) = 0;
-
-  using IterationCallback =
-      std::function<void(const AtomicString&, const CSSValue&)>;
-  virtual void ForEachProperty(const IterationCallback&) = 0;
-
-  virtual String SerializationForShorthand(const CSSProperty&) = 0;
-
-  const CSSValue* GetCustomProperty(const ExecutionContext&,
-                                    const AtomicString&);
-
- private:
-  IterationSource* StartIteration(ScriptState*, ExceptionState&) override;
-
-  CSSStyleValue* GetShorthandProperty(const CSSProperty&);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(StylePropertyMapReadOnly);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.cc b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
similarity index 84%
rename from third_party/blink/renderer/core/css/cssom/style_property_map_read_only.cc
rename to third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
index a3e889f..3adb7f9 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc
@@ -1,8 +1,8 @@
-// Copyright 2016 the chromium authors. All rights reserved.
+// Copyright 2018 the chromium authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h"
+#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h"
 
 #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
@@ -26,7 +26,8 @@
     : public PairIterable<String, CSSStyleValueVector>::IterationSource {
  public:
   explicit StylePropertyMapIterationSource(
-      HeapVector<StylePropertyMapReadOnly::StylePropertyMapEntry> values)
+      HeapVector<StylePropertyMapReadOnlyMainThread::StylePropertyMapEntry>
+          values)
       : index_(0), values_(values) {}
 
   bool Next(ScriptState*,
@@ -36,7 +37,7 @@
     if (index_ >= values_.size())
       return false;
 
-    const StylePropertyMapReadOnly::StylePropertyMapEntry& pair =
+    const StylePropertyMapReadOnlyMainThread::StylePropertyMapEntry& pair =
         values_.at(index_++);
     key = pair.first;
     value = pair.second;
@@ -50,12 +51,13 @@
 
  private:
   wtf_size_t index_;
-  const HeapVector<StylePropertyMapReadOnly::StylePropertyMapEntry> values_;
+  const HeapVector<StylePropertyMapReadOnlyMainThread::StylePropertyMapEntry>
+      values_;
 };
 
 }  // namespace
 
-CSSStyleValue* StylePropertyMapReadOnly::get(
+CSSStyleValue* StylePropertyMapReadOnlyMainThread::get(
     const ExecutionContext* execution_context,
     const String& property_name,
     ExceptionState& exception_state) {
@@ -93,7 +95,7 @@
                                                  custom_property_name, *value);
 }
 
-CSSStyleValueVector StylePropertyMapReadOnly::getAll(
+CSSStyleValueVector StylePropertyMapReadOnlyMainThread::getAll(
     const ExecutionContext* execution_context,
     const String& property_name,
     ExceptionState& exception_state) {
@@ -127,13 +129,14 @@
       property_id, custom_property_name, *value);
 }
 
-bool StylePropertyMapReadOnly::has(const ExecutionContext* execution_context,
-                                   const String& property_name,
-                                   ExceptionState& exception_state) {
+bool StylePropertyMapReadOnlyMainThread::has(
+    const ExecutionContext* execution_context,
+    const String& property_name,
+    ExceptionState& exception_state) {
   return !getAll(execution_context, property_name, exception_state).IsEmpty();
 }
 
-const CSSValue* StylePropertyMapReadOnly::GetCustomProperty(
+const CSSValue* StylePropertyMapReadOnlyMainThread::GetCustomProperty(
     const ExecutionContext& execution_context,
     const AtomicString& property_name) {
   const CSSValue* value = GetCustomProperty(property_name);
@@ -145,10 +148,10 @@
   return PropertyRegistry::ParseIfRegistered(*document, property_name, value);
 }
 
-StylePropertyMapReadOnly::IterationSource*
-StylePropertyMapReadOnly::StartIteration(ScriptState* script_state,
-                                         ExceptionState&) {
-  HeapVector<StylePropertyMapReadOnly::StylePropertyMapEntry> result;
+StylePropertyMapReadOnlyMainThread::IterationSource*
+StylePropertyMapReadOnlyMainThread::StartIteration(ScriptState* script_state,
+                                                   ExceptionState&) {
+  HeapVector<StylePropertyMapReadOnlyMainThread::StylePropertyMapEntry> result;
 
   const ExecutionContext& execution_context =
       *ExecutionContext::From(script_state);
@@ -178,7 +181,7 @@
   return new StylePropertyMapIterationSource(result);
 }
 
-CSSStyleValue* StylePropertyMapReadOnly::GetShorthandProperty(
+CSSStyleValue* StylePropertyMapReadOnlyMainThread::GetShorthandProperty(
     const CSSProperty& property) {
   DCHECK(property.IsShorthand());
   const auto serialization = SerializationForShorthand(property);
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h
new file mode 100644
index 0000000..dab11e66
--- /dev/null
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.h
@@ -0,0 +1,59 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_STYLE_PROPERTY_MAP_READ_ONLY_MAIN_THREAD_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_STYLE_PROPERTY_MAP_READ_ONLY_MAIN_THREAD_H_
+
+#include "third_party/blink/renderer/core/css/cssom/style_property_map_read_only.h"
+
+namespace blink {
+
+class CSSProperty;
+
+class CORE_EXPORT StylePropertyMapReadOnlyMainThread
+    : public StylePropertyMapReadOnly {
+ public:
+  using StylePropertyMapEntry = std::pair<String, CSSStyleValueVector>;
+
+  ~StylePropertyMapReadOnlyMainThread() override = default;
+
+  CSSStyleValue* get(const ExecutionContext*,
+                     const String& property_name,
+                     ExceptionState&) override;
+  CSSStyleValueVector getAll(const ExecutionContext*,
+                             const String& property_name,
+                             ExceptionState&) override;
+  bool has(const ExecutionContext*,
+           const String& property_name,
+           ExceptionState&) override;
+
+  unsigned int size() override = 0;
+
+ protected:
+  StylePropertyMapReadOnlyMainThread() = default;
+
+  virtual const CSSValue* GetProperty(CSSPropertyID) = 0;
+  virtual const CSSValue* GetCustomProperty(AtomicString) = 0;
+
+  using IterationCallback =
+      std::function<void(const AtomicString&, const CSSValue&)>;
+  virtual void ForEachProperty(const IterationCallback&) = 0;
+
+  virtual String SerializationForShorthand(const CSSProperty&) = 0;
+
+  const CSSValue* GetCustomProperty(const ExecutionContext&,
+                                    const AtomicString&);
+
+ private:
+  IterationSource* StartIteration(ScriptState*, ExceptionState&) override;
+
+  CSSStyleValue* GetShorthandProperty(const CSSProperty&);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StylePropertyMapReadOnlyMainThread);
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc
index 15a5b99..85cb342a 100644
--- a/third_party/blink/renderer/core/css/font_face.cc
+++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -714,8 +714,9 @@
           NOTREACHED();
         }
         RemoteFontFaceSource* source =
-            new RemoteFontFaceSource(css_font_face_, font_selector,
-                                     CSSValueToFontDisplay(display_.Get()));
+            MakeGarbageCollected<RemoteFontFaceSource>(
+                css_font_face_, font_selector,
+                CSSValueToFontDisplay(display_.Get()));
         item.Fetch(context, source);
         css_font_face_->AddSource(source);
       }
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
index 5e658a8b..2918f7a 100644
--- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -487,6 +487,44 @@
   return selector;
 }
 
+void CSSSelectorParser::CountRejectedNot(CSSParserTokenRange& range) {
+  bool exists_valid = false;
+  bool exists_invalid = false;
+
+  do {
+    if (exists_valid || exists_invalid) {
+      DCHECK(range.Peek().GetType() == kCommaToken);
+      range.ConsumeIncludingWhitespace();
+    }
+    // else we are parsing the first complex selector
+
+    failed_parsing_ = false;
+    bool consumed_invalid = !ConsumeComplexSelector(range) || failed_parsing_;
+    range.ConsumeWhitespace();
+    while (!range.AtEnd() && range.Peek().GetType() != kCommaToken) {
+      consumed_invalid = true;
+      range.ConsumeIncludingWhitespace();
+    }
+
+    if (consumed_invalid)
+      exists_invalid = true;
+    else
+      exists_valid = true;
+  } while (!range.AtEnd());
+
+  WebFeature feature;
+  if (exists_valid) {
+    if (exists_invalid)
+      feature = WebFeature::kCSSSelectorNotWithPartiallyValidList;
+    else
+      feature = WebFeature::kCSSSelectorNotWithValidList;
+  } else {
+    feature = WebFeature::kCSSSelectorNotWithInvalidList;
+  }
+  context_->Count(feature);
+  failed_parsing_ = true;
+}
+
 std::unique_ptr<CSSParserSelector> CSSSelectorParser::ConsumePseudo(
     CSSParserTokenRange& range) {
   DCHECK_EQ(range.Peek().GetType(), kColonToken);
@@ -577,11 +615,17 @@
       return selector;
     }
     case CSSSelector::kPseudoNot: {
+      CSSParserTokenRange fallback_block = block;
+
       std::unique_ptr<CSSParserSelector> inner_selector =
           ConsumeCompoundSelector(block);
       block.ConsumeWhitespace();
-      if (!inner_selector || !inner_selector->IsSimple() || !block.AtEnd())
+      if (!inner_selector || !inner_selector->IsSimple() ||
+          inner_selector->Relation() != CSSSelector::kSubSelector ||
+          !block.AtEnd()) {
+        CountRejectedNot(fallback_block);
         return nullptr;
+      }
       Vector<std::unique_ptr<CSSParserSelector>> selector_vector;
       selector_vector.push_back(std::move(inner_selector));
       selector->AdoptSelectorVector(selector_vector);
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.h b/third_party/blink/renderer/core/css/parser/css_selector_parser.h
index b1a8442..f75374c7 100644
--- a/third_party/blink/renderer/core/css/parser/css_selector_parser.h
+++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.h
@@ -80,6 +80,7 @@
   SplitCompoundAtImplicitShadowCrossingCombinator(
       std::unique_ptr<CSSParserSelector> compound_selector);
   void RecordUsageAndDeprecations(const CSSSelectorList&);
+  void CountRejectedNot(CSSParserTokenRange&);
 
   Member<const CSSParserContext> context_;
   Member<const StyleSheetContents> style_sheet_;
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
index b52452c..a795cba4 100644
--- a/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
+++ b/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
@@ -771,4 +771,88 @@
   }
 }
 
+TEST(CSSSelectorParserTest, UseCountRejectedNot) {
+  auto ExpectCount = [](const char* selector, WebFeature feature) {
+    std::unique_ptr<DummyPageHolder> dummy_holder =
+        DummyPageHolder::Create(IntSize(500, 500));
+    Document* doc = &dummy_holder->GetDocument();
+    Page::InsertOrdinaryPageForTesting(&dummy_holder->GetPage());
+    CSSParserContext* context = CSSParserContext::Create(
+        kHTMLStandardMode, SecureContextMode::kSecureContext,
+        CSSParserContext::kLiveProfile, doc);
+    StyleSheetContents* sheet = StyleSheetContents::Create(context);
+    EXPECT_FALSE(UseCounter::IsCounted(*doc, feature));
+
+    CSSTokenizer tokenizer(selector);
+    const auto tokens = tokenizer.TokenizeToEOF();
+    CSSParserTokenRange range(tokens);
+    CSSSelectorParser::ParseSelector(range, context, sheet);
+
+    bool result = UseCounter::IsCounted(*doc, feature);
+    EXPECT_TRUE(result);
+  };
+
+  ExpectCount(":not(:nonsense :gibberish)",
+              WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(:nonsense :gibberish, .a)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not()", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(,)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(,,)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(* .a)", WebFeature::kCSSSelectorNotWithValidList);
+  ExpectCount(":not(:nonsense)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(* * .previouslyFailed)",
+              WebFeature::kCSSSelectorNotWithValidList);
+  ExpectCount(":not(* :nonsense)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(:nonsense *)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(*,)", WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(*,,)", WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(:nonsense ,)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(:nonsense,,)", WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(*, *)", WebFeature::kCSSSelectorNotWithValidList);
+  ExpectCount(":not(*, :nonsense)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(* , * *)", WebFeature::kCSSSelectorNotWithValidList);
+  ExpectCount(":not(*, * :nonsense)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(:nonsense,*)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(:nonsense , :nonsense)",
+              WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(:nonsense, * *)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(:nonsense, * :nonsense )",
+              WebFeature::kCSSSelectorNotWithInvalidList);
+  ExpectCount(":not(*, :not(* * :nonsense))",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(:not(* * :nonsense) , *)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+  ExpectCount(":not(.a || :nonsense, *)",
+              WebFeature::kCSSSelectorNotWithPartiallyValidList);
+}
+
+TEST(CSSSelectorParserTest, SimpleNotNeverCounted) {
+  // :not with a simple selector from CSS Selectors 3 is not counted.
+  std::unique_ptr<DummyPageHolder> dummy_holder =
+      DummyPageHolder::Create(IntSize(500, 500));
+  Document* doc = &dummy_holder->GetDocument();
+  Page::InsertOrdinaryPageForTesting(&dummy_holder->GetPage());
+  CSSParserContext* context = CSSParserContext::Create(
+      kHTMLStandardMode, SecureContextMode::kSecureContext,
+      CSSParserContext::kLiveProfile, doc);
+  StyleSheetContents* sheet = StyleSheetContents::Create(context);
+
+  CSSTokenizer tokenizer(":not(*)");
+  const auto tokens = tokenizer.TokenizeToEOF();
+  CSSParserTokenRange range(tokens);
+  CSSSelectorParser::ParseSelector(range, context, sheet);
+
+  EXPECT_FALSE(
+      UseCounter::IsCounted(*doc, WebFeature::kCSSSelectorNotWithValidList));
+  EXPECT_FALSE(
+      UseCounter::IsCounted(*doc, WebFeature::kCSSSelectorNotWithInvalidList));
+  EXPECT_FALSE(UseCounter::IsCounted(
+      *doc, WebFeature::kCSSSelectorNotWithPartiallyValidList));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/property_registration.cc b/third_party/blink/renderer/core/css/property_registration.cc
index 7beccea..883f87f 100644
--- a/third_party/blink/renderer/core/css/property_registration.cc
+++ b/third_party/blink/renderer/core/css/property_registration.cc
@@ -160,9 +160,9 @@
     }
   }
   registry.RegisterProperty(
-      atomic_name, *new PropertyRegistration(atomic_name, syntax_descriptor,
-                                             descriptor->inherits(), initial,
-                                             std::move(initial_variable_data)));
+      atomic_name, *MakeGarbageCollected<PropertyRegistration>(
+                       atomic_name, syntax_descriptor, descriptor->inherits(),
+                       initial, std::move(initial_variable_data)));
 
   document->GetStyleEngine().CustomPropertyRegistered();
 }
diff --git a/third_party/blink/renderer/core/css/property_registration.h b/third_party/blink/renderer/core/css/property_registration.h
index 089a1b4..2986ee0 100644
--- a/third_party/blink/renderer/core/css/property_registration.h
+++ b/third_party/blink/renderer/core/css/property_registration.h
@@ -32,6 +32,12 @@
   static const PropertyRegistration* From(const ExecutionContext*,
                                           const AtomicString& property_name);
 
+  PropertyRegistration(const AtomicString& name,
+                       const CSSSyntaxDescriptor&,
+                       bool inherits,
+                       const CSSValue* initial,
+                       scoped_refptr<CSSVariableData> initial_variable_data);
+
   const CSSSyntaxDescriptor& Syntax() const { return syntax_; }
   bool Inherits() const { return inherits_; }
   const CSSValue* Initial() const { return initial_; }
@@ -47,12 +53,6 @@
  private:
   friend class ::blink::PropertyRegistry;
 
-  PropertyRegistration(const AtomicString& name,
-                       const CSSSyntaxDescriptor&,
-                       bool inherits,
-                       const CSSValue* initial,
-                       scoped_refptr<CSSVariableData> initial_variable_data);
-
   const CSSSyntaxDescriptor syntax_;
   const bool inherits_;
   const Member<const CSSValue> initial_;
diff --git a/third_party/blink/renderer/core/css/property_registry.h b/third_party/blink/renderer/core/css/property_registry.h
index cbb806a..6f7f0503d 100644
--- a/third_party/blink/renderer/core/css/property_registry.h
+++ b/third_party/blink/renderer/core/css/property_registry.h
@@ -16,7 +16,9 @@
   using RegistrationMap =
       HeapHashMap<AtomicString, Member<PropertyRegistration>>;
 
-  static PropertyRegistry* Create() { return new PropertyRegistry(); }
+  static PropertyRegistry* Create() {
+    return MakeGarbageCollected<PropertyRegistry>();
+  }
 
   void RegisterProperty(const AtomicString&, PropertyRegistration&);
   const PropertyRegistration* Registration(const AtomicString&) const;
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
index 851f2c5b..bd5d4b6 100644
--- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
@@ -261,9 +261,10 @@
       token_syntax.Parse(CSSParserTokenRange(tokens), context, false);
   ASSERT_TRUE(initial_value);
   ASSERT_TRUE(initial_value->IsVariableReferenceValue());
-  PropertyRegistration* registration = new PropertyRegistration(
-      "--prop3", token_syntax, false, initial_value,
-      ToCSSVariableReferenceValue(*initial_value).VariableDataValue());
+  PropertyRegistration* registration =
+      MakeGarbageCollected<PropertyRegistration>(
+          "--prop3", token_syntax, false, initial_value,
+          ToCSSVariableReferenceValue(*initial_value).VariableDataValue());
   ASSERT_TRUE(GetDocument().GetPropertyRegistry());
   GetDocument().GetPropertyRegistry()->RegisterProperty("--prop3",
                                                         *registration);
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 48ae031..6f57a02 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -170,7 +170,9 @@
 // ElementRuleCollector::CollectMatchingRules.
 class CORE_EXPORT RuleSet : public GarbageCollectedFinalized<RuleSet> {
  public:
-  static RuleSet* Create() { return new RuleSet; }
+  static RuleSet* Create() { return MakeGarbageCollected<RuleSet>(); }
+
+  RuleSet() : rule_count_(0) {}
 
   void AddRulesFromSheet(StyleSheetContents*,
                          const MediaQueryEvaluator&,
@@ -288,8 +290,6 @@
   using CompactRuleMap =
       HeapHashMap<AtomicString, Member<HeapVector<Member<const RuleData>>>>;
 
-  RuleSet() : rule_count_(0) {}
-
   void AddToRuleSet(const AtomicString& key, PendingRuleMap&, const RuleData*);
   void AddPageRule(StyleRulePage*);
   void AddViewportRule(StyleRuleViewport*);
@@ -307,7 +307,11 @@
 
   class PendingRuleMaps : public GarbageCollected<PendingRuleMaps> {
    public:
-    static PendingRuleMaps* Create() { return new PendingRuleMaps; }
+    static PendingRuleMaps* Create() {
+      return MakeGarbageCollected<PendingRuleMaps>();
+    }
+
+    PendingRuleMaps() = default;
 
     PendingRuleMap id_rules;
     PendingRuleMap class_rules;
@@ -315,9 +319,6 @@
     PendingRuleMap shadow_pseudo_element_rules;
 
     void Trace(blink::Visitor*);
-
-   private:
-    PendingRuleMaps() = default;
   };
 
   PendingRuleMaps* EnsurePendingRules() {
diff --git a/third_party/blink/renderer/core/css/threaded/multi_threaded_test_util.h b/third_party/blink/renderer/core/css/threaded/multi_threaded_test_util.h
index c97cdc47..b0e022ff 100644
--- a/third_party/blink/renderer/core/css/threaded/multi_threaded_test_util.h
+++ b/third_party/blink/renderer/core/css/threaded/multi_threaded_test_util.h
@@ -12,10 +12,10 @@
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/web_thread_supporting_gc.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 67899ff..ca5e41d 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -278,6 +278,7 @@
 #include "third_party/blink/renderer/platform/plugins/plugin_script_forbidden_scope.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/text/platform_locale.h"
 #include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
@@ -674,7 +675,7 @@
           this,
           &Document::ElementDataCacheClearTimerFired),
       timeline_(DocumentTimeline::Create(this)),
-      pending_animations_(new PendingAnimations(*this)),
+      pending_animations_(MakeGarbageCollected<PendingAnimations>(*this)),
       worklet_animation_controller_(
           MakeGarbageCollected<WorkletAnimationController>(this)),
       template_document_host_(nullptr),
@@ -6709,8 +6710,10 @@
 }
 
 ResizeObserverController& Document::EnsureResizeObserverController() {
-  if (!resize_observer_controller_)
-    resize_observer_controller_ = new ResizeObserverController();
+  if (!resize_observer_controller_) {
+    resize_observer_controller_ =
+        MakeGarbageCollected<ResizeObserverController>();
+  }
   return *resize_observer_controller_;
 }
 
@@ -7703,8 +7706,8 @@
           (disposition == mojom::FeaturePolicyDisposition::kReport ? "report"
                                                                    : "enforce"),
           SourceLocation::Capture());
-  Report* report =
-      new Report("feature-policy-violation", Url().GetString(), body);
+  Report* report = MakeGarbageCollected<Report>("feature-policy-violation",
+                                                Url().GetString(), body);
   ReportingContext::From(this)->QueueReport(report);
 
   bool is_null;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 06ff7da..18de74e 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -65,9 +65,9 @@
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/scroll/scroll_types.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/bit_vector.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc
index 83e4afe9..8178485 100644
--- a/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -53,7 +53,7 @@
 ProcessingInstruction* ProcessingInstruction::Create(Document& document,
                                                      const String& target,
                                                      const String& data) {
-  return new ProcessingInstruction(document, target, data);
+  return MakeGarbageCollected<ProcessingInstruction>(document, target, data);
 }
 
 ProcessingInstruction::~ProcessingInstruction() = default;
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.h b/third_party/blink/renderer/core/dom/processing_instruction.h
index e30343c..8341102c 100644
--- a/third_party/blink/renderer/core/dom/processing_instruction.h
+++ b/third_party/blink/renderer/core/dom/processing_instruction.h
@@ -41,6 +41,8 @@
   static ProcessingInstruction* Create(Document&,
                                        const String& target,
                                        const String& data);
+
+  ProcessingInstruction(Document&, const String& target, const String& data);
   ~ProcessingInstruction() override;
   void Trace(blink::Visitor*) override;
 
@@ -72,8 +74,6 @@
   void ClearEventListenerForXSLT();
 
  private:
-  ProcessingInstruction(Document&, const String& target, const String& data);
-
   String nodeName() const override;
   NodeType getNodeType() const override;
   Node* Clone(Document&, CloneChildrenFlag) const override;
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc
index 0d0d73a..805af53 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -41,7 +41,7 @@
 PseudoElement* PseudoElement::Create(Element* parent, PseudoId pseudo_id) {
   if (pseudo_id == kPseudoIdFirstLetter)
     return FirstLetterPseudoElement::Create(parent);
-  return new PseudoElement(parent, pseudo_id);
+  return MakeGarbageCollected<PseudoElement>(parent, pseudo_id);
 }
 
 const QualifiedName& PseudoElementTagName(PseudoId pseudo_id) {
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.h b/third_party/blink/renderer/core/dom/pseudo_element.h
index 20f7d3e..d3da1693 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element.h
+++ b/third_party/blink/renderer/core/dom/pseudo_element.h
@@ -38,6 +38,8 @@
  public:
   static PseudoElement* Create(Element* parent, PseudoId);
 
+  PseudoElement(Element*, PseudoId);
+
   scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
   void AttachLayoutTree(AttachContext&) override;
   bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
@@ -58,9 +60,6 @@
 
   virtual void Dispose();
 
- protected:
-  PseudoElement(Element*, PseudoId);
-
  private:
   PseudoId pseudo_id_;
 };
diff --git a/third_party/blink/renderer/core/dom/pseudo_element_data.h b/third_party/blink/renderer/core/dom/pseudo_element_data.h
index 2ab87d4..76db5ac 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element_data.h
+++ b/third_party/blink/renderer/core/dom/pseudo_element_data.h
@@ -14,6 +14,9 @@
 class PseudoElementData final : public GarbageCollected<PseudoElementData> {
  public:
   static PseudoElementData* Create();
+
+  PseudoElementData() = default;
+
   void SetPseudoElement(PseudoId, PseudoElement*);
   PseudoElement* GetPseudoElement(PseudoId) const;
   bool HasPseudoElements() const;
@@ -26,7 +29,6 @@
   }
 
  private:
-  PseudoElementData() = default;
   Member<PseudoElement> generated_before_;
   Member<PseudoElement> generated_after_;
   Member<PseudoElement> generated_first_letter_;
@@ -35,7 +37,7 @@
 };
 
 inline PseudoElementData* PseudoElementData::Create() {
-  return new PseudoElementData();
+  return MakeGarbageCollected<PseudoElementData>();
 }
 
 inline bool PseudoElementData::HasPseudoElements() const {
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
index fd5aabf..2a626e8 100644
--- a/third_party/blink/renderer/core/dom/range.cc
+++ b/third_party/blink/renderer/core/dom/range.cc
@@ -129,7 +129,7 @@
 }
 
 Range* Range::Create(Document& owner_document) {
-  return new Range(owner_document);
+  return MakeGarbageCollected<Range>(owner_document);
 }
 
 inline Range::Range(Document& owner_document,
@@ -153,17 +153,17 @@
                      unsigned start_offset,
                      Node* end_container,
                      unsigned end_offset) {
-  return new Range(owner_document, start_container, start_offset, end_container,
-                   end_offset);
+  return MakeGarbageCollected<Range>(owner_document, start_container,
+                                     start_offset, end_container, end_offset);
 }
 
 Range* Range::Create(Document& owner_document,
                      const Position& start,
                      const Position& end) {
-  return new Range(owner_document, start.ComputeContainerNode(),
-                   start.ComputeOffsetInContainerNode(),
-                   end.ComputeContainerNode(),
-                   end.ComputeOffsetInContainerNode());
+  return MakeGarbageCollected<Range>(
+      owner_document, start.ComputeContainerNode(),
+      start.ComputeOffsetInContainerNode(), end.ComputeContainerNode(),
+      end.ComputeOffsetInContainerNode());
 }
 
 void Range::Dispose() {
diff --git a/third_party/blink/renderer/core/dom/range.h b/third_party/blink/renderer/core/dom/range.h
index 6b85d17..ec46883 100644
--- a/third_party/blink/renderer/core/dom/range.h
+++ b/third_party/blink/renderer/core/dom/range.h
@@ -61,6 +61,13 @@
                        unsigned end_offset);
   static Range* Create(Document&, const Position&, const Position&);
 
+  explicit Range(Document&);
+  Range(Document&,
+        Node* start_container,
+        unsigned start_offset,
+        Node* end_container,
+        unsigned end_offset);
+
   void Dispose();
 
   Document& OwnerDocument() const {
@@ -172,13 +179,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit Range(Document&);
-  Range(Document&,
-        Node* start_container,
-        unsigned start_offset,
-        Node* end_container,
-        unsigned end_offset);
-
   void SetDocument(Document&);
 
   void CheckNodeBA(Node*, ExceptionState&) const;
diff --git a/third_party/blink/renderer/core/dom/scripted_task_queue.cc b/third_party/blink/renderer/core/dom/scripted_task_queue.cc
index ce70145f..0b3319f9 100644
--- a/third_party/blink/renderer/core/dom/scripted_task_queue.cc
+++ b/third_party/blink/renderer/core/dom/scripted_task_queue.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_task_queue_post_callback.h"
 #include "third_party/blink/renderer/core/dom/abort_signal.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/dom/slot_assignment.cc b/third_party/blink/renderer/core/dom/slot_assignment.cc
index f80d52a..bd70c6e 100644
--- a/third_party/blink/renderer/core/dom/slot_assignment.cc
+++ b/third_party/blink/renderer/core/dom/slot_assignment.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/dom/node_traversal.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
 #include "third_party/blink/renderer/core/dom/slot_assignment_engine.h"
+#include "third_party/blink/renderer/core/dom/slot_assignment_recalc_forbidden_scope.h"
 #include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_select_element.h"
 #include "third_party/blink/renderer/core/html/html_details_element.h"
@@ -226,6 +227,9 @@
 #if DCHECK_IS_ON()
   DCHECK(!owner_->GetDocument().IsSlotAssignmentRecalcForbidden());
 #endif
+  // To detect recursive RecalcAssignment, which shouldn't happen.
+  SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(owner_->GetDocument());
+
   needs_assignment_recalc_ = false;
 
   for (Member<HTMLSlotElement> slot : Slots())
diff --git a/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h b/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
index 5428e07b..056f77c9 100644
--- a/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
+++ b/third_party/blink/renderer/core/editing/commands/remove_css_property_command.h
@@ -38,13 +38,15 @@
   static RemoveCSSPropertyCommand* Create(Document& document,
                                           Element* element,
                                           CSSPropertyID property) {
-    return new RemoveCSSPropertyCommand(document, element, property);
+    return MakeGarbageCollected<RemoveCSSPropertyCommand>(document, element,
+                                                          property);
   }
 
+  RemoveCSSPropertyCommand(Document&, Element*, CSSPropertyID);
+
   void Trace(blink::Visitor*) override;
 
  private:
-  RemoveCSSPropertyCommand(Document&, Element*, CSSPropertyID);
   ~RemoveCSSPropertyCommand() override;
 
   void DoApply(EditingState*) override;
diff --git a/third_party/blink/renderer/core/editing/commands/remove_format_command.h b/third_party/blink/renderer/core/editing/commands/remove_format_command.h
index 31a9e05f..fcf1265 100644
--- a/third_party/blink/renderer/core/editing/commands/remove_format_command.h
+++ b/third_party/blink/renderer/core/editing/commands/remove_format_command.h
@@ -33,12 +33,12 @@
 class RemoveFormatCommand final : public CompositeEditCommand {
  public:
   static RemoveFormatCommand* Create(Document& document) {
-    return new RemoveFormatCommand(document);
+    return MakeGarbageCollected<RemoveFormatCommand>(document);
   }
 
- private:
   explicit RemoveFormatCommand(Document&);
 
+ private:
   void DoApply(EditingState*) override;
   InputEvent::InputType GetInputType() const override;
 };
diff --git a/third_party/blink/renderer/core/editing/commands/remove_node_command.h b/third_party/blink/renderer/core/editing/commands/remove_node_command.h
index 0cd1114..f4435cd 100644
--- a/third_party/blink/renderer/core/editing/commands/remove_node_command.h
+++ b/third_party/blink/renderer/core/editing/commands/remove_node_command.h
@@ -36,15 +36,15 @@
       Node* node,
       ShouldAssumeContentIsAlwaysEditable
           should_assume_content_is_always_editable) {
-    return new RemoveNodeCommand(node,
-                                 should_assume_content_is_always_editable);
+    return MakeGarbageCollected<RemoveNodeCommand>(
+        node, should_assume_content_is_always_editable);
   }
 
+  explicit RemoveNodeCommand(Node*, ShouldAssumeContentIsAlwaysEditable);
+
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit RemoveNodeCommand(Node*, ShouldAssumeContentIsAlwaysEditable);
-
   void DoApply(EditingState*) override;
   void DoUnapply() override;
 
diff --git a/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h b/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
index 99aaadc3..06fc182 100644
--- a/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
+++ b/third_party/blink/renderer/core/editing/commands/remove_node_preserving_children_command.h
@@ -36,16 +36,16 @@
       Node* node,
       ShouldAssumeContentIsAlwaysEditable
           should_assume_content_is_always_editable) {
-    return new RemoveNodePreservingChildrenCommand(
+    return MakeGarbageCollected<RemoveNodePreservingChildrenCommand>(
         node, should_assume_content_is_always_editable);
   }
 
+  RemoveNodePreservingChildrenCommand(Node*,
+                                      ShouldAssumeContentIsAlwaysEditable);
+
   void Trace(blink::Visitor*) override;
 
  private:
-  RemoveNodePreservingChildrenCommand(Node*,
-                                      ShouldAssumeContentIsAlwaysEditable);
-
   void DoApply(EditingState*) override;
 
   Member<Node> node_;
diff --git a/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h b/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
index 61168d6..3a07c17 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
+++ b/third_party/blink/renderer/core/editing/commands/replace_node_with_span_command.h
@@ -43,16 +43,16 @@
 class ReplaceNodeWithSpanCommand final : public SimpleEditCommand {
  public:
   static ReplaceNodeWithSpanCommand* Create(HTMLElement* element) {
-    return new ReplaceNodeWithSpanCommand(element);
+    return MakeGarbageCollected<ReplaceNodeWithSpanCommand>(element);
   }
 
+  explicit ReplaceNodeWithSpanCommand(HTMLElement*);
+
   HTMLSpanElement* SpanElement() { return span_element_.Get(); }
 
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit ReplaceNodeWithSpanCommand(HTMLElement*);
-
   void DoApply(EditingState*) override;
   void DoUnapply() override;
 
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.h b/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
index f5b9a7ff..b6f1789 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
+++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.h
@@ -53,19 +53,20 @@
       DocumentFragment* fragment,
       CommandOptions options,
       InputEvent::InputType input_type = InputEvent::InputType::kNone) {
-    return new ReplaceSelectionCommand(document, fragment, options, input_type);
+    return MakeGarbageCollected<ReplaceSelectionCommand>(document, fragment,
+                                                         options, input_type);
   }
 
+  ReplaceSelectionCommand(Document&,
+                          DocumentFragment*,
+                          CommandOptions,
+                          InputEvent::InputType);
+
   EphemeralRange InsertedRange() const;
 
   void Trace(blink::Visitor*) override;
 
  private:
-  ReplaceSelectionCommand(Document&,
-                          DocumentFragment*,
-                          CommandOptions,
-                          InputEvent::InputType);
-
   void DoApply(EditingState*) override;
   InputEvent::InputType GetInputType() const override;
   bool IsReplaceSelectionCommand() const override;
diff --git a/third_party/blink/renderer/core/events/page_transition_event.h b/third_party/blink/renderer/core/events/page_transition_event.h
index bcfb45a..9570909 100644
--- a/third_party/blink/renderer/core/events/page_transition_event.h
+++ b/third_party/blink/renderer/core/events/page_transition_event.h
@@ -35,16 +35,21 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static PageTransitionEvent* Create() { return new PageTransitionEvent; }
+  static PageTransitionEvent* Create() {
+    return MakeGarbageCollected<PageTransitionEvent>();
+  }
   static PageTransitionEvent* Create(const AtomicString& type, bool persisted) {
-    return new PageTransitionEvent(type, persisted);
+    return MakeGarbageCollected<PageTransitionEvent>(type, persisted);
   }
   static PageTransitionEvent* Create(
       const AtomicString& type,
       const PageTransitionEventInit* initializer) {
-    return new PageTransitionEvent(type, initializer);
+    return MakeGarbageCollected<PageTransitionEvent>(type, initializer);
   }
 
+  PageTransitionEvent();
+  PageTransitionEvent(const AtomicString& type, bool persisted);
+  PageTransitionEvent(const AtomicString&, const PageTransitionEventInit*);
   ~PageTransitionEvent() override;
 
   const AtomicString& InterfaceName() const override;
@@ -54,10 +59,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PageTransitionEvent();
-  PageTransitionEvent(const AtomicString& type, bool persisted);
-  PageTransitionEvent(const AtomicString&, const PageTransitionEventInit*);
-
   bool persisted_;
 };
 
diff --git a/third_party/blink/renderer/core/events/picture_in_picture_control_event.cc b/third_party/blink/renderer/core/events/picture_in_picture_control_event.cc
index b5315ddb..17e4158 100644
--- a/third_party/blink/renderer/core/events/picture_in_picture_control_event.cc
+++ b/third_party/blink/renderer/core/events/picture_in_picture_control_event.cc
@@ -9,13 +9,13 @@
 PictureInPictureControlEvent* PictureInPictureControlEvent::Create(
     const AtomicString& type,
     String id) {
-  return new PictureInPictureControlEvent(type, id);
+  return MakeGarbageCollected<PictureInPictureControlEvent>(type, id);
 }
 
 PictureInPictureControlEvent* PictureInPictureControlEvent::Create(
     const AtomicString& type,
     const PictureInPictureControlEventInit* initializer) {
-  return new PictureInPictureControlEvent(type, initializer);
+  return MakeGarbageCollected<PictureInPictureControlEvent>(type, initializer);
 }
 
 String PictureInPictureControlEvent::id() const {
diff --git a/third_party/blink/renderer/core/events/picture_in_picture_control_event.h b/third_party/blink/renderer/core/events/picture_in_picture_control_event.h
index e4273c0c..718b80317 100644
--- a/third_party/blink/renderer/core/events/picture_in_picture_control_event.h
+++ b/third_party/blink/renderer/core/events/picture_in_picture_control_event.h
@@ -22,14 +22,14 @@
       const AtomicString&,
       const PictureInPictureControlEventInit*);
 
-  String id() const;
-  void setId(String id);
-
- private:
   PictureInPictureControlEvent(AtomicString const&, String);
   PictureInPictureControlEvent(AtomicString const&,
                                const PictureInPictureControlEventInit*);
 
+  String id() const;
+  void setId(String id);
+
+ private:
   // id_ holds the id of a PictureIncPictureControlEvent, which is used to
   // convey which custom control fired the event by being clicked.
   String id_;
diff --git a/third_party/blink/renderer/core/events/pointer_event.h b/third_party/blink/renderer/core/events/pointer_event.h
index 7f7bacb..2262640 100644
--- a/third_party/blink/renderer/core/events/pointer_event.h
+++ b/third_party/blink/renderer/core/events/pointer_event.h
@@ -17,13 +17,18 @@
   static PointerEvent* Create(const AtomicString& type,
                               const PointerEventInit* initializer,
                               TimeTicks platform_time_stamp) {
-    return new PointerEvent(type, initializer, platform_time_stamp);
+    return MakeGarbageCollected<PointerEvent>(type, initializer,
+                                              platform_time_stamp);
   }
   static PointerEvent* Create(const AtomicString& type,
                               const PointerEventInit* initializer) {
     return PointerEvent::Create(type, initializer, CurrentTimeTicks());
   }
 
+  PointerEvent(const AtomicString&,
+               const PointerEventInit*,
+               TimeTicks platform_time_stamp);
+
   int32_t pointerId() const { return pointer_id_; }
   double width() const { return width_; }
   double height() const { return height_; }
@@ -65,10 +70,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PointerEvent(const AtomicString&,
-               const PointerEventInit*,
-               TimeTicks platform_time_stamp);
-
   int32_t pointer_id_;
   double width_;
   double height_;
diff --git a/third_party/blink/renderer/core/events/pop_state_event.cc b/third_party/blink/renderer/core/events/pop_state_event.cc
index a65b3a11..c7190b0 100644
--- a/third_party/blink/renderer/core/events/pop_state_event.cc
+++ b/third_party/blink/renderer/core/events/pop_state_event.cc
@@ -71,19 +71,20 @@
 }
 
 PopStateEvent* PopStateEvent::Create() {
-  return new PopStateEvent;
+  return MakeGarbageCollected<PopStateEvent>();
 }
 
 PopStateEvent* PopStateEvent::Create(
     scoped_refptr<SerializedScriptValue> serialized_state,
     History* history) {
-  return new PopStateEvent(std::move(serialized_state), history);
+  return MakeGarbageCollected<PopStateEvent>(std::move(serialized_state),
+                                             history);
 }
 
 PopStateEvent* PopStateEvent::Create(ScriptState* script_state,
                                      const AtomicString& type,
                                      const PopStateEventInit* initializer) {
-  return new PopStateEvent(script_state, type, initializer);
+  return MakeGarbageCollected<PopStateEvent>(script_state, type, initializer);
 }
 
 void PopStateEvent::SetSerializedState(
diff --git a/third_party/blink/renderer/core/events/pop_state_event.h b/third_party/blink/renderer/core/events/pop_state_event.h
index 42c6218..05390ec 100644
--- a/third_party/blink/renderer/core/events/pop_state_event.h
+++ b/third_party/blink/renderer/core/events/pop_state_event.h
@@ -42,7 +42,11 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  PopStateEvent();
+  PopStateEvent(ScriptState*, const AtomicString&, const PopStateEventInit*);
+  PopStateEvent(scoped_refptr<SerializedScriptValue>, History*);
   ~PopStateEvent() override;
+
   static PopStateEvent* Create();
   static PopStateEvent* Create(scoped_refptr<SerializedScriptValue>, History*);
   static PopStateEvent* Create(ScriptState*,
@@ -61,10 +65,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PopStateEvent();
-  PopStateEvent(ScriptState*, const AtomicString&, const PopStateEventInit*);
-  PopStateEvent(scoped_refptr<SerializedScriptValue>, History*);
-
   scoped_refptr<SerializedScriptValue> serialized_state_;
   scoped_refptr<DOMWrapperWorld> world_;
   TraceWrapperV8Reference<v8::Value> state_;
diff --git a/third_party/blink/renderer/core/events/progress_event.h b/third_party/blink/renderer/core/events/progress_event.h
index 61bc31478..ca1119f7 100644
--- a/third_party/blink/renderer/core/events/progress_event.h
+++ b/third_party/blink/renderer/core/events/progress_event.h
@@ -36,18 +36,28 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static ProgressEvent* Create() { return new ProgressEvent; }
+  static ProgressEvent* Create() {
+    return MakeGarbageCollected<ProgressEvent>();
+  }
   static ProgressEvent* Create(const AtomicString& type,
                                bool length_computable,
                                unsigned long long loaded,
                                unsigned long long total) {
-    return new ProgressEvent(type, length_computable, loaded, total);
+    return MakeGarbageCollected<ProgressEvent>(type, length_computable, loaded,
+                                               total);
   }
   static ProgressEvent* Create(const AtomicString& type,
                                const ProgressEventInit* initializer) {
-    return new ProgressEvent(type, initializer);
+    return MakeGarbageCollected<ProgressEvent>(type, initializer);
   }
 
+  ProgressEvent();
+  ProgressEvent(const AtomicString& type,
+                bool length_computable,
+                unsigned long long loaded,
+                unsigned long long total);
+  ProgressEvent(const AtomicString&, const ProgressEventInit*);
+
   bool lengthComputable() const { return length_computable_; }
   unsigned long long loaded() const { return loaded_; }
   unsigned long long total() const { return total_; }
@@ -56,14 +66,6 @@
 
   void Trace(blink::Visitor*) override;
 
- protected:
-  ProgressEvent();
-  ProgressEvent(const AtomicString& type,
-                bool length_computable,
-                unsigned long long loaded,
-                unsigned long long total);
-  ProgressEvent(const AtomicString&, const ProgressEventInit*);
-
  private:
   bool length_computable_;
   unsigned long long loaded_;
diff --git a/third_party/blink/renderer/core/events/promise_rejection_event.h b/third_party/blink/renderer/core/events/promise_rejection_event.h
index 8a153a82..afcc54a 100644
--- a/third_party/blink/renderer/core/events/promise_rejection_event.h
+++ b/third_party/blink/renderer/core/events/promise_rejection_event.h
@@ -25,9 +25,14 @@
       ScriptState* state,
       const AtomicString& type,
       const PromiseRejectionEventInit* initializer) {
-    return new PromiseRejectionEvent(state, type, initializer);
+    return MakeGarbageCollected<PromiseRejectionEvent>(state, type,
+                                                       initializer);
   }
 
+  PromiseRejectionEvent(ScriptState*,
+                        const AtomicString&,
+                        const PromiseRejectionEventInit*);
+
   ScriptValue reason(ScriptState*) const;
   ScriptPromise promise(ScriptState*) const;
 
@@ -40,9 +45,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PromiseRejectionEvent(ScriptState*,
-                        const AtomicString&,
-                        const PromiseRejectionEventInit*);
   ~PromiseRejectionEvent() override;
   void Dispose();
 
diff --git a/third_party/blink/renderer/core/events/resource_progress_event.h b/third_party/blink/renderer/core/events/resource_progress_event.h
index ade713d..f38c1a6 100644
--- a/third_party/blink/renderer/core/events/resource_progress_event.h
+++ b/third_party/blink/renderer/core/events/resource_progress_event.h
@@ -52,23 +52,22 @@
                                        unsigned long long loaded,
                                        unsigned long long total,
                                        const String& url) {
-    return new ResourceProgressEvent(type, length_computable, loaded, total,
-                                     url);
+    return MakeGarbageCollected<ResourceProgressEvent>(type, length_computable,
+                                                       loaded, total, url);
   }
 
+  ResourceProgressEvent(const AtomicString& type,
+                        bool length_computable,
+                        unsigned long long loaded,
+                        unsigned long long total,
+                        const String& url);
+
   const String& url() const;
 
   const AtomicString& InterfaceName() const override;
 
   void Trace(blink::Visitor*) override;
 
- protected:
-  ResourceProgressEvent(const AtomicString& type,
-                        bool length_computable,
-                        unsigned long long loaded,
-                        unsigned long long total,
-                        const String& url);
-
  private:
   String url_;
 };
diff --git a/third_party/blink/renderer/core/execution_context/remote_security_context.cc b/third_party/blink/renderer/core/execution_context/remote_security_context.cc
index e1012fb2..7561adc 100644
--- a/third_party/blink/renderer/core/execution_context/remote_security_context.cc
+++ b/third_party/blink/renderer/core/execution_context/remote_security_context.cc
@@ -24,7 +24,7 @@
 }
 
 RemoteSecurityContext* RemoteSecurityContext::Create() {
-  return new RemoteSecurityContext();
+  return MakeGarbageCollected<RemoteSecurityContext>();
 }
 
 void RemoteSecurityContext::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/execution_context/remote_security_context.h b/third_party/blink/renderer/core/execution_context/remote_security_context.h
index 08f0b8e78..3f9b4d7 100644
--- a/third_party/blink/renderer/core/execution_context/remote_security_context.h
+++ b/third_party/blink/renderer/core/execution_context/remote_security_context.h
@@ -17,6 +17,8 @@
   USING_GARBAGE_COLLECTED_MIXIN(RemoteSecurityContext);
 
  public:
+  RemoteSecurityContext();
+
   void Trace(blink::Visitor*) override;
 
   static RemoteSecurityContext* Create();
@@ -26,9 +28,6 @@
 
   // FIXME: implement
   void DidUpdateSecurityOrigin() override {}
-
- private:
-  RemoteSecurityContext();
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
index 7adc63fc..7520cb4 100644
--- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -86,7 +86,6 @@
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 7580b4f..37e97dc 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -72,7 +72,11 @@
 class PagePopupChromeClient final : public EmptyChromeClient {
  public:
   static PagePopupChromeClient* Create(WebPagePopupImpl* popup) {
-    return new PagePopupChromeClient(popup);
+    return MakeGarbageCollected<PagePopupChromeClient>(popup);
+  }
+
+  explicit PagePopupChromeClient(WebPagePopupImpl* popup) : popup_(popup) {
+    DCHECK(popup_->WidgetClient());
   }
 
   void SetWindowRect(const IntRect& rect, LocalFrame&) override {
@@ -82,10 +86,6 @@
   bool IsPopup() override { return true; }
 
  private:
-  explicit PagePopupChromeClient(WebPagePopupImpl* popup) : popup_(popup) {
-    DCHECK(popup_->WidgetClient());
-  }
-
   void CloseWindowSoon() override { popup_->ClosePopup(); }
 
   IntRect RootWindowRect() override { return popup_->WindowRectInScreen(); }
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index 75aa3ae8..f0a6c82 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -1094,10 +1094,10 @@
   // the containing view space, and rounded off.  See
   // LayoutEmbeddedContent::UpdateGeometry. To remove the lossy effect of
   // rounding off, use contentBoxRect directly.
-  LayoutRect unclipped_absolute_rect(box->PhysicalContentBoxRect());
-  box->MapToVisualRectInAncestorSpace(root_view, unclipped_absolute_rect);
-  unclipped_absolute_rect =
-      box->View()->GetFrameView()->DocumentToFrame(unclipped_absolute_rect);
+  LayoutRect unclipped_root_frame_rect(box->PhysicalContentBoxRect());
+  box->MapToVisualRectInAncestorSpace(root_view, unclipped_root_frame_rect);
+  unclipped_root_frame_rect =
+      root_view->GetFrameView()->DocumentToFrame(unclipped_root_frame_rect);
 
   // The frameRect is already in absolute space of the local frame to the
   // plugin so map it up to the root frame.
@@ -1112,20 +1112,19 @@
 
   window_rect = PixelSnappedIntRect(layout_window_rect);
 
-  LayoutRect layout_clipped_local_rect = unclipped_absolute_rect;
-  LayoutRect unclipped_layout_local_rect = layout_clipped_local_rect;
-  layout_clipped_local_rect.Intersect(
+  LayoutRect clipped_root_frame_rect = unclipped_root_frame_rect;
+  clipped_root_frame_rect.Intersect(
       LayoutRect(LayoutPoint(), LayoutSize(root_view->GetFrameView()->Size())));
 
   unclipped_int_local_rect =
-      box->AbsoluteToLocalQuad(FloatRect(unclipped_layout_local_rect),
+      box->AbsoluteToLocalQuad(FloatRect(unclipped_root_frame_rect),
                                kTraverseDocumentBoundaries | kUseTransforms)
           .EnclosingBoundingBox();
   // As a performance optimization, map the clipped rect separately if is
   // different than the unclipped rect.
-  if (layout_clipped_local_rect != unclipped_layout_local_rect) {
+  if (clipped_root_frame_rect != unclipped_root_frame_rect) {
     clipped_local_rect =
-        box->AbsoluteToLocalQuad(FloatRect(layout_clipped_local_rect),
+        box->AbsoluteToLocalQuad(FloatRect(clipped_root_frame_rect),
                                  kTraverseDocumentBoundaries | kUseTransforms)
             .EnclosingBoundingBox();
   } else {
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
index 6174820..8e07ace2 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -1295,6 +1295,102 @@
   web_view_helper.Reset();
 }
 
+TEST_F(WebPluginContainerTest, ClippedRectsForShiftedIframedElement) {
+  RegisterMockedURL("plugin_hidden_before_scroll.html");
+  RegisterMockedURL("shifted_plugin_containing_page.html");
+
+  // Must outlive |web_view_helper|.
+  TestPluginWebFrameClient plugin_web_frame_client;
+  frame_test_helpers::WebViewHelper web_view_helper;
+  WebViewImpl* web_view = web_view_helper.InitializeAndLoad(
+      base_url_ + "shifted_plugin_containing_page.html",
+      &plugin_web_frame_client);
+  EnablePlugins(web_view, WebSize(300, 300));
+  UpdateAllLifecyclePhases(web_view);
+  WebLocalFrame* iframe =
+      web_view->MainFrame()->FirstChild()->ToWebLocalFrame();
+  WebElement plugin_element =
+      iframe->GetDocument().GetElementById("plugin-hidden-before-scroll");
+  WebPluginContainerImpl* plugin_container_impl =
+      ToWebPluginContainerImpl(plugin_element.PluginContainer());
+
+  DCHECK(plugin_container_impl);
+
+  IntSize plugin_size(40, 40);
+  IntSize iframe_size(40, 40);
+
+  IntPoint iframe_offset_in_root_frame(0, 300);
+  IntPoint plugin_offset_in_iframe(0, 40);
+
+  auto compute_expected_values = [=](IntSize root_document_scroll_to,
+                                     IntSize iframe_scroll_to) {
+    IntPoint offset_in_iframe = plugin_offset_in_iframe - iframe_scroll_to;
+    IntPoint offset_in_root_document =
+        iframe_offset_in_root_frame - root_document_scroll_to;
+    // window_rect is a plugin rectangle in the root frame coordinates.
+    IntRect expected_window_rect =
+        IntRect(offset_in_root_document + offset_in_iframe, plugin_size);
+
+    // unobscured_rect is the visible part of the plugin, inside the iframe.
+    IntRect expected_unobscured_rect(IntPoint(iframe_scroll_to), iframe_size);
+    expected_unobscured_rect.Intersect({plugin_offset_in_iframe, plugin_size});
+    expected_unobscured_rect.MoveBy(-plugin_offset_in_iframe);
+
+    // clip_rect is the visible part of the unobscured_rect, inside the
+    // root_frame.
+    IntRect expected_clip_rect = expected_unobscured_rect;
+    expected_clip_rect.MoveBy(expected_window_rect.Location());
+    expected_clip_rect.Intersect({{0, 0}, IntSize(300, 300)});
+    expected_clip_rect.MoveBy(-expected_window_rect.Location());
+
+    return std::make_tuple(expected_window_rect, expected_clip_rect,
+                           expected_unobscured_rect);
+  };
+
+  IntSize root_document_scrolls_to[] = {IntSize(0, 0),
+                                        IntSize(0, 20),
+                                        IntSize(0, 300),
+                                        IntSize(0, 320),
+                                        IntSize(0, 340)};
+
+  IntSize iframe_scrolls_to[] = {IntSize(0, 0),
+                                 IntSize(0, 20),
+                                 IntSize(0, 40),
+                                 IntSize(0, 60),
+                                 IntSize(0, 80)};
+
+  for (auto& root_document_scroll_to : root_document_scrolls_to) {
+    for (auto& iframe_scroll_to : iframe_scrolls_to) {
+      web_view->SmoothScroll(root_document_scroll_to.Width(),
+                             root_document_scroll_to.Height(), 0);
+      iframe->SetScrollOffset(iframe_scroll_to);
+      UpdateAllLifecyclePhases(web_view);
+      RunPendingTasks();
+
+      auto expected_values =
+          compute_expected_values(root_document_scroll_to, iframe_scroll_to);
+
+      IntRect window_rect, clip_rect, unobscured_rect;
+      CalculateGeometry(plugin_container_impl, window_rect, clip_rect,
+                        unobscured_rect);
+
+      EXPECT_EQ(std::get<0>(expected_values), window_rect);
+      EXPECT_EQ(std::get<1>(expected_values), clip_rect);
+
+      // It seems that CalculateGeometry calculates x and y values for empty
+      // rectangles slightly differently, but these values are not important in
+      // the empty case.
+      if(std::get<2>(expected_values).IsEmpty())
+        EXPECT_TRUE(unobscured_rect.IsEmpty());
+      else
+        EXPECT_EQ(std::get<2>(expected_values), unobscured_rect);
+    }
+  }
+
+  // Cause the plugin's frame to be detached.
+  web_view_helper.Reset();
+}
+
 TEST_F(WebPluginContainerTest, ClippedRectsForSubpixelPositionedPlugin) {
   RegisterMockedURL("plugin_container.html");
 
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 12817d80..cb35912 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -288,8 +288,8 @@
 void WebViewImpl::SetPrerendererClient(
     WebPrerendererClient* prerenderer_client) {
   DCHECK(page_);
-  ProvidePrerendererClientTo(*page_,
-                             new PrerendererClient(*page_, prerenderer_client));
+  ProvidePrerendererClientTo(*page_, MakeGarbageCollected<PrerendererClient>(
+                                         *page_, prerenderer_client));
 }
 
 WebViewImpl::WebViewImpl(WebViewClient* client,
@@ -355,7 +355,7 @@
   AllInstances().insert(this);
 
   page_importance_signals_.SetObserver(client);
-  resize_viewport_anchor_ = new ResizeViewportAnchor(*page_);
+  resize_viewport_anchor_ = MakeGarbageCollected<ResizeViewportAnchor>(*page_);
 }
 
 WebViewImpl::~WebViewImpl() {
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
index c212d9f2..d35b65a 100644
--- a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
+++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -521,7 +521,8 @@
       stream_broken_ = true;
       return nullptr;
     }
-    return new ReadableStreamBytesConsumer(script_state_, reader);
+    return MakeGarbageCollected<ReadableStreamBytesConsumer>(script_state_,
+                                                             reader);
   }
   // We need to call these before calling CloseAndLockAndDisturb.
   const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 370ded0..c14847a 100644
--- a/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -557,7 +557,7 @@
   if (response.UrlListViaServiceWorker().IsEmpty()) {
     // Note: |urlListViaServiceWorker| is empty, unless the response came from a
     // service worker, in which case it will only be empty if it was created
-    // through new Response().
+    // through MakeGarbageCollected<Response>().
     response_data->SetURLList(url_list_);
   } else {
     DCHECK(response.WasFetchedViaServiceWorker());
diff --git a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
index 2f92f6fb..bb43d5f 100644
--- a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
+++ b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.cc
@@ -27,9 +27,13 @@
   static v8::Local<v8::Function> CreateFunction(
       ScriptState* script_state,
       ReadableStreamBytesConsumer* consumer) {
-    return (new OnFulfilled(script_state, consumer))->BindToV8Function();
+    return (MakeGarbageCollected<OnFulfilled>(script_state, consumer))
+        ->BindToV8Function();
   }
 
+  OnFulfilled(ScriptState* script_state, ReadableStreamBytesConsumer* consumer)
+      : ScriptFunction(script_state), consumer_(consumer) {}
+
   ScriptValue Call(ScriptValue v) override {
     bool done;
     v8::Local<v8::Value> item = v.V8Value();
@@ -62,9 +66,6 @@
   }
 
  private:
-  OnFulfilled(ScriptState* script_state, ReadableStreamBytesConsumer* consumer)
-      : ScriptFunction(script_state), consumer_(consumer) {}
-
   Member<ReadableStreamBytesConsumer> consumer_;
 };
 
@@ -73,9 +74,13 @@
   static v8::Local<v8::Function> CreateFunction(
       ScriptState* script_state,
       ReadableStreamBytesConsumer* consumer) {
-    return (new OnRejected(script_state, consumer))->BindToV8Function();
+    return (MakeGarbageCollected<OnRejected>(script_state, consumer))
+        ->BindToV8Function();
   }
 
+  OnRejected(ScriptState* script_state, ReadableStreamBytesConsumer* consumer)
+      : ScriptFunction(script_state), consumer_(consumer) {}
+
   ScriptValue Call(ScriptValue v) override {
     consumer_->OnRejected();
     return v;
@@ -87,9 +92,6 @@
   }
 
  private:
-  OnRejected(ScriptState* script_state, ReadableStreamBytesConsumer* consumer)
-      : ScriptFunction(script_state), consumer_(consumer) {}
-
   Member<ReadableStreamBytesConsumer> consumer_;
 };
 
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc
index fba853a..e420f2d 100644
--- a/third_party/blink/renderer/core/fetch/request.cc
+++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -617,13 +617,13 @@
 }
 
 Request* Request::Create(ScriptState* script_state, FetchRequestData* request) {
-  return new Request(script_state, request);
+  return MakeGarbageCollected<Request>(script_state, request);
 }
 
 Request* Request::Create(ScriptState* script_state,
                          const WebServiceWorkerRequest& web_request) {
   FetchRequestData* data = FetchRequestData::Create(script_state, web_request);
-  return new Request(script_state, data);
+  return MakeGarbageCollected<Request>(script_state, data);
 }
 
 Request* Request::Create(
@@ -631,7 +631,7 @@
     const mojom::blink::FetchAPIRequest& fetch_api_request) {
   FetchRequestData* data =
       FetchRequestData::Create(script_state, fetch_api_request);
-  return new Request(script_state, data);
+  return MakeGarbageCollected<Request>(script_state, data);
 }
 
 bool Request::ParseCredentialsMode(
@@ -875,7 +875,7 @@
   headers->SetGuard(headers_->GetGuard());
   auto* signal = new AbortSignal(ExecutionContext::From(script_state));
   signal->Follow(signal_);
-  return new Request(script_state, request, headers, signal);
+  return MakeGarbageCollected<Request>(script_state, request, headers, signal);
 }
 
 FetchRequestData* Request::PassRequestData(ScriptState* script_state,
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h
index fea6f2f..e51937d 100644
--- a/third_party/blink/renderer/core/fetch/request.h
+++ b/third_party/blink/renderer/core/fetch/request.h
@@ -55,6 +55,9 @@
   static Request* Create(ScriptState*, const WebServiceWorkerRequest&);
   static Request* Create(ScriptState*, const mojom::blink::FetchAPIRequest&);
 
+  Request(ScriptState*, FetchRequestData*, Headers*, AbortSignal*);
+  Request(ScriptState*, FetchRequestData*);
+
   // Returns false if |credentials_mode| doesn't represent a valid credentials
   // mode.
   static bool ParseCredentialsMode(const String& credentials_mode,
@@ -91,9 +94,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  Request(ScriptState*, FetchRequestData*, Headers*, AbortSignal*);
-  Request(ScriptState*, FetchRequestData*);
-
   const FetchRequestData* GetRequest() const { return request_; }
   static Request* CreateRequestWithRequestOrString(ScriptState*,
                                                    Request*,
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc
index 47475c8..8816b18 100644
--- a/third_party/blink/renderer/core/fetch/response.cc
+++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -246,7 +246,8 @@
   // "3. Let |r| be a new Response object, associated with a new response.
   // "4. Set |r|'s headers to a new Headers object whose list is
   // |r|'s response's header list, and guard is "response" "
-  Response* r = new Response(ExecutionContext::From(script_state));
+  Response* r =
+      MakeGarbageCollected<Response>(ExecutionContext::From(script_state));
   // "5. Set |r|'s response's status to |init|'s status member."
   r->response_->SetStatus(init->status());
 
@@ -319,22 +320,22 @@
 
 Response* Response::Create(ExecutionContext* context,
                            FetchResponseData* response) {
-  return new Response(context, response);
+  return MakeGarbageCollected<Response>(context, response);
 }
 
 Response* Response::Create(ScriptState* script_state,
                            mojom::blink::FetchAPIResponse& response) {
   auto* fetch_response_data =
       CreateFetchResponseDataFromFetchAPIResponse(script_state, response);
-  return new Response(ExecutionContext::From(script_state),
-                      fetch_response_data);
+  return MakeGarbageCollected<Response>(ExecutionContext::From(script_state),
+                                        fetch_response_data);
 }
 
 Response* Response::error(ScriptState* script_state) {
   FetchResponseData* response_data =
       FetchResponseData::CreateNetworkErrorResponse();
-  Response* r =
-      new Response(ExecutionContext::From(script_state), response_data);
+  Response* r = MakeGarbageCollected<Response>(
+      ExecutionContext::From(script_state), response_data);
   r->headers_->SetGuard(Headers::kImmutableGuard);
   return r;
 }
@@ -354,7 +355,8 @@
     return nullptr;
   }
 
-  Response* r = new Response(ExecutionContext::From(script_state));
+  Response* r =
+      MakeGarbageCollected<Response>(ExecutionContext::From(script_state));
   r->headers_->SetGuard(Headers::kImmutableGuard);
   r->response_->SetStatus(status);
   r->response_->HeaderList()->Set("Location", parsed_url);
@@ -438,7 +440,8 @@
     return nullptr;
   Headers* headers = Headers::Create(response->HeaderList());
   headers->SetGuard(headers_->GetGuard());
-  return new Response(GetExecutionContext(), response, headers);
+  return MakeGarbageCollected<Response>(GetExecutionContext(), response,
+                                        headers);
 }
 
 bool Response::HasPendingActivity() const {
diff --git a/third_party/blink/renderer/core/fetch/response.h b/third_party/blink/renderer/core/fetch/response.h
index 8c26302..b8c76fa 100644
--- a/third_party/blink/renderer/core/fetch/response.h
+++ b/third_party/blink/renderer/core/fetch/response.h
@@ -55,6 +55,10 @@
                             unsigned short status,
                             ExceptionState&);
 
+  explicit Response(ExecutionContext*);
+  Response(ExecutionContext*, FetchResponseData*);
+  Response(ExecutionContext*, FetchResponseData*, Headers*);
+
   const FetchResponseData* GetResponse() const { return response_; }
 
   // From Response.idl:
@@ -108,10 +112,6 @@
   bool IsBodyUsedForDCheck(ExceptionState&) override;
 
  private:
-  explicit Response(ExecutionContext*);
-  Response(ExecutionContext*, FetchResponseData*);
-  Response(ExecutionContext*, FetchResponseData*, Headers*);
-
   const TraceWrapperMember<FetchResponseData> response_;
   const Member<Headers> headers_;
   DISALLOW_COPY_AND_ASSIGN(Response);
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.cc b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
index 8c54d94..e3de27c 100644
--- a/third_party/blink/renderer/core/fileapi/public_url_manager.cc
+++ b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
@@ -100,7 +100,7 @@
 }  // namespace
 
 PublicURLManager* PublicURLManager::Create(ExecutionContext* context) {
-  return new PublicURLManager(context);
+  return MakeGarbageCollected<PublicURLManager>(context);
 }
 
 PublicURLManager::PublicURLManager(ExecutionContext* context)
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.h b/third_party/blink/renderer/core/fileapi/public_url_manager.h
index 26c71d7..7c808b2 100644
--- a/third_party/blink/renderer/core/fileapi/public_url_manager.h
+++ b/third_party/blink/renderer/core/fileapi/public_url_manager.h
@@ -50,6 +50,8 @@
  public:
   static PublicURLManager* Create(ExecutionContext*);
 
+  explicit PublicURLManager(ExecutionContext*);
+
   // Generates a new Blob URL and registers the URLRegistrable to the
   // corresponding URLRegistry with the Blob URL. Returns the serialization
   // of the Blob URL.
@@ -76,8 +78,6 @@
   }
 
  private:
-  explicit PublicURLManager(ExecutionContext*);
-
   typedef String URLString;
   // Map from URLs to the URLRegistry they are registered with.
   typedef HashMap<URLString, URLRegistry*> URLToRegistryMap;
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index 04d9568..e8a2f73 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -824,7 +824,8 @@
   double removal_date = MilestoneDate(info.anticipated_removal);
   DeprecationReportBody* body = MakeGarbageCollected<DeprecationReportBody>(
       info.id, removal_date, info.message, SourceLocation::Capture());
-  Report* report = new Report("deprecation", document->Url().GetString(), body);
+  Report* report = MakeGarbageCollected<Report>(
+      "deprecation", document->Url().GetString(), body);
 
   // Send the deprecation report to any ReportingObservers.
   ReportingContext::From(document)->QueueReport(report);
diff --git a/third_party/blink/renderer/core/frame/intervention.cc b/third_party/blink/renderer/core/frame/intervention.cc
index b243c517e..1f9c5daa 100644
--- a/third_party/blink/renderer/core/frame/intervention.cc
+++ b/third_party/blink/renderer/core/frame/intervention.cc
@@ -35,8 +35,8 @@
   // Construct the intervention report.
   InterventionReportBody* body = MakeGarbageCollected<InterventionReportBody>(
       id, message, SourceLocation::Capture());
-  Report* report =
-      new Report("intervention", document->Url().GetString(), body);
+  Report* report = MakeGarbageCollected<Report>(
+      "intervention", document->Url().GetString(), body);
 
   // Send the intervention report to any ReportingObservers.
   ReportingContext::From(document)->QueueReport(report);
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index ed064a4..49aa591e 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -603,9 +603,9 @@
   // is problematic; consider imposing a limit or other restriction if this
   // surfaces often as a problem (see crbug.com/587012).
   std::unique_ptr<SourceLocation> location = SourceLocation::Capture(source);
-  PostMessageTimer* timer =
-      new PostMessageTimer(*this, event, std::move(target), std::move(location),
-                           UserGestureIndicator::CurrentToken());
+  PostMessageTimer* timer = MakeGarbageCollected<PostMessageTimer>(
+      *this, event, std::move(target), std::move(location),
+      UserGestureIndicator::CurrentToken());
   timer->StartOneShot(TimeDelta(), FROM_HERE);
   timer->PauseIfNeeded();
   probe::AsyncTaskScheduled(document(), "postMessage", timer);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index fdaa9d2e..2f30ff7 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -967,7 +967,7 @@
       interface_registry_(interface_registry) {
   if (IsLocalRoot()) {
     probe_sink_ = new CoreProbeSink();
-    performance_monitor_ = new PerformanceMonitor(this);
+    performance_monitor_ = MakeGarbageCollected<PerformanceMonitor>(this);
     inspector_trace_events_ = MakeGarbageCollected<InspectorTraceEvents>();
     probe_sink_->addInspectorTraceEvents(inspector_trace_events_);
     if (RuntimeEnabledFeatures::AdTaggingEnabled()) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index dd05ebb..ede080e 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2297,7 +2297,8 @@
   if (frame_->GetDocument()->Printing())
     return;
   if (!print_context_) {
-    print_context_ = new PrintContext(frame_, /*use_printing_layout=*/true);
+    print_context_ = MakeGarbageCollected<PrintContext>(
+        frame_, /*use_printing_layout=*/true);
   }
   if (frame_->GetSettings())
     frame_->GetSettings()->SetShouldPrintBackgrounds(true);
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.cc b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
index 7017ecf..322cb06 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.cc
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.cc
@@ -140,7 +140,7 @@
     bool user_gesture,
     WebScriptExecutionCallback* callback) {
   ScriptState* script_state = ToScriptState(frame, *world);
-  return new PausableScriptExecutor(
+  return MakeGarbageCollected<PausableScriptExecutor>(
       frame, script_state, callback,
       new WebScriptExecutor(sources, world->GetWorldId(), user_gesture));
 }
@@ -160,9 +160,10 @@
       callback->Completed(Vector<v8::Local<v8::Value>>());
     return;
   }
-  PausableScriptExecutor* executor = new PausableScriptExecutor(
-      frame, script_state, callback,
-      new V8FunctionExecutor(isolate, function, receiver, argc, argv));
+  PausableScriptExecutor* executor =
+      MakeGarbageCollected<PausableScriptExecutor>(
+          frame, script_state, callback,
+          new V8FunctionExecutor(isolate, function, receiver, argc, argv));
   executor->Run();
 }
 
diff --git a/third_party/blink/renderer/core/frame/pausable_script_executor.h b/third_party/blink/renderer/core/frame/pausable_script_executor.h
index bc32d08..c268810f 100644
--- a/third_party/blink/renderer/core/frame/pausable_script_executor.h
+++ b/third_party/blink/renderer/core/frame/pausable_script_executor.h
@@ -43,13 +43,6 @@
                            int argc,
                            v8::Local<v8::Value> argv[],
                            WebScriptExecutionCallback*);
-  ~PausableScriptExecutor() override;
-
-  void Run();
-  void RunAsync(BlockingOption);
-  void ContextDestroyed(ExecutionContext*) override;
-
-  void Trace(blink::Visitor*) override;
 
   class Executor : public GarbageCollectedFinalized<Executor> {
    public:
@@ -60,12 +53,19 @@
     virtual void Trace(blink::Visitor* visitor) {}
   };
 
- private:
   PausableScriptExecutor(LocalFrame*,
                          ScriptState*,
                          WebScriptExecutionCallback*,
                          Executor*);
+  ~PausableScriptExecutor() override;
 
+  void Run();
+  void RunAsync(BlockingOption);
+  void ContextDestroyed(ExecutionContext*) override;
+
+  void Trace(blink::Visitor*) override;
+
+ private:
   void Fired() override;
 
   void ExecuteAndDestroySelf();
diff --git a/third_party/blink/renderer/core/frame/pausable_task.cc b/third_party/blink/renderer/core/frame/pausable_task.cc
index 292f3a3..99b9d6a3 100644
--- a/third_party/blink/renderer/core/frame/pausable_task.cc
+++ b/third_party/blink/renderer/core/frame/pausable_task.cc
@@ -20,7 +20,7 @@
   } else {
     // Manages its own lifetime and invokes the callback when script is
     // unpaused.
-    new PausableTask(context, std::move(callback));
+    MakeGarbageCollected<PausableTask>(context, std::move(callback));
   }
 }
 
diff --git a/third_party/blink/renderer/core/frame/pausable_task.h b/third_party/blink/renderer/core/frame/pausable_task.h
index 7c7a54c..d5ff5e02 100644
--- a/third_party/blink/renderer/core/frame/pausable_task.h
+++ b/third_party/blink/renderer/core/frame/pausable_task.h
@@ -23,6 +23,8 @@
   USING_GARBAGE_COLLECTED_MIXIN(PausableTask);
 
  public:
+  // Note: This asserts that the context is currently suspended.
+  PausableTask(ExecutionContext*, WebLocalFrame::PausableTaskCallback);
   ~PausableTask() override;
 
   // Checks if the context is paused, and, if not, executes the callback
@@ -35,9 +37,6 @@
   void Fired() override;
 
  private:
-  // Note: This asserts that the context is currently suspended.
-  PausableTask(ExecutionContext*, WebLocalFrame::PausableTaskCallback);
-
   void Dispose();
 
   WebLocalFrame::PausableTaskCallback callback_;
diff --git a/third_party/blink/renderer/core/frame/performance_monitor_test.cc b/third_party/blink/renderer/core/frame/performance_monitor_test.cc
index 4be237c..319bd6e 100644
--- a/third_party/blink/renderer/core/frame/performance_monitor_test.cc
+++ b/third_party/blink/renderer/core/frame/performance_monitor_test.cc
@@ -76,7 +76,7 @@
 void PerformanceMonitorTest::SetUp() {
   page_holder_ = DummyPageHolder::Create(IntSize(800, 600));
   page_holder_->GetDocument().SetURL(KURL("https://example.com/foo"));
-  monitor_ = new PerformanceMonitor(GetFrame());
+  monitor_ = MakeGarbageCollected<PerformanceMonitor>(GetFrame());
 
   // Create another dummy page holder and pretend this is the iframe.
   another_page_holder_ = DummyPageHolder::Create(IntSize(400, 300));
diff --git a/third_party/blink/renderer/core/frame/platform_event_controller.h b/third_party/blink/renderer/core/frame/platform_event_controller.h
index e24c466..aab6f4a 100644
--- a/third_party/blink/renderer/core/frame/platform_event_controller.h
+++ b/third_party/blink/renderer/core/frame/platform_event_controller.h
@@ -9,8 +9,8 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/page/page_visibility_observer.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/frame/remote_dom_window.h b/third_party/blink/renderer/core/frame/remote_dom_window.h
index dd3ccb0..ccacdd3 100644
--- a/third_party/blink/renderer/core/frame/remote_dom_window.h
+++ b/third_party/blink/renderer/core/frame/remote_dom_window.h
@@ -14,9 +14,11 @@
 class RemoteDOMWindow final : public DOMWindow {
  public:
   static RemoteDOMWindow* Create(RemoteFrame& frame) {
-    return new RemoteDOMWindow(frame);
+    return MakeGarbageCollected<RemoteDOMWindow>(frame);
   }
 
+  explicit RemoteDOMWindow(RemoteFrame&);
+
   RemoteFrame* GetFrame() const { return ToRemoteFrame(DOMWindow::GetFrame()); }
 
   // EventTarget overrides:
@@ -35,8 +37,6 @@
                            Document* source) override;
 
  private:
-  explicit RemoteDOMWindow(RemoteFrame&);
-
   // Intentionally private to prevent redundant checks when the type is
   // already RemoteDOMWindow.
   bool IsLocalDOMWindow() const override { return false; }
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index ad89ac2..1db7ea1 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -40,7 +40,7 @@
 RemoteFrame* RemoteFrame::Create(RemoteFrameClient* client,
                                  Page& page,
                                  FrameOwner* owner) {
-  RemoteFrame* frame = new RemoteFrame(client, page, owner);
+  RemoteFrame* frame = MakeGarbageCollected<RemoteFrame>(client, page, owner);
   PageScheduler* page_scheduler = page.GetPageScheduler();
   if (frame->IsMainFrame() && page_scheduler)
     page_scheduler->SetIsMainFrameLocal(false);
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h
index 84173c0..a2d54a2 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.h
+++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -25,6 +25,7 @@
  public:
   static RemoteFrame* Create(RemoteFrameClient*, Page&, FrameOwner*);
 
+  RemoteFrame(RemoteFrameClient*, Page&, FrameOwner*);
   ~RemoteFrame() override;
 
   // Frame overrides:
@@ -67,8 +68,6 @@
   bool IsIgnoredForHitTest() const;
 
  private:
-  RemoteFrame(RemoteFrameClient*, Page&, FrameOwner*);
-
   // Frame protected overrides:
   void DetachImpl(FrameDetachType) override;
 
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
index b60c1a4..3a840c69 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -41,7 +41,7 @@
 
 RemoteFrameClientImpl* RemoteFrameClientImpl::Create(
     WebRemoteFrameImpl* web_frame) {
-  return new RemoteFrameClientImpl(web_frame);
+  return MakeGarbageCollected<RemoteFrameClientImpl>(web_frame);
 }
 
 void RemoteFrameClientImpl::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
index fa9ad8cb..bfdd480 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -18,6 +18,8 @@
  public:
   static RemoteFrameClientImpl* Create(WebRemoteFrameImpl*);
 
+  explicit RemoteFrameClientImpl(WebRemoteFrameImpl*);
+
   void Trace(blink::Visitor*) override;
 
   // FrameClient overrides:
@@ -56,8 +58,6 @@
   WebRemoteFrameImpl* GetWebFrame() const { return web_frame_; }
 
  private:
-  explicit RemoteFrameClientImpl(WebRemoteFrameImpl*);
-
   Member<WebRemoteFrameImpl> web_frame_;
 };
 
diff --git a/third_party/blink/renderer/core/frame/remote_frame_owner.h b/third_party/blink/renderer/core/frame/remote_frame_owner.h
index 4b15040..2d3a436 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_owner.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_owner.h
@@ -29,10 +29,16 @@
       const ParsedFeaturePolicy& container_policy,
       const WebFrameOwnerProperties& frame_owner_properties,
       FrameOwnerElementType frame_owner_element_type) {
-    return new RemoteFrameOwner(flags, container_policy, frame_owner_properties,
-                                frame_owner_element_type);
+    return MakeGarbageCollected<RemoteFrameOwner>(flags, container_policy,
+                                                  frame_owner_properties,
+                                                  frame_owner_element_type);
   }
 
+  RemoteFrameOwner(SandboxFlags,
+                   const ParsedFeaturePolicy&,
+                   const WebFrameOwnerProperties&,
+                   FrameOwnerElementType frame_owner_element_type);
+
   // FrameOwner overrides:
   Frame* ContentFrame() const override { return frame_.Get(); }
   void SetContentFrame(Frame&) override;
@@ -87,11 +93,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RemoteFrameOwner(SandboxFlags,
-                   const ParsedFeaturePolicy&,
-                   const WebFrameOwnerProperties&,
-                   FrameOwnerElementType frame_owner_element_type);
-
   // Intentionally private to prevent redundant checks when the type is
   // already HTMLFrameOwnerElement.
   bool IsLocal() const override { return false; }
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc
index e572155..f74fd56 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -58,7 +58,7 @@
 }
 
 RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) {
-  RemoteFrameView* view = new RemoteFrameView(remote_frame);
+  RemoteFrameView* view = MakeGarbageCollected<RemoteFrameView>(remote_frame);
   view->Show();
   return view;
 }
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.h b/third_party/blink/renderer/core/frame/remote_frame_view.h
index a9732e5..37e7179f1 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_view.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_view.h
@@ -30,6 +30,7 @@
  public:
   static RemoteFrameView* Create(RemoteFrame*);
 
+  explicit RemoteFrameView(RemoteFrame*);
   ~RemoteFrameView() override;
 
   void AttachToLayout() override;
@@ -73,8 +74,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit RemoteFrameView(RemoteFrame*);
-
   LocalFrameView* ParentFrameView() const;
 
   void UpdateRenderThrottlingStatus(bool hidden, bool subtree_throttled);
diff --git a/third_party/blink/renderer/core/frame/reporting_context.cc b/third_party/blink/renderer/core/frame/reporting_context.cc
index aac718d..7692ab2 100644
--- a/third_party/blink/renderer/core/frame/reporting_context.cc
+++ b/third_party/blink/renderer/core/frame/reporting_context.cc
@@ -25,7 +25,7 @@
   ReportingContext* reporting_context =
       Supplement<ExecutionContext>::From<ReportingContext>(context);
   if (!reporting_context) {
-    reporting_context = new ReportingContext(*context);
+    reporting_context = MakeGarbageCollected<ReportingContext>(*context);
     Supplement<ExecutionContext>::ProvideTo(*context, reporting_context);
   }
   return reporting_context;
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.cc b/third_party/blink/renderer/core/frame/reporting_observer.cc
index 52ae8322..a296b04 100644
--- a/third_party/blink/renderer/core/frame/reporting_observer.cc
+++ b/third_party/blink/renderer/core/frame/reporting_observer.cc
@@ -10,7 +10,7 @@
 #include "third_party/blink/renderer/core/frame/report.h"
 #include "third_party/blink/renderer/core/frame/reporting_context.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
@@ -18,7 +18,8 @@
     ExecutionContext* execution_context,
     V8ReportingObserverCallback* callback,
     ReportingObserverOptions* options) {
-  return new ReportingObserver(execution_context, callback, options);
+  return MakeGarbageCollected<ReportingObserver>(execution_context, callback,
+                                                 options);
 }
 
 ReportingObserver::ReportingObserver(ExecutionContext* execution_context,
diff --git a/third_party/blink/renderer/core/frame/reporting_observer.h b/third_party/blink/renderer/core/frame/reporting_observer.h
index d29c32d0..d0b3722 100644
--- a/third_party/blink/renderer/core/frame/reporting_observer.h
+++ b/third_party/blink/renderer/core/frame/reporting_observer.h
@@ -29,6 +29,10 @@
                                    V8ReportingObserverCallback*,
                                    ReportingObserverOptions*);
 
+  explicit ReportingObserver(ExecutionContext*,
+                             V8ReportingObserverCallback*,
+                             ReportingObserverOptions*);
+
   // ActiveScriptWrappable
   bool HasPendingActivity() const final;
 
@@ -56,10 +60,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit ReportingObserver(ExecutionContext*,
-                             V8ReportingObserverCallback*,
-                             ReportingObserverOptions*);
-
   Member<ExecutionContext> execution_context_;
   TraceWrapperMember<V8ReportingObserverCallback> callback_;
   Member<ReportingObserverOptions> options_;
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h
index d9c8fe8..a18c1ed 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport.h
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -32,9 +32,13 @@
  public:
   static RootFrameViewport* Create(ScrollableArea& visual_viewport,
                                    ScrollableArea& layout_viewport) {
-    return new RootFrameViewport(visual_viewport, layout_viewport);
+    return MakeGarbageCollected<RootFrameViewport>(visual_viewport,
+                                                   layout_viewport);
   }
 
+  RootFrameViewport(ScrollableArea& visual_viewport,
+                    ScrollableArea& layout_viewport);
+
   void Trace(blink::Visitor*) override;
 
   void SetLayoutViewport(ScrollableArea&);
@@ -121,9 +125,6 @@
   ScrollbarTheme& GetPageScrollbarTheme() const override;
 
  private:
-  RootFrameViewport(ScrollableArea& visual_viewport,
-                    ScrollableArea& layout_viewport);
-
   enum ViewportToScrollFirst { kVisualViewport, kLayoutViewport };
 
   ScrollOffset ScrollOffsetFromScrollAnimators() const;
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
index c4049f3..50dfcfc 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc
@@ -144,9 +144,14 @@
  public:
   static RootLayoutViewportStub* Create(const IntSize& viewport_size,
                                         const IntSize& contents_size) {
-    return new RootLayoutViewportStub(viewport_size, contents_size);
+    return MakeGarbageCollected<RootLayoutViewportStub>(viewport_size,
+                                                        contents_size);
   }
 
+  RootLayoutViewportStub(const IntSize& viewport_size,
+                         const IntSize& contents_size)
+      : ScrollableAreaStub(viewport_size, contents_size) {}
+
   ScrollOffset MaximumScrollOffset() const override {
     return ScrollOffset(ContentsSize() - ViewportSize());
   }
@@ -158,10 +163,6 @@
   }
 
  private:
-  RootLayoutViewportStub(const IntSize& viewport_size,
-                         const IntSize& contents_size)
-      : ScrollableAreaStub(viewport_size, contents_size) {}
-
   int VisibleWidth() const override { return viewport_size_.Width(); }
   int VisibleHeight() const override { return viewport_size_.Height(); }
 };
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
index 7cde0405..ace639fc 100644
--- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc
@@ -40,6 +40,7 @@
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/dom_timer.h"
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -252,4 +253,26 @@
     DOMTimer::RemoveByID(context, timeout_id);
 }
 
+ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
+    ScriptState* script_state,
+    EventTarget& event_target,
+    const ImageBitmapSourceUnion& bitmap_source,
+    const ImageBitmapOptions* options) {
+  return ImageBitmapFactories::CreateImageBitmap(script_state, event_target,
+                                                 bitmap_source, options);
+}
+
+ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
+    ScriptState* script_state,
+    EventTarget& event_target,
+    const ImageBitmapSourceUnion& bitmap_source,
+    int sx,
+    int sy,
+    int sw,
+    int sh,
+    const ImageBitmapOptions* options) {
+  return ImageBitmapFactories::CreateImageBitmap(
+      script_state, event_target, bitmap_source, sx, sy, sw, sh, options);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
index 76c5bdd..2126c4a5 100644
--- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
+++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h
@@ -33,6 +33,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_OR_WORKER_GLOBAL_SCOPE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_OR_WORKER_GLOBAL_SCOPE_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/image_bitmap_source.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -41,10 +42,15 @@
 
 class EventTarget;
 class ExceptionState;
+class ImageBitmapOptions;
+class ScriptPromise;
 class ScriptState;
 class ScriptValue;
 class StringOrTrustedScript;
 
+typedef HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas
+    ImageBitmapSourceUnion;
+
 class WindowOrWorkerGlobalScope {
   STATIC_ONLY(WindowOrWorkerGlobalScope);
 
@@ -90,6 +96,19 @@
                                    const Vector<ScriptValue>&);
   static void clearTimeout(EventTarget&, int timeout_id);
   static void clearInterval(EventTarget&, int timeout_id);
+
+  static ScriptPromise createImageBitmap(ScriptState*,
+                                         EventTarget&,
+                                         const ImageBitmapSourceUnion&,
+                                         const ImageBitmapOptions*);
+  static ScriptPromise createImageBitmap(ScriptState*,
+                                         EventTarget&,
+                                         const ImageBitmapSourceUnion&,
+                                         int sx,
+                                         int sy,
+                                         int sw,
+                                         int sh,
+                                         const ImageBitmapOptions*);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
index 554430d..1b78426e 100644
--- a/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
+++ b/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl
@@ -28,6 +28,16 @@
 // https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
 // https://html.spec.whatwg.org/C/timers-and-user-prompts.html#timers
 
+// https://html.spec.whatwg.org/#imagebitmapsource
+typedef (HTMLImageElement or
+         SVGImageElement or
+         HTMLVideoElement or
+         HTMLCanvasElement or
+         Blob or
+         ImageData or
+         ImageBitmap or
+         OffscreenCanvas) ImageBitmapSource;
+
 [
     LegacyTreatAsPartialInterface,
     NoInterfaceObject, // Always used on target of 'implements'
@@ -46,4 +56,10 @@
     [CallWith=ScriptState] long setInterval(CallbackFunctionTreatedAsScriptValue handler, optional long timeout = 0, any... arguments);
     [CallWith=ScriptState, RaisesException] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments);
     void clearInterval(optional long handle = 0);
+
+    // ImageBitmap
+    [CallWith=ScriptState] Promise createImageBitmap(
+        ImageBitmapSource imageBitmap, optional ImageBitmapOptions options);
+    [CallWith=ScriptState] Promise createImageBitmap(
+        ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
 };
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc b/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
index 62575ac8..9dc6430 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc
@@ -21,9 +21,9 @@
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
 #include "third_party/skia/include/core/SkSurface.h"
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc b/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc
index 22c3a933..651efd1e 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc
@@ -59,7 +59,7 @@
   HeapVector<Member<Command>>* third_commands =
       MakeGarbageCollected<HeapVector<Member<Command>>>();
   third_commands->push_back(MakeGarbageCollected<Log>('c', log));
-  third_commands->push_back(new Recurse(queue));
+  third_commands->push_back(MakeGarbageCollected<Recurse>(queue));
   CustomElementReaction* third =
       MakeGarbageCollected<TestReaction>(third_commands);  // "Empty" recursion
 
@@ -74,7 +74,7 @@
       MakeGarbageCollected<HeapVector<Member<Command>>>();
   first_commands->push_back(MakeGarbageCollected<Log>('a', log));
   first_commands->push_back(MakeGarbageCollected<Enqueue>(queue, second));
-  first_commands->push_back(new Recurse(queue));
+  first_commands->push_back(MakeGarbageCollected<Recurse>(queue));
   CustomElementReaction* first = MakeGarbageCollected<TestReaction>(
       first_commands);  // Non-empty recursion
 
diff --git a/third_party/blink/renderer/core/html/forms/file_chooser.cc b/third_party/blink/renderer/core/html/forms/file_chooser.cc
index 5def216..2cd55b41 100644
--- a/third_party/blink/renderer/core/html/forms/file_chooser.cc
+++ b/third_party/blink/renderer/core/html/forms/file_chooser.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/public/platform/file_path_conversion.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/page/chrome_client_impl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
index 214bb72c..12884a0 100644
--- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
+++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -68,9 +68,11 @@
   static PopupMenuCSSFontSelector* Create(
       Document* document,
       CSSFontSelector* owner_font_selector) {
-    return new PopupMenuCSSFontSelector(document, owner_font_selector);
+    return MakeGarbageCollected<PopupMenuCSSFontSelector>(document,
+                                                          owner_font_selector);
   }
 
+  PopupMenuCSSFontSelector(Document*, CSSFontSelector*);
   ~PopupMenuCSSFontSelector() override;
 
   // We don't override willUseFontData() for now because the old PopupListBox
@@ -81,8 +83,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PopupMenuCSSFontSelector(Document*, CSSFontSelector*);
-
   void FontsNeedUpdate(FontSelector*) override;
 
   Member<CSSFontSelector> owner_font_selector_;
diff --git a/third_party/blink/renderer/core/html/forms/mock_file_chooser.h b/third_party/blink/renderer/core/html/forms/mock_file_chooser.h
index 38cfa228..2058d12 100644
--- a/third_party/blink/renderer/core/html/forms/mock_file_chooser.h
+++ b/third_party/blink/renderer/core/html/forms/mock_file_chooser.h
@@ -8,6 +8,7 @@
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/blink/public/mojom/choosers/file_chooser.mojom-blink.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type.cc b/third_party/blink/renderer/core/html/forms/password_input_type.cc
index b6f8b91e..5260d8f 100644
--- a/third_party/blink/renderer/core/html/forms/password_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/password_input_type.cc
@@ -45,7 +45,7 @@
 namespace blink {
 
 InputType* PasswordInputType::Create(HTMLInputElement& element) {
-  return new PasswordInputType(element);
+  return MakeGarbageCollected<PasswordInputType>(element);
 }
 
 void PasswordInputType::CountUsage() {
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type.h b/third_party/blink/renderer/core/html/forms/password_input_type.h
index 093a794..3722b54 100644
--- a/third_party/blink/renderer/core/html/forms/password_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/password_input_type.h
@@ -39,9 +39,10 @@
  public:
   static InputType* Create(HTMLInputElement&);
 
- private:
   explicit PasswordInputType(HTMLInputElement& element)
       : BaseTextInputType(element) {}
+
+ private:
   void CountUsage() override;
   const AtomicString& FormControlType() const override;
   bool ShouldSaveAndRestoreFormControlState() const override;
diff --git a/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc b/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
index 583d803..252e601 100644
--- a/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
+++ b/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc
@@ -54,7 +54,8 @@
     Document& document,
     PickerIndicatorOwner& picker_indicator_owner) {
   PickerIndicatorElement* element =
-      new PickerIndicatorElement(document, picker_indicator_owner);
+      MakeGarbageCollected<PickerIndicatorElement>(document,
+                                                   picker_indicator_owner);
   element->SetShadowPseudoId(AtomicString("-webkit-calendar-picker-indicator"));
   element->setAttribute(kIdAttr, shadow_element_names::PickerIndicator());
   return element;
diff --git a/third_party/blink/renderer/core/html/forms/picker_indicator_element.h b/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
index 9f675b2..b2d2834 100644
--- a/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
+++ b/third_party/blink/renderer/core/html/forms/picker_indicator_element.h
@@ -58,6 +58,8 @@
   };
 
   static PickerIndicatorElement* Create(Document&, PickerIndicatorOwner&);
+
+  PickerIndicatorElement(Document&, PickerIndicatorOwner&);
   ~PickerIndicatorElement() override;
   void Trace(blink::Visitor*) override;
 
@@ -74,7 +76,6 @@
   void DidEndChooser() override;
 
  private:
-  PickerIndicatorElement(Document&, PickerIndicatorOwner&);
   LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
   void DefaultEventHandler(Event&) override;
   void DetachLayoutTree(const AttachContext& = AttachContext()) override;
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
index 7f152f3..f4968e4f 100644
--- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -30,6 +30,9 @@
 class RadioButtonGroup : public GarbageCollected<RadioButtonGroup> {
  public:
   static RadioButtonGroup* Create();
+
+  RadioButtonGroup();
+
   bool IsEmpty() const { return members_.IsEmpty(); }
   bool IsRequired() const { return required_count_; }
   HTMLInputElement* CheckedButton() const { return checked_button_; }
@@ -43,7 +46,6 @@
   void Trace(blink::Visitor*);
 
  private:
-  RadioButtonGroup();
   void SetNeedsValidityCheckForAllButtons();
   bool IsValid() const;
   void SetCheckedButton(HTMLInputElement*);
@@ -64,7 +66,7 @@
     : checked_button_(nullptr), required_count_(0) {}
 
 RadioButtonGroup* RadioButtonGroup::Create() {
-  return new RadioButtonGroup;
+  return MakeGarbageCollected<RadioButtonGroup>();
 }
 
 inline bool RadioButtonGroup::IsValid() const {
diff --git a/third_party/blink/renderer/core/html/forms/radio_input_type.cc b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
index fefdaac..f12a9a1 100644
--- a/third_party/blink/renderer/core/html/forms/radio_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_input_type.cc
@@ -46,7 +46,7 @@
 }  // namespace
 
 InputType* RadioInputType::Create(HTMLInputElement& element) {
-  return new RadioInputType(element);
+  return MakeGarbageCollected<RadioInputType>(element);
 }
 
 const AtomicString& RadioInputType::FormControlType() const {
diff --git a/third_party/blink/renderer/core/html/forms/radio_input_type.h b/third_party/blink/renderer/core/html/forms/radio_input_type.h
index 9b9a70a5..e90755f0 100644
--- a/third_party/blink/renderer/core/html/forms/radio_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/radio_input_type.h
@@ -42,8 +42,9 @@
   CORE_EXPORT static HTMLInputElement* NextRadioButtonInGroup(HTMLInputElement*,
                                                               bool forward);
 
- private:
   RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(element) {}
+
+ private:
   const AtomicString& FormControlType() const override;
   bool ValueMissing(const String&) const override;
   String ValueMissingText() const override;
diff --git a/third_party/blink/renderer/core/html/forms/radio_node_list.h b/third_party/blink/renderer/core/html/forms/radio_node_list.h
index 81e76d5..fd958c1 100644
--- a/third_party/blink/renderer/core/html/forms/radio_node_list.h
+++ b/third_party/blink/renderer/core/html/forms/radio_node_list.h
@@ -40,17 +40,16 @@
                                CollectionType type,
                                const AtomicString& name) {
     DCHECK(type == kRadioNodeListType || type == kRadioImgNodeListType);
-    return new RadioNodeList(owner_node, name, type);
+    return MakeGarbageCollected<RadioNodeList>(owner_node, name, type);
   }
 
+  RadioNodeList(ContainerNode&, const AtomicString& name, CollectionType);
   ~RadioNodeList() override;
 
   String value() const;
   void setValue(const String&);
 
  private:
-  RadioNodeList(ContainerNode&, const AtomicString& name, CollectionType);
-
   bool CheckElementMatchesRadioNodeListFilter(const Element&) const;
 
   bool MatchesByIdOrName(const Element&) const;
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc
index 251a6c3..d32bc57 100644
--- a/third_party/blink/renderer/core/html/forms/range_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -71,7 +71,7 @@
 }
 
 InputType* RangeInputType::Create(HTMLInputElement& element) {
-  return new RangeInputType(element);
+  return MakeGarbageCollected<RangeInputType>(element);
 }
 
 RangeInputType::RangeInputType(HTMLInputElement& element)
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.h b/third_party/blink/renderer/core/html/forms/range_input_type.h
index bbdb85e..a0bd003 100644
--- a/third_party/blink/renderer/core/html/forms/range_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/range_input_type.h
@@ -44,11 +44,13 @@
 
  public:
   static InputType* Create(HTMLInputElement&);
+
+  RangeInputType(HTMLInputElement&);
+
   void Trace(blink::Visitor*) override;
   using InputType::GetElement;
 
  private:
-  RangeInputType(HTMLInputElement&);
   InputTypeView* CreateView() override;
   ValueMode GetValueMode() const override;
   void CountUsage() override;
diff --git a/third_party/blink/renderer/core/html/forms/reset_input_type.cc b/third_party/blink/renderer/core/html/forms/reset_input_type.cc
index e521ea8..f355452 100644
--- a/third_party/blink/renderer/core/html/forms/reset_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/reset_input_type.cc
@@ -40,7 +40,7 @@
 namespace blink {
 
 InputType* ResetInputType::Create(HTMLInputElement& element) {
-  return new ResetInputType(element);
+  return MakeGarbageCollected<ResetInputType>(element);
 }
 
 const AtomicString& ResetInputType::FormControlType() const {
diff --git a/third_party/blink/renderer/core/html/forms/reset_input_type.h b/third_party/blink/renderer/core/html/forms/reset_input_type.h
index b239a15..0e35bae 100644
--- a/third_party/blink/renderer/core/html/forms/reset_input_type.h
+++ b/third_party/blink/renderer/core/html/forms/reset_input_type.h
@@ -39,8 +39,9 @@
  public:
   static InputType* Create(HTMLInputElement&);
 
- private:
   ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) {}
+
+ private:
   const AtomicString& FormControlType() const override;
   bool SupportsValidation() const override;
   void HandleDOMActivateEvent(Event&) override;
diff --git a/third_party/blink/renderer/core/html/html_details_element.h b/third_party/blink/renderer/core/html/html_details_element.h
index 93c5cefd..a3854bd2 100644
--- a/third_party/blink/renderer/core/html/html_details_element.h
+++ b/third_party/blink/renderer/core/html/html_details_element.h
@@ -22,7 +22,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_DETAILS_ELEMENT_H_
 
 #include "third_party/blink/renderer/core/html/html_element.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/html/html_source_element.cc b/third_party/blink/renderer/core/html/html_source_element.cc
index 4f20b8b..38ed258c 100644
--- a/third_party/blink/renderer/core/html/html_source_element.cc
+++ b/third_party/blink/renderer/core/html/html_source_element.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 #define SOURCE_LOG_LEVEL 3
 
diff --git a/third_party/blink/renderer/core/html/html_source_element.h b/third_party/blink/renderer/core/html/html_source_element.h
index 43c74127..6f3fc9d5 100644
--- a/third_party/blink/renderer/core/html/html_source_element.h
+++ b/third_party/blink/renderer/core/html/html_source_element.h
@@ -28,8 +28,8 @@
 
 #include "third_party/blink/renderer/core/css/media_query_list_listener.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index 9dc115a..1e95f10f 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -42,9 +42,9 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/supplementable.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace cc {
 class Layer;
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc
index ae5e8ad..5eebce7 100644
--- a/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -698,7 +698,8 @@
 
 void HTMLVideoElement::OnEnteredPictureInPicture() {
   if (!picture_in_picture_interstitial_) {
-    picture_in_picture_interstitial_ = new PictureInPictureInterstitial(*this);
+    picture_in_picture_interstitial_ =
+        MakeGarbageCollected<PictureInPictureInterstitial>(*this);
     ShadowRoot& shadow_root = EnsureUserAgentShadowRoot();
     shadow_root.InsertBefore(picture_in_picture_interstitial_,
                              shadow_root.firstChild());
diff --git a/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc b/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
index 06712a7..a6d49398 100644
--- a/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
+++ b/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc
@@ -57,9 +57,9 @@
 PictureInPictureInterstitial::PictureInPictureInterstitial(
     HTMLVideoElement& videoElement)
     : HTMLDivElement(videoElement.GetDocument()),
-      resize_observer_(
-          ResizeObserver::Create(videoElement.GetDocument(),
-                                 new VideoElementResizeObserverDelegate(this))),
+      resize_observer_(ResizeObserver::Create(
+          videoElement.GetDocument(),
+          MakeGarbageCollected<VideoElementResizeObserverDelegate>(this))),
       interstitial_timer_(
           videoElement.GetDocument().GetTaskRunner(TaskType::kInternalMedia),
           this,
@@ -119,9 +119,9 @@
 Node::InsertionNotificationRequest PictureInPictureInterstitial::InsertedInto(
     ContainerNode& root) {
   if (GetVideoElement().isConnected() && !resize_observer_) {
-    resize_observer_ =
-        ResizeObserver::Create(GetVideoElement().GetDocument(),
-                               new VideoElementResizeObserverDelegate(this));
+    resize_observer_ = ResizeObserver::Create(
+        GetVideoElement().GetDocument(),
+        MakeGarbageCollected<VideoElementResizeObserverDelegate>(this));
     resize_observer_->observe(&GetVideoElement());
   }
 
diff --git a/third_party/blink/renderer/core/html/parser/background_html_parser.cc b/third_party/blink/renderer/core/html/parser/background_html_parser.cc
index e07e85a..8818320 100644
--- a/third_party/blink/renderer/core/html/parser/background_html_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/background_html_parser.cc
@@ -37,7 +37,6 @@
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_position.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
diff --git a/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h b/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
index fd1ea80..f555db1e 100644
--- a/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
+++ b/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h
@@ -32,7 +32,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/renderer/core/html/parser/nesting_level_incrementer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/html/plugin_document.cc b/third_party/blink/renderer/core/html/plugin_document.cc
index 8cbd7cd..70c83c2 100644
--- a/third_party/blink/renderer/core/html/plugin_document.cc
+++ b/third_party/blink/renderer/core/html/plugin_document.cc
@@ -52,9 +52,12 @@
 class PluginDocument::BeforeUnloadEventListener : public EventListener {
  public:
   static BeforeUnloadEventListener* Create(PluginDocument* document) {
-    return new BeforeUnloadEventListener(document);
+    return MakeGarbageCollected<BeforeUnloadEventListener>(document);
   }
 
+  explicit BeforeUnloadEventListener(PluginDocument* document)
+      : EventListener(kCPPEventListenerType), doc_(document) {}
+
   bool operator==(const EventListener& listener) const override {
     return this == &listener;
   }
@@ -69,9 +72,6 @@
   }
 
  private:
-  explicit BeforeUnloadEventListener(PluginDocument* document)
-      : EventListener(kCPPEventListenerType), doc_(document) {}
-
   void Invoke(ExecutionContext*, Event* event) override {
     DCHECK_EQ(event->type(), event_type_names::kBeforeunload);
     if (show_dialog_)
@@ -87,20 +87,21 @@
  public:
   static PluginDocumentParser* Create(PluginDocument* document,
                                       Color background_color) {
-    return new PluginDocumentParser(document, background_color);
+    return MakeGarbageCollected<PluginDocumentParser>(document,
+                                                      background_color);
   }
 
+  PluginDocumentParser(Document* document, Color background_color)
+      : RawDataDocumentParser(document),
+        embed_element_(nullptr),
+        background_color_(background_color) {}
+
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(embed_element_);
     RawDataDocumentParser::Trace(visitor);
   }
 
  private:
-  PluginDocumentParser(Document* document, Color background_color)
-      : RawDataDocumentParser(document),
-        embed_element_(nullptr),
-        background_color_(background_color) {}
-
   void AppendBytes(const char*, size_t) override;
 
   void Finish() override;
diff --git a/third_party/blink/renderer/core/html/plugin_document.h b/third_party/blink/renderer/core/html/plugin_document.h
index 5566a47..8339e57 100644
--- a/third_party/blink/renderer/core/html/plugin_document.h
+++ b/third_party/blink/renderer/core/html/plugin_document.h
@@ -38,9 +38,11 @@
  public:
   static PluginDocument* Create(const DocumentInit& initializer,
                                 Color background_color) {
-    return new PluginDocument(initializer, background_color);
+    return MakeGarbageCollected<PluginDocument>(initializer, background_color);
   }
 
+  PluginDocument(const DocumentInit&, Color background_color);
+
   void SetPluginNode(HTMLPlugInElement* plugin_node) {
     plugin_node_ = plugin_node;
   }
@@ -57,8 +59,6 @@
  private:
   class BeforeUnloadEventListener;
 
-  PluginDocument(const DocumentInit&, Color background_color);
-
   DocumentParser* CreateParser() override;
 
   Member<HTMLPlugInElement> plugin_node_;
diff --git a/third_party/blink/renderer/core/html/rel_list.h b/third_party/blink/renderer/core/html/rel_list.h
index a7c227f..62c0c9e7 100644
--- a/third_party/blink/renderer/core/html/rel_list.h
+++ b/third_party/blink/renderer/core/html/rel_list.h
@@ -11,10 +11,13 @@
 
 class RelList final : public DOMTokenList {
  public:
-  static RelList* Create(Element* element) { return new RelList(element); }
+  static RelList* Create(Element* element) {
+    return MakeGarbageCollected<RelList>(element);
+  }
+
+  explicit RelList(Element*);
 
  private:
-  explicit RelList(Element*);
   bool ValidateTokenValue(const AtomicString&, ExceptionState&) const override;
 };
 
diff --git a/third_party/blink/renderer/core/css/themeChromiumAndroid.css b/third_party/blink/renderer/core/html/resources/android.css
similarity index 100%
rename from third_party/blink/renderer/core/css/themeChromiumAndroid.css
rename to third_party/blink/renderer/core/html/resources/android.css
diff --git a/third_party/blink/renderer/core/css/html.css b/third_party/blink/renderer/core/html/resources/html.css
similarity index 100%
rename from third_party/blink/renderer/core/css/html.css
rename to third_party/blink/renderer/core/html/resources/html.css
diff --git a/third_party/blink/renderer/core/css/themeInputMultipleFields.css b/third_party/blink/renderer/core/html/resources/input_multiple_fields.css
similarity index 100%
rename from third_party/blink/renderer/core/css/themeInputMultipleFields.css
rename to third_party/blink/renderer/core/html/resources/input_multiple_fields.css
diff --git a/third_party/blink/renderer/core/css/themeChromiumLinux.css b/third_party/blink/renderer/core/html/resources/linux.css
similarity index 100%
rename from third_party/blink/renderer/core/css/themeChromiumLinux.css
rename to third_party/blink/renderer/core/html/resources/linux.css
diff --git a/third_party/blink/renderer/core/css/themeMac.css b/third_party/blink/renderer/core/html/resources/mac.css
similarity index 100%
rename from third_party/blink/renderer/core/css/themeMac.css
rename to third_party/blink/renderer/core/html/resources/mac.css
diff --git a/third_party/blink/renderer/core/css/quirks.css b/third_party/blink/renderer/core/html/resources/quirks.css
similarity index 100%
rename from third_party/blink/renderer/core/css/quirks.css
rename to third_party/blink/renderer/core/html/resources/quirks.css
diff --git a/third_party/blink/renderer/core/css/themeWin.css b/third_party/blink/renderer/core/html/resources/win.css
similarity index 94%
rename from third_party/blink/renderer/core/css/themeWin.css
rename to third_party/blink/renderer/core/html/resources/win.css
index ed659ee..e3d49d1 100644
--- a/third_party/blink/renderer/core/css/themeWin.css
+++ b/third_party/blink/renderer/core/html/resources/win.css
@@ -29,13 +29,13 @@
  */
 
 /* These styles override the default styling for HTML elements as defined in
-   WebCore/css/html.css. So far we have used this file exclusively for
-   making our form elements match Firefox's. */
+   core/html/resources/tml.css. So far we have used this file exclusively
+   for making our form elements match Firefox's. */
 
 /*
  * Update padding for all text-like types including unknown types.
  * Non-text types have input[type="foo" i] with padding properties in
- * html.css or themeInputMultipleFields.css.
+ * html.css or input_multiple_fields.css.
  */
 input {
     padding:1px 0;
diff --git a/third_party/blink/renderer/core/css/themeWinQuirks.css b/third_party/blink/renderer/core/html/resources/win_quirks.css
similarity index 92%
rename from third_party/blink/renderer/core/css/themeWinQuirks.css
rename to third_party/blink/renderer/core/html/resources/win_quirks.css
index c69b74c..196d0820 100644
--- a/third_party/blink/renderer/core/css/themeWinQuirks.css
+++ b/third_party/blink/renderer/core/html/resources/win_quirks.css
@@ -29,8 +29,8 @@
  */
 
 /* These styles override the default styling for HTML elements in quirks-mode
-   as defined in WebCore/css/quirks.css. So far we have used this file exclusively for
-   making our form elements match Firefox's. */
+   as defined in core/html/resources/quirks.css. So far we have used this
+   file exclusively for making our form elements match Firefox's. */
 
 textarea {
   /* Matches IE's text offsets in quirksmode (causes text to wrap the same as IE). */
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index da0fea8..a24a466 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/saturated_arithmetic.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
index f89011e..f41dc15 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
@@ -46,7 +46,6 @@
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
 #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
-#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
 #include "third_party/blink/renderer/core/svg/svg_image_element.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -54,6 +53,7 @@
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "v8/include/v8.h"
@@ -139,7 +139,7 @@
   return promise;
 }
 
-ScriptPromise ImageBitmapFactories::createImageBitmap(
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
     ScriptState* script_state,
     EventTarget& event_target,
     const ImageBitmapSourceUnion& bitmap_source,
@@ -150,11 +150,11 @@
       ToImageBitmapSourceInternal(bitmap_source, options, false);
   if (!bitmap_source_internal)
     return ScriptPromise();
-  return createImageBitmap(script_state, event_target, bitmap_source_internal,
+  return CreateImageBitmap(script_state, event_target, bitmap_source_internal,
                            base::Optional<IntRect>(), options);
 }
 
-ScriptPromise ImageBitmapFactories::createImageBitmap(
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
     ScriptState* script_state,
     EventTarget& event_target,
     const ImageBitmapSourceUnion& bitmap_source,
@@ -170,11 +170,11 @@
   if (!bitmap_source_internal)
     return ScriptPromise();
   base::Optional<IntRect> crop_rect = IntRect(sx, sy, sw, sh);
-  return createImageBitmap(script_state, event_target, bitmap_source_internal,
+  return CreateImageBitmap(script_state, event_target, bitmap_source_internal,
                            crop_rect, options);
 }
 
-ScriptPromise ImageBitmapFactories::createImageBitmap(
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
     ScriptState* script_state,
     EventTarget& event_target,
     ImageBitmapSource* bitmap_source,
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
index b59e50a..1b4e045 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
@@ -32,6 +32,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_IMAGEBITMAP_IMAGE_BITMAP_FACTORIES_H_
 
 #include <memory>
+
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/renderer/bindings/core/v8/image_bitmap_source.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -39,6 +40,7 @@
 #include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
 #include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/window_or_worker_global_scope.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/name_client.h"
@@ -56,9 +58,6 @@
 class ImageBitmapSource;
 class ImageBitmapOptions;
 
-typedef HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas
-    ImageBitmapSourceUnion;
-
 class ImageBitmapFactories final
     : public GarbageCollectedFinalized<ImageBitmapFactories>,
       public Supplement<LocalDOMWindow>,
@@ -69,11 +68,11 @@
  public:
   static const char kSupplementName[];
 
-  static ScriptPromise createImageBitmap(ScriptState*,
+  static ScriptPromise CreateImageBitmap(ScriptState*,
                                          EventTarget&,
                                          const ImageBitmapSourceUnion&,
                                          const ImageBitmapOptions*);
-  static ScriptPromise createImageBitmap(ScriptState*,
+  static ScriptPromise CreateImageBitmap(ScriptState*,
                                          EventTarget&,
                                          const ImageBitmapSourceUnion&,
                                          int sx,
@@ -81,7 +80,7 @@
                                          int sw,
                                          int sh,
                                          const ImageBitmapOptions*);
-  static ScriptPromise createImageBitmap(ScriptState*,
+  static ScriptPromise CreateImageBitmap(ScriptState*,
                                          EventTarget&,
                                          ImageBitmapSource*,
                                          base::Optional<IntRect> crop_rect,
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.idl b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.idl
deleted file mode 100644
index 5ef7a454..0000000
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.idl
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// https://html.spec.whatwg.org/#imagebitmapfactories
-
-typedef (HTMLImageElement or
-         SVGImageElement or
-         HTMLVideoElement or
-         HTMLCanvasElement or
-         Blob or
-         ImageData or
-         ImageBitmap or
-         OffscreenCanvas) ImageBitmapSource;
-
-[
-    LegacyTreatAsPartialInterface,
-    NoInterfaceObject, // Always used on target of 'implements'
-    Exposed=(Window,Worker)
-] interface ImageBitmapFactories {
-    [CallWith=ScriptState] Promise createImageBitmap(
-        ImageBitmapSource imageBitmap, optional ImageBitmapOptions options);
-    [CallWith=ScriptState] Promise createImageBitmap(
-        ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
-};
-
-Window implements ImageBitmapFactories;
-WorkerGlobalScope implements ImageBitmapFactories;
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index 2be15f2..8ad2449 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -163,7 +163,8 @@
       keyboard_event_manager_(
           MakeGarbageCollected<KeyboardEventManager>(frame, *scroll_manager_)),
       pointer_event_manager_(
-          new PointerEventManager(frame, *mouse_event_manager_)),
+          MakeGarbageCollected<PointerEventManager>(frame,
+                                                    *mouse_event_manager_)),
       gesture_manager_(
           MakeGarbageCollected<GestureManager>(frame,
                                                *scroll_manager_,
diff --git a/third_party/blink/renderer/core/inspector/devtools_session.cc b/third_party/blink/renderer/core/inspector/devtools_session.cc
index a1a06e4..347b9a74 100644
--- a/third_party/blink/renderer/core/inspector/devtools_session.cc
+++ b/third_party/blink/renderer/core/inspector/devtools_session.cc
@@ -17,7 +17,6 @@
 #include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/web_test_support.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
index bc591c8..04bb17da 100644
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -1340,7 +1340,8 @@
 
   // Construct the test report.
   TestReportBody* body = new TestReportBody(message);
-  Report* report = new Report("test", document->Url().GetString(), body);
+  Report* report =
+      MakeGarbageCollected<Report>("test", document->Url().GetString(), body);
 
   // Send the test report to any ReportingObservers.
   ReportingContext::From(document)->QueueReport(report);
diff --git a/third_party/blink/renderer/core/inspector/inspector_task_runner.cc b/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
index 19b36ad..656bff6 100644
--- a/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
@@ -6,7 +6,7 @@
 
 #include "third_party/blink/renderer/core/inspector/thread_debugger.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
index 4e39a33..c8610b5 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/intersection_observer/intersection_observation.h"
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc b/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc
index a5138a0..d591ee54 100644
--- a/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc
+++ b/third_party/blink/renderer/core/layout/custom/css_layout_definition.cc
@@ -127,7 +127,7 @@
   // TODO(ikilpatrick): Instead of creating a new style_map each time here,
   // store on LayoutCustom, and update when the style changes.
   StylePropertyMapReadOnly* style_map =
-      new PrepopulatedComputedStylePropertyMap(
+      MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
           layout_custom.GetDocument(), layout_custom.StyleRef(),
           layout_custom.GetNode(), definition_->native_invalidation_properties_,
           definition_->custom_invalidation_properties_);
diff --git a/third_party/blink/renderer/core/layout/custom/custom_layout_child.cc b/third_party/blink/renderer/core/layout/custom/custom_layout_child.cc
index 4b20a13..a992eaa 100644
--- a/third_party/blink/renderer/core/layout/custom/custom_layout_child.cc
+++ b/third_party/blink/renderer/core/layout/custom/custom_layout_child.cc
@@ -15,7 +15,7 @@
 CustomLayoutChild::CustomLayoutChild(const CSSLayoutDefinition& definition,
                                      LayoutBox* box)
     : box_(box),
-      style_map_(new PrepopulatedComputedStylePropertyMap(
+      style_map_(MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
           box->GetDocument(),
           box->StyleRef(),
           box->GetNode(),
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet.cc
index 7457bd7..85f475c 100644
--- a/third_party/blink/renderer/core/layout/custom/layout_worklet.cc
+++ b/third_party/blink/renderer/core/layout/custom/layout_worklet.cc
@@ -36,7 +36,7 @@
 LayoutWorklet::LayoutWorklet(LocalFrame* frame)
     : Worklet(frame->GetDocument()),
       Supplement<LocalDOMWindow>(*frame->DomWindow()),
-      pending_layout_registry_(new PendingLayoutRegistry()) {}
+      pending_layout_registry_(MakeGarbageCollected<PendingLayoutRegistry>()) {}
 
 LayoutWorklet::~LayoutWorklet() = default;
 
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.cc b/third_party/blink/renderer/core/layout/layout_list_marker.cc
index 9d8b679..9529cd9 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -36,7 +36,7 @@
 
 const int kCMarkerPaddingPx = 7;
 
-// TODO(glebl): Move to WebKit/Source/core/css/html.css after
+// TODO(glebl): Move to core/html/resources/html.css after
 // Blink starts to support ::marker crbug.com/457718
 // Recommended UA margin for list markers.
 const int kCUAMarkerMarginEm = 1;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc
index 4010a8d..5c154fb 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_default.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -92,9 +92,9 @@
   String extra_style_sheet = LayoutTheme::ExtraDefaultStyleSheet();
   String multiple_fields_style_sheet =
       RuntimeEnabledFeatures::InputMultipleFieldsUIEnabled()
-          ? GetDataResourceAsASCIIString("themeInputMultipleFields.css")
+          ? GetDataResourceAsASCIIString("input_multiple_fields.css")
           : String();
-  String windows_style_sheet = GetDataResourceAsASCIIString("themeWin.css");
+  String windows_style_sheet = GetDataResourceAsASCIIString("win.css");
   StringBuilder builder;
   builder.ReserveCapacity(extra_style_sheet.length() +
                           multiple_fields_style_sheet.length() +
@@ -106,7 +106,7 @@
 }
 
 String LayoutThemeDefault::ExtraQuirksStyleSheet() {
-  return GetDataResourceAsASCIIString("themeWinQuirks.css");
+  return GetDataResourceAsASCIIString("win_quirks.css");
 }
 
 Color LayoutThemeDefault::ActiveListBoxSelectionBackgroundColor() const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_linux.cc b/third_party/blink/renderer/core/layout/layout_theme_linux.cc
index 73418a48..6033536b 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_linux.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme_linux.cc
@@ -19,7 +19,7 @@
 
 String LayoutThemeLinux::ExtraDefaultStyleSheet() {
   return LayoutThemeDefault::ExtraDefaultStyleSheet() +
-         GetDataResourceAsASCIIString("themeChromiumLinux.css");
+         GetDataResourceAsASCIIString("linux.css");
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.mm b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
index 0e82ef5..2563c9fb7 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_mac.mm
+++ b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -1004,8 +1004,8 @@
 
 String LayoutThemeMac::ExtraDefaultStyleSheet() {
   return LayoutTheme::ExtraDefaultStyleSheet() +
-         GetDataResourceAsASCIIString("themeInputMultipleFields.css") +
-         GetDataResourceAsASCIIString("themeMac.css");
+         GetDataResourceAsASCIIString("input_multiple_fields.css") +
+         GetDataResourceAsASCIIString("mac.css");
 }
 
 bool LayoutThemeMac::ThemeDrawsFocusRing(const ComputedStyle& style) const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc
index 0d602a5..34ebc54d 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc
@@ -42,8 +42,8 @@
 
 String LayoutThemeMobile::ExtraDefaultStyleSheet() {
   return LayoutThemeDefault::ExtraDefaultStyleSheet() +
-         GetDataResourceAsASCIIString("themeChromiumLinux.css") +
-         GetDataResourceAsASCIIString("themeChromiumAndroid.css");
+         GetDataResourceAsASCIIString("linux.css") +
+         GetDataResourceAsASCIIString("android.css");
 }
 
 String LayoutThemeMobile::ExtraFullscreenStyleSheet() {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index 68d5d00a..7b8c40f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -270,22 +270,24 @@
     NGLineBoxFragmentBuilder::ChildList* line_box,
     FontBaseline baseline_type) {
   DCHECK(box->needs_box_fragment);
-
-  // The inline box should have the height of the font metrics without the
-  // line-height property. Compute from style because |box->metrics| includes
-  // the line-height property.
   DCHECK(box->style);
   const ComputedStyle& style = *box->style;
-  NGLineHeightMetrics metrics(style, baseline_type);
 
-  // Extend the block direction of the box by borders and paddings. Inline
-  // direction is already included into positions in NGLineBreaker.
-  NGLogicalOffset offset(
-      LayoutUnit(),
-      -metrics.ascent - (box->borders.line_over + box->padding.line_over));
-  NGLogicalSize size(
-      LayoutUnit(),
-      metrics.LineHeight() + box->borders.BlockSum() + box->padding.BlockSum());
+  NGLogicalOffset offset;
+  NGLogicalSize size;
+  if (!is_empty_line_) {
+    // The inline box should have the height of the font metrics without the
+    // line-height property. Compute from style because |box->metrics| includes
+    // the line-height property.
+    NGLineHeightMetrics metrics(style, baseline_type);
+
+    // Extend the block direction of the box by borders and paddings. Inline
+    // direction is already included into positions in NGLineBreaker.
+    offset.block_offset =
+        -metrics.ascent - (box->borders.line_over + box->padding.line_over);
+    size.block_size = metrics.LineHeight() + box->borders.BlockSum() +
+                      box->padding.BlockSum();
+  }
 
   unsigned fragment_end = line_box->size();
   DCHECK(box->item);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index d160dee..38640e50 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -114,6 +114,8 @@
   // The box state for the line box.
   NGInlineBoxState& LineBoxState() { return stack_.front(); }
 
+  void SetIsEmptyLine(bool is_empty_line) { is_empty_line_ = is_empty_line; }
+
   // Initialize the box state stack for a new line.
   // @return The initial box state for the line.
   NGInlineBoxState* OnBeginPlaceItems(const ComputedStyle*, FontBaseline, bool);
@@ -246,6 +248,8 @@
 
   Vector<NGInlineBoxState, 4> stack_;
   Vector<BoxData, 4> box_data_list_;
+
+  bool is_empty_line_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 48cb484..1bf2b86 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -239,6 +239,7 @@
 
   // Compute heights of all inline items by placing the dominant baseline at 0.
   // The baseline is adjusted after the height of the line box is computed.
+  box_states_->SetIsEmptyLine(line_info->IsEmptyLine());
   NGInlineBoxState* box =
       box_states_->OnBeginPlaceItems(&line_style, baseline_type_, quirks_mode_);
 #if DCHECK_IS_ON()
@@ -359,6 +360,7 @@
   // shouldn't trigger creation of a line. Exit now if that's the case.
   if (line_info->IsEmptyLine()) {
     container_builder_.SetIsEmptyLineBox();
+    container_builder_.AddChildren(line_box_);
     return;
   }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index b96bb893..4585f67 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -126,6 +126,51 @@
   EXPECT_EQ(line1.Children()[0]->GetLayoutObject(), ellipsis.GetLayoutObject());
 }
 
+// This test ensures box fragments are generated when necessary, even when the
+// line is empty. One such case is when the line contains a containing box of an
+// out-of-flow object.
+TEST_F(NGInlineLayoutAlgorithmTest,
+       EmptyLineWithOutOfFlowInInlineContainingBlock) {
+  SetBodyInnerHTML(R"HTML(
+    <!DOCTYPE html>
+    <style>
+    oof-container {
+      position: relative;
+    }
+    oof {
+      position: absolute;
+      width: 100px;
+      height: 100px;
+    }
+    html, body { margin: 0; }
+    html {
+      font-size: 10px;
+    }
+    </style>
+    <div id=container>
+      <oof-container>
+        <oof></oof>
+      </oof-container>
+    </div>
+  )HTML");
+  LayoutBlockFlow* block_flow =
+      ToLayoutBlockFlow(GetLayoutObjectByElementId("container"));
+  const NGPhysicalBoxFragment* container = block_flow->CurrentFragment();
+  ASSERT_TRUE(container);
+  EXPECT_EQ(LayoutUnit(), container->Size().height);
+
+  EXPECT_EQ(2u, container->Children().size());
+  const NGPhysicalLineBoxFragment& linebox =
+      ToNGPhysicalLineBoxFragment(*container->Children()[0]);
+
+  EXPECT_EQ(1u, linebox.Children().size());
+  EXPECT_EQ(NGPhysicalSize(), linebox.Size());
+
+  const NGPhysicalBoxFragment& oof_container =
+      ToNGPhysicalBoxFragment(*linebox.Children()[0]);
+  EXPECT_EQ(NGPhysicalSize(), oof_container.Size());
+}
+
 // This test ensures that if an inline box generates (or does not generate) box
 // fragments for a wrapped line, it should consistently do so for other lines
 // too, when the inline box is fragmented to multiple lines.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
index d44674bc..d70c22a1 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -83,11 +83,6 @@
 }
 
 scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() {
-#if DCHECK_IS_ON()
-  if (line_box_type_ == NGPhysicalLineBoxFragment::kEmptyLineBox)
-    DCHECK_EQ(children_.size(), 0u);
-#endif
-
   writing_mode_ = ToLineWritingMode(writing_mode_);
 
   if (!break_token_)
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index e939c438..a9db9c28 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -191,6 +191,10 @@
       }
       LayoutSize corrected_offset = additional_offset - first_fragment_offset;
       for (auto& outline : blockflow_outline_rects) {
+        // Skip if both width and height are zero. Contaning blocks in empty
+        // linebox is one such case.
+        if (outline.Size().IsZero())
+          continue;
         if (UNLIKELY(block_for_flipping))
           block_for_flipping->FlipForWritingMode(outline);
         outline.Move(corrected_offset);
diff --git a/third_party/blink/renderer/core/loader/interactive_detector_test.cc b/third_party/blink/renderer/core/loader/interactive_detector_test.cc
index 6aff06f..9e5a3f4 100644
--- a/third_party/blink/renderer/core/loader/interactive_detector_test.cc
+++ b/third_party/blink/renderer/core/loader/interactive_detector_test.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/loader/long_task_detector_test.cc b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
index 005df8b..453bf7c9 100644
--- a/third_party/blink/renderer/core/loader/long_task_detector_test.cc
+++ b/third_party/blink/renderer/core/loader/long_task_detector_test.cc
@@ -6,8 +6,8 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/loader/navigation_scheduler.h b/third_party/blink/renderer/core/loader/navigation_scheduler.h
index e70e2a9..00acdcb 100644
--- a/third_party/blink/renderer/core/loader/navigation_scheduler.h
+++ b/third_party/blink/renderer/core/loader/navigation_scheduler.h
@@ -41,7 +41,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
diff --git a/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc b/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
index ace9b866..a8ff441 100644
--- a/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
+++ b/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc
@@ -32,8 +32,8 @@
     ExecutionContext& execution_context,
     int64_t ukm_source_id,
     const std::vector<WTF::String>& subresource_patterns_to_block) {
-  return new PreviewsResourceLoadingHints(&execution_context, ukm_source_id,
-                                          subresource_patterns_to_block);
+  return MakeGarbageCollected<PreviewsResourceLoadingHints>(
+      &execution_context, ukm_source_id, subresource_patterns_to_block);
 }
 
 PreviewsResourceLoadingHints::PreviewsResourceLoadingHints(
diff --git a/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h b/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
index 20540b1f..2ad7cc2 100644
--- a/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
+++ b/third_party/blink/renderer/core/loader/previews_resource_loading_hints.h
@@ -32,6 +32,10 @@
       int64_t ukm_source_id,
       const std::vector<WTF::String>& subresource_patterns_to_block);
 
+  PreviewsResourceLoadingHints(
+      ExecutionContext* execution_context,
+      int64_t ukm_source_id,
+      const std::vector<WTF::String>& subresource_patterns_to_block);
   ~PreviewsResourceLoadingHints();
 
   // Returns true if load of resource with URL |resource_url| and priority
@@ -47,11 +51,6 @@
   void RecordUKM(ukm::UkmRecorder* ukm_recorder) const;
 
  private:
-  PreviewsResourceLoadingHints(
-      ExecutionContext* execution_context,
-      int64_t ukm_source_id,
-      const std::vector<WTF::String>& subresource_patterns_to_block);
-
   // Reports to console when loading of |resource_url| is blocked.
   void ReportBlockedLoading(const KURL& resource_url) const;
 
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.cc b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
index 7fe7f67..6208a53 100644
--- a/third_party/blink/renderer/core/loader/private/prerender_handle.cc
+++ b/third_party/blink/renderer/core/loader/private/prerender_handle.cc
@@ -61,7 +61,7 @@
     prerenderer_client->WillAddPrerender(prerender);
   prerender->Add();
 
-  return new PrerenderHandle(document, prerender);
+  return MakeGarbageCollected<PrerenderHandle>(document, prerender);
 }
 
 PrerenderHandle::PrerenderHandle(Document& document, Prerender* prerender)
diff --git a/third_party/blink/renderer/core/loader/private/prerender_handle.h b/third_party/blink/renderer/core/loader/private/prerender_handle.h
index edee2a3c..382c28f8 100644
--- a/third_party/blink/renderer/core/loader/private/prerender_handle.h
+++ b/third_party/blink/renderer/core/loader/private/prerender_handle.h
@@ -53,6 +53,7 @@
                                  const KURL&,
                                  unsigned prerender_rel_types);
 
+  PrerenderHandle(Document&, Prerender*);
   virtual ~PrerenderHandle();
 
   void Cancel();
@@ -65,8 +66,6 @@
   EAGERLY_FINALIZE();
 
  private:
-  PrerenderHandle(Document&, Prerender*);
-
   void Detach();
 
   Member<Prerender> prerender_;
diff --git a/third_party/blink/renderer/core/loader/progress_tracker.cc b/third_party/blink/renderer/core/loader/progress_tracker.cc
index ce1fa37..1e0088c4 100644
--- a/third_party/blink/renderer/core/loader/progress_tracker.cc
+++ b/third_party/blink/renderer/core/loader/progress_tracker.cc
@@ -66,7 +66,7 @@
 };
 
 ProgressTracker* ProgressTracker::Create(LocalFrame* frame) {
-  return new ProgressTracker(frame);
+  return MakeGarbageCollected<ProgressTracker>(frame);
 }
 
 ProgressTracker::ProgressTracker(LocalFrame* frame)
diff --git a/third_party/blink/renderer/core/loader/progress_tracker.h b/third_party/blink/renderer/core/loader/progress_tracker.h
index 036571e3..4ff4e18 100644
--- a/third_party/blink/renderer/core/loader/progress_tracker.h
+++ b/third_party/blink/renderer/core/loader/progress_tracker.h
@@ -52,6 +52,7 @@
  public:
   static ProgressTracker* Create(LocalFrame*);
 
+  explicit ProgressTracker(LocalFrame*);
   ~ProgressTracker();
   void Trace(blink::Visitor*);
   void Dispose();
@@ -70,8 +71,6 @@
   void CompleteProgress(unsigned long identifier);
 
  private:
-  explicit ProgressTracker(LocalFrame*);
-
   LocalFrameClient* GetLocalFrameClient() const;
 
   void MaybeSendProgress();
diff --git a/third_party/blink/renderer/core/loader/progress_tracker_test.cc b/third_party/blink/renderer/core/loader/progress_tracker_test.cc
index 4cbb6faa..cb9ca79 100644
--- a/third_party/blink/renderer/core/loader/progress_tracker_test.cc
+++ b/third_party/blink/renderer/core/loader/progress_tracker_test.cc
@@ -34,7 +34,7 @@
   }
 
   void SetUp() override {
-    client_ = new ProgressClient;
+    client_ = MakeGarbageCollected<ProgressClient>();
     PageTestBase::SetupPageWithClients(nullptr, client_.Get());
   }
 
diff --git a/third_party/blink/renderer/core/loader/resource/font_resource.h b/third_party/blink/renderer/core/loader/resource/font_resource.h
index e04f861c..d5f2b7cc 100644
--- a/third_party/blink/renderer/core/loader/resource/font_resource.h
+++ b/third_party/blink/renderer/core/loader/resource/font_resource.h
@@ -33,7 +33,7 @@
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/loader/subresource_filter.cc b/third_party/blink/renderer/core/loader/subresource_filter.cc
index 7117a45d..1c7168a5 100644
--- a/third_party/blink/renderer/core/loader/subresource_filter.cc
+++ b/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/mojo/mojo_watcher.cc b/third_party/blink/renderer/core/mojo/mojo_watcher.cc
index 50834d4..aab35c5b 100644
--- a/third_party/blink/renderer/core/mojo/mojo_watcher.cc
+++ b/third_party/blink/renderer/core/mojo/mojo_watcher.cc
@@ -10,7 +10,7 @@
 #include "third_party/blink/renderer/core/mojo/mojo_handle_signals.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 29aad26c..bee3dcd 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -124,7 +124,7 @@
 }
 
 Page* Page::Create(PageClients& page_clients) {
-  Page* page = new Page(page_clients);
+  Page* page = MakeGarbageCollected<Page>(page_clients);
   page->SetPageScheduler(ThreadScheduler::Current()->CreatePageScheduler(page));
   return page;
 }
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h
index 8d2baa9..676f1c7 100644
--- a/third_party/blink/renderer/core/page/page.h
+++ b/third_party/blink/renderer/core/page/page.h
@@ -109,6 +109,7 @@
   // An "ordinary" page is a fully-featured page owned by a web view.
   static Page* CreateOrdinary(PageClients&, Page* opener);
 
+  explicit Page(PageClients&);
   ~Page() override;
 
   void CloseSoon();
@@ -320,8 +321,6 @@
  private:
   friend class ScopedPagePauser;
 
-  explicit Page(PageClients&);
-
   void InitGroup();
 
   // SettingsDelegate overrides.
diff --git a/third_party/blink/renderer/core/page/page_animator.cc b/third_party/blink/renderer/core/page/page_animator.cc
index 82157069..6482e12c 100644
--- a/third_party/blink/renderer/core/page/page_animator.cc
+++ b/third_party/blink/renderer/core/page/page_animator.cc
@@ -23,7 +23,7 @@
       updating_layout_and_style_for_painting_(false) {}
 
 PageAnimator* PageAnimator::Create(Page& page) {
-  return new PageAnimator(page);
+  return MakeGarbageCollected<PageAnimator>(page);
 }
 
 void PageAnimator::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/page/page_animator.h b/third_party/blink/renderer/core/page/page_animator.h
index 24e2d52..2f127f66 100644
--- a/third_party/blink/renderer/core/page/page_animator.h
+++ b/third_party/blink/renderer/core/page/page_animator.h
@@ -18,6 +18,9 @@
 class CORE_EXPORT PageAnimator final : public GarbageCollected<PageAnimator> {
  public:
   static PageAnimator* Create(Page&);
+
+  explicit PageAnimator(Page&);
+
   void Trace(blink::Visitor*);
   void ScheduleVisualUpdate(LocalFrame*);
   void ServiceScriptedAnimations(
@@ -40,8 +43,6 @@
   AnimationClock& Clock() { return animation_clock_; }
 
  private:
-  explicit PageAnimator(Page&);
-
   Member<Page> page_;
   bool servicing_animations_;
   bool updating_layout_and_style_for_painting_;
diff --git a/third_party/blink/renderer/core/page/page_popup_controller.cc b/third_party/blink/renderer/core/page/page_popup_controller.cc
index 433aeea..fa7fceee 100644
--- a/third_party/blink/renderer/core/page/page_popup_controller.cc
+++ b/third_party/blink/renderer/core/page/page_popup_controller.cc
@@ -45,7 +45,7 @@
 
 PagePopupController* PagePopupController::Create(PagePopup& popup,
                                                  PagePopupClient* client) {
-  return new PagePopupController(popup, client);
+  return MakeGarbageCollected<PagePopupController>(popup, client);
 }
 
 void PagePopupController::setValueAndClosePopup(int num_value,
diff --git a/third_party/blink/renderer/core/page/page_popup_controller.h b/third_party/blink/renderer/core/page/page_popup_controller.h
index dc4d5bf..53653b68 100644
--- a/third_party/blink/renderer/core/page/page_popup_controller.h
+++ b/third_party/blink/renderer/core/page/page_popup_controller.h
@@ -46,6 +46,9 @@
 
  public:
   static PagePopupController* Create(PagePopup&, PagePopupClient*);
+
+  PagePopupController(PagePopup&, PagePopupClient*);
+
   void setValueAndClosePopup(int num_value, const String& string_value);
   void setValue(const String&);
   void closePopup();
@@ -60,8 +63,6 @@
   void setWindowRect(int x, int y, int width, int height);
 
  private:
-  PagePopupController(PagePopup&, PagePopupClient*);
-
   PagePopup& popup_;
   PagePopupClient* popup_client_;
 };
diff --git a/third_party/blink/renderer/core/page/page_popup_supplement.cc b/third_party/blink/renderer/core/page/page_popup_supplement.cc
index 241ceea..c09b2ae7 100644
--- a/third_party/blink/renderer/core/page/page_popup_supplement.cc
+++ b/third_party/blink/renderer/core/page/page_popup_supplement.cc
@@ -63,7 +63,8 @@
                                   PagePopup& popup,
                                   PagePopupClient* popup_client) {
   DCHECK(popup_client);
-  ProvideTo(frame, new PagePopupSupplement(frame, popup, popup_client));
+  ProvideTo(frame, MakeGarbageCollected<PagePopupSupplement>(frame, popup,
+                                                             popup_client));
 }
 
 void PagePopupSupplement::Uninstall(LocalFrame& frame) {
diff --git a/third_party/blink/renderer/core/page/page_popup_supplement.h b/third_party/blink/renderer/core/page/page_popup_supplement.h
index f3136d9..c1511cb 100644
--- a/third_party/blink/renderer/core/page/page_popup_supplement.h
+++ b/third_party/blink/renderer/core/page/page_popup_supplement.h
@@ -55,10 +55,12 @@
   static void Uninstall(LocalFrame&);
 
   PagePopupController* GetPagePopupController() const;
+
+  PagePopupSupplement(LocalFrame&, PagePopup&, PagePopupClient*);
+
   void Trace(blink::Visitor*) override;
 
  private:
-  PagePopupSupplement(LocalFrame&, PagePopup&, PagePopupClient*);
   void Dispose();
 
   Member<PagePopupController> controller_;
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
index 337e2659..7ab0459 100644
--- a/third_party/blink/renderer/core/page/pointer_lock_controller.cc
+++ b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -40,7 +40,7 @@
     : page_(page), lock_pending_(false) {}
 
 PointerLockController* PointerLockController::Create(Page* page) {
-  return new PointerLockController(page);
+  return MakeGarbageCollected<PointerLockController>(page);
 }
 
 void PointerLockController::RequestPointerLock(Element* target) {
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.h b/third_party/blink/renderer/core/page/pointer_lock_controller.h
index b22b611..681c3e4 100644
--- a/third_party/blink/renderer/core/page/pointer_lock_controller.h
+++ b/third_party/blink/renderer/core/page/pointer_lock_controller.h
@@ -44,6 +44,8 @@
  public:
   static PointerLockController* Create(Page*);
 
+  explicit PointerLockController(Page*);
+
   void RequestPointerLock(Element* target);
   void RequestPointerUnlock();
   void ElementRemoved(Element*);
@@ -62,7 +64,6 @@
   void Trace(blink::Visitor*);
 
  private:
-  explicit PointerLockController(Page*);
   void ClearElement();
   void EnqueueEvent(const AtomicString& type, Element*);
   void EnqueueEvent(const AtomicString& type, Document*);
diff --git a/third_party/blink/renderer/core/page/print_context.cc b/third_party/blink/renderer/core/page/print_context.cc
index 1cf8b1a..358bebb 100644
--- a/third_party/blink/renderer/core/page/print_context.cc
+++ b/third_party/blink/renderer/core/page/print_context.cc
@@ -327,7 +327,9 @@
 }
 
 ScopedPrintContext::ScopedPrintContext(LocalFrame* frame)
-    : context_(new PrintContext(frame, /*use_printing_layout=*/true)) {}
+    : context_(
+          MakeGarbageCollected<PrintContext>(frame,
+                                             /*use_printing_layout=*/true)) {}
 
 ScopedPrintContext::~ScopedPrintContext() {
   context_->EndPrintMode();
diff --git a/third_party/blink/renderer/core/page/print_context_test.cc b/third_party/blink/renderer/core/page/print_context_test.cc
index ce97c39..6633f49 100644
--- a/third_party/blink/renderer/core/page/print_context_test.cc
+++ b/third_party/blink/renderer/core/page/print_context_test.cc
@@ -72,8 +72,9 @@
 
   void SetUp() override {
     RenderingTest::SetUp();
-    print_context_ = new PrintContext(GetDocument().GetFrame(),
-                                      /*use_printing_layout=*/true);
+    print_context_ =
+        MakeGarbageCollected<PrintContext>(GetDocument().GetFrame(),
+                                           /*use_printing_layout=*/true);
   }
 
   PrintContext& GetPrintContext() { return *print_context_.Get(); }
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
index 18dde2a..20099b81 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
@@ -92,7 +92,7 @@
 
 // static
 RootScrollerController* RootScrollerController::Create(Document& document) {
-  return new RootScrollerController(document);
+  return MakeGarbageCollected<RootScrollerController>(document);
 }
 
 RootScrollerController::RootScrollerController(Document& document)
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
index 07daee1e..3ca6c59 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h
@@ -42,6 +42,8 @@
   // of this class need to be made aware of layout updates.
   static RootScrollerController* Create(Document&);
 
+  RootScrollerController(Document&);
+
   void Trace(blink::Visitor*);
 
   // Sets the element that will be used as the root scroller. This can be
@@ -93,8 +95,6 @@
   void PerformRootScrollerSelection();
 
  private:
-  RootScrollerController(Document&);
-
   // Ensures the effective root scroller is currently valid and replaces it
   // with the default if not.
   void RecomputeEffectiveRootScroller();
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index bcd9abe..972ea3d7 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -3265,8 +3265,10 @@
 
 PaintLayerResourceInfo& PaintLayer::EnsureResourceInfo() {
   PaintLayerRareData& rare_data = EnsureRareData();
-  if (!rare_data.resource_info)
-    rare_data.resource_info = new PaintLayerResourceInfo(this);
+  if (!rare_data.resource_info) {
+    rare_data.resource_info =
+        MakeGarbageCollected<PaintLayerResourceInfo>(this);
+  }
   return *rare_data.resource_info;
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index c44aa7e..48def2b 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -244,9 +244,10 @@
   // FIXME: We should pass in the LayoutBox but this opens a window
   // for crashers during PaintLayer setup (see crbug.com/368062).
   static PaintLayerScrollableArea* Create(PaintLayer& layer) {
-    return new PaintLayerScrollableArea(layer);
+    return MakeGarbageCollected<PaintLayerScrollableArea>(layer);
   }
 
+  explicit PaintLayerScrollableArea(PaintLayer&);
   ~PaintLayerScrollableArea() override;
   void Dispose();
   bool HasBeenDisposed() const override;
@@ -552,8 +553,6 @@
   }
 
  private:
-  explicit PaintLayerScrollableArea(PaintLayer&);
-
   bool NeedsScrollbarReconstruction() const;
 
   void ResetScrollOriginChanged() { scroll_origin_changed_ = false; }
diff --git a/third_party/blink/renderer/core/paint/paint_timing.cc b/third_party/blink/renderer/core/paint/paint_timing.cc
index fc43dde..5cd87b8 100644
--- a/third_party/blink/renderer/core/paint/paint_timing.cc
+++ b/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -47,7 +47,7 @@
 PaintTiming& PaintTiming::From(Document& document) {
   PaintTiming* timing = Supplement<Document>::From<PaintTiming>(document);
   if (!timing) {
-    timing = new PaintTiming(document);
+    timing = MakeGarbageCollected<PaintTiming>(document);
     ProvideTo(document, timing);
   }
   return *timing;
diff --git a/third_party/blink/renderer/core/paint/paint_timing.h b/third_party/blink/renderer/core/paint/paint_timing.h
index 7990b7b..ea77cac 100644
--- a/third_party/blink/renderer/core/paint/paint_timing.h
+++ b/third_party/blink/renderer/core/paint/paint_timing.h
@@ -35,6 +35,7 @@
  public:
   static const char kSupplementName[];
 
+  explicit PaintTiming(Document&);
   virtual ~PaintTiming() = default;
 
   static PaintTiming& From(Document&);
@@ -110,7 +111,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit PaintTiming(Document&);
   LocalFrame* GetFrame() const;
   void NotifyPaintTimingChanged();
 
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer.cc b/third_party/blink/renderer/core/resize_observer/resize_observer.cc
index 33acd56e..831ac96a 100644
--- a/third_party/blink/renderer/core/resize_observer/resize_observer.cc
+++ b/third_party/blink/renderer/core/resize_observer/resize_observer.cc
@@ -17,11 +17,11 @@
 
 ResizeObserver* ResizeObserver::Create(Document& document,
                                        V8ResizeObserverCallback* callback) {
-  return new ResizeObserver(callback, document);
+  return MakeGarbageCollected<ResizeObserver>(callback, document);
 }
 
 ResizeObserver* ResizeObserver::Create(Document& document, Delegate* delegate) {
-  return new ResizeObserver(delegate, document);
+  return MakeGarbageCollected<ResizeObserver>(delegate, document);
 }
 
 ResizeObserver::ResizeObserver(V8ResizeObserverCallback* callback,
@@ -50,7 +50,7 @@
   if (observer_map.Contains(this))
     return;  // Already registered.
 
-  auto* observation = new ResizeObservation(target, this);
+  auto* observation = MakeGarbageCollected<ResizeObservation>(target, this);
   observations_.insert(observation);
   observer_map.Set(this, observation);
 
@@ -141,7 +141,8 @@
       content_rect.SetHeight(AdjustForAbsoluteZoom::AdjustLayoutUnit(
           content_rect.Height(), style));
     }
-    auto* entry = new ResizeObserverEntry(observation->Target(), content_rect);
+    auto* entry = MakeGarbageCollected<ResizeObserverEntry>(
+        observation->Target(), content_rect);
     entries.push_back(entry);
   }
 
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer.h b/third_party/blink/renderer/core/resize_observer/resize_observer.h
index 1aaea12..384c9ca 100644
--- a/third_party/blink/renderer/core/resize_observer/resize_observer.h
+++ b/third_party/blink/renderer/core/resize_observer/resize_observer.h
@@ -43,6 +43,8 @@
   static ResizeObserver* Create(Document&, V8ResizeObserverCallback*);
   static ResizeObserver* Create(Document&, Delegate*);
 
+  ResizeObserver(V8ResizeObserverCallback*, Document&);
+  ResizeObserver(Delegate*, Document&);
   ~ResizeObserver() override = default;
 
   // API methods
@@ -64,9 +66,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  ResizeObserver(V8ResizeObserverCallback*, Document&);
-  ResizeObserver(Delegate*, Document&);
-
   using ObservationList = HeapLinkedHashSet<WeakMember<ResizeObservation>>;
 
   // Either of |callback_| and |delegate_| should be non-null.
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
index 24cbf2f..1c02202f 100644
--- a/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
+++ b/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc
@@ -74,9 +74,9 @@
   Element* dom_target = GetDocument().getElementById("domTarget");
   Element* svg_target = GetDocument().getElementById("svgTarget");
   ResizeObservation* dom_observation =
-      new ResizeObservation(dom_target, observer);
+      MakeGarbageCollected<ResizeObservation>(dom_target, observer);
   ResizeObservation* svg_observation =
-      new ResizeObservation(svg_target, observer);
+      MakeGarbageCollected<ResizeObservation>(svg_target, observer);
 
   // Initial observation is out of sync
   ASSERT_TRUE(dom_observation->ObservationSizeOutOfSync());
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc
index 57ebf222..8a92a60 100644
--- a/third_party/blink/renderer/core/script/classic_pending_script.cc
+++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
 #include "third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
index f85c4438..4e4b708f 100644
--- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
+++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
@@ -28,9 +28,10 @@
 
  public:
   static ProgrammaticScrollAnimator* Create(ScrollableArea* scrollable_area) {
-    return new ProgrammaticScrollAnimator(scrollable_area);
+    return MakeGarbageCollected<ProgrammaticScrollAnimator>(scrollable_area);
   }
 
+  explicit ProgrammaticScrollAnimator(ScrollableArea*);
   ~ProgrammaticScrollAnimator() override;
 
   void ScrollToOffsetWithoutAnimation(const ScrollOffset&,
@@ -54,8 +55,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit ProgrammaticScrollAnimator(ScrollableArea*);
-
   void NotifyOffsetChanged(const ScrollOffset&);
   void AnimationFinished();
 
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_mac.h b/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
index de89825..199a27e8 100644
--- a/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
+++ b/third_party/blink/renderer/core/scroll/scroll_animator_mac.h
@@ -33,8 +33,8 @@
 #include "third_party/blink/renderer/platform/geometry/float_size.h"
 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/retain_ptr.h"
 
 OBJC_CLASS BlinkScrollAnimationHelperDelegate;
diff --git a/third_party/blink/renderer/core/streams/underlying_source_base.cc b/third_party/blink/renderer/core/streams/underlying_source_base.cc
index 0d58346..3f7700e7 100644
--- a/third_party/blink/renderer/core/streams/underlying_source_base.cc
+++ b/third_party/blink/renderer/core/streams/underlying_source_base.cc
@@ -18,7 +18,8 @@
   // construct multiple streams).
   DCHECK(!controller_);
 
-  controller_ = new ReadableStreamDefaultControllerWrapper(js_controller);
+  controller_ = MakeGarbageCollected<ReadableStreamDefaultControllerWrapper>(
+      js_controller);
 
   return Start(script_state);
 }
diff --git a/third_party/blink/renderer/core/style/content_data.cc b/third_party/blink/renderer/core/style/content_data.cc
index 6175e0b..71af0bca 100644
--- a/third_party/blink/renderer/core/style/content_data.cc
+++ b/third_party/blink/renderer/core/style/content_data.cc
@@ -47,7 +47,7 @@
 }
 
 ContentData* ContentData::Create(QuoteType quote) {
-  return new QuoteContentData(quote);
+  return MakeGarbageCollected<QuoteContentData>(quote);
 }
 
 ContentData* ContentData::Clone() const {
diff --git a/third_party/blink/renderer/core/style/content_data.h b/third_party/blink/renderer/core/style/content_data.h
index eed5cbe..9dfcb0e9 100644
--- a/third_party/blink/renderer/core/style/content_data.h
+++ b/third_party/blink/renderer/core/style/content_data.h
@@ -177,6 +177,8 @@
   friend class ContentData;
 
  public:
+  QuoteContentData(QuoteType quote) : quote_(quote) {}
+
   QuoteType Quote() const { return quote_; }
   void SetQuote(QuoteType quote) { quote_ = quote; }
 
@@ -191,8 +193,6 @@
   }
 
  private:
-  QuoteContentData(QuoteType quote) : quote_(quote) {}
-
   ContentData* CloneInternal() const override { return Create(Quote()); }
 
   QuoteType quote_;
diff --git a/third_party/blink/renderer/core/style/filter_operation.h b/third_party/blink/renderer/core/style/filter_operation.h
index 5ea6f1c7..bd8ae57 100644
--- a/third_party/blink/renderer/core/style/filter_operation.h
+++ b/third_party/blink/renderer/core/style/filter_operation.h
@@ -132,9 +132,11 @@
  public:
   static ReferenceFilterOperation* Create(const AtomicString& url,
                                           SVGResource* resource) {
-    return new ReferenceFilterOperation(url, resource);
+    return MakeGarbageCollected<ReferenceFilterOperation>(url, resource);
   }
 
+  ReferenceFilterOperation(const AtomicString& url, SVGResource*);
+
   bool AffectsOpacity() const override { return true; }
   bool MovesPixels() const override { return true; }
   FloatRect MapRect(const FloatRect&) const override;
@@ -152,8 +154,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  ReferenceFilterOperation(const AtomicString& url, SVGResource*);
-
   FilterOperation* Blend(const FilterOperation* from,
                          double progress) const override {
     NOTREACHED();
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index 228aa962..4325e7cc 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
 #include "third_party/blink/renderer/core/xlink_names.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -47,21 +48,20 @@
 class RepeatEvent final : public Event {
  public:
   static RepeatEvent* Create(const AtomicString& type, int repeat) {
-    return new RepeatEvent(type, Bubbles::kNo, Cancelable::kNo, repeat);
+    return MakeGarbageCollected<RepeatEvent>(type, Bubbles::kNo,
+                                             Cancelable::kNo, repeat);
   }
 
-  ~RepeatEvent() override = default;
-
-  int Repeat() const { return repeat_; }
-
-  void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
-
- protected:
   RepeatEvent(const AtomicString& type,
               Bubbles bubbles,
               Cancelable cancelable,
               int repeat = -1)
       : Event(type, bubbles, cancelable), repeat_(repeat) {}
+  ~RepeatEvent() override = default;
+
+  int Repeat() const { return repeat_; }
+
+  void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
 
  private:
   int repeat_;
diff --git a/third_party/blink/renderer/core/svg/pattern_attributes.h b/third_party/blink/renderer/core/svg/pattern_attributes.h
index b19ea53..85e7696 100644
--- a/third_party/blink/renderer/core/svg/pattern_attributes.h
+++ b/third_party/blink/renderer/core/svg/pattern_attributes.h
@@ -172,16 +172,16 @@
     : public GarbageCollected<PatternAttributesWrapper> {
  public:
   static PatternAttributesWrapper* Create() {
-    return new PatternAttributesWrapper;
+    return MakeGarbageCollected<PatternAttributesWrapper>();
   }
 
+  PatternAttributesWrapper() = default;
+
   PatternAttributes& Attributes() { return attributes_; }
   void Set(const PatternAttributes& attributes) { attributes_ = attributes; }
   void Trace(blink::Visitor* visitor) { visitor->Trace(attributes_); }
 
  private:
-  PatternAttributesWrapper() = default;
-
   PatternAttributes attributes_;
 };
 
diff --git a/third_party/blink/renderer/core/svg/radial_gradient_attributes.h b/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
index 1fe61dd..747d1d36 100644
--- a/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
+++ b/third_party/blink/renderer/core/svg/radial_gradient_attributes.h
@@ -117,9 +117,11 @@
     : public GarbageCollectedFinalized<RadialGradientAttributesWrapper> {
  public:
   static RadialGradientAttributesWrapper* Create() {
-    return new RadialGradientAttributesWrapper;
+    return MakeGarbageCollected<RadialGradientAttributesWrapper>();
   }
 
+  RadialGradientAttributesWrapper() = default;
+
   RadialGradientAttributes& Attributes() { return attributes_; }
   void Set(const RadialGradientAttributes& attributes) {
     attributes_ = attributes;
@@ -127,8 +129,6 @@
   void Trace(blink::Visitor* visitor) { visitor->Trace(attributes_); }
 
  private:
-  RadialGradientAttributesWrapper() = default;
-
   RadialGradientAttributes attributes_;
 };
 
diff --git a/third_party/blink/renderer/core/svg/svg_style_element.cc b/third_party/blink/renderer/core/svg/svg_style_element.cc
index 18724c75..25f587b 100644
--- a/third_party/blink/renderer/core/svg/svg_style_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_style_element.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/core/css/css_style_sheet.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/media_type_names.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/testing/data/plugin_hidden_before_scroll.html b/third_party/blink/renderer/core/testing/data/plugin_hidden_before_scroll.html
new file mode 100644
index 0000000..b3732ee5
--- /dev/null
+++ b/third_party/blink/renderer/core/testing/data/plugin_hidden_before_scroll.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css">
+    body { margin: 0; padding: 0; }
+  </style>
+</head>
+<body>
+  <div style="width: 40px; height: 40px"></div>
+  <object id="plugin-hidden-before-scroll"
+      border=0
+      type="application/x-webkit-test-webplugin"
+      width="40"
+      height="40">
+  </object>
+  <div style="width: 40px; height: 40px"></div>
+</body>
+</html>
diff --git a/third_party/blink/renderer/core/testing/data/shifted_plugin_containing_page.html b/third_party/blink/renderer/core/testing/data/shifted_plugin_containing_page.html
new file mode 100644
index 0000000..8040c78
--- /dev/null
+++ b/third_party/blink/renderer/core/testing/data/shifted_plugin_containing_page.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <style type="text/css">
+    body { margin: 0; padding: 0; }
+  </style>
+</head>
+<body>
+  <div style="width: 200px; height: 100vh"></div>
+  <iframe
+      src="plugin_hidden_before_scroll.html"
+      id="iframe-with-plugin"
+      height="40"
+      width="40"
+      frameBorder="0">
+  </iframe>
+  <div style="width: 200px; height: 100vh"></div>
+</body>
+</html>
diff --git a/third_party/blink/renderer/core/testing/record_test.h b/third_party/blink/renderer/core/testing/record_test.h
index d3acf6af..cda756d8 100644
--- a/third_party/blink/renderer/core/testing/record_test.h
+++ b/third_party/blink/renderer/core/testing/record_test.h
@@ -21,7 +21,9 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static RecordTest* Create() { return new RecordTest; }
+  static RecordTest* Create() { return MakeGarbageCollected<RecordTest>(); }
+
+  RecordTest();
   ~RecordTest() override;
 
   void setStringLongRecord(const Vector<std::pair<String, int32_t>>& arg);
@@ -55,8 +57,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RecordTest();
-
   Vector<std::pair<String, int32_t>> string_long_record_;
   base::Optional<Vector<std::pair<String, int32_t>>>
       nullable_string_long_record_;
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc
index ec874b87..777788c 100644
--- a/third_party/blink/renderer/core/timing/performance.cc
+++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -590,7 +590,7 @@
 
 void Performance::AddPaintTiming(PerformancePaintTiming::PaintType type,
                                  TimeTicks start_time) {
-  PerformanceEntry* entry = new PerformancePaintTiming(
+  PerformanceEntry* entry = MakeGarbageCollected<PerformancePaintTiming>(
       type, MonotonicTimeToDOMHighResTimeStamp(start_time));
   // Always buffer First Paint & First Contentful Paint.
   if (type == PerformancePaintTiming::PaintType::kFirstPaint)
diff --git a/third_party/blink/renderer/core/timing/performance_event_timing.cc b/third_party/blink/renderer/core/timing/performance_event_timing.cc
index de16cc8..0fcd390 100644
--- a/third_party/blink/renderer/core/timing/performance_event_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_event_timing.cc
@@ -19,17 +19,19 @@
   // TODO(npm): enable this DCHECK once https://crbug.com/852846 is fixed.
   // DCHECK_LE(start_time, processing_start);
   DCHECK_LE(processing_start, processing_end);
-  return new PerformanceEventTiming(event_type, performance_entry_names::kEvent,
-                                    start_time, processing_start,
-                                    processing_end, cancelable);
+  return MakeGarbageCollected<PerformanceEventTiming>(
+      event_type, performance_entry_names::kEvent, start_time, processing_start,
+      processing_end, cancelable);
 }
 
 // static
 PerformanceEventTiming* PerformanceEventTiming::CreateFirstInputTiming(
     PerformanceEventTiming* entry) {
-  PerformanceEventTiming* first_input = new PerformanceEventTiming(
-      entry->name(), performance_entry_names::kFirstInput, entry->startTime(),
-      entry->processingStart(), entry->processingEnd(), entry->cancelable());
+  PerformanceEventTiming* first_input =
+      MakeGarbageCollected<PerformanceEventTiming>(
+          entry->name(), performance_entry_names::kFirstInput,
+          entry->startTime(), entry->processingStart(), entry->processingEnd(),
+          entry->cancelable());
   first_input->SetDuration(entry->duration());
   return first_input;
 }
diff --git a/third_party/blink/renderer/core/timing/performance_event_timing.h b/third_party/blink/renderer/core/timing/performance_event_timing.h
index 5adb319..8680dc9 100644
--- a/third_party/blink/renderer/core/timing/performance_event_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_event_timing.h
@@ -25,6 +25,12 @@
   static PerformanceEventTiming* CreateFirstInputTiming(
       PerformanceEventTiming* entry);
 
+  PerformanceEventTiming(const AtomicString& event_type,
+                         const AtomicString& entry_type,
+                         DOMHighResTimeStamp start_time,
+                         DOMHighResTimeStamp processing_start,
+                         DOMHighResTimeStamp processing_end,
+                         bool cancelable);
   ~PerformanceEventTiming() override;
 
   AtomicString entryType() const override { return entry_type_; }
@@ -42,12 +48,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PerformanceEventTiming(const AtomicString& event_type,
-                         const AtomicString& entry_type,
-                         DOMHighResTimeStamp start_time,
-                         DOMHighResTimeStamp processing_start,
-                         DOMHighResTimeStamp processing_end,
-                         bool cancelable);
   AtomicString entry_type_;
   DOMHighResTimeStamp processing_start_;
   DOMHighResTimeStamp processing_end_;
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
index f3161af94..970b0f9 100644
--- a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -22,9 +22,9 @@
     const String& frame_id,
     const String& frame_name,
     const SubTaskAttribution::EntriesVector& sub_task_attributions) {
-  return new PerformanceLongTaskTiming(start_time, end_time, name, frame_src,
-                                       frame_id, frame_name,
-                                       sub_task_attributions);
+  return MakeGarbageCollected<PerformanceLongTaskTiming>(
+      start_time, end_time, name, frame_src, frame_id, frame_name,
+      sub_task_attributions);
 }
 
 PerformanceLongTaskTiming::PerformanceLongTaskTiming(
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.h b/third_party/blink/renderer/core/timing/performance_long_task_timing.h
index 7d77508..e903a1e7 100644
--- a/third_party/blink/renderer/core/timing/performance_long_task_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.h
@@ -29,14 +29,6 @@
       const String& frame_name,
       const SubTaskAttribution::EntriesVector& sub_task_attributions);
 
-  AtomicString entryType() const override;
-  PerformanceEntryType EntryTypeEnum() const override;
-
-  TaskAttributionVector attribution() const;
-
-  void Trace(blink::Visitor*) override;
-
- private:
   PerformanceLongTaskTiming(
       double start_time,
       double end_time,
@@ -45,6 +37,15 @@
       const String& frame_id,
       const String& frame_name,
       const SubTaskAttribution::EntriesVector& sub_task_attributions);
+
+  AtomicString entryType() const override;
+  PerformanceEntryType EntryTypeEnum() const override;
+
+  TaskAttributionVector attribution() const;
+
+  void Trace(blink::Visitor*) override;
+
+ private:
   ~PerformanceLongTaskTiming() override;
 
   void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/third_party/blink/renderer/core/timing/performance_mark.h b/third_party/blink/renderer/core/timing/performance_mark.h
index fdd362f3..a472017 100644
--- a/third_party/blink/renderer/core/timing/performance_mark.h
+++ b/third_party/blink/renderer/core/timing/performance_mark.h
@@ -41,9 +41,15 @@
                                  const AtomicString& name,
                                  double start_time,
                                  const ScriptValue& detail) {
-    return new PerformanceMark(script_state, name, start_time, detail);
+    return MakeGarbageCollected<PerformanceMark>(script_state, name, start_time,
+                                                 detail);
   }
 
+  PerformanceMark(ScriptState*,
+                  const AtomicString& name,
+                  double start_time,
+                  const ScriptValue& detail);
+
   AtomicString entryType() const override;
   PerformanceEntryType EntryTypeEnum() const override;
 
@@ -52,11 +58,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PerformanceMark(ScriptState*,
-                  const AtomicString& name,
-                  double start_time,
-                  const ScriptValue& detail);
-
   ~PerformanceMark() override = default;
 
   scoped_refptr<DOMWrapperWorld> world_;
diff --git a/third_party/blink/renderer/core/timing/performance_measure.h b/third_party/blink/renderer/core/timing/performance_measure.h
index 43ba506..e80be2a2 100644
--- a/third_party/blink/renderer/core/timing/performance_measure.h
+++ b/third_party/blink/renderer/core/timing/performance_measure.h
@@ -43,9 +43,16 @@
                                     double start_time,
                                     double end_time,
                                     const ScriptValue& detail) {
-    return new PerformanceMeasure(script_state, name, start_time, end_time,
-                                  detail);
+    return MakeGarbageCollected<PerformanceMeasure>(
+        script_state, name, start_time, end_time, detail);
   }
+
+  PerformanceMeasure(ScriptState*,
+                     const AtomicString& name,
+                     double start_time,
+                     double end_time,
+                     const ScriptValue& detail);
+
   ScriptValue detail(ScriptState*) const;
 
   AtomicString entryType() const override;
@@ -56,11 +63,6 @@
   }
 
  private:
-  PerformanceMeasure(ScriptState*,
-                     const AtomicString& name,
-                     double start_time,
-                     double end_time,
-                     const ScriptValue& detail);
   ~PerformanceMeasure() override = default;
   scoped_refptr<SerializedScriptValue> detail_;
 };
diff --git a/third_party/blink/renderer/core/timing/performance_navigation.h b/third_party/blink/renderer/core/timing/performance_navigation.h
index faac8cb..36c987c 100644
--- a/third_party/blink/renderer/core/timing/performance_navigation.h
+++ b/third_party/blink/renderer/core/timing/performance_navigation.h
@@ -50,9 +50,11 @@
 
  public:
   static PerformanceNavigation* Create(LocalFrame* frame) {
-    return new PerformanceNavigation(frame);
+    return MakeGarbageCollected<PerformanceNavigation>(frame);
   }
 
+  explicit PerformanceNavigation(LocalFrame*);
+
   enum PerformanceNavigationType {
     kTypeNavigate,
     kTypeReload,
@@ -66,9 +68,6 @@
   ScriptValue toJSONForBinding(ScriptState*) const;
 
   void Trace(blink::Visitor*) override;
-
- private:
-  explicit PerformanceNavigation(LocalFrame*);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/timing/performance_observer.cc b/third_party/blink/renderer/core/timing/performance_observer.cc
index be21c17d..6693106 100644
--- a/third_party/blink/renderer/core/timing/performance_observer.cc
+++ b/third_party/blink/renderer/core/timing/performance_observer.cc
@@ -31,12 +31,12 @@
   ExecutionContext* context = ExecutionContext::From(script_state);
   if (window) {
     UseCounter::Count(context, WebFeature::kPerformanceObserverForWindow);
-    return new PerformanceObserver(
+    return MakeGarbageCollected<PerformanceObserver>(
         context, DOMWindowPerformance::performance(*window), callback);
   }
   if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) {
     UseCounter::Count(context, WebFeature::kPerformanceObserverForWorker);
-    return new PerformanceObserver(
+    return MakeGarbageCollected<PerformanceObserver>(
         context, WorkerGlobalScopePerformance::performance(*scope), callback);
   }
   V8ThrowException::ThrowTypeError(
@@ -129,7 +129,7 @@
   PerformanceEntryVector performance_entries;
   performance_entries.swap(performance_entries_);
   PerformanceObserverEntryList* entry_list =
-      new PerformanceObserverEntryList(performance_entries);
+      MakeGarbageCollected<PerformanceObserverEntryList>(performance_entries);
   callback_->InvokeAndReportException(this, entry_list, this);
 }
 
diff --git a/third_party/blink/renderer/core/timing/performance_observer.h b/third_party/blink/renderer/core/timing/performance_observer.h
index bfbc929..b23b07a 100644
--- a/third_party/blink/renderer/core/timing/performance_observer.h
+++ b/third_party/blink/renderer/core/timing/performance_observer.h
@@ -39,6 +39,10 @@
                                      V8PerformanceObserverCallback*);
   static void ResumeSuspendedObservers();
 
+  PerformanceObserver(ExecutionContext*,
+                      Performance*,
+                      V8PerformanceObserverCallback*);
+
   void observe(const PerformanceObserverInit*, ExceptionState&);
   void disconnect();
   PerformanceEntryVector takeRecords();
@@ -51,9 +55,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PerformanceObserver(ExecutionContext*,
-                      Performance*,
-                      V8PerformanceObserverCallback*);
   void Deliver();
   bool ShouldBeSuspended() const;
 
diff --git a/third_party/blink/renderer/core/timing/performance_observer_test.cc b/third_party/blink/renderer/core/timing/performance_observer_test.cc
index 469856dd..d4e9fcc4 100644
--- a/third_party/blink/renderer/core/timing/performance_observer_test.cc
+++ b/third_party/blink/renderer/core/timing/performance_observer_test.cc
@@ -35,8 +35,8 @@
         v8::Function::New(script_state->GetContext(), nullptr).ToLocalChecked();
     base_ = MakeGarbageCollected<MockPerformance>(script_state);
     cb_ = V8PerformanceObserverCallback::Create(callback);
-    observer_ = new PerformanceObserver(ExecutionContext::From(script_state),
-                                        base_, cb_);
+    observer_ = MakeGarbageCollected<PerformanceObserver>(
+        ExecutionContext::From(script_state), base_, cb_);
   }
 
   bool IsRegistered() { return observer_->is_registered_; }
diff --git a/third_party/blink/renderer/core/timing/performance_resource_timing.h b/third_party/blink/renderer/core/timing/performance_resource_timing.h
index 115bb6b..919c4167 100644
--- a/third_party/blink/renderer/core/timing/performance_resource_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_resource_timing.h
@@ -49,12 +49,21 @@
   friend class PerformanceResourceTimingTest;
 
  public:
+  // This constructor is for PerformanceNavigationTiming.
+  // Related doc: https://goo.gl/uNecAj.
+  PerformanceResourceTiming(const AtomicString& name,
+                            TimeTicks time_origin,
+                            const WebVector<WebServerTimingInfo>&);
+  PerformanceResourceTiming(const WebResourceTimingInfo&,
+                            TimeTicks time_origin,
+                            const AtomicString& initiator_type);
   ~PerformanceResourceTiming() override;
   static PerformanceResourceTiming* Create(
       const WebResourceTimingInfo& info,
       TimeTicks time_origin,
       const AtomicString& initiator_type = g_null_atom) {
-    return new PerformanceResourceTiming(info, time_origin, initiator_type);
+    return MakeGarbageCollected<PerformanceResourceTiming>(info, time_origin,
+                                                           initiator_type);
   }
 
   AtomicString entryType() const override;
@@ -85,21 +94,12 @@
  protected:
   void BuildJSONValue(V8ObjectBuilder&) const override;
 
-  // This constructor is for PerformanceNavigationTiming.
-  // Related doc: https://goo.gl/uNecAj.
-  PerformanceResourceTiming(const AtomicString& name,
-                            TimeTicks time_origin,
-                            const WebVector<WebServerTimingInfo>&);
   virtual AtomicString AlpnNegotiatedProtocol() const;
   virtual AtomicString ConnectionInfo() const;
 
   TimeTicks TimeOrigin() const { return time_origin_; }
 
  private:
-  PerformanceResourceTiming(const WebResourceTimingInfo&,
-                            TimeTicks time_origin,
-                            const AtomicString& initiator_type);
-
   static AtomicString GetNextHopProtocol(
       const AtomicString& alpn_negotiated_protocol,
       const AtomicString& connection_info);
diff --git a/third_party/blink/renderer/core/timing/performance_server_timing.cc b/third_party/blink/renderer/core/timing/performance_server_timing.cc
index 63b1dba8..291804f7 100644
--- a/third_party/blink/renderer/core/timing/performance_server_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_server_timing.cc
@@ -45,8 +45,8 @@
     const WebVector<WebServerTimingInfo>& entries) {
   HeapVector<Member<PerformanceServerTiming>> result;
   for (const auto& entry : entries) {
-    result.push_back(new PerformanceServerTiming(entry.name, entry.duration,
-                                                 entry.description));
+    result.push_back(MakeGarbageCollected<PerformanceServerTiming>(
+        entry.name, entry.duration, entry.description));
   }
   return result;
 }
diff --git a/third_party/blink/renderer/core/timing/performance_server_timing.h b/third_party/blink/renderer/core/timing/performance_server_timing.h
index 4f453bc..d32262a 100644
--- a/third_party/blink/renderer/core/timing/performance_server_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_server_timing.h
@@ -20,6 +20,9 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  PerformanceServerTiming(const String& name,
+                          double duration,
+                          const String& description);
   ~PerformanceServerTiming() override;
 
   const String& name() const { return name_; }
@@ -34,10 +37,6 @@
   ScriptValue toJSONForBinding(ScriptState*) const;
 
  private:
-  PerformanceServerTiming(const String& name,
-                          double duration,
-                          const String& description);
-
   const String name_;
   double duration_;
   const String description_;
diff --git a/third_party/blink/renderer/core/timing/performance_test.cc b/third_party/blink/renderer/core/timing/performance_test.cc
index d5aba7a..794d214 100644
--- a/third_party/blink/renderer/core/timing/performance_test.cc
+++ b/third_party/blink/renderer/core/timing/performance_test.cc
@@ -50,8 +50,8 @@
         v8::Function::New(script_state->GetContext(), nullptr).ToLocalChecked();
     base_ = MakeGarbageCollected<TestPerformance>(script_state);
     cb_ = V8PerformanceObserverCallback::Create(callback);
-    observer_ = new PerformanceObserver(ExecutionContext::From(script_state),
-                                        base_, cb_);
+    observer_ = MakeGarbageCollected<PerformanceObserver>(
+        ExecutionContext::From(script_state), base_, cb_);
   }
 
   void SetUp() override {
diff --git a/third_party/blink/renderer/core/timing/performance_timing.h b/third_party/blink/renderer/core/timing/performance_timing.h
index 4423f9b5..3fdb85a 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_timing.h
@@ -60,9 +60,11 @@
 
  public:
   static PerformanceTiming* Create(LocalFrame* frame) {
-    return new PerformanceTiming(frame);
+    return MakeGarbageCollected<PerformanceTiming>(frame);
   }
 
+  explicit PerformanceTiming(LocalFrame*);
+
   unsigned long long navigationStart() const;
   unsigned long long inputStart() const;
   unsigned long long unloadEventStart() const;
@@ -156,8 +158,6 @@
   unsigned long long MonotonicTimeToIntegerMilliseconds(TimeTicks) const;
 
  private:
-  explicit PerformanceTiming(LocalFrame*);
-
   const DocumentTiming* GetDocumentTiming() const;
   const CSSTiming* CssTiming() const;
   const DocumentParserTiming* GetDocumentParserTiming() const;
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index 7448d20..9004cc77 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -191,8 +191,8 @@
       PerformanceServerTiming::ParseServerTiming(*info);
   if (!server_timing.empty())
     UseCounter::Count(GetFrame(), WebFeature::kPerformanceServerTiming);
-  return new PerformanceNavigationTiming(GetFrame(), info, time_origin_,
-                                         server_timing);
+  return MakeGarbageCollected<PerformanceNavigationTiming>(
+      GetFrame(), info, time_origin_, server_timing);
 }
 
 void WindowPerformance::UpdateLongTaskInstrumentation() {
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
index a8f85db2..f849cba 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -21,7 +21,7 @@
 #include "third_party/blink/renderer/core/workers/dedicated_worker_thread.h"
 #include "third_party/blink/renderer/core/workers/worker_options.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/wtf.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
index 9407e99..84d3d4a 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
@@ -48,7 +48,7 @@
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/core/workers/worker_thread.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
index 884dade..1fd643b3 100644
--- a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
+++ b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
@@ -17,11 +17,11 @@
     ExecutionContext* context) {
   DCHECK(context);
   DCHECK(context->IsContextThread());
-  return new ParentExecutionContextTaskRunners(context);
+  return MakeGarbageCollected<ParentExecutionContextTaskRunners>(context);
 }
 
 ParentExecutionContextTaskRunners* ParentExecutionContextTaskRunners::Create() {
-  return new ParentExecutionContextTaskRunners(nullptr);
+  return MakeGarbageCollected<ParentExecutionContextTaskRunners>(nullptr);
 }
 
 ParentExecutionContextTaskRunners::ParentExecutionContextTaskRunners(
diff --git a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
index 87f22db..05adfb5d 100644
--- a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
+++ b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h
@@ -35,6 +35,10 @@
   // tests that don't have a parent frame.
   static ParentExecutionContextTaskRunners* Create();
 
+  // ExecutionContext could be nullptr if the worker is not associated with a
+  // particular context.
+  explicit ParentExecutionContextTaskRunners(ExecutionContext*);
+
   // Might return nullptr for unsupported task types. This can be called from
   // any threads.
   scoped_refptr<base::SingleThreadTaskRunner> Get(TaskType)
@@ -48,10 +52,6 @@
                                     WTF::IntHash<TaskType>,
                                     TaskTypeTraits>;
 
-  // ExecutionContext could be nullptr if the worker is not associated with a
-  // particular context.
-  explicit ParentExecutionContextTaskRunners(ExecutionContext*);
-
   void ContextDestroyed(ExecutionContext*) LOCKS_EXCLUDED(mutex_) override;
 
   Mutex mutex_;
diff --git a/third_party/blink/renderer/core/workers/threaded_object_proxy_base.cc b/third_party/blink/renderer/core/workers/threaded_object_proxy_base.cc
index f368899..1730f2ef 100644
--- a/third_party/blink/renderer/core/workers/threaded_object_proxy_base.cc
+++ b/third_party/blink/renderer/core/workers/threaded_object_proxy_base.cc
@@ -10,7 +10,7 @@
 #include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
 #include "third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
index 63ddb16..dc7d022c 100644
--- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -25,7 +25,7 @@
 #include "third_party/blink/renderer/core/workers/worklet_pending_tasks.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h
index e588b52..a7a03d2f5 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.h
+++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -41,9 +41,10 @@
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
 #include "third_party/blink/renderer/core/workers/worker_backing_thread_startup_data.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
diff --git a/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc b/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc
index 17152f5..940a822 100644
--- a/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc
+++ b/third_party/blink/renderer/core/workers/worklet_module_responses_map.cc
@@ -6,6 +6,7 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc b/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
index 113a255..e936e50 100644
--- a/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
+++ b/third_party/blink/renderer/core/workers/worklet_module_tree_client.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
 #include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index 625161f5..813044e 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -41,7 +41,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
 #include "third_party/blink/renderer/platform/network/encoded_form_data.h"
 #include "third_party/blink/renderer/platform/network/http_header_map.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
index 86dcf058e..efae8f56 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index 97629de8..594f207 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h"
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
 #include "third_party/blink/renderer/modules/bluetooth/request_device_options.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
index 44911fb..84eb2b0 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
@@ -49,14 +49,16 @@
   static Path2D* Create(Path2DOrString pathorstring) {
     DCHECK(!pathorstring.IsNull());
     if (pathorstring.IsPath2D())
-      return new Path2D(pathorstring.GetAsPath2D());
+      return MakeGarbageCollected<Path2D>(pathorstring.GetAsPath2D());
     if (pathorstring.IsString())
-      return new Path2D(pathorstring.GetAsString());
+      return MakeGarbageCollected<Path2D>(pathorstring.GetAsString());
     NOTREACHED();
     return nullptr;
   }
-  static Path2D* Create() { return new Path2D; }
-  static Path2D* Create(const Path& path) { return new Path2D(path); }
+  static Path2D* Create() { return MakeGarbageCollected<Path2D>(); }
+  static Path2D* Create(const Path& path) {
+    return MakeGarbageCollected<Path2D>(path);
+  }
 
   const Path& GetPath() const { return path_; }
 
@@ -70,18 +72,13 @@
     path_.AddPath(path->GetPath(), matrix->GetAffineTransform());
   }
 
-  ~Path2D() override = default;
-
- private:
   Path2D() : CanvasPath() {}
-
   Path2D(const Path& path) : CanvasPath(path) {}
-
   Path2D(Path2D* path) : CanvasPath(path->GetPath()) {}
-
   Path2D(const String& path_data) : CanvasPath() {
     BuildPathFromString(path_data, path_);
   }
+  ~Path2D() override = default;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index 27c7198..1378ca9 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/modules/permissions/permission_utils.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 // And now, a brief note about clipboard permissions.
 //
diff --git a/third_party/blink/renderer/modules/credentialmanager/password_credential.cc b/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
index dad8579..a06539b 100644
--- a/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
@@ -32,8 +32,8 @@
   if (exception_state.HadException())
     return nullptr;
 
-  return new PasswordCredential(data->id(), data->password(), data->name(),
-                                icon_url);
+  return MakeGarbageCollected<PasswordCredential>(data->id(), data->password(),
+                                                  data->name(), icon_url);
 }
 
 // https://w3c.github.io/webappsec-credential-management/#construct-passwordcredential-form
@@ -84,7 +84,7 @@
                                                const String& password,
                                                const String& name,
                                                const KURL& icon_url) {
-  return new PasswordCredential(id, password, name, icon_url);
+  return MakeGarbageCollected<PasswordCredential>(id, password, name, icon_url);
 }
 
 PasswordCredential::PasswordCredential(const String& id,
diff --git a/third_party/blink/renderer/modules/credentialmanager/password_credential.h b/third_party/blink/renderer/modules/credentialmanager/password_credential.h
index 038a482..168609d 100644
--- a/third_party/blink/renderer/modules/credentialmanager/password_credential.h
+++ b/third_party/blink/renderer/modules/credentialmanager/password_credential.h
@@ -28,6 +28,11 @@
                                     const String& name,
                                     const KURL& icon_url);
 
+  PasswordCredential(const String& id,
+                     const String& password,
+                     const String& name,
+                     const KURL& icon);
+
   // Credential:
   bool IsPasswordCredential() const override;
 
@@ -37,11 +42,6 @@
   const KURL& iconURL() const { return icon_url_; }
 
  private:
-  PasswordCredential(const String& id,
-                     const String& password,
-                     const String& name,
-                     const KURL& icon);
-
   const String password_;
   const String name_;
   const KURL icon_url_;
diff --git a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
index 26249cb..42d7ab4 100644
--- a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h"
 #include "third_party/blink/renderer/modules/credentialmanager/scoped_promise_resolver.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
@@ -29,7 +30,8 @@
     DOMArrayBuffer* raw_id,
     AuthenticatorResponse* response,
     const AuthenticationExtensionsClientOutputs* extension_outputs) {
-  return new PublicKeyCredential(id, raw_id, response, extension_outputs);
+  return MakeGarbageCollected<PublicKeyCredential>(id, raw_id, response,
+                                                   extension_outputs);
 }
 
 PublicKeyCredential::PublicKeyCredential(
diff --git a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
index f8b82ed..a358b2c 100644
--- a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
+++ b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
@@ -28,6 +28,12 @@
       AuthenticatorResponse*,
       const AuthenticationExtensionsClientOutputs*);
 
+  explicit PublicKeyCredential(
+      const String& id,
+      DOMArrayBuffer* raw_id,
+      AuthenticatorResponse*,
+      const AuthenticationExtensionsClientOutputs* extension_outputs);
+
   DOMArrayBuffer* rawId() const { return raw_id_.Get(); }
   AuthenticatorResponse* response() const { return response_.Get(); }
   static ScriptPromise isUserVerifyingPlatformAuthenticatorAvailable(
@@ -39,12 +45,6 @@
   bool IsPublicKeyCredential() const override;
 
  private:
-  explicit PublicKeyCredential(
-      const String& id,
-      DOMArrayBuffer* raw_id,
-      AuthenticatorResponse*,
-      const AuthenticationExtensionsClientOutputs* extension_outputs);
-
   const Member<DOMArrayBuffer> raw_id_;
   const Member<AuthenticatorResponse> response_;
   Member<const AuthenticationExtensionsClientOutputs> extension_outputs_;
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc b/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
index aaae8633..e27b374 100644
--- a/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
+++ b/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc
@@ -97,7 +97,7 @@
       RoundedIntSize(container_size), color_params, context_settings_, zoom);
   PaintSize* paint_size = PaintSize::Create(specified_size);
   StylePropertyMapReadOnly* style_map =
-      new PrepopulatedComputedStylePropertyMap(
+      MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
           layout_object.GetDocument(), layout_object.StyleRef(),
           layout_object.GetNode(), native_invalidation_properties_,
           custom_invalidation_properties_);
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
index 20967530..9d390fa3 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h
@@ -30,10 +30,15 @@
       const CanvasColorParams& color_params,
       const PaintRenderingContext2DSettings* context_settings,
       float zoom) {
-    return new PaintRenderingContext2D(container_size, color_params,
-                                       context_settings, zoom);
+    return MakeGarbageCollected<PaintRenderingContext2D>(
+        container_size, color_params, context_settings, zoom);
   }
 
+  PaintRenderingContext2D(const IntSize& container_size,
+                          const CanvasColorParams&,
+                          const PaintRenderingContext2DSettings*,
+                          float zoom);
+
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(context_settings_);
     ScriptWrappable::Trace(visitor);
@@ -89,11 +94,6 @@
   void WillOverwriteCanvas() override;
 
  private:
-  PaintRenderingContext2D(const IntSize& container_size,
-                          const CanvasColorParams&,
-                          const PaintRenderingContext2DSettings*,
-                          float zoom);
-
   void InitializePaintRecorder();
   cc::PaintCanvas* Canvas() const;
 
diff --git a/third_party/blink/renderer/modules/csspaint/paint_size.h b/third_party/blink/renderer/modules/csspaint/paint_size.h
index 40f9c46..283cb805 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_size.h
+++ b/third_party/blink/renderer/modules/csspaint/paint_size.h
@@ -16,15 +16,17 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static PaintSize* Create(FloatSize size) { return new PaintSize(size); }
+  static PaintSize* Create(FloatSize size) {
+    return MakeGarbageCollected<PaintSize>(size);
+  }
+
+  explicit PaintSize(FloatSize size) : size_(size) {}
   ~PaintSize() override = default;
 
   float width() const { return size_.Width(); }
   float height() const { return size_.Height(); }
 
  private:
-  explicit PaintSize(FloatSize size) : size_(size) {}
-
   FloatSize size_;
 };
 
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
index 86dc6de..62ef724e 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -34,7 +34,7 @@
 
 // static
 PaintWorklet* PaintWorklet::Create(LocalFrame* frame) {
-  return new PaintWorklet(frame);
+  return MakeGarbageCollected<PaintWorklet>(frame);
 }
 
 PaintWorklet::PaintWorklet(LocalFrame* frame)
@@ -129,7 +129,7 @@
 WorkletGlobalScopeProxy* PaintWorklet::CreateGlobalScope() {
   DCHECK(NeedsToCreateGlobalScope());
   if (!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()) {
-    return new PaintWorkletGlobalScopeProxy(
+    return MakeGarbageCollected<PaintWorkletGlobalScopeProxy>(
         To<Document>(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
         pending_generator_registry_, GetNumberOfGlobalScopes() + 1);
   }
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet.h b/third_party/blink/renderer/modules/csspaint/paint_worklet.h
index 4df2043..791459e 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet.h
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet.h
@@ -33,6 +33,7 @@
   static PaintWorklet* From(LocalDOMWindow&);
   static PaintWorklet* Create(LocalFrame*);
 
+  explicit PaintWorklet(LocalFrame*);
   ~PaintWorklet() override;
 
   void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
@@ -50,8 +51,6 @@
   void Trace(blink::Visitor*) override;
 
  protected:
-  explicit PaintWorklet(LocalFrame*);
-
   // Since paint worklet has more than one global scope, we MUST override this
   // function and provide our own selection logic.
   wtf_size_t SelectGlobalScope() final;
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
index b805ef0..fd6e0bad 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -96,9 +96,9 @@
     PaintWorkletPendingGeneratorRegistry* pending_generator_registry,
     size_t global_scope_number) {
   DCHECK(!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled());
-  auto* global_scope =
-      new PaintWorkletGlobalScope(frame, std::move(creation_params),
-                                  reporting_proxy, pending_generator_registry);
+  auto* global_scope = MakeGarbageCollected<PaintWorkletGlobalScope>(
+      frame, std::move(creation_params), reporting_proxy,
+      pending_generator_registry);
   String context_name("PaintWorklet #");
   context_name.append(String::Number(global_scope_number));
   global_scope->ScriptController()->InitializeContextIfNeeded(context_name,
@@ -114,7 +114,8 @@
     std::unique_ptr<GlobalScopeCreationParams> creation_params,
     WorkerThread* thread) {
   DCHECK(RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled());
-  return new PaintWorkletGlobalScope(std::move(creation_params), thread);
+  return MakeGarbageCollected<PaintWorkletGlobalScope>(
+      std::move(creation_params), thread);
 }
 
 PaintWorkletGlobalScope::PaintWorkletGlobalScope(
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
index 95bcd051..958840f 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h
@@ -37,6 +37,12 @@
       std::unique_ptr<GlobalScopeCreationParams>,
       WorkerThread*);
 
+  PaintWorkletGlobalScope(LocalFrame*,
+                          std::unique_ptr<GlobalScopeCreationParams>,
+                          WorkerReportingProxy&,
+                          PaintWorkletPendingGeneratorRegistry*);
+  PaintWorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
+                          WorkerThread*);
   ~PaintWorkletGlobalScope() override;
   void Dispose() final;
 
@@ -51,14 +57,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PaintWorkletGlobalScope(LocalFrame*,
-                          std::unique_ptr<GlobalScopeCreationParams>,
-                          WorkerReportingProxy&,
-                          PaintWorkletPendingGeneratorRegistry*);
-
-  PaintWorkletGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
-                          WorkerThread*);
-
   // Registers the global scope with a proxy client, if not already done. Only
   // used for worklet-thread bound PaintWorkletGlobalScopes.
   void RegisterWithProxyClientIfNeeded();
diff --git a/third_party/blink/renderer/modules/exported/web_idb_value.cc b/third_party/blink/renderer/modules/exported/web_idb_value.cc
index 760124d0..11ea645 100644
--- a/third_party/blink/renderer/modules/exported/web_idb_value.cc
+++ b/third_party/blink/renderer/modules/exported/web_idb_value.cc
@@ -38,6 +38,13 @@
   return private_->BlobInfo();
 }
 
+std::unique_ptr<IDBValue> WebIDBValue::ReleaseIdbValue() noexcept {
+#if DCHECK_IS_ON()
+  ReleaseIdbValueOwnership();
+#endif  // DCHECK_IS_ON()
+  return std::move(private_);
+}
+
 #if DCHECK_IS_ON()
 
 void WebIDBValue::ReleaseIdbValueOwnership() {
diff --git a/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc b/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
index 85317b25..1d57b05b 100644
--- a/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
+++ b/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
@@ -183,12 +183,12 @@
         fs->root(), entry->base_name, FileSystemFlags::Create(),
         MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(
             new_resolver),
-        new PromiseErrorCallback(new_resolver));
+        MakeGarbageCollected<PromiseErrorCallback>(new_resolver));
   } else {
     fs->GetFile(fs->root(), entry->base_name, FileSystemFlags::Create(),
                 MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(
                     new_resolver),
-                new PromiseErrorCallback(new_resolver));
+                MakeGarbageCollected<PromiseErrorCallback>(new_resolver));
   }
   return result;
 }
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
index 973408af..c6c2d052 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_base_handle.cc
@@ -21,7 +21,7 @@
   filesystem()->GetParent(
       this,
       MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
@@ -33,7 +33,7 @@
   filesystem()->Move(
       this, parent, name,
       MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
@@ -45,7 +45,7 @@
   filesystem()->Copy(
       this, parent, name,
       MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
@@ -54,7 +54,7 @@
   ScriptPromise result = resolver->Promise();
   filesystem()->Remove(this,
                        new VoidCallbacks::OnDidSucceedPromiseImpl(resolver),
-                       new PromiseErrorCallback(resolver));
+                       MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
index e551158..2afc8215 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_directory_handle.cc
@@ -28,7 +28,7 @@
   filesystem()->GetFile(
       this, name, flags,
       MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
@@ -43,7 +43,7 @@
   filesystem()->GetDirectory(
       this, name, flags,
       MakeGarbageCollected<EntryCallbacks::OnDidGetEntryPromiseImpl>(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
@@ -60,7 +60,7 @@
       context, mojom::blink::FileSystemType::kTemporary, /*size=*/0,
       FileSystemCallbacks::Create(
           new FileSystemCallbacks::OnDidOpenFileSystemPromiseImpl(resolver),
-          new PromiseErrorCallback(resolver), context,
+          MakeGarbageCollected<PromiseErrorCallback>(resolver), context,
           mojom::blink::FileSystemType::kTemporary),
       LocalFileSystem::kAsynchronous);
   return result;
@@ -96,7 +96,7 @@
   ScriptPromise result = resolver->Promise();
   filesystem()->RemoveRecursively(
       this, new VoidCallbacks::OnDidSucceedPromiseImpl(resolver),
-      new PromiseErrorCallback(resolver));
+      MakeGarbageCollected<PromiseErrorCallback>(resolver));
   return result;
 }
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
index 58bcbe6..95e9823 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
 #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
 #include "third_party/blink/renderer/modules/filesystem/file_system_writer.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
@@ -65,12 +66,13 @@
   ScriptPromise result = resolver->Promise();
   KURL file_system_url = filesystem()->CreateFileSystemURL(this);
   FileSystemDispatcher::From(ExecutionContext::From(script_state))
-      .CreateSnapshotFile(file_system_url,
-                          SnapshotFileCallback::Create(
-                              filesystem(), name(), file_system_url,
-                              new OnDidCreateSnapshotFilePromise(resolver),
-                              new PromiseErrorCallback(resolver),
-                              ExecutionContext::From(script_state)));
+      .CreateSnapshotFile(
+          file_system_url,
+          SnapshotFileCallback::Create(
+              filesystem(), name(), file_system_url,
+              new OnDidCreateSnapshotFilePromise(resolver),
+              MakeGarbageCollected<PromiseErrorCallback>(resolver),
+              ExecutionContext::From(script_state)));
   return result;
 }
 
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
index 2154d71..9a0dcd3 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_system_writer.cc
@@ -156,7 +156,8 @@
   auto reader = stream->getReader(script_state, exception_state);
   if (exception_state.HadException())
     return ScriptPromise();
-  auto* consumer = new ReadableStreamBytesConsumer(script_state, reader);
+  auto* consumer =
+      MakeGarbageCollected<ReadableStreamBytesConsumer>(script_state, reader);
 
   stream_loader_ = FetchDataLoader::CreateLoaderAsDataPipe(
       ExecutionContext::From(script_state)
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
index aa5b9b4..702cd3c 100644
--- a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
+++ b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/geolocation/position_error.h b/third_party/blink/renderer/modules/geolocation/position_error.h
index f25efd13f..ae30a3ab 100644
--- a/third_party/blink/renderer/modules/geolocation/position_error.h
+++ b/third_party/blink/renderer/modules/geolocation/position_error.h
@@ -43,18 +43,18 @@
   };
 
   static PositionError* Create(ErrorCode code, const String& message) {
-    return new PositionError(code, message);
+    return MakeGarbageCollected<PositionError>(code, message);
   }
 
+  PositionError(ErrorCode code, const String& message)
+      : code_(code), message_(message), is_fatal_(false) {}
+
   ErrorCode code() const { return code_; }
   const String& message() const { return message_; }
   void SetIsFatal(bool is_fatal) { is_fatal_ = is_fatal; }
   bool IsFatal() const { return is_fatal_; }
 
  private:
-  PositionError(ErrorCode code, const String& message)
-      : code_(code), message_(message), is_fatal_(false) {}
-
   ErrorCode code_;
   String message_;
   // Whether the error is fatal, such that no request can ever obtain a good
diff --git a/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc b/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
index db1f481b2..7da6e62 100644
--- a/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
+++ b/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc
@@ -8,7 +8,7 @@
 
 // static
 PhotoCapabilities* PhotoCapabilities::Create() {
-  return new PhotoCapabilities();
+  return MakeGarbageCollected<PhotoCapabilities>();
 }
 
 Vector<String> PhotoCapabilities::fillLightMode() const {
diff --git a/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h b/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
index 334c0a3352..802b653 100644
--- a/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
+++ b/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h
@@ -18,6 +18,8 @@
 
  public:
   static PhotoCapabilities* Create();
+
+  PhotoCapabilities() = default;
   ~PhotoCapabilities() override = default;
 
   MediaSettingsRange* imageHeight() const { return image_height_; }
@@ -41,8 +43,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PhotoCapabilities() = default;
-
   Member<MediaSettingsRange> image_height_;
   Member<MediaSettingsRange> image_width_;
   Vector<media::mojom::blink::FillLightMode> fill_light_modes_;
diff --git a/third_party/blink/renderer/modules/installedapp/related_application.h b/third_party/blink/renderer/modules/installedapp/related_application.h
index 79e64d01..fbddca66 100644
--- a/third_party/blink/renderer/modules/installedapp/related_application.h
+++ b/third_party/blink/renderer/modules/installedapp/related_application.h
@@ -18,9 +18,13 @@
   static RelatedApplication* Create(const String& platform,
                                     const String& url,
                                     const String& id) {
-    return new RelatedApplication(platform, url, id);
+    return MakeGarbageCollected<RelatedApplication>(platform, url, id);
   }
 
+  RelatedApplication(const String& platform,
+                     const String& url,
+                     const String& id)
+      : platform_(platform), url_(url), id_(id) {}
   ~RelatedApplication() override = default;
 
   String platform() const { return platform_; }
@@ -28,11 +32,6 @@
   String id() const { return id_; }
 
  private:
-  RelatedApplication(const String& platform,
-                     const String& url,
-                     const String& id)
-      : platform_(platform), url_(url), id_(id) {}
-
   const String platform_;
   const String url_;
   const String id_;
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
index 1ecaabd..710ecb6 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
index 3bfca89..2a6da96 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
index 95ba9f7..95aace3 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
 #include "third_party/blink/renderer/platform/keyboard_codes.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
index 774dc5e..088f046 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h"
 #include "third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h"
 #include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
index aa680c9..47e0580 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
 #include "third_party/blink/renderer/modules/device_orientation/device_orientation_event.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/media_download_in_product_help_manager.cc b/third_party/blink/renderer/modules/media_controls/media_download_in_product_help_manager.cc
index 0a6dc38..4ee08861 100644
--- a/third_party/blink/renderer/modules/media_controls/media_download_in_product_help_manager.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_download_in_product_help_manager.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
index 5b2017f..f247426 100644
--- a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
+++ b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -356,7 +356,7 @@
 
 /**
  * The overlay-play-button is disabled if the video element is loaded via
- * MHTML, and a ruleset for input[type=button]:disabled in themeWin.css has
+ * MHTML, and a ruleset for input[type=button]:disabled in win.css has
  * higher priority than the above ruleset.
  */
 video::-webkit-media-controls-overlay-play-button:disabled {
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index f37a6e588..57fa303 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -170,12 +170,11 @@
     static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
                                                   bool* flag_to_set,
                                                   ScriptValue* arg_to_set) {
-      MyScriptFunction* self =
-          new MyScriptFunction(script_state, flag_to_set, arg_to_set);
+      MyScriptFunction* self = MakeGarbageCollected<MyScriptFunction>(
+          script_state, flag_to_set, arg_to_set);
       return self->BindToV8Function();
     }
 
-   private:
     MyScriptFunction(ScriptState* script_state,
                      bool* flag_to_set,
                      ScriptValue* arg_to_set)
@@ -187,6 +186,8 @@
       *arg_to_set_ = arg;
       return arg;
     }
+
+   private:
     bool* flag_to_set_;
     ScriptValue* arg_to_set_;
   };
diff --git a/third_party/blink/renderer/modules/payments/payment_address_test.cc b/third_party/blink/renderer/modules/payments/payment_address_test.cc
index 5ec262e..80f5b65 100644
--- a/third_party/blink/renderer/modules/payments/payment_address_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_address_test.cc
@@ -28,7 +28,8 @@
   input->recipient = "Jon Doe";
   input->phone = "Phone Number";
 
-  PaymentAddress* output = new PaymentAddress(std::move(input));
+  PaymentAddress* output =
+      MakeGarbageCollected<PaymentAddress>(std::move(input));
 
   EXPECT_EQ("US", output->country());
   EXPECT_EQ(3U, output->addressLine().size());
@@ -51,7 +52,8 @@
       payments::mojom::blink::PaymentAddress::New();
   input->script_code = "Latn";
 
-  PaymentAddress* output = new PaymentAddress(std::move(input));
+  PaymentAddress* output =
+      MakeGarbageCollected<PaymentAddress>(std::move(input));
 
   EXPECT_TRUE(output->languageCode().IsEmpty());
 }
@@ -61,7 +63,8 @@
       payments::mojom::blink::PaymentAddress::New();
   input->language_code = "en";
 
-  PaymentAddress* output = new PaymentAddress(std::move(input));
+  PaymentAddress* output =
+      MakeGarbageCollected<PaymentAddress>(std::move(input));
 
   EXPECT_EQ("en", output->languageCode());
 }
diff --git a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
index d8a139f..55b96f6 100644
--- a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
+++ b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc
@@ -22,7 +22,8 @@
           PaymentAppServiceWorkerRegistration>(registration);
 
   if (!supplement) {
-    supplement = new PaymentAppServiceWorkerRegistration(&registration);
+    supplement = MakeGarbageCollected<PaymentAppServiceWorkerRegistration>(
+        &registration);
     ProvideTo(registration, supplement);
   }
 
diff --git a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
index 337c715f..5e8f5a0a 100644
--- a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
+++ b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
@@ -24,7 +24,9 @@
  public:
   static const char kSupplementName[];
 
+  explicit PaymentAppServiceWorkerRegistration(ServiceWorkerRegistration*);
   virtual ~PaymentAppServiceWorkerRegistration();
+
   static PaymentAppServiceWorkerRegistration& From(ServiceWorkerRegistration&);
 
   static PaymentManager* paymentManager(ScriptState*,
@@ -34,8 +36,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit PaymentAppServiceWorkerRegistration(ServiceWorkerRegistration*);
-
   Member<ServiceWorkerRegistration> registration_;
   Member<PaymentManager> payment_manager_;
 };
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc
index 6f09a6e..d67dd5b2 100644
--- a/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/renderer/modules/payments/payment_manager.h"
 #include "third_party/blink/renderer/modules/permissions/permission_utils.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -248,10 +249,11 @@
               mojom::blink::PermissionName::PAYMENT_HANDLER),
           LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
                                                      : nullptr),
-          WTF::Bind(&PaymentInstruments::OnRequestPermission,
-                    WrapPersistent(this), WrapPersistent(resolver),
-                    instrument_key,
-                    WrapPersistent(new PaymentInstrumentParameter(details))));
+          WTF::Bind(
+              &PaymentInstruments::OnRequestPermission, WrapPersistent(this),
+              WrapPersistent(resolver), instrument_key,
+              WrapPersistent(
+                  MakeGarbageCollected<PaymentInstrumentParameter>(details))));
   return resolver->Promise();
 }
 
diff --git a/third_party/blink/renderer/modules/payments/payment_manager.cc b/third_party/blink/renderer/modules/payments/payment_manager.cc
index 29517bb..f9db07d 100644
--- a/third_party/blink/renderer/modules/payments/payment_manager.cc
+++ b/third_party/blink/renderer/modules/payments/payment_manager.cc
@@ -16,12 +16,12 @@
 
 PaymentManager* PaymentManager::Create(
     ServiceWorkerRegistration* registration) {
-  return new PaymentManager(registration);
+  return MakeGarbageCollected<PaymentManager>(registration);
 }
 
 PaymentInstruments* PaymentManager::instruments() {
   if (!instruments_)
-    instruments_ = new PaymentInstruments(manager_);
+    instruments_ = MakeGarbageCollected<PaymentInstruments>(manager_);
   return instruments_;
 }
 
diff --git a/third_party/blink/renderer/modules/payments/payment_manager.h b/third_party/blink/renderer/modules/payments/payment_manager.h
index 139d001..20677a3 100644
--- a/third_party/blink/renderer/modules/payments/payment_manager.h
+++ b/third_party/blink/renderer/modules/payments/payment_manager.h
@@ -23,6 +23,8 @@
  public:
   static PaymentManager* Create(ServiceWorkerRegistration*);
 
+  explicit PaymentManager(ServiceWorkerRegistration*);
+
   PaymentInstruments* instruments();
 
   const String& userHint();
@@ -31,8 +33,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit PaymentManager(ServiceWorkerRegistration*);
-
   void OnServiceConnectionError();
 
   Member<ServiceWorkerRegistration> registration_;
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index c0608a6..34f940d 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -57,6 +57,7 @@
 #include "third_party/blink/renderer/platform/uuid.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
@@ -778,8 +779,9 @@
     const HeapVector<Member<PaymentMethodData>>& method_data,
     const PaymentDetailsInit* details,
     ExceptionState& exception_state) {
-  return new PaymentRequest(execution_context, method_data, details,
-                            PaymentOptions::Create(), exception_state);
+  return MakeGarbageCollected<PaymentRequest>(execution_context, method_data,
+                                              details, PaymentOptions::Create(),
+                                              exception_state);
 }
 
 PaymentRequest* PaymentRequest::Create(
@@ -788,8 +790,8 @@
     const PaymentDetailsInit* details,
     const PaymentOptions* options,
     ExceptionState& exception_state) {
-  return new PaymentRequest(execution_context, method_data, details, options,
-                            exception_state);
+  return MakeGarbageCollected<PaymentRequest>(
+      execution_context, method_data, details, options, exception_state);
 }
 
 PaymentRequest::~PaymentRequest() = default;
@@ -1152,7 +1154,7 @@
     return;
   }
 
-  shipping_address_ = new PaymentAddress(std::move(address));
+  shipping_address_ = MakeGarbageCollected<PaymentAddress>(std::move(address));
 
   PaymentRequestUpdateEvent* event = PaymentRequestUpdateEvent::Create(
       GetExecutionContext(), event_type_names::kShippingaddresschange);
@@ -1222,8 +1224,8 @@
       return;
     }
 
-    shipping_address_ =
-        new PaymentAddress(std::move(response->shipping_address));
+    shipping_address_ = MakeGarbageCollected<PaymentAddress>(
+        std::move(response->shipping_address));
     shipping_option_ = response->shipping_option;
   } else {
     if (response->shipping_address || !response->shipping_option.IsNull()) {
@@ -1258,9 +1260,9 @@
     // connection to display a success or failure message to the user.
     retry_resolver_.Clear();
   } else if (accept_resolver_) {
-    payment_response_ = new PaymentResponse(accept_resolver_->GetScriptState(),
-                                            std::move(response),
-                                            shipping_address_.Get(), this, id_);
+    payment_response_ = MakeGarbageCollected<PaymentResponse>(
+        accept_resolver_->GetScriptState(), std::move(response),
+        shipping_address_.Get(), this, id_);
     accept_resolver_->Resolve(payment_response_);
 
     // Do not close the mojo connection here. The merchant website should call
diff --git a/third_party/blink/renderer/modules/payments/payment_request.h b/third_party/blink/renderer/modules/payments/payment_request.h
index 1aeb2c3..9045d35 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/third_party/blink/renderer/modules/payments/payment_request.h
@@ -59,6 +59,11 @@
                                 const PaymentOptions*,
                                 ExceptionState&);
 
+  PaymentRequest(ExecutionContext*,
+                 const HeapVector<Member<PaymentMethodData>>&,
+                 const PaymentDetailsInit*,
+                 const PaymentOptions*,
+                 ExceptionState&);
   ~PaymentRequest() override;
 
   ScriptPromise show(ScriptState*);
@@ -106,12 +111,6 @@
   };
 
  private:
-  PaymentRequest(ExecutionContext*,
-                 const HeapVector<Member<PaymentMethodData>>&,
-                 const PaymentDetailsInit*,
-                 const PaymentOptions*,
-                 ExceptionState&);
-
   // LifecycleObserver:
   void ContextDestroyed(ExecutionContext*) override;
 
diff --git a/third_party/blink/renderer/modules/payments/payment_request_event.cc b/third_party/blink/renderer/modules/payments/payment_request_event.cc
index aa3623d..863cf8e2 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_event.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_event.cc
@@ -21,7 +21,8 @@
 PaymentRequestEvent* PaymentRequestEvent::Create(
     const AtomicString& type,
     const PaymentRequestEventInit* initializer) {
-  return new PaymentRequestEvent(type, initializer, nullptr, nullptr);
+  return MakeGarbageCollected<PaymentRequestEvent>(type, initializer, nullptr,
+                                                   nullptr);
 }
 
 PaymentRequestEvent* PaymentRequestEvent::Create(
@@ -29,8 +30,8 @@
     const PaymentRequestEventInit* initializer,
     RespondWithObserver* respond_with_observer,
     WaitUntilObserver* wait_until_observer) {
-  return new PaymentRequestEvent(type, initializer, respond_with_observer,
-                                 wait_until_observer);
+  return MakeGarbageCollected<PaymentRequestEvent>(
+      type, initializer, respond_with_observer, wait_until_observer);
 }
 
 PaymentRequestEvent::~PaymentRequestEvent() = default;
diff --git a/third_party/blink/renderer/modules/payments/payment_request_event.h b/third_party/blink/renderer/modules/payments/payment_request_event.h
index 586578f..24333aa 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_event.h
+++ b/third_party/blink/renderer/modules/payments/payment_request_event.h
@@ -31,6 +31,11 @@
                                      const PaymentRequestEventInit*,
                                      RespondWithObserver*,
                                      WaitUntilObserver*);
+
+  PaymentRequestEvent(const AtomicString& type,
+                      const PaymentRequestEventInit*,
+                      RespondWithObserver*,
+                      WaitUntilObserver*);
   ~PaymentRequestEvent() override;
 
   const AtomicString& InterfaceName() const override;
@@ -49,11 +54,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PaymentRequestEvent(const AtomicString& type,
-                      const PaymentRequestEventInit*,
-                      RespondWithObserver*,
-                      WaitUntilObserver*);
-
   String top_origin_;
   String payment_request_origin_;
   String payment_request_id_;
diff --git a/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc b/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
index 8122f169..c8e5ee19 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc
@@ -23,7 +23,8 @@
     ExecutionContext* context,
     int event_id,
     WaitUntilObserver* observer) {
-  return new PaymentRequestRespondWithObserver(context, event_id, observer);
+  return MakeGarbageCollected<PaymentRequestRespondWithObserver>(
+      context, event_id, observer);
 }
 
 void PaymentRequestRespondWithObserver::OnResponseRejected(
diff --git a/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h b/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
index 12e6cb5..558336f0 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
+++ b/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h
@@ -21,6 +21,9 @@
 class MODULES_EXPORT PaymentRequestRespondWithObserver final
     : public RespondWithObserver {
  public:
+  PaymentRequestRespondWithObserver(ExecutionContext*,
+                                    int event_id,
+                                    WaitUntilObserver*);
   ~PaymentRequestRespondWithObserver() override = default;
 
   static PaymentRequestRespondWithObserver* Create(ExecutionContext*,
@@ -35,11 +38,6 @@
   void OnNoResponse() override;
 
   void Trace(blink::Visitor*) override;
-
- private:
-  PaymentRequestRespondWithObserver(ExecutionContext*,
-                                    int event_id,
-                                    WaitUntilObserver*);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_request_update_event.cc b/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
index bd8596d5..080fc25 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request_update_event.cc
@@ -91,7 +91,8 @@
     ExecutionContext* execution_context,
     const AtomicString& type,
     const PaymentRequestUpdateEventInit* init) {
-  return new PaymentRequestUpdateEvent(execution_context, type, init);
+  return MakeGarbageCollected<PaymentRequestUpdateEvent>(execution_context,
+                                                         type, init);
 }
 
 void PaymentRequestUpdateEvent::SetPaymentDetailsUpdater(
diff --git a/third_party/blink/renderer/modules/payments/payment_request_update_event.h b/third_party/blink/renderer/modules/payments/payment_request_update_event.h
index 4c833e6b..d8618f53 100644
--- a/third_party/blink/renderer/modules/payments/payment_request_update_event.h
+++ b/third_party/blink/renderer/modules/payments/payment_request_update_event.h
@@ -26,6 +26,9 @@
   USING_GARBAGE_COLLECTED_MIXIN(PaymentRequestUpdateEvent)
 
  public:
+  PaymentRequestUpdateEvent(ExecutionContext*,
+                            const AtomicString& type,
+                            const PaymentRequestUpdateEventInit*);
   ~PaymentRequestUpdateEvent() override;
 
   static PaymentRequestUpdateEvent* Create(
@@ -49,11 +52,6 @@
 
   void OnUpdateEventTimeoutForTesting();
 
- protected:
-  PaymentRequestUpdateEvent(ExecutionContext*,
-                            const AtomicString& type,
-                            const PaymentRequestUpdateEventInit*);
-
  private:
   void OnUpdateEventTimeout(TimerBase*);
 
diff --git a/third_party/blink/renderer/modules/payments/payment_response_test.cc b/third_party/blink/renderer/modules/payments/payment_response_test.cc
index f2cb3ea..e95f4ef 100644
--- a/third_party/blink/renderer/modules/payments/payment_response_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_response_test.cc
@@ -59,9 +59,9 @@
   input->payer->phone = "0123";
   MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
 
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
-                          complete_callback, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), nullptr, complete_callback,
+      "id");
 
   EXPECT_EQ("foo", output->methodName());
   EXPECT_EQ("standardShippingOption", output->shippingOption());
@@ -91,9 +91,9 @@
       BuildPaymentResponseForTest();
   input->stringified_details = "transactionId";
   MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
-                          complete_callback, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), nullptr, complete_callback,
+      "id");
 
   ScriptValue details = output->details(scope.GetScriptState());
   ASSERT_TRUE(details.V8Value()->IsObject());
@@ -114,9 +114,9 @@
   input->method_name = "foo";
   input->stringified_details = "{\"transactionId\": 123}";
   MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
-                          complete_callback, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), nullptr, complete_callback,
+      "id");
   EXPECT_EQ(output->details(scope.GetScriptState()),
             output->details(scope.GetScriptState()));
 }
@@ -128,9 +128,9 @@
   input->method_name = "foo";
   input->stringified_details = "{\"transactionId\": 123}";
   MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
-                          complete_callback, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), nullptr, complete_callback,
+      "id");
 
   EXPECT_CALL(*complete_callback,
               Complete(scope.GetScriptState(), PaymentStateResolver::kSuccess));
@@ -145,9 +145,9 @@
   input->method_name = "foo";
   input->stringified_details = "{\"transactionId\": 123}";
   MockPaymentStateResolver* complete_callback = new MockPaymentStateResolver;
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), nullptr,
-                          complete_callback, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), nullptr, complete_callback,
+      "id");
 
   EXPECT_CALL(*complete_callback,
               Complete(scope.GetScriptState(), PaymentStateResolver::kFail));
@@ -173,11 +173,11 @@
   input->shipping_address->address_line.push_back("BIN1");
   input->shipping_address->address_line.push_back("First floor");
   PaymentAddress* address =
-      new PaymentAddress(std::move(input->shipping_address));
+      MakeGarbageCollected<PaymentAddress>(std::move(input->shipping_address));
 
-  PaymentResponse* output =
-      new PaymentResponse(scope.GetScriptState(), std::move(input), address,
-                          new MockPaymentStateResolver, "id");
+  PaymentResponse* output = MakeGarbageCollected<PaymentResponse>(
+      scope.GetScriptState(), std::move(input), address,
+      new MockPaymentStateResolver, "id");
   ScriptValue json_object = output->toJSONForBinding(scope.GetScriptState());
   EXPECT_TRUE(json_object.IsObject());
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
index 7ea2eb6..f5d3e24 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -60,7 +60,8 @@
     ExecutionContext* context,
     std::unique_ptr<WebRTCDataChannelHandler> handler) {
   DCHECK(handler);
-  RTCDataChannel* channel = new RTCDataChannel(context, std::move(handler));
+  RTCDataChannel* channel =
+      MakeGarbageCollected<RTCDataChannel>(context, std::move(handler));
   channel->PauseIfNeeded();
 
   return channel;
@@ -79,7 +80,8 @@
                                       "RTCDataChannel is not supported");
     return nullptr;
   }
-  RTCDataChannel* channel = new RTCDataChannel(context, std::move(handler));
+  RTCDataChannel* channel =
+      MakeGarbageCollected<RTCDataChannel>(context, std::move(handler));
   channel->PauseIfNeeded();
 
   return channel;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
index 1337d25..bcc0e81 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
@@ -64,6 +64,8 @@
                                 const String& label,
                                 const WebRTCDataChannelInit&,
                                 ExceptionState&);
+
+  RTCDataChannel(ExecutionContext*, std::unique_ptr<WebRTCDataChannelHandler>);
   ~RTCDataChannel() override;
 
   ReadyState GetHandlerState() const;
@@ -123,7 +125,6 @@
   void DidDetectError() override;
 
  private:
-  RTCDataChannel(ExecutionContext*, std::unique_ptr<WebRTCDataChannelHandler>);
   void Dispose();
 
   void ScheduleDispatchEvent(Event*);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
index 7d047b4..9ea0734 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc
@@ -28,13 +28,13 @@
 
 RTCDataChannelEvent* RTCDataChannelEvent::Create(const AtomicString& type,
                                                  RTCDataChannel* channel) {
-  return new RTCDataChannelEvent(type, channel);
+  return MakeGarbageCollected<RTCDataChannelEvent>(type, channel);
 }
 
 RTCDataChannelEvent* RTCDataChannelEvent::Create(
     const AtomicString& type,
     const RTCDataChannelEventInit* initializer) {
-  return new RTCDataChannelEvent(type, initializer);
+  return MakeGarbageCollected<RTCDataChannelEvent>(type, initializer);
 }
 
 RTCDataChannelEvent::RTCDataChannelEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
index 2cde6d4..e6efc56 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h
@@ -36,6 +36,8 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  RTCDataChannelEvent(const AtomicString& type, RTCDataChannel*);
+  RTCDataChannelEvent(const AtomicString& type, const RTCDataChannelEventInit*);
   ~RTCDataChannelEvent() override;
 
   static RTCDataChannelEvent* Create(const AtomicString& type,
@@ -51,10 +53,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCDataChannelEvent(const AtomicString& type,
-                      RTCDataChannel*);
-
-  RTCDataChannelEvent(const AtomicString& type, const RTCDataChannelEventInit*);
   Member<RTCDataChannel> channel_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
index 8d75ee7..cd60d6e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc
@@ -50,7 +50,8 @@
     ExecutionContext* context,
     std::unique_ptr<WebRTCDTMFSenderHandler> dtmf_sender_handler) {
   DCHECK(dtmf_sender_handler);
-  return new RTCDTMFSender(context, std::move(dtmf_sender_handler));
+  return MakeGarbageCollected<RTCDTMFSender>(context,
+                                             std::move(dtmf_sender_handler));
 }
 
 RTCDTMFSender::RTCDTMFSender(ExecutionContext* context,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
index b18362b0..dbf139f1 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h
@@ -47,6 +47,8 @@
  public:
   static RTCDTMFSender* Create(ExecutionContext*,
                                std::unique_ptr<WebRTCDTMFSenderHandler>);
+
+  RTCDTMFSender(ExecutionContext*, std::unique_ptr<WebRTCDTMFSenderHandler>);
   ~RTCDTMFSender() override;
 
   bool canInsertDTMF() const;
@@ -71,8 +73,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCDTMFSender(ExecutionContext*,
-                std::unique_ptr<WebRTCDTMFSenderHandler>);
   void Dispose();
 
   // WebRTCDTMFSenderHandlerClient
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
index 93748331..8b32118 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc
@@ -30,13 +30,13 @@
 namespace blink {
 
 RTCDTMFToneChangeEvent* RTCDTMFToneChangeEvent::Create(const String& tone) {
-  return new RTCDTMFToneChangeEvent(tone);
+  return MakeGarbageCollected<RTCDTMFToneChangeEvent>(tone);
 }
 
 RTCDTMFToneChangeEvent* RTCDTMFToneChangeEvent::Create(
     const AtomicString& type,
     const RTCDTMFToneChangeEventInit* initializer) {
-  return new RTCDTMFToneChangeEvent(initializer);
+  return MakeGarbageCollected<RTCDTMFToneChangeEvent>(initializer);
 }
 
 RTCDTMFToneChangeEvent::RTCDTMFToneChangeEvent(const String& tone)
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
index 088f2f63..46db919c 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h
@@ -36,6 +36,8 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  explicit RTCDTMFToneChangeEvent(const String& tone);
+  explicit RTCDTMFToneChangeEvent(const RTCDTMFToneChangeEventInit*);
   ~RTCDTMFToneChangeEvent() override;
 
   static RTCDTMFToneChangeEvent* Create(const String& tone);
@@ -50,9 +52,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit RTCDTMFToneChangeEvent(const String& tone);
-  explicit RTCDTMFToneChangeEvent(const RTCDTMFToneChangeEventInit*);
-
   String tone_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
index 9fa4ef4..dcbe9c5 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
@@ -66,13 +66,13 @@
                       WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
   }
 
-  return new RTCIceCandidate(WebRTCICECandidate::Create(
+  return MakeGarbageCollected<RTCIceCandidate>(WebRTCICECandidate::Create(
       candidate_init->candidate(), sdp_mid, sdp_m_line_index));
 }
 
 RTCIceCandidate* RTCIceCandidate::Create(
     scoped_refptr<WebRTCICECandidate> web_candidate) {
-  return new RTCIceCandidate(std::move(web_candidate));
+  return MakeGarbageCollected<RTCIceCandidate>(std::move(web_candidate));
 }
 
 RTCIceCandidate::RTCIceCandidate(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
index 6c3c687..1aec3ed 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h
@@ -53,6 +53,8 @@
                                  ExceptionState&);
   static RTCIceCandidate* Create(scoped_refptr<WebRTCICECandidate>);
 
+  explicit RTCIceCandidate(scoped_refptr<WebRTCICECandidate>);
+
   String candidate() const;
   void setCandidate(String);
   String sdpMid() const;
@@ -65,8 +67,6 @@
   scoped_refptr<WebRTCICECandidate> WebCandidate() const;
 
  private:
-  explicit RTCIceCandidate(scoped_refptr<WebRTCICECandidate>);
-
   scoped_refptr<WebRTCICECandidate> web_candidate_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index b3049c04..32caf50 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -85,7 +85,7 @@
       frame->GetTaskRunner(TaskType::kNetworking);
   scoped_refptr<base::SingleThreadTaskRunner> host_thread =
       Platform::Current()->GetWebRtcWorkerThread();
-  return new RTCIceTransport(
+  return MakeGarbageCollected<RTCIceTransport>(
       context, std::move(proxy_thread), std::move(host_thread),
       std::make_unique<DefaultIceTransportAdapterCrossThreadFactory>());
 }
@@ -95,9 +95,9 @@
     scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
     scoped_refptr<base::SingleThreadTaskRunner> host_thread,
     std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory) {
-  return new RTCIceTransport(context, std::move(proxy_thread),
-                             std::move(host_thread),
-                             std::move(adapter_factory));
+  return MakeGarbageCollected<RTCIceTransport>(context, std::move(proxy_thread),
+                                               std::move(host_thread),
+                                               std::move(adapter_factory));
 }
 
 RTCIceTransport::RTCIceTransport(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
index 96ccf58..6f3c822 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h
@@ -64,6 +64,11 @@
       scoped_refptr<base::SingleThreadTaskRunner> host_thread,
       std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
 
+  explicit RTCIceTransport(
+      ExecutionContext* context,
+      scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
+      scoped_refptr<base::SingleThreadTaskRunner> host_thread,
+      std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
   ~RTCIceTransport() override;
 
   // Returns true if start() has been called.
@@ -122,12 +127,6 @@
   void Trace(blink::Visitor* visitor) override;
 
  private:
-  explicit RTCIceTransport(
-      ExecutionContext* context,
-      scoped_refptr<base::SingleThreadTaskRunner> proxy_thread,
-      scoped_refptr<base::SingleThreadTaskRunner> host_thread,
-      std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory);
-
   // IceTransportProxy::Delegate overrides.
   void OnGatheringStateChanged(cricket::IceGatheringState new_state) override;
   void OnCandidateGathered(const cricket::Candidate& candidate) override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.cc
index ee5dba94..ac3110ba 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.cc
@@ -30,7 +30,7 @@
 RTCLegacyStatsReport* RTCLegacyStatsReport::Create(const String& id,
                                                    const String& type,
                                                    double timestamp) {
-  return new RTCLegacyStatsReport(id, type, timestamp);
+  return MakeGarbageCollected<RTCLegacyStatsReport>(id, type, timestamp);
 }
 
 RTCLegacyStatsReport::RTCLegacyStatsReport(const String& id,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.h b/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.h
index f7adcb61..d784ee0 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.h
@@ -41,6 +41,8 @@
                                       const String& type,
                                       double timestamp);
 
+  RTCLegacyStatsReport(const String& id, const String& type, double timestamp);
+
   double timestamp() const { return timestamp_; }
   String id() { return id_; }
   String type() { return type_; }
@@ -50,8 +52,6 @@
   void AddStatistic(const String& name, const String& value);
 
  private:
-  RTCLegacyStatsReport(const String& id, const String& type, double timestamp);
-
   String id_;
   String type_;
   double timestamp_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index ef2bb31..7fc2789 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -270,7 +270,8 @@
       : resolver_(resolver) {}
 
   void OnSuccess(rtc::scoped_refptr<rtc::RTCCertificate> certificate) override {
-    resolver_->Resolve(new RTCCertificate(std::move(certificate)));
+    resolver_->Resolve(
+        MakeGarbageCollected<RTCCertificate>(std::move(certificate)));
   }
 
   void OnError() override { resolver_->Reject(); }
@@ -662,7 +663,7 @@
     return nullptr;
   }
 
-  RTCPeerConnection* peer_connection = new RTCPeerConnection(
+  RTCPeerConnection* peer_connection = MakeGarbageCollected<RTCPeerConnection>(
       context, std::move(configuration), rtc_configuration->hasSdpSemantics(),
       constraints, exception_state);
   peer_connection->PauseIfNeeded();
@@ -1439,7 +1440,8 @@
     certificates.ReserveCapacity(
         SafeCast<wtf_size_t>(webrtc_configuration.certificates.size()));
     for (const auto& webrtc_certificate : webrtc_configuration.certificates) {
-      certificates.emplace_back(new RTCCertificate(webrtc_certificate));
+      certificates.emplace_back(
+          MakeGarbageCollected<RTCCertificate>(webrtc_certificate));
     }
     result->setCertificates(certificates);
   }
@@ -2304,7 +2306,8 @@
   RTCRtpSender* sender;
   if (sender_it == rtp_senders_.end()) {
     // Create new sender (with empty stream set).
-    sender = new RTCRtpSender(this, std::move(web_sender), kind, track, {});
+    sender = MakeGarbageCollected<RTCRtpSender>(
+        this, std::move(web_sender), kind, track, MediaStreamVector());
     rtp_senders_.push_back(sender);
   } else {
     // Update existing sender (not touching the stream set).
@@ -2333,7 +2336,8 @@
   RTCRtpReceiver* receiver;
   if (receiver_it == rtp_receivers_.end()) {
     // Create new receiver.
-    receiver = new RTCRtpReceiver(std::move(web_receiver), track, {});
+    receiver = MakeGarbageCollected<RTCRtpReceiver>(std::move(web_receiver),
+                                                    track, MediaStreamVector());
     // Receiving tracks should be muted by default. SetReadyState() propagates
     // the related state changes to ensure it is muted on all layers. It also
     // fires events - which is not desired - but because they fire synchronously
@@ -2365,8 +2369,8 @@
   auto* transceiver_it = FindTransceiver(*web_transceiver);
   if (transceiver_it == transceivers_.end()) {
     // Create new tranceiver.
-    transceiver = new RTCRtpTransceiver(this, std::move(web_transceiver),
-                                        sender, receiver);
+    transceiver = MakeGarbageCollected<RTCRtpTransceiver>(
+        this, std::move(web_transceiver), sender, receiver);
     transceivers_.push_back(transceiver);
   } else {
     // Update existing transceiver.
@@ -2568,11 +2572,11 @@
     streams.push_back(stream);
   }
   DCHECK(FindReceiver(*web_receiver) == rtp_receivers_.end());
-  RTCRtpReceiver* rtp_receiver =
-      new RTCRtpReceiver(std::move(web_receiver), track, streams);
+  RTCRtpReceiver* rtp_receiver = MakeGarbageCollected<RTCRtpReceiver>(
+      std::move(web_receiver), track, streams);
   rtp_receivers_.push_back(rtp_receiver);
-  ScheduleDispatchEvent(
-      new RTCTrackEvent(rtp_receiver, rtp_receiver->track(), streams, nullptr));
+  ScheduleDispatchEvent(MakeGarbageCollected<RTCTrackEvent>(
+      rtp_receiver, rtp_receiver->track(), streams, nullptr));
 }
 
 void RTCPeerConnection::DidRemoveReceiverPlanB(
@@ -2687,7 +2691,7 @@
 
   // Fire "pc.ontrack" synchronously.
   for (auto& transceiver : track_events) {
-    auto* track_event = new RTCTrackEvent(
+    auto* track_event = MakeGarbageCollected<RTCTrackEvent>(
         transceiver->receiver(), transceiver->receiver()->track(),
         transceiver->receiver()->streams(), transceiver);
     DispatchEvent(*track_event);
@@ -2955,7 +2959,7 @@
 void RTCPeerConnection::ScheduleDispatchEvent(Event* event,
                                               BoolFunction setup_function) {
   scheduled_events_.push_back(
-      new EventWrapper(event, std::move(setup_function)));
+      MakeGarbageCollected<EventWrapper>(event, std::move(setup_function)));
 
   dispatch_scheduled_event_runner_->RunAsync();
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index 06030fd..b5f9b6bc 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -114,6 +114,12 @@
                                    const RTCConfiguration*,
                                    const Dictionary&,
                                    ExceptionState&);
+
+  RTCPeerConnection(ExecutionContext*,
+                    webrtc::PeerConnectionInterface::RTCConfiguration,
+                    bool sdp_semantics_specified,
+                    WebMediaConstraints,
+                    ExceptionState&);
   ~RTCPeerConnection() override;
 
   ScriptPromise createOffer(ScriptState*, const RTCOfferOptions*);
@@ -353,12 +359,6 @@
    private:
     BoolFunction setup_function_;
   };
-
-  RTCPeerConnection(ExecutionContext*,
-                    webrtc::PeerConnectionInterface::RTCConfiguration,
-                    bool sdp_semantics_specified,
-                    WebMediaConstraints,
-                    ExceptionState&);
   void Dispose();
 
   void ScheduleDispatchEvent(Event*);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
index be01010..747643b 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc
@@ -32,13 +32,13 @@
 
 RTCPeerConnectionIceEvent* RTCPeerConnectionIceEvent::Create(
     RTCIceCandidate* candidate) {
-  return new RTCPeerConnectionIceEvent(candidate);
+  return MakeGarbageCollected<RTCPeerConnectionIceEvent>(candidate);
 }
 
 RTCPeerConnectionIceEvent* RTCPeerConnectionIceEvent::Create(
     const AtomicString& type,
     const RTCPeerConnectionIceEventInit* initializer) {
-  return new RTCPeerConnectionIceEvent(type, initializer);
+  return MakeGarbageCollected<RTCPeerConnectionIceEvent>(type, initializer);
 }
 
 RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(RTCIceCandidate* candidate)
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
index f57ca47..fd335e0 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h
@@ -36,6 +36,9 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  RTCPeerConnectionIceEvent(RTCIceCandidate*);
+  RTCPeerConnectionIceEvent(const AtomicString& type,
+                            const RTCPeerConnectionIceEventInit*);
   ~RTCPeerConnectionIceEvent() override;
 
   static RTCPeerConnectionIceEvent* Create(RTCIceCandidate*);
@@ -51,11 +54,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCPeerConnectionIceEvent(RTCIceCandidate*);
-
-  RTCPeerConnectionIceEvent(const AtomicString& type,
-                            const RTCPeerConnectionIceEventInit*);
-
   Member<RTCIceCandidate> candidate_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
index 4a5986e0..77a0948 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc
@@ -99,8 +99,9 @@
       return nullptr;
     }
   }
-  return new RTCQuicTransport(context, transport, certificates, exception_state,
-                              std::move(p2p_quic_transport_factory));
+  return MakeGarbageCollected<RTCQuicTransport>(
+      context, transport, certificates, exception_state,
+      std::move(p2p_quic_transport_factory));
 }
 
 RTCQuicTransport::RTCQuicTransport(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
index e189bbd..c69f9e7 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h
@@ -63,6 +63,12 @@
       ExceptionState& exception_state,
       std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory);
 
+  RTCQuicTransport(
+      ExecutionContext* context,
+      RTCIceTransport* transport,
+      const HeapVector<Member<RTCCertificate>>& certificates,
+      ExceptionState& exception_state,
+      std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory);
   ~RTCQuicTransport() override;
 
   // Called by the RTCIceTransport when it is being closed.
@@ -97,13 +103,6 @@
   void Trace(blink::Visitor* visitor) override;
 
  private:
-  RTCQuicTransport(
-      ExecutionContext* context,
-      RTCIceTransport* transport,
-      const HeapVector<Member<RTCCertificate>>& certificates,
-      ExceptionState& exception_state,
-      std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory);
-
   // QuicTransportProxy::Delegate overrides;
   void OnConnected() override;
   void OnConnectionFailed(const std::string& error_details,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
index c128328..5c2df98 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
@@ -24,9 +24,9 @@
 
 HeapVector<Member<RTCCertificate>> GenerateLocalRTCCertificates() {
   HeapVector<Member<RTCCertificate>> certificates;
-  certificates.push_back(
-      new RTCCertificate(rtc::RTCCertificateGenerator::GenerateCertificate(
-          rtc::KeyParams::ECDSA(), absl::nullopt)));
+  certificates.push_back(MakeGarbageCollected<RTCCertificate>(
+      rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams::ECDSA(),
+                                                        absl::nullopt)));
   return certificates;
 }
 
@@ -135,7 +135,7 @@
         return std::make_unique<MockP2PQuicTransport>();
       }));
   HeapVector<Member<RTCCertificate>> certificates;
-  certificates.push_back(new RTCCertificate(certificate));
+  certificates.push_back(MakeGarbageCollected<RTCCertificate>(certificate));
   Persistent<RTCQuicTransport> quic_transport = CreateQuicTransport(
       scope, ice_transport, certificates, std::move(mock_factory));
   quic_transport->start(CreateRemoteRTCQuicParameters1(), ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index c481adf..341b232 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -72,7 +72,8 @@
     DCHECK_EQ(web_contributing_source->SourceType(),
               WebRTCRtpContributingSourceType::CSRC);
     RTCRtpContributingSource* contributing_source =
-        new RTCRtpContributingSource(this, *web_contributing_source);
+        MakeGarbageCollected<RTCRtpContributingSource>(
+            this, *web_contributing_source);
     contributing_sources_.push_back(contributing_source);
   }
   // Clear the flag and schedule a microtask to reset it to true. This makes
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc b/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
index a3177aec..ec940e15 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc
@@ -53,12 +53,13 @@
   else
     UseCounter::Count(context, WebFeature::kRTCSessionDescriptionInitNoSdp);
 
-  return new RTCSessionDescription(WebRTCSessionDescription(type, sdp));
+  return MakeGarbageCollected<RTCSessionDescription>(
+      WebRTCSessionDescription(type, sdp));
 }
 
 RTCSessionDescription* RTCSessionDescription::Create(
     WebRTCSessionDescription web_session_description) {
-  return new RTCSessionDescription(web_session_description);
+  return MakeGarbageCollected<RTCSessionDescription>(web_session_description);
 }
 
 RTCSessionDescription::RTCSessionDescription(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h b/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
index 96bb3fa..6e89b71 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h
@@ -50,6 +50,8 @@
                                        const RTCSessionDescriptionInit*);
   static RTCSessionDescription* Create(WebRTCSessionDescription);
 
+  explicit RTCSessionDescription(WebRTCSessionDescription);
+
   String type() const;
   void setType(const String&);
 
@@ -61,8 +63,6 @@
   WebRTCSessionDescription WebSessionDescription();
 
  private:
-  explicit RTCSessionDescription(WebRTCSessionDescription);
-
   WebRTCSessionDescription web_session_description_;
 };
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
index 99862de..e056b92 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
@@ -45,8 +45,8 @@
     RTCPeerConnection* requester,
     V8RTCSessionDescriptionCallback* success_callback,
     V8RTCPeerConnectionErrorCallback* error_callback) {
-  return new RTCSessionDescriptionRequestImpl(context, operation, requester,
-                                              success_callback, error_callback);
+  return MakeGarbageCollected<RTCSessionDescriptionRequestImpl>(
+      context, operation, requester, success_callback, error_callback);
 }
 
 RTCSessionDescriptionRequestImpl::RTCSessionDescriptionRequestImpl(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
index 5fe43b1d..142915a0 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h
@@ -59,6 +59,12 @@
       RTCPeerConnection*,
       V8RTCSessionDescriptionCallback*,
       V8RTCPeerConnectionErrorCallback*);
+
+  RTCSessionDescriptionRequestImpl(ExecutionContext*,
+                                   RTCCreateSessionDescriptionOperation,
+                                   RTCPeerConnection*,
+                                   V8RTCSessionDescriptionCallback*,
+                                   V8RTCPeerConnectionErrorCallback*);
   ~RTCSessionDescriptionRequestImpl() override;
 
   void RequestSucceeded(const WebRTCSessionDescription&) override;
@@ -70,12 +76,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCSessionDescriptionRequestImpl(ExecutionContext*,
-                                   RTCCreateSessionDescriptionOperation,
-                                   RTCPeerConnection*,
-                                   V8RTCSessionDescriptionCallback*,
-                                   V8RTCPeerConnectionErrorCallback*);
-
   void Clear();
 
   RTCCreateSessionDescriptionOperation operation_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
index 4d189e5..fd2bded 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
@@ -20,7 +20,7 @@
     ScriptPromiseResolver* resolver,
     const char* interface_name,
     const char* property_name) {
-  return new RTCSessionDescriptionRequestPromiseImpl(
+  return MakeGarbageCollected<RTCSessionDescriptionRequestPromiseImpl>(
       operation, requester, resolver, interface_name, property_name);
 }
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
index 45398426..00eb8f45 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h
@@ -27,6 +27,12 @@
       ScriptPromiseResolver*,
       const char* interface_name,
       const char* property_name);
+
+  RTCSessionDescriptionRequestPromiseImpl(RTCCreateSessionDescriptionOperation,
+                                          RTCPeerConnection*,
+                                          ScriptPromiseResolver*,
+                                          const char* interface_name,
+                                          const char* property_name);
   ~RTCSessionDescriptionRequestPromiseImpl() override;
 
   // RTCSessionDescriptionRequest
@@ -36,12 +42,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCSessionDescriptionRequestPromiseImpl(RTCCreateSessionDescriptionOperation,
-                                          RTCPeerConnection*,
-                                          ScriptPromiseResolver*,
-                                          const char* interface_name,
-                                          const char* property_name);
-
   void Clear();
 
   RTCCreateSessionDescriptionOperation operation_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
index 9ac3290..3bcc1ef5 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
@@ -33,7 +33,8 @@
                                                  RTCPeerConnection* requester,
                                                  V8RTCStatsCallback* callback,
                                                  MediaStreamTrack* selector) {
-  return new RTCStatsRequestImpl(context, requester, callback, selector);
+  return MakeGarbageCollected<RTCStatsRequestImpl>(context, requester, callback,
+                                                   selector);
 }
 
 RTCStatsRequestImpl::RTCStatsRequestImpl(ExecutionContext* context,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
index 8d1e8b6..31fb7cf 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h
@@ -47,6 +47,11 @@
                                      RTCPeerConnection*,
                                      V8RTCStatsCallback*,
                                      MediaStreamTrack*);
+
+  RTCStatsRequestImpl(ExecutionContext*,
+                      RTCPeerConnection*,
+                      V8RTCStatsCallback*,
+                      MediaStreamTrack*);
   ~RTCStatsRequestImpl() override;
 
   RTCStatsResponseBase* CreateResponse() override;
@@ -61,11 +66,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCStatsRequestImpl(ExecutionContext*,
-                      RTCPeerConnection*,
-                      V8RTCStatsCallback*,
-                      MediaStreamTrack*);
-
   void Clear();
 
   // This request object is held by WebRTCPeerConnectionHandler, which doesn't
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
index bea019f..f7f3f4e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc
@@ -27,7 +27,7 @@
 namespace blink {
 
 RTCStatsResponse* RTCStatsResponse::Create() {
-  return new RTCStatsResponse();
+  return MakeGarbageCollected<RTCStatsResponse>();
 }
 
 RTCStatsResponse::RTCStatsResponse() = default;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h b/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
index 28733466..b3b6d94 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h
@@ -41,6 +41,8 @@
  public:
   static RTCStatsResponse* Create();
 
+  RTCStatsResponse();
+
   const HeapVector<Member<RTCLegacyStatsReport>>& result() const {
     return result_;
   }
@@ -51,8 +53,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCStatsResponse();
-
   HeapVector<Member<RTCLegacyStatsReport>> result_;
   HashMap<String, int> idmap_;
 };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
index c886564..bc83ff16 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
@@ -14,7 +14,7 @@
 
 RTCTrackEvent* RTCTrackEvent::Create(const AtomicString& type,
                                      const RTCTrackEventInit* eventInitDict) {
-  return new RTCTrackEvent(type, eventInitDict);
+  return MakeGarbageCollected<RTCTrackEvent>(type, eventInitDict);
 }
 
 RTCTrackEvent::RTCTrackEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
index 56aa478..dedd3ce8 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h
@@ -29,6 +29,8 @@
                 MediaStreamTrack*,
                 const HeapVector<Member<MediaStream>>&,
                 RTCRtpTransceiver*);
+  RTCTrackEvent(const AtomicString& type,
+                const RTCTrackEventInit* eventInitDict);
 
   RTCRtpReceiver* receiver() const;
   MediaStreamTrack* track() const;
@@ -38,9 +40,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCTrackEvent(const AtomicString& type,
-                const RTCTrackEventInit* eventInitDict);
-
   Member<RTCRtpReceiver> receiver_;
   Member<MediaStreamTrack> track_;
   HeapVector<Member<MediaStream>> streams_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
index 8073a46..11c6c25 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc
@@ -42,8 +42,9 @@
     RTCPeerConnection* requester,
     V8VoidFunction* success_callback,
     V8RTCPeerConnectionErrorCallback* error_callback) {
-  return new RTCVoidRequestImpl(context, std::move(operation), requester,
-                                success_callback, error_callback);
+  return MakeGarbageCollected<RTCVoidRequestImpl>(context, std::move(operation),
+                                                  requester, success_callback,
+                                                  error_callback);
 }
 
 RTCVoidRequestImpl::RTCVoidRequestImpl(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
index b4480a0..113f7a14 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h
@@ -57,6 +57,12 @@
       RTCPeerConnection*,
       V8VoidFunction*,
       V8RTCPeerConnectionErrorCallback*);
+
+  RTCVoidRequestImpl(ExecutionContext*,
+                     base::Optional<RTCSetSessionDescriptionOperation>,
+                     RTCPeerConnection*,
+                     V8VoidFunction*,
+                     V8RTCPeerConnectionErrorCallback*);
   ~RTCVoidRequestImpl() override;
 
   // RTCVoidRequest
@@ -69,12 +75,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCVoidRequestImpl(ExecutionContext*,
-                     base::Optional<RTCSetSessionDescriptionOperation>,
-                     RTCPeerConnection*,
-                     V8VoidFunction*,
-                     V8RTCPeerConnectionErrorCallback*);
-
   void Clear();
 
   base::Optional<RTCSetSessionDescriptionOperation> operation_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
index 1ad1811..4e8dd213 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc
@@ -17,8 +17,8 @@
     ScriptPromiseResolver* resolver,
     const char* interface_name,
     const char* property_name) {
-  return new RTCVoidRequestPromiseImpl(std::move(operation), requester,
-                                       resolver, interface_name, property_name);
+  return MakeGarbageCollected<RTCVoidRequestPromiseImpl>(
+      std::move(operation), requester, resolver, interface_name, property_name);
 }
 
 RTCVoidRequestPromiseImpl::RTCVoidRequestPromiseImpl(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
index 4970a36..2757d437 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h
@@ -26,6 +26,12 @@
       ScriptPromiseResolver*,
       const char* interface_name,
       const char* property_name);
+
+  RTCVoidRequestPromiseImpl(base::Optional<RTCSetSessionDescriptionOperation>,
+                            RTCPeerConnection*,
+                            ScriptPromiseResolver*,
+                            const char* interface_name,
+                            const char* property_name);
   ~RTCVoidRequestPromiseImpl() override;
 
   // RTCVoidRequest
@@ -35,12 +41,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  RTCVoidRequestPromiseImpl(base::Optional<RTCSetSessionDescriptionOperation>,
-                            RTCPeerConnection*,
-                            ScriptPromiseResolver*,
-                            const char* interface_name,
-                            const char* property_name);
-
   void Clear();
 
   base::Optional<RTCSetSessionDescriptionOperation> operation_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
index 17fd6ec..43db1d2f 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc
@@ -14,8 +14,8 @@
 RTCVoidRequestScriptPromiseResolverImpl::Create(ScriptPromiseResolver* resolver,
                                                 const char* interface_name,
                                                 const char* property_name) {
-  return new RTCVoidRequestScriptPromiseResolverImpl(resolver, interface_name,
-                                                     property_name);
+  return MakeGarbageCollected<RTCVoidRequestScriptPromiseResolverImpl>(
+      resolver, interface_name, property_name);
 }
 
 RTCVoidRequestScriptPromiseResolverImpl::
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
index 73ecbe2..20d9d22 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h
@@ -18,6 +18,10 @@
       ScriptPromiseResolver*,
       const char* interface_name,
       const char* property_name);
+
+  RTCVoidRequestScriptPromiseResolverImpl(ScriptPromiseResolver*,
+                                          const char* interface_name,
+                                          const char* property_name);
   ~RTCVoidRequestScriptPromiseResolverImpl() override;
 
   // RTCVoidRequest
@@ -27,10 +31,6 @@
   void Trace(blink::Visitor*) override;
 
  protected:
-  RTCVoidRequestScriptPromiseResolverImpl(ScriptPromiseResolver*,
-                                          const char* interface_name,
-                                          const char* property_name);
-
   Member<ScriptPromiseResolver> resolver_;
   const char* interface_name_;
   const char* property_name_;
diff --git a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
index 479d7df..e2b8613 100644
--- a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
@@ -24,7 +24,7 @@
     std::unique_ptr<WebRTCStatsReport> report) {
   DCHECK(
       ExecutionContext::From(resolver_->GetScriptState())->IsContextThread());
-  resolver_->Resolve(new RTCStatsReport(std::move(report)));
+  resolver_->Resolve(MakeGarbageCollected<RTCStatsReport>(std::move(report)));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/permissions/navigator_permissions.cc b/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
index f54b436..e477dc3b 100644
--- a/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
@@ -29,7 +29,7 @@
 Permissions* NavigatorPermissions::permissions(Navigator& navigator) {
   NavigatorPermissions& self = NavigatorPermissions::From(navigator);
   if (!self.permissions_)
-    self.permissions_ = new Permissions();
+    self.permissions_ = MakeGarbageCollected<Permissions>();
   return self.permissions_.Get();
 }
 
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.cc b/third_party/blink/renderer/modules/permissions/permission_status.cc
index 36d78015..5e83c7f6 100644
--- a/third_party/blink/renderer/modules/permissions/permission_status.cc
+++ b/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -26,8 +26,8 @@
     ExecutionContext* execution_context,
     MojoPermissionStatus status,
     MojoPermissionDescriptor descriptor) {
-  PermissionStatus* permission_status =
-      new PermissionStatus(execution_context, status, std::move(descriptor));
+  PermissionStatus* permission_status = MakeGarbageCollected<PermissionStatus>(
+      execution_context, status, std::move(descriptor));
   permission_status->PauseIfNeeded();
   permission_status->StartListening();
   return permission_status;
diff --git a/third_party/blink/renderer/modules/permissions/permission_status.h b/third_party/blink/renderer/modules/permissions/permission_status.h
index 56ee2c8..797286c2 100644
--- a/third_party/blink/renderer/modules/permissions/permission_status.h
+++ b/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -40,6 +40,10 @@
   static PermissionStatus* CreateAndListen(ExecutionContext*,
                                            MojoPermissionStatus,
                                            MojoPermissionDescriptor);
+
+  PermissionStatus(ExecutionContext*,
+                   MojoPermissionStatus,
+                   MojoPermissionDescriptor);
   ~PermissionStatus() override;
   void Dispose();
 
@@ -62,10 +66,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PermissionStatus(ExecutionContext*,
-                   MojoPermissionStatus,
-                   MojoPermissionDescriptor);
-
   void StartListening();
   void StopListening();
 
diff --git a/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc b/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
index 4d107eb9..db143ca 100644
--- a/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc
@@ -34,7 +34,7 @@
   WorkerNavigatorPermissions& self =
       WorkerNavigatorPermissions::From(worker_navigator);
   if (!self.permissions_)
-    self.permissions_ = new Permissions();
+    self.permissions_ = MakeGarbageCollected<Permissions>();
   return self.permissions_;
 }
 
diff --git a/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc b/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
index 022abe8c..cfd09a8 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
 #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
index bce1706..b6a8505 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_control.h"
 #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
 #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
index 2102054e..fdf447f 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h"
 #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
@@ -22,7 +23,7 @@
 // static
 PictureInPictureControllerImpl* PictureInPictureControllerImpl::Create(
     Document& document) {
-  return new PictureInPictureControllerImpl(document);
+  return MakeGarbageCollected<PictureInPictureControllerImpl>(document);
 }
 
 // static
@@ -121,7 +122,7 @@
   if (picture_in_picture_window_)
     picture_in_picture_window_->OnClose();
 
-  picture_in_picture_window_ = new PictureInPictureWindow(
+  picture_in_picture_window_ = MakeGarbageCollected<PictureInPictureWindow>(
       GetSupplementable(), picture_in_picture_window_size);
 
   picture_in_picture_element_->DispatchEvent(
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
index af5d4b7..1c5c2f3 100644
--- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
+++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
@@ -27,6 +27,7 @@
   WTF_MAKE_NONCOPYABLE(PictureInPictureControllerImpl);
 
  public:
+  explicit PictureInPictureControllerImpl(Document&);
   ~PictureInPictureControllerImpl() override;
 
   // Meant to be called internally by PictureInPictureController::From()
@@ -68,8 +69,6 @@
   void OnExitedPictureInPicture(ScriptPromiseResolver*) override;
   void OnPictureInPictureControlClicked(const WebString& control_id) override;
 
-  explicit PictureInPictureControllerImpl(Document&);
-
   // The Picture-in-Picture element for the associated document.
   Member<HTMLVideoElement> picture_in_picture_element_;
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation.cc b/third_party/blink/renderer/modules/presentation/presentation.cc
index 4e7b5db1..385e1de 100644
--- a/third_party/blink/renderer/modules/presentation/presentation.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation.cc
@@ -20,7 +20,7 @@
 // static
 Presentation* Presentation::Create(LocalFrame* frame) {
   DCHECK(frame);
-  Presentation* presentation = new Presentation(frame);
+  Presentation* presentation = MakeGarbageCollected<Presentation>(frame);
   PresentationController* controller = PresentationController::From(*frame);
   DCHECK(controller);
   controller->SetPresentation(presentation);
@@ -59,7 +59,7 @@
   }
 
   if (!receiver_)
-    receiver_ = new PresentationReceiver(GetFrame());
+    receiver_ = MakeGarbageCollected<PresentationReceiver>(GetFrame());
 
   return receiver_;
 }
diff --git a/third_party/blink/renderer/modules/presentation/presentation.h b/third_party/blink/renderer/modules/presentation/presentation.h
index b29256c..8948c2c4 100644
--- a/third_party/blink/renderer/modules/presentation/presentation.h
+++ b/third_party/blink/renderer/modules/presentation/presentation.h
@@ -27,6 +27,8 @@
  public:
   static Presentation* Create(LocalFrame*);
 
+  explicit Presentation(LocalFrame*);
+
   void Trace(blink::Visitor*) override;
 
   PresentationRequest* defaultRequest() const;
@@ -35,8 +37,6 @@
   PresentationReceiver* receiver();
 
  private:
-  explicit Presentation(LocalFrame*);
-
   // Default PresentationRequest used by the embedder.
   Member<PresentationRequest> default_request_;
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability.cc b/third_party/blink/renderer/modules/presentation/presentation_availability.cc
index f6f23a4..f4510ba9 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability.cc
@@ -23,8 +23,8 @@
     const WTF::Vector<KURL>& urls,
     bool value) {
   PresentationAvailability* presentation_availability =
-      new PresentationAvailability(resolver->GetExecutionContext(), urls,
-                                   value);
+      MakeGarbageCollected<PresentationAvailability>(
+          resolver->GetExecutionContext(), urls, value);
   presentation_availability->PauseIfNeeded();
   presentation_availability->UpdateListening();
   return presentation_availability;
diff --git a/third_party/blink/renderer/modules/presentation/presentation_availability.h b/third_party/blink/renderer/modules/presentation/presentation_availability.h
index 496a74b..bbef7b4 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_availability.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_availability.h
@@ -38,6 +38,8 @@
   static PresentationAvailability* Take(PresentationAvailabilityProperty*,
                                         const WTF::Vector<KURL>&,
                                         bool);
+
+  PresentationAvailability(ExecutionContext*, const WTF::Vector<KURL>&, bool);
   ~PresentationAvailability() override;
 
   // EventTarget implementation.
@@ -81,8 +83,6 @@
     kInactive,
   };
 
-  PresentationAvailability(ExecutionContext*, const WTF::Vector<KURL>&, bool);
-
   void SetState(State);
   void UpdateListening();
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
index b0a9d67..0c3875d 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/modules/presentation/presentation_receiver.h"
 #include "third_party/blink/renderer/modules/presentation/presentation_request.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
 namespace blink {
@@ -303,9 +304,9 @@
   DCHECK(receiver);
 
   ReceiverPresentationConnection* connection =
-      new ReceiverPresentationConnection(*receiver->GetFrame(), receiver,
-                                         presentation_info.id,
-                                         presentation_info.url);
+      MakeGarbageCollected<ReceiverPresentationConnection>(
+          *receiver->GetFrame(), receiver, presentation_info.id,
+          presentation_info.url);
   connection->Init(std::move(controller_connection),
                    std::move(receiver_connection_request));
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h b/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
index c24c93f..af32dc8 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h
@@ -20,17 +20,24 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  PresentationConnectionAvailableEvent(const AtomicString& event_type,
+                                       PresentationConnection*);
+  PresentationConnectionAvailableEvent(
+      const AtomicString& event_type,
+      const PresentationConnectionAvailableEventInit* initializer);
   ~PresentationConnectionAvailableEvent() override;
 
   static PresentationConnectionAvailableEvent* Create(
       const AtomicString& event_type,
       PresentationConnection* connection) {
-    return new PresentationConnectionAvailableEvent(event_type, connection);
+    return MakeGarbageCollected<PresentationConnectionAvailableEvent>(
+        event_type, connection);
   }
   static PresentationConnectionAvailableEvent* Create(
       const AtomicString& event_type,
       const PresentationConnectionAvailableEventInit* initializer) {
-    return new PresentationConnectionAvailableEvent(event_type, initializer);
+    return MakeGarbageCollected<PresentationConnectionAvailableEvent>(
+        event_type, initializer);
   }
 
   PresentationConnection* connection() { return connection_.Get(); }
@@ -40,12 +47,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PresentationConnectionAvailableEvent(const AtomicString& event_type,
-                                       PresentationConnection*);
-  PresentationConnectionAvailableEvent(
-      const AtomicString& event_type,
-      const PresentationConnectionAvailableEventInit* initializer);
-
   Member<PresentationConnection> connection_;
 };
 
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h b/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
index 744d7f7..e719dd6 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h
@@ -19,19 +19,27 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  PresentationConnectionCloseEvent(const AtomicString& event_type,
+                                   const String& reason,
+                                   const String& message);
+  PresentationConnectionCloseEvent(
+      const AtomicString& event_type,
+      const PresentationConnectionCloseEventInit* initializer);
   ~PresentationConnectionCloseEvent() override = default;
 
   static PresentationConnectionCloseEvent* Create(
       const AtomicString& event_type,
       const String& reason,
       const String& message) {
-    return new PresentationConnectionCloseEvent(event_type, reason, message);
+    return MakeGarbageCollected<PresentationConnectionCloseEvent>(
+        event_type, reason, message);
   }
 
   static PresentationConnectionCloseEvent* Create(
       const AtomicString& event_type,
       const PresentationConnectionCloseEventInit* initializer) {
-    return new PresentationConnectionCloseEvent(event_type, initializer);
+    return MakeGarbageCollected<PresentationConnectionCloseEvent>(event_type,
+                                                                  initializer);
   }
 
   const String& reason() const { return reason_; }
@@ -42,13 +50,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  PresentationConnectionCloseEvent(const AtomicString& event_type,
-                                   const String& reason,
-                                   const String& message);
-  PresentationConnectionCloseEvent(
-      const AtomicString& event_type,
-      const PresentationConnectionCloseEventInit* initializer);
-
   String reason_;
   String message_;
 };
diff --git a/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
index 9ec4337..3e97d54 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -35,7 +35,8 @@
 
 // static
 void PresentationController::ProvideTo(LocalFrame& frame) {
-  Supplement<LocalFrame>::ProvideTo(frame, new PresentationController(frame));
+  Supplement<LocalFrame>::ProvideTo(
+      frame, MakeGarbageCollected<PresentationController>(frame));
 }
 
 // static
diff --git a/third_party/blink/renderer/modules/presentation/presentation_controller.h b/third_party/blink/renderer/modules/presentation/presentation_controller.h
index f514ac0..2d7a4b0 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_controller.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_controller.h
@@ -38,6 +38,7 @@
  public:
   static const char kSupplementName[];
 
+  PresentationController(LocalFrame&);
   ~PresentationController() override;
 
   static PresentationController* From(LocalFrame&);
@@ -77,9 +78,6 @@
   virtual void AddAvailabilityObserver(PresentationAvailabilityObserver*);
   virtual void RemoveAvailabilityObserver(PresentationAvailabilityObserver*);
 
- protected:
-  PresentationController(LocalFrame&);
-
  private:
   // Implementation of ContextLifecycleObserver.
   void ContextDestroyed(ExecutionContext*) override;
diff --git a/third_party/blink/renderer/modules/presentation/presentation_receiver.cc b/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
index cfbe7e85..4a0d6af 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
@@ -25,7 +25,8 @@
 
 PresentationReceiver::PresentationReceiver(LocalFrame* frame)
     : ContextLifecycleObserver(frame->GetDocument()),
-      connection_list_(new PresentationConnectionList(frame->GetDocument())),
+      connection_list_(MakeGarbageCollected<PresentationConnectionList>(
+          frame->GetDocument())),
       receiver_binding_(this) {
   auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider();
   interface_provider->GetInterface(mojo::MakeRequest(&presentation_service_));
diff --git a/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc b/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
index 069f151..e09a512 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
@@ -79,7 +79,8 @@
 
 TEST_F(PresentationReceiverTest, NoConnectionUnresolvedConnectionList) {
   V8TestingScope scope;
-  auto* receiver = new PresentationReceiver(&scope.GetFrame());
+  auto* receiver =
+      MakeGarbageCollected<PresentationReceiver>(&scope.GetFrame());
 
   auto* event_handler =
       new StrictMock<MockEventListenerForPresentationReceiver>();
@@ -95,7 +96,8 @@
 
 TEST_F(PresentationReceiverTest, OneConnectionResolvedConnectionListNoEvent) {
   V8TestingScope scope;
-  auto* receiver = new PresentationReceiver(&scope.GetFrame());
+  auto* receiver =
+      MakeGarbageCollected<PresentationReceiver>(&scope.GetFrame());
 
   auto* event_handler =
       new StrictMock<MockEventListenerForPresentationReceiver>();
@@ -116,7 +118,8 @@
 
 TEST_F(PresentationReceiverTest, TwoConnectionsFireOnconnectionavailableEvent) {
   V8TestingScope scope;
-  auto* receiver = new PresentationReceiver(&scope.GetFrame());
+  auto* receiver =
+      MakeGarbageCollected<PresentationReceiver>(&scope.GetFrame());
 
   StrictMock<MockEventListenerForPresentationReceiver>* event_handler =
       new StrictMock<MockEventListenerForPresentationReceiver>();
@@ -147,7 +150,8 @@
 
 TEST_F(PresentationReceiverTest, TwoConnectionsNoEvent) {
   V8TestingScope scope;
-  auto* receiver = new PresentationReceiver(&scope.GetFrame());
+  auto* receiver =
+      MakeGarbageCollected<PresentationReceiver>(&scope.GetFrame());
 
   StrictMock<MockEventListenerForPresentationReceiver>* event_handler =
       new StrictMock<MockEventListenerForPresentationReceiver>();
diff --git a/third_party/blink/renderer/modules/presentation/presentation_request.cc b/third_party/blink/renderer/modules/presentation/presentation_request.cc
index c7c6e1f4..3258500b 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_request.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_request.cc
@@ -95,7 +95,8 @@
     return nullptr;
   }
 
-  return new PresentationRequest(execution_context, parsed_urls);
+  return MakeGarbageCollected<PresentationRequest>(execution_context,
+                                                   parsed_urls);
 }
 
 const AtomicString& PresentationRequest::InterfaceName() const {
diff --git a/third_party/blink/renderer/modules/presentation/presentation_request.h b/third_party/blink/renderer/modules/presentation/presentation_request.h
index 25405c7..65d59f6 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_request.h
+++ b/third_party/blink/renderer/modules/presentation/presentation_request.h
@@ -28,6 +28,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  PresentationRequest(ExecutionContext*, const Vector<KURL>&);
   ~PresentationRequest() override = default;
 
   static PresentationRequest* Create(ExecutionContext*,
@@ -60,8 +61,6 @@
                           RegisteredEventListener&) override;
 
  private:
-  PresentationRequest(ExecutionContext*, const Vector<KURL>&);
-
   Member<PresentationAvailabilityProperty> availability_property_;
   Vector<KURL> urls_;
 };
diff --git a/third_party/blink/renderer/modules/push_messaging/push_controller.cc b/third_party/blink/renderer/modules/push_messaging/push_controller.cc
index c460c4f..7af810a 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_controller.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_controller.cc
@@ -23,7 +23,8 @@
 const char PushController::kSupplementName[] = "PushController";
 
 void ProvidePushControllerTo(LocalFrame& frame, WebPushClient* client) {
-  PushController::ProvideTo(frame, new PushController(frame, client));
+  PushController::ProvideTo(
+      frame, MakeGarbageCollected<PushController>(frame, client));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/push_messaging/push_event.h b/third_party/blink/renderer/modules/push_messaging/push_event.h
index 37459ebf..296a1db 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_event.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_event.h
@@ -24,13 +24,17 @@
   static PushEvent* Create(const AtomicString& type,
                            PushMessageData* data,
                            WaitUntilObserver* observer) {
-    return new PushEvent(type, data, observer);
+    return MakeGarbageCollected<PushEvent>(type, data, observer);
   }
   static PushEvent* Create(const AtomicString& type,
                            const PushEventInit* initializer) {
-    return new PushEvent(type, initializer);
+    return MakeGarbageCollected<PushEvent>(type, initializer);
   }
 
+  PushEvent(const AtomicString& type,
+            PushMessageData* data,
+            WaitUntilObserver* observer);
+  PushEvent(const AtomicString& type, const PushEventInit* initializer);
   ~PushEvent() override;
 
   // ExtendableEvent interface.
@@ -41,11 +45,6 @@
   void Trace(blink::Visitor* visitor) override;
 
  private:
-  PushEvent(const AtomicString& type,
-            PushMessageData* data,
-            WaitUntilObserver* observer);
-  PushEvent(const AtomicString& type, const PushEventInit* initializer);
-
   Member<PushMessageData> data_;
 };
 
diff --git a/third_party/blink/renderer/modules/push_messaging/push_manager.h b/third_party/blink/renderer/modules/push_messaging/push_manager.h
index 9bebc0a3..5e60a64 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_manager.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_manager.h
@@ -22,9 +22,11 @@
 
  public:
   static PushManager* Create(ServiceWorkerRegistration* registration) {
-    return new PushManager(registration);
+    return MakeGarbageCollected<PushManager>(registration);
   }
 
+  explicit PushManager(ServiceWorkerRegistration* registration);
+
   // Web-exposed property:
   static Vector<String> supportedContentEncodings();
 
@@ -40,8 +42,6 @@
   void Trace(blink::Visitor* visitor) override;
 
  private:
-  explicit PushManager(ServiceWorkerRegistration* registration);
-
   Member<ServiceWorkerRegistration> registration_;
 };
 
diff --git a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
index 6282e7a..69220f1c 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
@@ -37,14 +37,15 @@
             ? message_data.GetAsArrayBufferView().View()->buffer()
             : message_data.GetAsArrayBuffer();
 
-    return new PushMessageData(static_cast<const char*>(buffer->Data()),
-                               buffer->ByteLength());
+    return MakeGarbageCollected<PushMessageData>(
+        static_cast<const char*>(buffer->Data()), buffer->ByteLength());
   }
 
   if (message_data.IsUSVString()) {
     CString encoded_string = UTF8Encoding().Encode(
         message_data.GetAsUSVString(), WTF::kNoUnencodables);
-    return new PushMessageData(encoded_string.data(), encoded_string.length());
+    return MakeGarbageCollected<PushMessageData>(encoded_string.data(),
+                                                 encoded_string.length());
   }
 
   DCHECK(message_data.IsNull());
diff --git a/third_party/blink/renderer/modules/push_messaging/push_message_data.h b/third_party/blink/renderer/modules/push_messaging/push_message_data.h
index 3288be3d..1185601 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_message_data.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_message_data.h
@@ -28,6 +28,7 @@
   static PushMessageData* Create(
       const ArrayBufferOrArrayBufferViewOrUSVString& data);
 
+  PushMessageData(const char* data, unsigned bytes_size);
   ~PushMessageData() override;
 
   DOMArrayBuffer* arrayBuffer() const;
@@ -37,8 +38,6 @@
   String text() const;
 
  private:
-  PushMessageData(const char* data, unsigned bytes_size);
-
   Vector<char> data_;
 };
 
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
index 70c9325..57dbbcb8 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc
@@ -45,7 +45,8 @@
           service_worker_registration);
 
   if (!bridge) {
-    bridge = new PushMessagingBridge(*service_worker_registration);
+    bridge =
+        MakeGarbageCollected<PushMessagingBridge>(*service_worker_registration);
     Supplement<ServiceWorkerRegistration>::ProvideTo(
         *service_worker_registration, bridge);
   }
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
index 58f13a2..e508221 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
@@ -33,6 +33,7 @@
 
   static PushMessagingBridge* From(ServiceWorkerRegistration* registration);
 
+  explicit PushMessagingBridge(ServiceWorkerRegistration& registration);
   virtual ~PushMessagingBridge();
 
   // Asynchronously determines the permission state for the current origin.
@@ -40,8 +41,6 @@
                                    const PushSubscriptionOptionsInit* options);
 
  private:
-  explicit PushMessagingBridge(ServiceWorkerRegistration& registration);
-
   // Method to be invoked when the permission status has been retrieved from the
   // permission service. Will settle the given |resolver|.
   void DidGetPermissionState(ScriptPromiseResolver* resolver,
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
index 660a4023..4d677717 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
@@ -52,7 +52,8 @@
     ServiceWorkerRegistration* service_worker_registration) {
   if (!push_subscription)
     return nullptr;
-  return new PushSubscription(*push_subscription, service_worker_registration);
+  return MakeGarbageCollected<PushSubscription>(*push_subscription,
+                                                service_worker_registration);
 }
 
 void PushSubscription::Dispose(WebPushSubscription* push_subscription) {
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription.h b/third_party/blink/renderer/modules/push_messaging/push_subscription.h
index f6c00ac..0fbed77 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription.h
@@ -35,6 +35,8 @@
       ServiceWorkerRegistration* service_worker_registration);
   static void Dispose(WebPushSubscription* subscription_raw);
 
+  PushSubscription(const WebPushSubscription& subscription,
+                   ServiceWorkerRegistration* service_worker_registration);
   ~PushSubscription() override;
 
   KURL endpoint() const { return endpoint_; }
@@ -53,9 +55,6 @@
   FRIEND_TEST_ALL_PREFIXES(PushSubscriptionTest,
                            SerializesToBase64URLWithoutPadding);
 
-  PushSubscription(const WebPushSubscription& subscription,
-                   ServiceWorkerRegistration* service_worker_registration);
-
   KURL endpoint_;
 
   Member<PushSubscriptionOptions> options_;
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
index 824b415..baca043 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h
@@ -28,9 +28,11 @@
 
   static PushSubscriptionOptions* Create(
       const WebPushSubscriptionOptions& options) {
-    return new PushSubscriptionOptions(options);
+    return MakeGarbageCollected<PushSubscriptionOptions>(options);
   }
 
+  explicit PushSubscriptionOptions(const WebPushSubscriptionOptions& options);
+
   bool userVisibleOnly() const { return user_visible_only_; }
 
   // Mutable by web developer. See https://github.com/w3c/push-api/issues/198.
@@ -41,8 +43,6 @@
   void Trace(blink::Visitor* visitor) override;
 
  private:
-  explicit PushSubscriptionOptions(const WebPushSubscriptionOptions& options);
-
   bool user_visible_only_;
   Member<DOMArrayBuffer> application_server_key_;
 };
diff --git a/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc b/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
index 9be70c87..f2f784b 100644
--- a/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
+++ b/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc
@@ -46,6 +46,7 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
index 49deb38..bc20e505 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -73,7 +73,7 @@
 
 // static
 RemotePlayback* RemotePlayback::Create(HTMLMediaElement& element) {
-  return new RemotePlayback(element);
+  return MakeGarbageCollected<RemotePlayback>(element);
 }
 
 RemotePlayback::RemotePlayback(HTMLMediaElement& element)
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
index a820634..bed56ca 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -57,6 +57,8 @@
 
   static RemotePlayback* Create(HTMLMediaElement&);
 
+  explicit RemotePlayback(HTMLMediaElement&);
+
   // Notifies this object that disableRemotePlayback attribute was set on the
   // corresponding media element.
   void RemotePlaybackDisabled();
@@ -135,8 +137,6 @@
   friend class RemotePlaybackTest;
   friend class MediaControlsImplTest;
 
-  explicit RemotePlayback(HTMLMediaElement&);
-
   // Calls the specified availability callback with the current availability.
   // Need a void() method to post it as a task.
   void NotifyInitialAvailability(int callback_id);
diff --git a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
index 391732c..ef206c04 100644
--- a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
+++ b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc
@@ -12,8 +12,8 @@
     ExecutionContext* execution_context,
     const SpatialSensorOptions* options,
     ExceptionState& exception_state) {
-  return new RelativeOrientationSensor(execution_context, options,
-                                       exception_state);
+  return MakeGarbageCollected<RelativeOrientationSensor>(
+      execution_context, options, exception_state);
 }
 
 // static
diff --git a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
index a4507715..fca41a4 100644
--- a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
+++ b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h
@@ -19,12 +19,11 @@
                                            ExceptionState&);
   static RelativeOrientationSensor* Create(ExecutionContext*, ExceptionState&);
 
-  void Trace(blink::Visitor*) override;
-
- private:
   RelativeOrientationSensor(ExecutionContext*,
                             const SpatialSensorOptions*,
                             ExceptionState&);
+
+  void Trace(blink::Visitor*) override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.h b/third_party/blink/renderer/modules/shapedetection/shape_detector.h
index c752ac2..7b7e2cd 100644
--- a/third_party/blink/renderer/modules/shapedetection/shape_detector.h
+++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.h
@@ -8,7 +8,7 @@
 #include "skia/public/interfaces/bitmap.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h"
+#include "third_party/blink/renderer/core/frame/window_or_worker_global_scope.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.cc b/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.cc
index c0feb20..5d9830ec 100644
--- a/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.cc
+++ b/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.cc
@@ -35,7 +35,7 @@
     PlatformSpeechSynthesizerClient* client,
     ExecutionContext* context) {
   PlatformSpeechSynthesizerMock* synthesizer =
-      new PlatformSpeechSynthesizerMock(client, context);
+      MakeGarbageCollected<PlatformSpeechSynthesizerMock>(client, context);
   synthesizer->InitializeVoiceList();
   client->VoicesDidChange();
   return synthesizer;
diff --git a/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.h b/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.h
index 3c690abe..bfd6ff74 100644
--- a/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.h
+++ b/third_party/blink/renderer/modules/speech/testing/platform_speech_synthesizer_mock.h
@@ -38,7 +38,10 @@
   static PlatformSpeechSynthesizerMock* Create(PlatformSpeechSynthesizerClient*,
                                                ExecutionContext*);
 
+  explicit PlatformSpeechSynthesizerMock(PlatformSpeechSynthesizerClient*,
+                                         ExecutionContext*);
   ~PlatformSpeechSynthesizerMock() override;
+
   void Speak(PlatformSpeechSynthesisUtterance*) override;
   void Pause() override;
   void Resume() override;
@@ -47,9 +50,6 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  explicit PlatformSpeechSynthesizerMock(PlatformSpeechSynthesizerClient*,
-                                         ExecutionContext*);
-
   void InitializeVoiceList() override;
 
   void SpeakNext();
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
index 0aa8c97..055cb2b5 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.cc b/third_party/blink/renderer/modules/webaudio/panner_node.cc
index ab8be73..3eca10b 100644
--- a/third_party/blink/renderer/modules/webaudio/panner_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -714,7 +714,7 @@
     return nullptr;
   }
 
-  return new PannerNode(context);
+  return MakeGarbageCollected<PannerNode>(context);
 }
 
 PannerNode* PannerNode::Create(BaseAudioContext* context,
diff --git a/third_party/blink/renderer/modules/webaudio/panner_node.h b/third_party/blink/renderer/modules/webaudio/panner_node.h
index 3ea7ba71..775241fb 100644
--- a/third_party/blink/renderer/modules/webaudio/panner_node.h
+++ b/third_party/blink/renderer/modules/webaudio/panner_node.h
@@ -214,6 +214,8 @@
                             ExceptionState&);
   PannerHandler& GetPannerHandler() const;
 
+  PannerNode(BaseAudioContext&);
+
   void Trace(blink::Visitor*) override;
 
   // Uses a 3D cartesian coordinate system
@@ -245,8 +247,6 @@
   void setConeOuterGain(double, ExceptionState&);
 
  private:
-  PannerNode(BaseAudioContext&);
-
   Member<AudioParam> position_x_;
   Member<AudioParam> position_y_;
   Member<AudioParam> position_z_;
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
index 79217399..d99e2f78 100644
--- a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
+++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
@@ -72,7 +72,8 @@
     return nullptr;
   }
 
-  PeriodicWave* periodic_wave = new PeriodicWave(context.sampleRate());
+  PeriodicWave* periodic_wave =
+      MakeGarbageCollected<PeriodicWave>(context.sampleRate());
   periodic_wave->CreateBandLimitedTables(real.data(), imag.data(), real.size(),
                                          disable_normalization);
   return periodic_wave;
@@ -108,25 +109,25 @@
 }
 
 PeriodicWave* PeriodicWave::CreateSine(float sample_rate) {
-  PeriodicWave* periodic_wave = new PeriodicWave(sample_rate);
+  PeriodicWave* periodic_wave = MakeGarbageCollected<PeriodicWave>(sample_rate);
   periodic_wave->GenerateBasicWaveform(OscillatorHandler::SINE);
   return periodic_wave;
 }
 
 PeriodicWave* PeriodicWave::CreateSquare(float sample_rate) {
-  PeriodicWave* periodic_wave = new PeriodicWave(sample_rate);
+  PeriodicWave* periodic_wave = MakeGarbageCollected<PeriodicWave>(sample_rate);
   periodic_wave->GenerateBasicWaveform(OscillatorHandler::SQUARE);
   return periodic_wave;
 }
 
 PeriodicWave* PeriodicWave::CreateSawtooth(float sample_rate) {
-  PeriodicWave* periodic_wave = new PeriodicWave(sample_rate);
+  PeriodicWave* periodic_wave = MakeGarbageCollected<PeriodicWave>(sample_rate);
   periodic_wave->GenerateBasicWaveform(OscillatorHandler::SAWTOOTH);
   return periodic_wave;
 }
 
 PeriodicWave* PeriodicWave::CreateTriangle(float sample_rate) {
-  PeriodicWave* periodic_wave = new PeriodicWave(sample_rate);
+  PeriodicWave* periodic_wave = MakeGarbageCollected<PeriodicWave>(sample_rate);
   periodic_wave->GenerateBasicWaveform(OscillatorHandler::TRIANGLE);
   return periodic_wave;
 }
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.h b/third_party/blink/renderer/modules/webaudio/periodic_wave.h
index 16ae6e615..685213f 100644
--- a/third_party/blink/renderer/modules/webaudio/periodic_wave.h
+++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.h
@@ -64,6 +64,7 @@
                               const PeriodicWaveOptions*,
                               ExceptionState&);
 
+  explicit PeriodicWave(float sample_rate);
   ~PeriodicWave() override;
 
   // Returns pointers to the lower and higher wave data for the pitch range
@@ -90,8 +91,6 @@
   unsigned NumberOfRanges() const { return number_of_ranges_; }
 
  private:
-  explicit PeriodicWave(float sample_rate);
-
   void GenerateBasicWaveform(int);
 
   size_t v8_external_memory_;
diff --git a/third_party/blink/renderer/modules/webdatabase/database_tracker.cc b/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
index a6d1208..99bdad21 100644
--- a/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
+++ b/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/modules/webdatabase/quota_tracker.h"
 #include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 6484c83..f73275e 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -102,6 +102,7 @@
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/third_party/blink/renderer/modules/webmidi/midi_port.cc b/third_party/blink/renderer/modules/webmidi/midi_port.cc
index 776eaa6..f271681 100644
--- a/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/frame/use_counter.h"
 #include "third_party/blink/renderer/modules/webmidi/midi_access.h"
 #include "third_party/blink/renderer/modules/webmidi/midi_connection_event.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 using midi::mojom::PortState;
 
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index 18b0ea8..68dc041a 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -62,6 +62,7 @@
 #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc
index e35180d..95500107a 100644
--- a/third_party/blink/renderer/modules/xr/xr.cc
+++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -15,6 +15,8 @@
 #include "third_party/blink/renderer/modules/event_modules.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
 #include "third_party/blink/renderer/modules/xr/xr_device.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
 namespace blink {
 
 namespace {
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.cc b/third_party/blink/renderer/platform/audio/audio_destination.cc
index 629a474..6f99b282 100644
--- a/third_party/blink/renderer/platform/audio/audio_destination.cc
+++ b/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -40,7 +40,7 @@
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc b/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
index 51b93a03..faac2ca 100644
--- a/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
+++ b/third_party/blink/renderer/platform/audio/hrtf_database_loader.cc
@@ -31,8 +31,8 @@
 #include "base/location.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
index 049cc6b..e96a3aa 100644
--- a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
+++ b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
@@ -9,12 +9,12 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/audio/audio_utilities.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/audio/reverb_convolver.cc b/third_party/blink/renderer/platform/audio/reverb_convolver.cc
index 9389e03..64ae945 100644
--- a/third_party/blink/renderer/platform/audio/reverb_convolver.cc
+++ b/third_party/blink/renderer/platform/audio/reverb_convolver.cc
@@ -36,8 +36,8 @@
 #include "third_party/blink/renderer/platform/audio/audio_bus.h"
 #include "third_party/blink/renderer/platform/audio/vector_math.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.cc b/third_party/blink/renderer/platform/bindings/parkable_string.cc
index 258a459..f2189c0 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string.cc
+++ b/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -16,8 +16,8 @@
 #include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/address_sanitizer.h"
 #include "third_party/blink/renderer/platform/wtf/thread_specific.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
index 843a120..32e89b0 100644
--- a/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
+++ b/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
@@ -10,8 +10,8 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/blob/blob_data.cc b/third_party/blink/renderer/platform/blob/blob_data.cc
index 57889d8d..2abdefe 100644
--- a/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -48,7 +48,6 @@
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/text/line_ending.h"
 #include "third_party/blink/renderer/platform/uuid.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/text/cstring.h"
 #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc
index 19a61d5..5e03ba6e 100644
--- a/third_party/blink/renderer/platform/exported/platform.cc
+++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -64,8 +64,8 @@
 #include "third_party/blink/renderer/platform/memory_coordinator.h"
 #include "third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h"
 #include "third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/webrtc/api/rtpparameters.h"
 #include "third_party/webrtc/p2p/base/portallocator.h"
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
index 3e43c9d..3214da58 100644
--- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -13,7 +13,7 @@
 #include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/gpu/GrTexture.h"
 
diff --git a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
index 4f633fe..5fb4c57 100644
--- a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
@@ -11,9 +11,9 @@
 #include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h"
 #include "third_party/blink/renderer/platform/graphics/main_thread_mutator_client.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
index ed6279a..1e185d0 100644
--- a/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc
@@ -8,7 +8,6 @@
 #include "third_party/blink/public/platform/interface_provider.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
index f77ac15..d66820e9 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
@@ -20,8 +20,8 @@
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
index d6dd9d1c..fd85381 100644
--- a/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
+++ b/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
@@ -39,9 +39,9 @@
 #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
 #include "third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkPixmap.h"
 #include "third_party/skia/include/core/SkSurface.h"
diff --git a/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc b/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc
index 6686196..b7172f9 100644
--- a/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc
+++ b/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc
@@ -19,7 +19,7 @@
 
 PaintFilterEffect* PaintFilterEffect::Create(Filter* filter,
                                              const PaintFlags& flags) {
-  return new PaintFilterEffect(filter, flags);
+  return MakeGarbageCollected<PaintFilterEffect>(filter, flags);
 }
 
 sk_sp<PaintFilter> PaintFilterEffect::CreateImageFilter() {
diff --git a/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h b/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h
index 599f5cc1..5150316 100644
--- a/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h
+++ b/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h
@@ -13,6 +13,8 @@
 class PLATFORM_EXPORT PaintFilterEffect : public FilterEffect {
  public:
   static PaintFilterEffect* Create(Filter*, const PaintFlags&);
+
+  PaintFilterEffect(Filter*, const PaintFlags&);
   ~PaintFilterEffect() override;
 
   FilterEffectType GetFilterEffectType() const override {
@@ -24,8 +26,6 @@
   sk_sp<PaintFilter> CreateImageFilter() override;
 
  private:
-  PaintFilterEffect(Filter*, const PaintFlags&);
-
   PaintFlags flags_;
 };
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
index 087e15b..4ef2065b 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.cc
@@ -11,9 +11,9 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/waitable_event.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
index 4c2c741..ba59633 100644
--- a/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
+++ b/third_party/blink/renderer/platform/graphics/image_frame_generator_test.cc
@@ -33,10 +33,10 @@
 #include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
 #include "third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h"
 #include "third_party/blink/renderer/platform/image-decoders/segment_reader.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc b/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc
index 64a283c..76a59a71 100644
--- a/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc
+++ b/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc
@@ -9,7 +9,7 @@
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/skia/include/gpu/GrContext.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
index bb5b343..b618d59c 100644
--- a/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
+++ b/third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.cc
@@ -8,7 +8,7 @@
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/wtf.h"
 
diff --git a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
index 582151f..bb8b1e7e 100644
--- a/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
@@ -10,8 +10,8 @@
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
 #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/skia/include/core/SkImage.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index e9ecfc58..d2f5032 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -49,9 +49,9 @@
 #include "third_party/blink/renderer/platform/heap/stack_frame_depth.h"
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/heap/visitor.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
index 7e5c651..7f5e4200 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.h
@@ -70,7 +70,7 @@
   static RawResource* CreateForTest(ResourceRequest request,
                                     ResourceType type) {
     ResourceLoaderOptions options;
-    return new RawResource(request, type, options);
+    return MakeGarbageCollected<RawResource>(request, type, options);
   }
   static RawResource* CreateForTest(const KURL& url,
                                     scoped_refptr<const SecurityOrigin> origin,
@@ -80,6 +80,10 @@
     return CreateForTest(request, type);
   }
 
+  RawResource(const ResourceRequest&,
+              ResourceType,
+              const ResourceLoaderOptions&);
+
   // Resource implementation
   MatchStatus CanReuse(const FetchParameters&) const override;
   bool WillFollowRedirect(const ResourceRequest&,
@@ -114,14 +118,10 @@
 
     Resource* Create(const ResourceRequest& request,
                      const ResourceLoaderOptions& options) const override {
-      return new RawResource(request, type_, options);
+      return MakeGarbageCollected<RawResource>(request, type_, options);
     }
   };
 
-  RawResource(const ResourceRequest&,
-              ResourceType,
-              const ResourceLoaderOptions&);
-
   // Resource implementation
   void DidAddClient(ResourceClient*) override;
   void AppendData(const char*, size_t) override;
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
index ccebb11..a28d04a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
@@ -210,7 +210,7 @@
 
   Persistent<DummyClient> dummy_client = MakeGarbageCollected<DummyClient>();
   Persistent<RemovingClient> removing_client =
-      new RemovingClient(dummy_client.Get());
+      MakeGarbageCollected<RemovingClient>(dummy_client.Get());
   raw->AddClient(dummy_client, platform_->test_task_runner().get());
   raw->AddClient(removing_client, platform_->test_task_runner().get());
   platform_->RunUntilIdle();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h
index 68a0df0..3847b60c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -45,9 +45,9 @@
 #include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
 #include "third_party/blink/renderer/platform/memory_coordinator.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "third_party/blink/renderer/platform/timer.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
index 1bb482a3..86b3758 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -75,8 +75,10 @@
 
  public:
   static ResourceFetcher* Create(FetchContext* context) {
-    return new ResourceFetcher(context);
+    return MakeGarbageCollected<ResourceFetcher>(context);
   }
+
+  ResourceFetcher(FetchContext*);
   virtual ~ResourceFetcher();
   virtual void Trace(blink::Visitor*);
 
@@ -197,8 +199,6 @@
     kIncludingKeepaliveLoaders,
   };
 
-  ResourceFetcher(FetchContext*);
-
   void InitializeRevalidation(ResourceRequest&, Resource*);
   // When |security_origin| of the ResourceLoaderOptions is not a nullptr, it'll
   // be used instead of the associated FetchContext's SecurityOrigin.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index e0c0fb08..783d74e 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -362,7 +362,8 @@
   request1.SetHTTPHeaderField(http_names::kCacheControl, "no-cache");
   FetchParameters fetch_params1(request1);
   Persistent<RequestSameResourceOnComplete> client =
-      new RequestSameResourceOnComplete(fetch_params1, fetcher1);
+      MakeGarbageCollected<RequestSameResourceOnComplete>(fetch_params1,
+                                                          fetcher1);
   platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
   EXPECT_TRUE(client->NotifyFinishedCalled());
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
index 9f67274..a9e198f 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -374,7 +374,7 @@
 }
 
 ResourceLoadScheduler* ResourceLoadScheduler::Create(FetchContext* context) {
-  return new ResourceLoadScheduler(
+  return MakeGarbageCollected<ResourceLoadScheduler>(
       context
           ? context
           : &FetchContext::NullInstance(Thread::Current()->GetTaskRunner()));
@@ -430,7 +430,8 @@
          ThrottleOption::kThrottleable == option);
   pending_requests_[option].insert(request_info);
   pending_request_map_.insert(
-      *id, new ClientInfo(client, option, priority, intra_priority));
+      *id, MakeGarbageCollected<ClientInfo>(client, option, priority,
+                                            intra_priority));
 
   // Remember the ClientId since MaybeRun() below may destruct the caller
   // instance and |id| may be inaccessible after the call.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
index b159141..7f327a2 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h
@@ -148,6 +148,8 @@
       std::numeric_limits<size_t>::max();
 
   static ResourceLoadScheduler* Create(FetchContext* = nullptr);
+
+  ResourceLoadScheduler(FetchContext*);
   ~ResourceLoadScheduler() override;
 
   void Trace(blink::Visitor*);
@@ -252,8 +254,6 @@
   bool IsClientDelayable(const ClientIdWithPriority& info,
                          ThrottleOption option) const;
 
-  ResourceLoadScheduler(FetchContext*);
-
   // Generates the next ClientId.
   ClientId GenerateClientId();
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index b07bb4f..5ff1ba1b 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -292,8 +292,8 @@
                                        ResourceLoadScheduler* scheduler,
                                        Resource* resource,
                                        uint32_t inflight_keepalive_bytes) {
-  return new ResourceLoader(fetcher, scheduler, resource,
-                            inflight_keepalive_bytes);
+  return MakeGarbageCollected<ResourceLoader>(fetcher, scheduler, resource,
+                                              inflight_keepalive_bytes);
 }
 
 ResourceLoader::ResourceLoader(ResourceFetcher* fetcher,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
index d509ab9..2cc7f9c 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -68,6 +68,12 @@
                                 ResourceLoadScheduler*,
                                 Resource*,
                                 uint32_t inflight_keepalive_bytes = 0);
+
+  // Assumes ResourceFetcher and Resource are non-null.
+  ResourceLoader(ResourceFetcher*,
+                 ResourceLoadScheduler*,
+                 Resource*,
+                 uint32_t inflight_keepalive_bytes);
   ~ResourceLoader() override;
   void Trace(blink::Visitor*) override;
 
@@ -149,12 +155,6 @@
   friend class SubresourceIntegrityTest;
   class CodeCacheRequest;
 
-  // Assumes ResourceFetcher and Resource are non-null.
-  ResourceLoader(ResourceFetcher*,
-                 ResourceLoadScheduler*,
-                 Resource*,
-                 uint32_t inflight_keepalive_bytes);
-
   bool ShouldFetchCodeCache();
   void StartWith(const ResourceRequest&);
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
index 9d5f60e..d97d53a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_response_test.cc
@@ -7,9 +7,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/memory_coordinator.cc b/third_party/blink/renderer/platform/memory_coordinator.cc
index 7905068..a65474a 100644
--- a/third_party/blink/renderer/platform/memory_coordinator.cc
+++ b/third_party/blink/renderer/platform/memory_coordinator.cc
@@ -12,8 +12,8 @@
 #include "third_party/blink/renderer/platform/fonts/font_global_context.h"
 #include "third_party/blink/renderer/platform/graphics/image_decoding_store.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
 
 #if defined(OS_ANDROID)
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.cc b/third_party/blink/renderer/platform/network/network_state_notifier.cc
index d9f41fa..769ce62 100644
--- a/third_party/blink/renderer/platform/network/network_state_notifier.cc
+++ b/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -30,7 +30,7 @@
 #include "net/nqe/network_quality_estimator_params.h"
 #include "third_party/blink/public/common/client_hints/client_hints.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h b/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
index b5eecfd..7de4760 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h
@@ -13,17 +13,18 @@
     : public GarbageCollected<RTCAnswerOptionsPlatform> {
  public:
   static RTCAnswerOptionsPlatform* Create(bool voice_activity_detection) {
-    return new RTCAnswerOptionsPlatform(voice_activity_detection);
+    return MakeGarbageCollected<RTCAnswerOptionsPlatform>(
+        voice_activity_detection);
   }
 
+  explicit RTCAnswerOptionsPlatform(bool voice_activity_detection)
+      : voice_activity_detection_(voice_activity_detection) {}
+
   bool VoiceActivityDetection() const { return voice_activity_detection_; }
 
   void Trace(blink::Visitor* visitor) {}
 
  private:
-  explicit RTCAnswerOptionsPlatform(bool voice_activity_detection)
-      : voice_activity_detection_(voice_activity_detection) {}
-
   bool voice_activity_detection_;
 };
 
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h b/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
index 16971566..0ee6920 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h
@@ -16,19 +16,11 @@
                                          int32_t offer_to_receive_audio,
                                          bool voice_activity_detection,
                                          bool ice_restart) {
-    return new RTCOfferOptionsPlatform(offer_to_receive_video,
-                                       offer_to_receive_audio,
-                                       voice_activity_detection, ice_restart);
+    return MakeGarbageCollected<RTCOfferOptionsPlatform>(
+        offer_to_receive_video, offer_to_receive_audio,
+        voice_activity_detection, ice_restart);
   }
 
-  int32_t OfferToReceiveVideo() const { return offer_to_receive_video_; }
-  int32_t OfferToReceiveAudio() const { return offer_to_receive_audio_; }
-  bool VoiceActivityDetection() const { return voice_activity_detection_; }
-  bool IceRestart() const { return ice_restart_; }
-
-  void Trace(blink::Visitor* visitor) {}
-
- private:
   RTCOfferOptionsPlatform(int32_t offer_to_receive_video,
                           int32_t offer_to_receive_audio,
                           bool voice_activity_detection,
@@ -38,6 +30,14 @@
         voice_activity_detection_(voice_activity_detection),
         ice_restart_(ice_restart) {}
 
+  int32_t OfferToReceiveVideo() const { return offer_to_receive_video_; }
+  int32_t OfferToReceiveAudio() const { return offer_to_receive_audio_; }
+  bool VoiceActivityDetection() const { return voice_activity_detection_; }
+  bool IceRestart() const { return ice_restart_; }
+
+  void Trace(blink::Visitor* visitor) {}
+
+ private:
   int32_t offer_to_receive_video_;
   int32_t offer_to_receive_audio_;
   bool voice_activity_detection_;
diff --git a/third_party/blink/renderer/platform/plugins/plugin_data.cc b/third_party/blink/renderer/platform/plugins/plugin_data.cc
index 9cf65405..29721cb 100644
--- a/third_party/blink/renderer/platform/plugins/plugin_data.cc
+++ b/third_party/blink/renderer/platform/plugins/plugin_data.cc
@@ -101,9 +101,9 @@
   Vector<mojom::blink::PluginInfoPtr> plugins;
   registry->GetPlugins(false, main_frame_origin_, &plugins);
   for (const auto& plugin : plugins) {
-    auto* plugin_info =
-        new PluginInfo(plugin->name, FilePathToWebString(plugin->filename),
-                       plugin->description, plugin->background_color);
+    auto* plugin_info = MakeGarbageCollected<PluginInfo>(
+        plugin->name, FilePathToWebString(plugin->filename),
+        plugin->description, plugin->background_color);
     plugins_.push_back(plugin_info);
     for (const auto& mime : plugin->mime_types) {
       auto* mime_info = MakeGarbageCollected<MimeClassInfo>(
diff --git a/third_party/blink/renderer/platform/plugins/plugin_data.h b/third_party/blink/renderer/platform/plugins/plugin_data.h
index fc395cb..bb48e3956 100644
--- a/third_party/blink/renderer/platform/plugins/plugin_data.h
+++ b/third_party/blink/renderer/platform/plugins/plugin_data.h
@@ -96,7 +96,9 @@
  public:
   void Trace(blink::Visitor*);
 
-  static PluginData* Create() { return new PluginData(); }
+  static PluginData* Create() { return MakeGarbageCollected<PluginData>(); }
+
+  PluginData() = default;
 
   const HeapVector<Member<PluginInfo>>& Plugins() const { return plugins_; }
   const HeapVector<Member<MimeClassInfo>>& Mimes() const { return mimes_; }
@@ -112,8 +114,6 @@
   static void RefreshBrowserSidePluginCache();
 
  private:
-  PluginData() = default;
-
   HeapVector<Member<PluginInfo>> plugins_;
   HeapVector<Member<MimeClassInfo>> mimes_;
   scoped_refptr<const SecurityOrigin> main_frame_origin_;
diff --git a/third_party/blink/renderer/platform/prerender.h b/third_party/blink/renderer/platform/prerender.h
index 0c7f509..5f0f7fdd 100644
--- a/third_party/blink/renderer/platform/prerender.h
+++ b/third_party/blink/renderer/platform/prerender.h
@@ -59,9 +59,10 @@
                            const KURL& url,
                            unsigned rel_types,
                            const Referrer& referrer) {
-    return new Prerender(client, url, rel_types, referrer);
+    return MakeGarbageCollected<Prerender>(client, url, rel_types, referrer);
   }
 
+  Prerender(PrerenderClient*, const KURL&, unsigned rel_types, const Referrer&);
   ~Prerender();
   void Trace(blink::Visitor*);
 
@@ -89,8 +90,6 @@
   void DidSendDOMContentLoadedForPrerender();
 
  private:
-  Prerender(PrerenderClient*, const KURL&, unsigned rel_types, const Referrer&);
-
   // The embedder's prerendering support holds on to pending Prerender objects;
   // those references should not keep the PrerenderClient alive -- if the client
   // becomes otherwise unreachable it should be GCed (at which point it will
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread.cc b/third_party/blink/renderer/platform/scheduler/common/thread.cc
index a0aa1664..0c92352c 100644
--- a/third_party/blink/renderer/platform/scheduler/common/thread.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/thread.cc
@@ -9,10 +9,10 @@
 #include "build/build_config.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/assertions.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/thread_specific.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
index b420bee161..cf19a89 100644
--- a/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
@@ -18,16 +18,21 @@
 // static
 std::unique_ptr<WebThreadScheduler>
 WebThreadScheduler::CreateMainThreadScheduler(
+    std::unique_ptr<base::MessagePump> message_pump,
     base::Optional<base::Time> initial_virtual_time) {
   // Ensure categories appear as an option in chrome://tracing.
   WarmupTracingCategories();
   // Workers might be short-lived, so placing warmup here.
   TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("worker.scheduler"));
-
+  auto sequence_manager =
+      message_pump
+          ? base::sequence_manager::
+                CreateSequenceManagerOnCurrentThreadWithPump(
+                    base::MessageLoop::TYPE_DEFAULT, std::move(message_pump))
+          : base::sequence_manager::CreateSequenceManagerOnCurrentThread();
   std::unique_ptr<MainThreadSchedulerImpl> scheduler(
-      new MainThreadSchedulerImpl(
-          base::sequence_manager::CreateSequenceManagerOnCurrentThread(),
-          initial_virtual_time));
+      new MainThreadSchedulerImpl(std::move(sequence_manager),
+                                  initial_virtual_time));
   return std::move(scheduler);
 }
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index d00eeb9e..c8f6eeb 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -24,7 +24,6 @@
 #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/resource_loading_task_runner_handle_impl.h"
 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 using base::sequence_manager::TaskQueue;
 using testing::UnorderedElementsAre;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
index 547e4b6..0862bdf 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
@@ -10,8 +10,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 
 using testing::_;
 using testing::AnyOf;
diff --git a/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc b/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc
index 0ab189b4..defd1e33 100644
--- a/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc
+++ b/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc
@@ -29,7 +29,7 @@
 
 PlatformSpeechSynthesisUtterance* PlatformSpeechSynthesisUtterance::Create(
     PlatformSpeechSynthesisUtteranceClient* client) {
-  return new PlatformSpeechSynthesisUtterance(client);
+  return MakeGarbageCollected<PlatformSpeechSynthesisUtterance>(client);
 }
 
 PlatformSpeechSynthesisUtterance::PlatformSpeechSynthesisUtterance(
diff --git a/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h b/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h
index 60fee9f1..69ec13bf 100644
--- a/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h
+++ b/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h
@@ -48,6 +48,9 @@
   static PlatformSpeechSynthesisUtterance* Create(
       PlatformSpeechSynthesisUtteranceClient*);
 
+  explicit PlatformSpeechSynthesisUtterance(
+      PlatformSpeechSynthesisUtteranceClient*);
+
   const String& GetText() const { return text_; }
   void SetText(const String& text) { text_ = text; }
 
@@ -77,9 +80,6 @@
   void Trace(blink::Visitor*);
 
  private:
-  explicit PlatformSpeechSynthesisUtterance(
-      PlatformSpeechSynthesisUtteranceClient*);
-
   Member<PlatformSpeechSynthesisUtteranceClient> client_;
   String text_;
   String lang_;
diff --git a/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.cc b/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.cc
index 3a06d21..630cb12b 100644
--- a/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.cc
+++ b/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.cc
@@ -38,7 +38,7 @@
 PlatformSpeechSynthesizer* PlatformSpeechSynthesizer::Create(
     PlatformSpeechSynthesizerClient* client) {
   PlatformSpeechSynthesizer* synthesizer =
-      new PlatformSpeechSynthesizer(client);
+      MakeGarbageCollected<PlatformSpeechSynthesizer>(client);
 #if defined(OS_ANDROID)
 // On Android devices we don't fetch voices until the object
 // is touched to avoid needlessly binding to TTS service, see
diff --git a/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.h b/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.h
index 355aa48..f15bc8ea 100644
--- a/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.h
+++ b/third_party/blink/renderer/platform/speech/platform_speech_synthesizer.h
@@ -64,6 +64,7 @@
  public:
   static PlatformSpeechSynthesizer* Create(PlatformSpeechSynthesizerClient*);
 
+  explicit PlatformSpeechSynthesizer(PlatformSpeechSynthesizerClient*);
   virtual ~PlatformSpeechSynthesizer();
 
   virtual void Speak(PlatformSpeechSynthesisUtterance*);
@@ -93,8 +94,6 @@
   virtual void Trace(blink::Visitor*);
 
  protected:
-  explicit PlatformSpeechSynthesizer(PlatformSpeechSynthesizerClient*);
-
   virtual void InitializeVoiceList();
 
   Vector<scoped_refptr<PlatformSpeechSynthesisVoice>> voice_list_;
diff --git a/third_party/blink/renderer/platform/web_thread_supporting_gc.h b/third_party/blink/renderer/platform/web_thread_supporting_gc.h
index 03731ef..d31e43d 100644
--- a/third_party/blink/renderer/platform/web_thread_supporting_gc.h
+++ b/third_party/blink/renderer/platform/web_thread_supporting_gc.h
@@ -9,8 +9,8 @@
 #include "base/threading/thread_checker.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/heap/gc_task_runner.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/web_task_runner.h"
 #include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/noncopyable.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index 842d261..8ddad89 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -287,7 +287,6 @@
 crbug.com/591099 fast/forms/textarea/basic-textareas-quirks.html [ Failure ]
 crbug.com/889721 fast/inline/continuation-outlines-with-layers.html [ Failure ]
 crbug.com/889721 fast/inline/continuation-outlines.html [ Failure ]
-crbug.com/835484 fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
 crbug.com/889721 fast/inline/outline-continuations.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-update-transform.html [ Failure ]
 crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure Pass ]
@@ -317,11 +316,7 @@
 crbug.com/591099 media/controls/buttons-after-reset.html [ Failure Pass ]
 crbug.com/591099 media/controls/lazy-loaded-style.html [ Failure ]
 crbug.com/591099 paint/float/float-under-inline-self-painting-change.html [ Failure ]
-crbug.com/835484 paint/inline/focus-ring-under-absolute-with-relative-continuation.html [ Failure ]
-crbug.com/591099 paint/invalidation/clip/clip-with-layout-delta.html [ Failure ]
 crbug.com/591099 paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Failure ]
-crbug.com/591099 paint/invalidation/crbug-371640-4.html [ Failure ]
-crbug.com/591099 paint/invalidation/crbug-371640.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-change-keeping-geometry.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change-keeping-geometry-grid.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-self-change-keeping-geometry.html [ Failure ]
@@ -329,10 +324,7 @@
 crbug.com/591099 paint/invalidation/flexbox/justify-self-change-keeping-geometry.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/repaint-on-margin-change.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/scrollbars-changed.html [ Failure ]
-crbug.com/889721 paint/invalidation/outline/focus-continuations.html [ Failure ]
-crbug.com/835484 paint/invalidation/outline/focus-enable-continuations.html [ Failure ]
 crbug.com/591099 paint/invalidation/outline/focus-ring-on-child-move.html [ Failure ]
-crbug.com/889721 paint/invalidation/outline/focus-ring-on-continuation-move.html [ Failure ]
 crbug.com/835484 paint/invalidation/outline/inline-focus.html [ Failure ]
 crbug.com/591099 paint/invalidation/outline/outline-change-invalidation.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/opacity-change-on-overflow-float.html [ Failure ]
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations
index 05a3b7e6..4a617848 100644
--- a/third_party/blink/web_tests/MSANExpectations
+++ b/third_party/blink/web_tests/MSANExpectations
@@ -115,7 +115,7 @@
 
 crbug.com/856601 [ Linux ] fast/css/visited-link-hang.html [ Pass Timeout ]
 crbug.com/856601 [ Linux ] http/tests/devtools/elements/styles-4/styles-inline-element-style-changes-should-not-force-style-recalc.js [ Pass Timeout ]
-crbug.com/856601 [ Linux ] http/tests/event-timing/event-timing-retrievability.html [ Pass Timeout ]
+crbug.com/856601 [ Linux ] external/wpt/event-timing/event-timing-retrievability.html [ Pass Timeout ]
 
 # Slow idlharness.js tests on MSAN
 crbug.com/856601 [ Linux ] external/wpt/BackgroundSync/interfaces.https.any.html [ Timeout Pass ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index 07d5871..db8bc3b 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -904,13 +904,13 @@
 crbug.com/874695 http/tests/devtools/tracing/decode-resize.js [ Slow ]
 crbug.com/874695 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Slow ]
 crbug.com/874695 http/tests/devtools/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.js [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-bufferbeforeonload.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-crossiframe.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-observethenonload.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-onloadthenobserve-firstInput.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-onloadthenobserve.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-retrievability.html [ Slow ]
-crbug.com/874695 http/tests/event-timing/event-timing-timingconditions.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-bufferbeforeonload.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-crossiframe.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-observethenonload.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-onloadthenobserve-firstInput.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-onloadthenobserve.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-retrievability.html [ Slow ]
+crbug.com/874695 external/wpt/event-timing/event-timing-timingconditions.html [ Slow ]
 crbug.com/874695 http/tests/fetch/serviceworker/body-mixin-base-https-other-https.html [ Slow ]
 crbug.com/874695 http/tests/fetch/serviceworker-proxied/thorough/access-control-base-https-other-https.html [ Slow ]
 crbug.com/874695 http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index eec021d..7bd7573 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2783,8 +2783,8 @@
 crbug.com/763830 virtual/outofblink-cors/http/tests/security/cors-rfc1918/ [ Skip ]
 crbug.com/763830 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/ [ Skip ]
 
-crbug.com/831729 http/tests/event-timing/event-timing-crossiframe.html [ Timeout ]
-crbug.com/831729 http/tests/event-timing/event-timing-observer-manual.html [ Skip ]
+crbug.com/831729 external/wpt/event-timing/event-timing-crossiframe.html [ Timeout ]
+crbug.com/831729 external/wpt/event-timing/event-timing-observer-manual.html [ Skip ]
 
 # Working on getting the CSP tests going:
 crbug.com/694525 external/wpt/content-security-policy/connect-src/worker-from-guid.sub.html [ Skip ]
@@ -2998,6 +2998,7 @@
 crbug.com/893480 external/wpt/infrastructure/testdriver/actions/multiDevice.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac10.13 ] external/wpt/preload/dynamic-adding-preload-imagesrcset.tentative.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-text/text-transform/text-transform-capitalize-033.html [ Failure ]
 crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/content-type/response.window.html [ Timeout ]
 crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/fetch/content-type/response.window.html [ Timeout ]
diff --git a/third_party/blink/web_tests/editing/assert_selection.js b/third_party/blink/web_tests/editing/assert_selection.js
index 639d88f5c..9dd24e1 100644
--- a/third_party/blink/web_tests/editing/assert_selection.js
+++ b/third_party/blink/web_tests/editing/assert_selection.js
@@ -61,7 +61,7 @@
 };
 
 // border-size of IFRAME which hosts sample HTML. This value comes from
-// "core/css/html.css".
+// "core/html/resources/html.css".
 const kIFrameBorderSize = 2;
 
 /** @const @type {string} */
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index c8606f0..8ab9701 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -104993,6 +104993,18 @@
      {}
     ]
    ],
+   "svg/shapes/reftests/disabled-shapes-01.svg": [
+    [
+     "/svg/shapes/reftests/disabled-shapes-01.svg",
+     [
+      [
+       "/svg/shapes/reftests/support/empty.svg",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "svg/shapes/reftests/pathlength-001.svg": [
     [
      "/svg/shapes/reftests/pathlength-001.svg",
@@ -151615,41 +151627,11 @@
      {}
     ]
    ],
-   "custom-elements/adopted-callback-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/attribute-changed-callback-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/connected-callbacks-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/connected-callbacks-html-fragment-parsing-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/custom-element-reaction-queue-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/custom-element-registry/per-global-expected.txt": [
     [
      {}
     ]
    ],
-   "custom-elements/disconnected-callbacks-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/historical-expected.txt": [
     [
      {}
@@ -151660,11 +151642,6 @@
      {}
     ]
    ],
-   "custom-elements/parser/parser-sets-attributes-and-children-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt": [
     [
      {}
@@ -151675,137 +151652,17 @@
      {}
     ]
    ],
-   "custom-elements/reactions/Attr-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/CSSStyleDeclaration-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/ChildNode-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/DOMStringMap-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/DOMTokenList-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/Document-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/Element-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/ElementContentEditable-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLAnchorElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/reactions/HTMLButtonElement-expected.txt": [
     [
      {}
     ]
    ],
-   "custom-elements/reactions/HTMLElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLOptionElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLOptionsCollection-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLOutputElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLSelectElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLTableElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLTableRowElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLTableSectionElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLTitleElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/NamedNodeMap-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/Node-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/ParentNode-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/Range-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/Selection-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/ShadowRoot-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/reactions/resources/reactions.js": [
     [
      {}
     ]
    ],
-   "custom-elements/reactions/with-exceptions-expected.txt": [
+   "custom-elements/resources/custom-elements-helpers.js": [
     [
      {}
     ]
@@ -151825,16 +151682,6 @@
      {}
     ]
    ],
-   "custom-elements/upgrading-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/upgrading/Document-importNode-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "device-memory/META.yml": [
     [
      {}
@@ -176725,11 +176572,6 @@
      {}
     ]
    ],
-   "resources/custom-elements-helpers.js": [
-    [
-     {}
-    ]
-   ],
    "resources/idlharness.js": [
     [
      {}
@@ -181130,6 +180972,11 @@
      {}
     ]
    ],
+   "svg/shapes/reftests/support/empty.svg": [
+    [
+     {}
+    ]
+   ],
    "svg/struct/UnknownElement/interface-expected.txt": [
     [
      {}
@@ -243120,6 +242967,18 @@
      {}
     ]
    ],
+   "media-capabilities/decodingInfoEncryptedMedia.http.html": [
+    [
+     "/media-capabilities/decodingInfoEncryptedMedia.http.html",
+     {}
+    ]
+   ],
+   "media-capabilities/decodingInfoEncryptedMedia.https.html": [
+    [
+     "/media-capabilities/decodingInfoEncryptedMedia.https.html",
+     {}
+    ]
+   ],
    "media-capabilities/encodingInfo.html": [
     [
      "/media-capabilities/encodingInfo.html",
@@ -272680,6 +272539,12 @@
      {}
     ]
    ],
+   "svg/shapes/scripted/disabled-shapes-not-hit.svg": [
+    [
+     "/svg/shapes/scripted/disabled-shapes-not-hit.svg",
+     {}
+    ]
+   ],
    "svg/struct/UnknownElement/interface.svg": [
     [
      "/svg/struct/UnknownElement/interface.svg",
@@ -379873,18 +379738,10 @@
    "e1d5315930d173980cff522fdedcc81e8b48fcb7",
    "support"
   ],
-  "custom-elements/adopted-callback-expected.txt": [
-   "45341e7b05674efebcbdef26c424319f011b657f",
-   "support"
-  ],
   "custom-elements/adopted-callback.html": [
    "5c08a04a4210d7f8bc3d752fa3e4db220aa26118",
    "testharness"
   ],
-  "custom-elements/attribute-changed-callback-expected.txt": [
-   "6d5a37c503afd4bc0333e4ed9c8b128761d602ba",
-   "support"
-  ],
   "custom-elements/attribute-changed-callback.html": [
    "5090bfbfbfecdfbfbfb7c52579824cd333c93cdc",
    "testharness"
@@ -379893,14 +379750,6 @@
    "e3001a2c4855e9c10afaf46cdd2fe60fcd2a1cd3",
    "testharness"
   ],
-  "custom-elements/connected-callbacks-expected.txt": [
-   "c2a78e67c99588a247df8d89a8cd37a82d903ccb",
-   "support"
-  ],
-  "custom-elements/connected-callbacks-html-fragment-parsing-expected.txt": [
-   "1ea67d2d951d5a4df31db494caecd685e489a47e",
-   "support"
-  ],
   "custom-elements/connected-callbacks-html-fragment-parsing.html": [
    "f24cc209c893ff0e6f69fd19651e0bad66419cd1",
    "testharness"
@@ -379909,10 +379758,6 @@
    "d6e68262a850a9a952877264fdf64594e8025375",
    "testharness"
   ],
-  "custom-elements/custom-element-reaction-queue-expected.txt": [
-   "e1d0f496b5d6cf0f128f4425197f58885d176d9c",
-   "support"
-  ],
   "custom-elements/custom-element-reaction-queue.html": [
    "737dab117d3bd8d296ca6235d04e7664e35740c0",
    "testharness"
@@ -379933,10 +379778,6 @@
    "e020d95a576852b8a95c1f72a6061571efb6a4af",
    "testharness"
   ],
-  "custom-elements/disconnected-callbacks-expected.txt": [
-   "bd7b81c7b41e2ed6995a316bc33d6104803ff56e",
-   "support"
-  ],
   "custom-elements/disconnected-callbacks.html": [
    "7f5a4d0f8e76d495acfdedfe172ef5acfdac75b4",
    "testharness"
@@ -379950,7 +379791,7 @@
    "testharness"
   ],
   "custom-elements/htmlconstructor/newtarget-expected.txt": [
-   "dca4aab2592fd53d08f9de3cec1e6641cca44f56",
+   "46c1cf2b39b28fdcaa93518c225142276651d423",
    "support"
   ],
   "custom-elements/htmlconstructor/newtarget.html": [
@@ -379985,10 +379826,6 @@
    "82e970f1ae810f54a3d37c5c5b142143422bda11",
    "testharness"
   ],
-  "custom-elements/parser/parser-sets-attributes-and-children-expected.txt": [
-   "af50412f1e8909461e393cedbd8f1e099547dd5d",
-   "support"
-  ],
   "custom-elements/parser/parser-sets-attributes-and-children.html": [
    "987bf8525fb4a950f41ffa73d3952a1c78db5cdf",
    "testharness"
@@ -380002,7 +379839,7 @@
    "testharness"
   ],
   "custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt": [
-   "0b792e639777adc2ab33eb1758160c30fd00ef0d",
+   "35cb638573fad9e71ff37c427f5a38a54853a88c",
    "support"
   ],
   "custom-elements/parser/parser-uses-registry-of-owner-document.html": [
@@ -380029,90 +379866,50 @@
    "9e5bafbedfec42d28eb94c95ed84396941bc61ac",
    "testharness"
   ],
-  "custom-elements/reactions/Attr-expected.txt": [
-   "601e1a251433b8dcb81851cfa5dcb090c81e22c2",
-   "support"
-  ],
   "custom-elements/reactions/Attr.html": [
    "c9fa37f961159fffc19e8fdbe72df8b5686681a2",
    "testharness"
   ],
-  "custom-elements/reactions/CSSStyleDeclaration-expected.txt": [
-   "53b676c79e467c76146139c6e45ace9f92e89ce2",
-   "support"
-  ],
   "custom-elements/reactions/CSSStyleDeclaration.html": [
    "95274d8c75749e8c3b215407dccc81270d02f67b",
    "testharness"
   ],
-  "custom-elements/reactions/ChildNode-expected.txt": [
-   "0e78d755d494fb46faaa21f419f7cfe59f7cef55",
-   "support"
-  ],
   "custom-elements/reactions/ChildNode.html": [
    "f808b67a80a93703951424a6c08beeab1f4b5dfc",
    "testharness"
   ],
-  "custom-elements/reactions/DOMStringMap-expected.txt": [
-   "d2c4180eced092e297fe0fe6ab45d7b353537769",
-   "support"
-  ],
   "custom-elements/reactions/DOMStringMap.html": [
    "5e34dfe2ba11c73275e0659f8671e02f88f9c2dd",
    "testharness"
   ],
-  "custom-elements/reactions/DOMTokenList-expected.txt": [
-   "3f7106805a58b718987cf8dcb44388dc5bcde43f",
-   "support"
-  ],
   "custom-elements/reactions/DOMTokenList.html": [
    "14a643c4a87455866e752873319cd43a4bc419cd",
    "testharness"
   ],
-  "custom-elements/reactions/Document-expected.txt": [
-   "000c261e84e3c714afa3b4671d809be4f7860931",
-   "support"
-  ],
   "custom-elements/reactions/Document.html": [
    "721ad1f4ced84b8c81291fe92fa402e7b6384358",
    "testharness"
   ],
-  "custom-elements/reactions/Element-expected.txt": [
-   "5e3a72016d92caccdabc4cfea6aa89bce1203ca7",
-   "support"
-  ],
   "custom-elements/reactions/Element.html": [
    "8370724061ad193e71574596efa68c916e55535c",
    "testharness"
   ],
-  "custom-elements/reactions/ElementContentEditable-expected.txt": [
-   "33e03d9e4119aca2522ebe4ccb43d48453cf6d4b",
-   "support"
-  ],
   "custom-elements/reactions/ElementContentEditable.html": [
    "bdb10761cb8dd900f430c0d618cb914b3805a550",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLAnchorElement-expected.txt": [
-   "715e2b1e03ca53ffe51279e46d8c485b31cc70a3",
-   "support"
-  ],
   "custom-elements/reactions/HTMLAnchorElement.html": [
    "c6eeb1dce90b2a3ffe099cba80e64d71f2741f81",
    "testharness"
   ],
   "custom-elements/reactions/HTMLButtonElement-expected.txt": [
-   "f1de8330029fd7afc25ffa5eac30451e113a236f",
+   "1d0816469b1003108878242c3ed121953786d244",
    "support"
   ],
   "custom-elements/reactions/HTMLButtonElement.html": [
    "90390108b42155b2e5fcd5984d3a43a3ad1f9f6b",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLElement-expected.txt": [
-   "3445b7d68c1963c0e1d0c6e4fc938090f5ea7fe3",
-   "support"
-  ],
   "custom-elements/reactions/HTMLElement.html": [
    "5fe422cdfc1df56d58e4eeac1be4669ba8fee967",
    "testharness"
@@ -380121,114 +379918,58 @@
    "dc4b22a22eea3ea841b1380e7db3e75e7f4eb256",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLOptionElement-expected.txt": [
-   "a554192d302a25f6b374b629a1415f515281544c",
-   "support"
-  ],
   "custom-elements/reactions/HTMLOptionElement.html": [
    "418ef282b32fd5e7c29f21a0a9eb17b6c4796167",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLOptionsCollection-expected.txt": [
-   "ab1725734e76dbda2961afd5e733961c139796dc",
-   "support"
-  ],
   "custom-elements/reactions/HTMLOptionsCollection.html": [
    "0d64259d063182d4bb52ca6b4073d443af9ca1cf",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLOutputElement-expected.txt": [
-   "a6cf394dcf716e6dc965cec3f53993dc04e686f5",
-   "support"
-  ],
   "custom-elements/reactions/HTMLOutputElement.html": [
    "02e669bc7a75558686dd56b4ab8fc5918892de2e",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLSelectElement-expected.txt": [
-   "2e24913f9d9d011d2e3a003b643a1f38699ad6c6",
-   "support"
-  ],
   "custom-elements/reactions/HTMLSelectElement.html": [
    "7c79634f668b294e5c32224e15e96e2397883777",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLTableElement-expected.txt": [
-   "9d06692ecbdf6ad4f84f19375aa3c23882820950",
-   "support"
-  ],
   "custom-elements/reactions/HTMLTableElement.html": [
    "6adf2623d6bc208e4eaa41e1683b754f9cccf061",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLTableRowElement-expected.txt": [
-   "208b20d0c4c3260414cbf9420e1974a7fb8fd885",
-   "support"
-  ],
   "custom-elements/reactions/HTMLTableRowElement.html": [
    "a9a00a5da330b15614419940956f6579f6e13bb1",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLTableSectionElement-expected.txt": [
-   "fa807159b4e2e843fd1214cddb5924bd288e71fc",
-   "support"
-  ],
   "custom-elements/reactions/HTMLTableSectionElement.html": [
    "cbb0a146e8012ac8e44934604443fb300fbcfbb8",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLTitleElement-expected.txt": [
-   "a62831e61e1205100af49904e58aabef03a926e3",
-   "support"
-  ],
   "custom-elements/reactions/HTMLTitleElement.html": [
    "6678944c919d45c42ca68f2585575d398287b15e",
    "testharness"
   ],
-  "custom-elements/reactions/NamedNodeMap-expected.txt": [
-   "13044816a91056dc521e3fcdfc4650c34f1700b5",
-   "support"
-  ],
   "custom-elements/reactions/NamedNodeMap.html": [
    "fa21b3ada9ab2bd79370947d81ae6d5fb1984f45",
    "testharness"
   ],
-  "custom-elements/reactions/Node-expected.txt": [
-   "11e3580fa500b124fcf2b3ef117e29097fd077fa",
-   "support"
-  ],
   "custom-elements/reactions/Node.html": [
    "94da3d020e2f6df524abe4b314b3be30fa20fa9f",
    "testharness"
   ],
-  "custom-elements/reactions/ParentNode-expected.txt": [
-   "213bc158e8d4e435b8275f8bb0bdeabc755dc4d7",
-   "support"
-  ],
   "custom-elements/reactions/ParentNode.html": [
    "b143b5a982b5b44f6f953d1071c82ef22659b0a0",
    "testharness"
   ],
-  "custom-elements/reactions/Range-expected.txt": [
-   "56db8c71208e659efaf69e50436803ce1a02bfa3",
-   "support"
-  ],
   "custom-elements/reactions/Range.html": [
    "c4a8252ff620757778a01e43676d3f9c9999d7cb",
    "testharness"
   ],
-  "custom-elements/reactions/Selection-expected.txt": [
-   "3c6fcd53b8f929bbb3afc5c662c4b24beb5e31d6",
-   "support"
-  ],
   "custom-elements/reactions/Selection.html": [
    "84214201aaaf32481e17d45a8b889cc8c5d01a10",
    "testharness"
   ],
-  "custom-elements/reactions/ShadowRoot-expected.txt": [
-   "0af7b628f5a311d52bf87e246675b4368b85341b",
-   "support"
-  ],
   "custom-elements/reactions/ShadowRoot.html": [
    "9997d9c8362b5e4838572f403e2eb0fb0f418121",
    "testharness"
@@ -380237,14 +379978,14 @@
    "6ac7ab838d9ac82e994fc4b963815103c4e35063",
    "support"
   ],
-  "custom-elements/reactions/with-exceptions-expected.txt": [
-   "cfa873d937a1b8cb1fdeb2f5c01226d46dcb1dc9",
-   "support"
-  ],
   "custom-elements/reactions/with-exceptions.html": [
    "82e0f59c93022fcd6321c6b8ad1f8d7014b74382",
    "testharness"
   ],
+  "custom-elements/resources/custom-elements-helpers.js": [
+   "6f73fe20d0fbf25eed2fbfec530fb516e83cc214",
+   "support"
+  ],
   "custom-elements/resources/empty-html-document.html": [
    "eaca3f49fd15840a3688a10a91b56524566893c5",
    "support"
@@ -380258,25 +379999,17 @@
    "support"
   ],
   "custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html": [
-   "b8f00aaa161d1dee32783b69b06cd1b65968b6f1",
+   "5582bca4bb3a5396bd245031df4ddf8f2b7d1d91",
    "testharness"
   ],
   "custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html": [
-   "addcdf3cec582fb0f2d2714668c41dbb0296a113",
+   "9dccd4ca24df3c2cae5fef4ee209ab195546192f",
    "testharness"
   ],
-  "custom-elements/upgrading-expected.txt": [
-   "0255ad2d7ff5681d5a94545e136f90bb65aafab7",
-   "support"
-  ],
   "custom-elements/upgrading.html": [
    "aaea0cb4a021169631c2b50d0f597cb727a0b614",
    "testharness"
   ],
-  "custom-elements/upgrading/Document-importNode-expected.txt": [
-   "a8801106f29dbab20fc76646ab7e26d7b81e2d74",
-   "support"
-  ],
   "custom-elements/upgrading/Document-importNode.html": [
    "b80f90648d110a358bef090d3d9830077264cf70",
    "testharness"
@@ -408930,7 +408663,7 @@
    "support"
   ],
   "interfaces/payment-request.idl": [
-   "baf9ee36db9c898e500609dcdaf152ccbfbc704a",
+   "63a9ccccad4d57356760a65cadbdd3faec47bce4",
    "support"
   ],
   "interfaces/performance-timeline.idl": [
@@ -409130,7 +408863,7 @@
    "support"
   ],
   "interfaces/webxr.idl": [
-   "ffa9ed4e91abde01ef1b442d2e8c5daa8a40305d",
+   "5561369931f749224f2dcf87d5fc921af64d82b2",
    "support"
   ],
   "interfaces/worklets.idl": [
@@ -409598,7 +409331,15 @@
    "support"
   ],
   "media-capabilities/decodingInfo.html": [
-   "cb14e2b516f89d8e9083345be1d242bdeb436e6c",
+   "fb6e785ac9694c81224f9edf85b4fa803069c553",
+   "testharness"
+  ],
+  "media-capabilities/decodingInfoEncryptedMedia.http.html": [
+   "3fc15a64d810ab8dd1161f79c2724ffecdc30262",
+   "testharness"
+  ],
+  "media-capabilities/decodingInfoEncryptedMedia.https.html": [
+   "ca94d0b6499e2f81b715eaee0d4213b66b7d8b7d",
    "testharness"
   ],
   "media-capabilities/encodingInfo-expected.txt": [
@@ -432325,10 +432066,6 @@
    "6805c323df5a975231648b830e33ce183c3cbbd3",
    "support"
   ],
-  "resources/custom-elements-helpers.js": [
-   "6f73fe20d0fbf25eed2fbfec530fb516e83cc214",
-   "support"
-  ],
   "resources/idlharness.js": [
    "926a615e59c9cd6f602c6e700494d1600ac6d0a5",
    "support"
@@ -438729,6 +438466,10 @@
    "27d01efc64b9345f7deaeb6960c3d4b7ce8386b1",
    "reftest"
   ],
+  "svg/shapes/reftests/disabled-shapes-01.svg": [
+   "d92eea169a6904c969fa0d6df363324194a1b335",
+   "reftest"
+  ],
   "svg/shapes/reftests/pathlength-001-ref.svg": [
    "0ec9e0353ae4bcdf12acbdfe0e3aa85c22565054",
    "support"
@@ -438753,10 +438494,18 @@
    "506952f54b4b0b59d10a106af50ae61062873e99",
    "reftest"
   ],
+  "svg/shapes/reftests/support/empty.svg": [
+   "0c7be4e2da4480937124138e7dee3e26bd018abe",
+   "support"
+  ],
   "svg/shapes/rx-ry-not-inherited.svg": [
    "ff943e8b5c4718f57d99e6e520a7897e8356537b",
    "testharness"
   ],
+  "svg/shapes/scripted/disabled-shapes-not-hit.svg": [
+   "5a621d9f21dcaf4da0c3edab2d3ba11f261a9e6b",
+   "testharness"
+  ],
   "svg/struct/UnknownElement/interface-expected.txt": [
    "72545cd3af1eade527319a21c965e1399175adcd",
    "support"
@@ -448694,7 +448443,7 @@
    "support"
   ],
   "webxr/idlharness.https.window-expected.txt": [
-   "f7745f67431bbfc8d5f72601fc8c082f37ebfdb9",
+   "5a81cea93e4b73e6b7c4ee064fb2729c3a55e0cc",
    "support"
   ],
   "webxr/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/adopted-callback-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/adopted-callback-expected.txt
deleted file mode 100644
index 45341e7..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/adopted-callback-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: document_types is not defined
-PASS Inserting a custom element into the owner document must not enqueue and invoke adoptedCallback
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback-expected.txt
deleted file mode 100644
index 6d5a37c5..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/attribute-changed-callback-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: attributeChangedCallback Uncaught ReferenceError: define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-expected.txt
deleted file mode 100644
index c2a78e67..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: connectedCallback Uncaught ReferenceError: document_types is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-html-fragment-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-html-fragment-parsing-expected.txt
deleted file mode 100644
index 1ea67d2d..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/connected-callbacks-html-fragment-parsing-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: the HTML fragment parsing algorithm must not create a custom element synchronously Uncaught ReferenceError: document_types is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-reaction-queue-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-reaction-queue-expected.txt
deleted file mode 100644
index e1d0f49..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/custom-element-reaction-queue-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: Each element must have its own custom element reaction queue Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/disconnected-callbacks-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/disconnected-callbacks-expected.txt
deleted file mode 100644
index bd7b81c7..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/disconnected-callbacks-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: disconnectedCallback Uncaught ReferenceError: document_types is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt
index dca4aab2..46c1cf2 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt
@@ -1,4 +1,15 @@
 This is a testharness.js-based test.
-FAIL Custom Elements: [HTMLConstructor] derives prototype from NewTarget Uncaught ReferenceError: test_with_window is not defined
+PASS Use NewTarget's prototype, not the one stored at definition time
+PASS Rethrow any exceptions thrown while getting the prototype
+PASS If prototype is not object (null), derives the fallback from NewTarget's realm (autonomous custom elements)
+PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (autonomous custom elements)
+PASS If prototype is not object (5), derives the fallback from NewTarget's realm (autonomous custom elements)
+PASS If prototype is not object (string), derives the fallback from NewTarget's realm (autonomous custom elements)
+PASS If prototype is not object (null), derives the fallback from NewTarget's realm (customized built-in elements)
+PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (customized built-in elements)
+PASS If prototype is not object (5), derives the fallback from NewTarget's realm (customized built-in elements)
+PASS If prototype is not object (string), derives the fallback from NewTarget's realm (customized built-in elements)
+FAIL HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly assert_equals: Should never have gotten .prototype expected 0 but got 1
+FAIL HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect assert_equals: Should never have gotten .prototype expected 0 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-sets-attributes-and-children-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-sets-attributes-and-children-expected.txt
deleted file mode 100644
index af50412f..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-sets-attributes-and-children-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: Changes to the HTML parser Uncaught ReferenceError: create_attribute_changed_callback_log is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
index 0b792e6..35cb638 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt
@@ -1,5 +1,4 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: test_with_window is not defined
 PASS HTML parser must not instantiate custom elements inside template elements
 PASS HTML parser must not use the registry of the owner element's document inside an iframe
 PASS HTML parser must use the registry of the content document inside an iframe
@@ -8,5 +7,7 @@
 PASS HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument()
 PASS HTML parser must use the registry of window.document in a document created by new Document
 PASS HTML parser must use the registry of window.document in a document created by XMLHttpRequest
+FAIL document.write() must not instantiate a custom element without a defined insertion point assert_false: expected false got true
+FAIL document.writeln() must not instantiate a custom element without a defined insertion point assert_false: expected false got true
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt
deleted file mode 100644
index 53b676c7..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-This is a testharness.js-based test.
-FAIL cssText on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL cssText on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL cssText on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL cssText on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important and the style attribute is observed define_new_custom_element is not defined
-FAIL setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important but the style attribute is not observed define_new_custom_element is not defined
-FAIL removeProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it removes a property from the observed style attribute define_new_custom_element is not defined
-FAIL removeProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it removes a property from the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL cssFloat on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL cssFloat on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A camel case attribute (borderWidth) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL A camel case attribute (borderWidth) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A camel case attribute (borderWidth) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL A camel case attribute (borderWidth) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A dashed property (border-width) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL A dashed property (border-width) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A dashed property (border-width) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL A dashed property (border-width) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute define_new_custom_element is not defined
-FAIL A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed define_new_custom_element is not defined
-FAIL A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute define_new_custom_element is not defined
-FAIL A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ChildNode-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ChildNode-expected.txt
deleted file mode 100644
index 0e78d75..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ChildNode-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-FAIL before on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL before on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL after on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL after on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL replaceWith on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL replaceWith on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL remove on ChildNode must enqueue a disconnected reaction define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMStringMap-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMStringMap-expected.txt
deleted file mode 100644
index d2c4180e..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMStringMap-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL setter on DOMStringMap must enqueue an attributeChanged reaction when adding an observed data attribute define_new_custom_element is not defined
-FAIL setter on DOMStringMap must not enqueue an attributeChanged reaction when adding an unobserved data attribute define_new_custom_element is not defined
-FAIL setter on DOMStringMap must enqueue an attributeChanged reaction when mutating the value of an observed data attribute define_new_custom_element is not defined
-FAIL setter on DOMStringMap must enqueue an attributeChanged reaction when mutating the value of an observed data attribute to the same value define_new_custom_element is not defined
-FAIL setter on DOMStringMap must not enqueue an attributeChanged reaction when mutating the value of an unobserved data attribute define_new_custom_element is not defined
-FAIL deleter on DOMStringMap must enqueue an attributeChanged reaction when removing an observed data attribute define_new_custom_element is not defined
-FAIL deleter on DOMStringMap must not enqueue an attributeChanged reaction when removing an unobserved data attribute define_new_custom_element is not defined
-FAIL deleter on DOMStringMap must not enqueue an attributeChanged reaction when it does not remove a data attribute define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMTokenList-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMTokenList-expected.txt
deleted file mode 100644
index 3f7106805..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/DOMTokenList-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This is a testharness.js-based test.
-FAIL add on DOMTokenList must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL add on DOMTokenList must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL add on DOMTokenList must enqueue an attributeChanged reaction when adding a value to an existing attribute define_new_custom_element is not defined
-FAIL add on DOMTokenList must not enqueue an attributeChanged reaction when adding a value to an unobserved attribute define_new_custom_element is not defined
-FAIL add on DOMTokenList must enqueue exactly one attributeChanged reaction when adding multiple values to an attribute define_new_custom_element is not defined
-FAIL remove on DOMTokenList must enqueue an attributeChanged reaction when removing a value from an attribute define_new_custom_element is not defined
-FAIL remove on DOMTokenList must enqueue exactly one attributeChanged reaction when removing multiple values to an attribute define_new_custom_element is not defined
-FAIL remove on DOMTokenList must enqueue an attributeChanged reaction even when removing a non-existent value from an attribute define_new_custom_element is not defined
-FAIL remove on DOMTokenList must not enqueue an attributeChanged reaction when removing a value from an unobserved attribute define_new_custom_element is not defined
-FAIL toggle on DOMTokenList must enqueue an attributeChanged reaction when adding a value to an attribute define_new_custom_element is not defined
-FAIL toggle on DOMTokenList must enqueue an attributeChanged reaction when removing a value from an attribute define_new_custom_element is not defined
-FAIL replace on DOMTokenList must enqueue an attributeChanged reaction when replacing a value in an attribute define_new_custom_element is not defined
-FAIL replace on DOMTokenList must not enqueue an attributeChanged reaction when the token to replace does not exist in the attribute define_new_custom_element is not defined
-FAIL replace on DOMTokenList must not enqueue an attributeChanged reaction when replacing a value in an unobserved attribute define_new_custom_element is not defined
-FAIL the stringifier of DOMTokenList must enqueue an attributeChanged reaction when adding an observed attribute define_new_custom_element is not defined
-FAIL the stringifier of DOMTokenList must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL the stringifier of DOMTokenList must enqueue an attributeChanged reaction when mutating the value of an observed attribute define_new_custom_element is not defined
-FAIL the stringifier of DOMTokenList must not enqueue an attributeChanged reaction when mutating the value of an unobserved attribute define_new_custom_element is not defined
-FAIL the stringifier of DOMTokenList must enqueue an attributeChanged reaction when the setter is called with the original value of the attribute define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document-expected.txt
deleted file mode 100644
index 000c261..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Document-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on Document interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element-expected.txt
deleted file mode 100644
index 5e3a720..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Element-expected.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-This is a testharness.js-based test.
-FAIL id on Element must enqueue an attributeChanged reaction when adding id content attribute define_new_custom_element is not defined
-FAIL id on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL className on Element must enqueue an attributeChanged reaction when adding class content attribute define_new_custom_element is not defined
-FAIL className on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL slot on Element must enqueue an attributeChanged reaction when adding slot content attribute define_new_custom_element is not defined
-FAIL slot on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setAttribute on Element must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setAttribute on Element must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setAttribute on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setAttribute on Element must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNS on Element must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setAttributeNS on Element must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNS on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setAttributeNS on Element must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL removeAttribute on Element must not enqueue an attributeChanged reaction when removing an unobserved attribute define_new_custom_element is not defined
-FAIL removeAttribute on Element must enqueue an attributeChanged reaction when removing an existing attribute define_new_custom_element is not defined
-FAIL removeAttribute on Element must not enqueue an attributeChanged reaction when removing an existing unobserved attribute define_new_custom_element is not defined
-FAIL removeAttributeNS on Element must not enqueue an attributeChanged reaction when removing an unobserved attribute define_new_custom_element is not defined
-FAIL removeAttributeNS on Element must enqueue an attributeChanged reaction when removing an existing attribute define_new_custom_element is not defined
-FAIL removeAttributeNS on Element must not enqueue an attributeChanged reaction when removing an existing unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNode on Element must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setAttributeNode on Element must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNode on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setAttributeNode on Element must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNodeNS on Element must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setAttributeNodeNS on Element must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setAttributeNodeNS on Element must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setAttributeNodeNS on Element must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL removeAttributeNode on Element must not enqueue an attributeChanged reaction when removing an unobserved attribute define_new_custom_element is not defined
-FAIL removeAttributeNode on Element must enqueue an attributeChanged reaction when removing an existing attribute define_new_custom_element is not defined
-FAIL removeAttributeNode on Element must not enqueue an attributeChanged reaction when removing an existing unobserved attribute define_new_custom_element is not defined
-FAIL insertAdjacentElement on Element must enqueue a connected reaction define_new_custom_element is not defined
-FAIL insertAdjacentElement on Element must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL innerHTML on Element must enqueue a connected reaction for a newly constructed custom element define_new_custom_element is not defined
-FAIL innerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element define_new_custom_element is not defined
-FAIL innerHTML on Element must enqueue a disconnected reaction define_new_custom_element is not defined
-FAIL outerHTML on Element must enqueue a connected reaction for a newly constructed custom element define_new_custom_element is not defined
-FAIL outerHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element define_new_custom_element is not defined
-FAIL outerHTML on Element must enqueue a disconnected reaction define_new_custom_element is not defined
-FAIL insertAdjacentHTML on Element must enqueue a connected reaction for a newly constructed custom element define_new_custom_element is not defined
-FAIL insertAdjacentHTML on Element must enqueue a attributeChanged reaction for a newly constructed custom element define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ElementContentEditable-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ElementContentEditable-expected.txt
deleted file mode 100644
index 33e03d9..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ElementContentEditable-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL contentEditable on ElementContentEditable must enqueue an attributeChanged reaction when adding contenteditable content attribute define_new_custom_element is not defined
-FAIL contentEditable on ElementContentEditable must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAnchorElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAnchorElement-expected.txt
deleted file mode 100644
index 715e2b1..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLAnchorElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLAnchorElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement-expected.txt
index f1de833..1d08164 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLButtonElement-expected.txt
@@ -1,23 +1,23 @@
 This is a testharness.js-based test.
-FAIL autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when adding autofocus content attribute define_build_in_custom_element is not defined
-FAIL autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL disabled on HTMLButtonElement must enqueue an attributeChanged reaction when adding disabled content attribute define_build_in_custom_element is not defined
-FAIL disabled on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL name on HTMLButtonElement must enqueue an attributeChanged reaction when adding name content attribute define_build_in_custom_element is not defined
-FAIL name on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL value on HTMLButtonElement must enqueue an attributeChanged reaction when adding value content attribute define_build_in_custom_element is not defined
-FAIL value on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL type on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL type on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL formAction on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL formAction on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL formEnctype on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL formEnctype on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL formMethod on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL formMethod on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
-FAIL formTarget on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute define_build_in_custom_element is not defined
-FAIL formTarget on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute define_build_in_custom_element is not defined
+FAIL autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when adding autofocus content attribute assert_equals: expected "true" but got ""
+FAIL autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_equals: expected "true" but got ""
+FAIL disabled on HTMLButtonElement must enqueue an attributeChanged reaction when adding disabled content attribute assert_equals: expected "true" but got ""
+FAIL disabled on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_equals: expected "true" but got ""
+PASS name on HTMLButtonElement must enqueue an attributeChanged reaction when adding name content attribute
+PASS name on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+PASS value on HTMLButtonElement must enqueue an attributeChanged reaction when adding value content attribute
+PASS value on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+PASS type on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute
+PASS type on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+PASS formAction on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute
+PASS formAction on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+PASS formEnctype on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute
+PASS formEnctype on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+PASS formMethod on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute
+PASS formMethod on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
+FAIL formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute assert_equals: expected "true" but got ""
+FAIL formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_equals: expected "true" but got ""
+PASS formTarget on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute
+PASS formTarget on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt
deleted file mode 100644
index 3445b7d..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-This is a testharness.js-based test.
-FAIL title on HTMLElement must enqueue an attributeChanged reaction when adding title content attribute define_new_custom_element is not defined
-FAIL title on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL lang on HTMLElement must enqueue an attributeChanged reaction when adding lang content attribute define_new_custom_element is not defined
-FAIL lang on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL translate on HTMLElement must enqueue an attributeChanged reaction when adding translate content attribute define_new_custom_element is not defined
-FAIL translate on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL dir on HTMLElement must enqueue an attributeChanged reaction when adding dir content attribute define_new_custom_element is not defined
-FAIL dir on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL hidden on HTMLElement must enqueue an attributeChanged reaction when adding hidden content attribute define_new_custom_element is not defined
-FAIL hidden on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL tabIndex on HTMLElement must enqueue an attributeChanged reaction when adding tabindex content attribute define_new_custom_element is not defined
-FAIL tabIndex on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL accessKey on HTMLElement must enqueue an attributeChanged reaction when adding accesskey content attribute define_new_custom_element is not defined
-FAIL accessKey on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL draggable on HTMLElement must enqueue an attributeChanged reaction when adding draggable content attribute define_new_custom_element is not defined
-FAIL draggable on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL spellcheck on HTMLElement must enqueue an attributeChanged reaction when adding spellcheck content attribute define_new_custom_element is not defined
-FAIL spellcheck on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL innerText on HTMLElement must enqueue a disconnected reaction define_new_custom_element is not defined
-FAIL outerText on HTMLElement must enqueue a disconnected reaction define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionElement-expected.txt
deleted file mode 100644
index a554192..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLOptionElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionsCollection-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionsCollection-expected.txt
deleted file mode 100644
index ab172573..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOptionsCollection-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLOptionsCollection interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOutputElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOutputElement-expected.txt
deleted file mode 100644
index a6cf394..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLOutputElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLOutputElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLSelectElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLSelectElement-expected.txt
deleted file mode 100644
index 2e24913..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLSelectElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLSelectElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableElement-expected.txt
deleted file mode 100644
index 9d06692..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLTableElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableRowElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableRowElement-expected.txt
deleted file mode 100644
index 208b20d..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableRowElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLTableRowElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableSectionElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableSectionElement-expected.txt
deleted file mode 100644
index fa80715..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTableSectionElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLTableSectionElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTitleElement-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTitleElement-expected.txt
deleted file mode 100644
index a62831e..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/HTMLTitleElement-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on HTMLTitleElement interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/NamedNodeMap-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/NamedNodeMap-expected.txt
deleted file mode 100644
index 13044816..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/NamedNodeMap-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-FAIL setNamedItem on NamedNodeMap must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setNamedItem on NamedNodeMap must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setNamedItem on NamedNodeMap must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setNamedItem on NamedNodeMap must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL setNamedItemNS on NamedNodeMap must enqueue an attributeChanged reaction when adding an attribute define_new_custom_element is not defined
-FAIL setNamedItemNS on NamedNodeMap must not enqueue an attributeChanged reaction when adding an unobserved attribute define_new_custom_element is not defined
-FAIL setNamedItemNS on NamedNodeMap must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL setNamedItemNS on NamedNodeMap must enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL removeNamedItem on NamedNodeMap must not enqueue an attributeChanged reaction when removing an unobserved attribute define_new_custom_element is not defined
-FAIL removeNamedItem on NamedNodeMap must enqueue an attributeChanged reaction when removing an existing attribute define_new_custom_element is not defined
-FAIL removeNamedItem on NamedNodeMap must not enqueue an attributeChanged reaction when removing an existing unobserved attribute define_new_custom_element is not defined
-FAIL removeNamedItemNS on NamedNodeMap must not enqueue an attributeChanged reaction when removing an unobserved attribute define_new_custom_element is not defined
-FAIL removeNamedItemNS on NamedNodeMap must enqueue an attributeChanged reaction when removing an existing attribute define_new_custom_element is not defined
-FAIL removeNamedItemNS on NamedNodeMap must not enqueue an attributeChanged reaction when removing an existing unobserved attribute define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Node-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Node-expected.txt
deleted file mode 100644
index 11e3580..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Node-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-FAIL nodeValue on Node must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL nodeValue on Node must not enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL textContent on Node must enqueue an attributeChanged reaction when replacing an existing attribute define_new_custom_element is not defined
-FAIL textContent on Node must not enqueue an attributeChanged reaction when replacing an existing unobserved attribute define_new_custom_element is not defined
-FAIL cloneNode on Node must enqueue an attributeChanged reaction when cloning an element with an observed attribute define_new_custom_element is not defined
-FAIL cloneNode on Node must not enqueue an attributeChanged reaction when cloning an element with an unobserved attribute define_new_custom_element is not defined
-FAIL cloneNode on Node must enqueue an attributeChanged reaction when cloning an element only for observed attributes define_new_custom_element is not defined
-FAIL insertBefore on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL insertBefore on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL appendChild on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL appendChild on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL replaceChild on ChildNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL replaceChild on ChildNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL removeChild on ChildNode must enqueue a disconnected reaction define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ParentNode-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ParentNode-expected.txt
deleted file mode 100644
index 213bc15..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ParentNode-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL prepend on ParentNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL prepend on ParentNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL append on ParentNode must enqueue a connected reaction define_new_custom_element is not defined
-FAIL append on ParentNode must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Range-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Range-expected.txt
deleted file mode 100644
index 56db8c7..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Range-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-FAIL deleteContents on Range must enqueue a disconnected reaction define_new_custom_element is not defined
-FAIL extractContents on Range must enqueue a disconnected reaction define_new_custom_element is not defined
-FAIL cloneContents on Range must enqueue an attributeChanged reaction when cloning an element with an observed attribute define_new_custom_element is not defined
-FAIL cloneContents on Range must not enqueue an attributeChanged reaction when cloning an element with an unobserved attribute define_new_custom_element is not defined
-FAIL cloneContents on Range must enqueue an attributeChanged reaction when cloning an element only for observed attributes define_new_custom_element is not defined
-FAIL insertNode on Range must enqueue a connected reaction define_new_custom_element is not defined
-FAIL insertNode on Range must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL surroundContents on Range must enqueue a connected reaction define_new_custom_element is not defined
-FAIL surroundContents on Range must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document define_new_custom_element is not defined
-FAIL createContextualFragment on Range must construct a custom element define_new_custom_element is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ShadowRoot-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ShadowRoot-expected.txt
deleted file mode 100644
index 0af7b628..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/ShadowRoot-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions on ShadowRoot interface Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/with-exceptions-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/reactions/with-exceptions-expected.txt
deleted file mode 100644
index cfa873d9..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/with-exceptions-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: CEReactions interaction with exceptions Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/resources/custom-elements-helpers.js b/third_party/blink/web_tests/external/wpt/custom-elements/resources/custom-elements-helpers.js
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/resources/custom-elements-helpers.js
rename to third_party/blink/web_tests/external/wpt/custom-elements/resources/custom-elements-helpers.js
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html b/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html
index b8f00aa..5582bca 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-construct.html
@@ -8,7 +8,7 @@
  <meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter">
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
- <script src="/resources/custom-elements-helpers.js"></script>
+ <script src="./resources/custom-elements-helpers.js"></script>
  </head>
  <body>
  <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html b/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html
index addcdf3c..9dccd4c 100644
--- a/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html
+++ b/third_party/blink/web_tests/external/wpt/custom-elements/throw-on-dynamic-markup-insertion-counter-reactions.html
@@ -8,7 +8,7 @@
 <meta name="help" content="https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#throw-on-dynamic-markup-insertion-counter">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="/resources/custom-elements-helpers.js"></script>
+<script src="./resources/custom-elements-helpers.js"></script>
 </head>
 <body>
 <div id="log"></div>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/upgrading-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/upgrading-expected.txt
deleted file mode 100644
index 0255ad2d..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/upgrading-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Custom Elements: Enqueue a custom element upgrade reaction Uncaught ReferenceError: document_types is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/upgrading/Document-importNode-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/upgrading/Document-importNode-expected.txt
deleted file mode 100644
index a8801106..0000000
--- a/third_party/blink/web_tests/external/wpt/custom-elements/upgrading/Document-importNode-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Document-importNode Uncaught ReferenceError: test_with_window is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-bufferbeforeonload.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-bufferbeforeonload.html
similarity index 94%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-bufferbeforeonload.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-bufferbeforeonload.html
index d011c5f..223f5ed0 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-bufferbeforeonload.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-bufferbeforeonload.html
@@ -5,8 +5,11 @@
 <button id='button' onclick='clickDelay()'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
-<img src=resources/slow-image.php>
+<img src=resources/slow-image.py>
 
 <script>
   let clickTimeMin;
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-crossiframe.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-crossiframe.html
similarity index 95%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-crossiframe.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-crossiframe.html
index ae55463..0e77b38 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-crossiframe.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-crossiframe.html
@@ -10,8 +10,11 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
-<img src=./resources/slow-image.php>
+<img src=./resources/slow-image.py>
 <iframe src=resources/event-timing-crossiframe-childframe.html></iframe>
 <script>
   let clickTimeMin;
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-observer-manual.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-observer-manual.html
similarity index 98%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-observer-manual.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-observer-manual.html
index 9ef7e32..c0bd6f3 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-observer-manual.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-observer-manual.html
@@ -53,7 +53,7 @@
 
   function onMakeBusy() {
     log("busy start");
-    setTimeout(()=>{
+    step_timeout(()=>{
       mainThreadBusy(2000);
       log("busy end");
     }, 0);
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-observethenonload.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-observethenonload.html
similarity index 96%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-observethenonload.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-observethenonload.html
index 18d398b..3d72e6a 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-observethenonload.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-observethenonload.html
@@ -6,8 +6,11 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
-<img src=resources/slow-image.php>
+<img src=resources/slow-image.py>
 
 <script>
   let timeBeforeFirstClick;
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve-firstInput.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve-firstInput.html
similarity index 94%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve-firstInput.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve-firstInput.html
index cf50a98..16f48411 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve-firstInput.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve-firstInput.html
@@ -5,6 +5,9 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
 
 <script>
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve.html
similarity index 95%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve.html
index cc8948a..7dc1132 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-onloadthenobserve.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-onloadthenobserve.html
@@ -7,6 +7,9 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
 <script>
   let callbackTime;
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-only-observe-firstInput.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-only-observe-firstInput.html
similarity index 93%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-only-observe-firstInput.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-only-observe-firstInput.html
index 5fa6ba9..2f24d51 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-only-observe-firstInput.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-only-observe-firstInput.html
@@ -5,6 +5,9 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
 
 <script>
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-retrievability.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-retrievability.html
similarity index 90%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-retrievability.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-retrievability.html
index 42f2e86..f38761b 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-retrievability.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-retrievability.html
@@ -5,8 +5,11 @@
 <button id='button' onclick='1'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
-<img src=resources/slow-image.php>
+<img src=resources/slow-image.py>
 
 <script>
   function validateEntries() {
diff --git a/third_party/blink/web_tests/http/tests/event-timing/event-timing-timingconditions.html b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-timingconditions.html
similarity index 95%
rename from third_party/blink/web_tests/http/tests/event-timing/event-timing-timingconditions.html
rename to third_party/blink/web_tests/external/wpt/event-timing/event-timing-timingconditions.html
index 8a3c2230..1e5dd2f 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/event-timing-timingconditions.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/event-timing-timingconditions.html
@@ -7,6 +7,9 @@
   onfocus='mainThreadBusy(60)'>Generate a 'click' event</button>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+
 <script src=resources/event-timing-support.js></script>
 <script>
   let trustedClickStart;
diff --git a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-crossiframe-childframe.html b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-crossiframe-childframe.html
similarity index 97%
rename from third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-crossiframe-childframe.html
rename to third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-crossiframe-childframe.html
index a1ce118..7491fd8 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-crossiframe-childframe.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-crossiframe-childframe.html
@@ -2,7 +2,7 @@
 <html>
 <script src=event-timing-support.js></script>
 <button id='button_child_frame' onclick='2'>Generate a 'click' event</button>
-<img src=slow-image.php>
+<img src=slow-image.py>
 <script>
   const clickTimeMin = performance.now();
   clickAndBlockMain('button_child_frame');
diff --git a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-observer-manual-childframe.html b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-observer-manual-childframe.html
similarity index 97%
rename from third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-observer-manual-childframe.html
rename to third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-observer-manual-childframe.html
index 9fc4667..9985366 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-observer-manual-childframe.html
+++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-observer-manual-childframe.html
@@ -25,7 +25,7 @@
 
   function onMakeBusy() {
     log("busy start");
-    setTimeout(()=>{
+    step_timeout(()=>{
       mainThreadBusy(2000);
       log("busy end");
     }, 0);
diff --git a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-support.js b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-support.js
similarity index 86%
rename from third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-support.js
rename to third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-support.js
index ceee4b5..a2a583c89 100644
--- a/third_party/blink/web_tests/http/tests/event-timing/resources/event-timing-support.js
+++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/event-timing-support.js
@@ -1,31 +1,20 @@
 // Clicks on the element with the given ID. It adds an event handler to the element
 // which ensures that the events have a long duration and reported by EventTiming
-// where appropriate.
+// where appropriate. Calls |callback| during event handler.
 function clickOnElement(id, callback) {
   const element = document.getElementById(id);
   const rect = element.getBoundingClientRect();
   const xCenter = rect.x + rect.width / 2;
   const yCenter = rect.y + rect.height / 2;
   const leftButton = 0;
-  var pointerActions = [{
-    source: "mouse",
-    actions: [
-      { name: "pointerDown", x: xCenter, y: yCenter, button: leftButton },
-      { name: "pointerUp" },
-    ]
-  }];
-  var clickHandler = () => {
+  const clickHandler = () => {
     mainThreadBusy(60);
     if (callback)
       callback();
     element.removeEventListener("click", clickHandler);
   };
   element.addEventListener("click", clickHandler);
-  if (!chrome || !chrome.gpuBenchmarking) {
-    reject();
-  } else {
-    chrome.gpuBenchmarking.pointerActionSequence(pointerActions);
-  }
+  test_driver.click(element);
 }
 
 function mainThreadBusy(duration) {
@@ -64,7 +53,7 @@
 
 function wait() {
   return new Promise((resolve, reject) => {
-    setTimeout(() => {
+    step_timeout(() => {
       resolve();
     }, 0);
   });
diff --git a/third_party/blink/web_tests/external/wpt/event-timing/resources/slow-image.py b/third_party/blink/web_tests/external/wpt/event-timing/resources/slow-image.py
new file mode 100644
index 0000000..5c2d1b1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/event-timing/resources/slow-image.py
@@ -0,0 +1,7 @@
+import time
+
+def main(request, response):
+    # Sleep for 500ms to delay onload.
+    time.sleep(0.5)
+    response.headers.set("Cache-Control", "no-cache, must-revalidate");
+    response.headers.set("Location", "data:image/gif;base64,R0lGODlhAQABAJAAAMjIyAAAACwAAAAAAQABAAACAgQBADs%3D");
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl b/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl
index baf9ee3..63a9cccc 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/payment-request.idl
@@ -68,6 +68,7 @@
 
 dictionary PaymentOptions {
   boolean requestPayerName = false;
+  boolean requestBillingAddress = false;
   boolean requestPayerEmail = false;
   boolean requestPayerPhone = false;
   boolean requestShipping = false;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
index ffa9ed4e..556136993 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -5,7 +5,8 @@
 
 [SecureContext, Exposed=Window] interface XR : EventTarget {
   // Methods
-  Promise<XRDevice?> requestDevice();
+  Promise<void> supportsSessionMode(XRSessionMode mode);
+  Promise<XRSession> requestSession(optional XRSessionCreationOptions parameters);
 
   // Events
   attribute EventHandler ondevicechange;
@@ -16,14 +17,14 @@
   [SameObject] readonly attribute XR xr;
 };
 
-[SecureContext, Exposed=Window] interface XRDevice {
-  // Methods
-  Promise<void> supportsSession(optional XRSessionCreationOptions options);
-  Promise<XRSession> requestSession(optional XRSessionCreationOptions options);
+enum XRSessionMode {
+  "inline",
+  "immersive-vr",
+  "immersive-ar"
 };
 
 dictionary XRSessionCreationOptions {
-  boolean immersive = false;
+  XRSessionMode mode = "inline";
   XRPresentationContext outputContext;
 };
 
@@ -35,8 +36,7 @@
 
 [SecureContext, Exposed=Window] interface XRSession : EventTarget {
   // Attributes
-  readonly attribute XRDevice device;
-  readonly attribute boolean immersive;
+  readonly attribute XRSessionMode mode;
   readonly attribute XRPresentationContext outputContext;
   readonly attribute XREnvironmentBlendMode environmentBlendMode;
 
@@ -60,6 +60,7 @@
   attribute EventHandler onresetpose;
   attribute EventHandler onend;
   attribute EventHandler onselect;
+  attribute EventHandler oninputsourceschange;
   attribute EventHandler onselectstart;
   attribute EventHandler onselectend;
 };
@@ -68,10 +69,9 @@
 
 [SecureContext, Exposed=Window] interface XRFrame {
   readonly attribute XRSession session;
-  readonly attribute FrozenArray<XRView> views;
 
-  XRDevicePose? getDevicePose(XRCoordinateSystem coordinateSystem);
-  XRInputPose? getInputPose(XRInputSource inputSource, XRCoordinateSystem coordinateSystem);
+  XRViewerPose? getViewerPose(XRFrameOfReference frameOfRef);
+  XRInputPose? getInputPose(XRInputSource inputSource, XRFrameOfReference frameOfRef);
 };
 
 [SecureContext, Exposed=Window] interface XRCoordinateSystem : EventTarget {
@@ -108,6 +108,7 @@
 [SecureContext, Exposed=Window] interface XRView {
   readonly attribute XREye eye;
   readonly attribute Float32Array projectionMatrix;
+  readonly attribute Float32Array viewMatrix;
 };
 
 [SecureContext, Exposed=Window] interface XRViewport {
@@ -117,10 +118,9 @@
   readonly attribute long height;
 };
 
-[SecureContext, Exposed=Window] interface XRDevicePose {
-  readonly attribute Float32Array poseModelMatrix;
-
-  Float32Array getViewMatrix(XRView view);
+[SecureContext, Exposed=Window] interface XRViewerPose {
+  readonly attribute Float32Array poseMatrix;
+  readonly attribute FrozenArray<XRView> views;
 };
 
 enum XRHandedness {
@@ -165,7 +165,6 @@
   boolean depth = true;
   boolean stencil = false;
   boolean alpha = true;
-  boolean multiview = false;
   double framebufferScaleFactor = 1.0;
 };
 
@@ -180,7 +179,6 @@
   readonly attribute boolean depth;
   readonly attribute boolean stencil;
   readonly attribute boolean alpha;
-  readonly attribute boolean multiview;
 
   readonly attribute WebGLFramebuffer framebuffer;
   readonly attribute unsigned long framebufferWidth;
@@ -195,11 +193,11 @@
 };
 
 partial dictionary WebGLContextAttributes {
-    XRDevice compatibleXRDevice = null;
+    boolean xrCompatible = null;
 };
 
 partial interface mixin WebGLRenderingContextBase {
-    Promise<void> setCompatibleXRDevice(XRDevice device);
+    Promise<void> makeXRCompatible();
 };
 
 [SecureContext, Exposed=Window] interface XRPresentationContext {
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
index f7745f67..5a81cea9 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -9,28 +9,23 @@
 PASS XR interface: existence and properties of interface prototype object
 PASS XR interface: existence and properties of interface prototype object's "constructor" property
 PASS XR interface: existence and properties of interface prototype object's @@unscopables property
-PASS XR interface: operation requestDevice()
+FAIL XR interface: operation supportsSessionMode(XRSessionMode) assert_own_property: interface prototype object missing non-static operation expected property "supportsSessionMode" missing
+FAIL XR interface: operation requestSession(XRSessionCreationOptions) assert_own_property: interface prototype object missing non-static operation expected property "requestSession" missing
 PASS XR interface: attribute ondevicechange
 PASS XR must be primary interface of navigator.xr
 PASS Stringification of navigator.xr
-PASS XR interface: navigator.xr must inherit property "requestDevice()" with the proper type
+FAIL XR interface: navigator.xr must inherit property "supportsSessionMode(XRSessionMode)" with the proper type assert_inherits: property "supportsSessionMode" not found in prototype chain
+FAIL XR interface: calling supportsSessionMode(XRSessionMode) on navigator.xr with too few arguments must throw TypeError assert_inherits: property "supportsSessionMode" not found in prototype chain
+FAIL XR interface: navigator.xr must inherit property "requestSession(XRSessionCreationOptions)" with the proper type assert_inherits: property "requestSession" not found in prototype chain
+FAIL XR interface: calling requestSession(XRSessionCreationOptions) on navigator.xr with too few arguments must throw TypeError assert_inherits: property "requestSession" not found in prototype chain
 PASS XR interface: navigator.xr must inherit property "ondevicechange" with the proper type
-PASS XRDevice interface: existence and properties of interface object
-PASS XRDevice interface object length
-PASS XRDevice interface object name
-PASS XRDevice interface: existence and properties of interface prototype object
-PASS XRDevice interface: existence and properties of interface prototype object's "constructor" property
-PASS XRDevice interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRDevice interface: operation supportsSession(XRSessionCreationOptions)
-PASS XRDevice interface: operation requestSession(XRSessionCreationOptions)
 PASS XRSession interface: existence and properties of interface object
 PASS XRSession interface object length
 PASS XRSession interface object name
 PASS XRSession interface: existence and properties of interface prototype object
 PASS XRSession interface: existence and properties of interface prototype object's "constructor" property
 PASS XRSession interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRSession interface: attribute device
-PASS XRSession interface: attribute immersive
+FAIL XRSession interface: attribute mode assert_true: The prototype object must have a property "mode" expected true got false
 PASS XRSession interface: attribute outputContext
 PASS XRSession interface: attribute environmentBlendMode
 PASS XRSession interface: attribute depthNear
@@ -46,6 +41,7 @@
 PASS XRSession interface: attribute onresetpose
 PASS XRSession interface: attribute onend
 FAIL XRSession interface: attribute onselect assert_true: The prototype object must have a property "onselect" expected true got false
+FAIL XRSession interface: attribute oninputsourceschange assert_true: The prototype object must have a property "oninputsourceschange" expected true got false
 FAIL XRSession interface: attribute onselectstart assert_true: The prototype object must have a property "onselectstart" expected true got false
 FAIL XRSession interface: attribute onselectend assert_true: The prototype object must have a property "onselectend" expected true got false
 PASS XRFrame interface: existence and properties of interface object
@@ -55,9 +51,8 @@
 PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property
 PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRFrame interface: attribute session
-PASS XRFrame interface: attribute views
-PASS XRFrame interface: operation getDevicePose(XRCoordinateSystem)
-PASS XRFrame interface: operation getInputPose(XRInputSource, XRCoordinateSystem)
+FAIL XRFrame interface: operation getViewerPose(XRFrameOfReference) assert_own_property: interface prototype object missing non-static operation expected property "getViewerPose" missing
+PASS XRFrame interface: operation getInputPose(XRInputSource, XRFrameOfReference)
 PASS XRCoordinateSystem interface: existence and properties of interface object
 PASS XRCoordinateSystem interface object length
 PASS XRCoordinateSystem interface object name
@@ -89,6 +84,7 @@
 PASS XRView interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRView interface: attribute eye
 PASS XRView interface: attribute projectionMatrix
+FAIL XRView interface: attribute viewMatrix assert_true: The prototype object must have a property "viewMatrix" expected true got false
 PASS XRViewport interface: existence and properties of interface object
 PASS XRViewport interface object length
 PASS XRViewport interface object name
@@ -99,14 +95,14 @@
 PASS XRViewport interface: attribute y
 PASS XRViewport interface: attribute width
 PASS XRViewport interface: attribute height
-PASS XRDevicePose interface: existence and properties of interface object
-PASS XRDevicePose interface object length
-PASS XRDevicePose interface object name
-PASS XRDevicePose interface: existence and properties of interface prototype object
-PASS XRDevicePose interface: existence and properties of interface prototype object's "constructor" property
-PASS XRDevicePose interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRDevicePose interface: attribute poseModelMatrix
-PASS XRDevicePose interface: operation getViewMatrix(XRView)
+FAIL XRViewerPose interface: existence and properties of interface object assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface object length assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface object name assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface: attribute poseMatrix assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
+FAIL XRViewerPose interface: attribute views assert_own_property: self does not have own property "XRViewerPose" expected property "XRViewerPose" missing
 PASS XRInputSource interface: existence and properties of interface object
 PASS XRInputSource interface object length
 PASS XRInputSource interface object name
@@ -150,7 +146,6 @@
 PASS XRWebGLLayer interface: attribute depth
 PASS XRWebGLLayer interface: attribute stencil
 PASS XRWebGLLayer interface: attribute alpha
-PASS XRWebGLLayer interface: attribute multiview
 PASS XRWebGLLayer interface: attribute framebuffer
 PASS XRWebGLLayer interface: attribute framebufferWidth
 PASS XRWebGLLayer interface: attribute framebufferHeight
@@ -186,7 +181,7 @@
 FAIL XRCoordinateSystemEvent interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing
 FAIL XRCoordinateSystemEvent interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing
 FAIL XRCoordinateSystemEvent interface: attribute coordinateSystem assert_own_property: self does not have own property "XRCoordinateSystemEvent" expected property "XRCoordinateSystemEvent" missing
-PASS WebGLRenderingContext interface: operation setCompatibleXRDevice(XRDevice)
+FAIL WebGLRenderingContext interface: operation makeXRCompatible() assert_own_property: interface prototype object missing non-static operation expected property "makeXRCompatible" missing
 PASS Navigator interface: attribute xr
 PASS Navigator interface: navigator must inherit property "xr" with the proper type
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/css/ignore-empty-focus-ring-rects-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/css/ignore-empty-focus-ring-rects-expected.png
index 6e730b7..5710296 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/css/ignore-empty-focus-ring-rects-expected.png
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/fast/css/ignore-empty-focus-ring-rects-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/clip/clip-with-layout-delta-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/clip/clip-with-layout-delta-expected.txt
new file mode 100644
index 0000000..7c3a9399
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/clip/clip-with-layout-delta-expected.txt
@@ -0,0 +1,54 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "LayoutNGBlockFlow (relative positioned) DIV",
+          "rect": [108, 8, 100, 100],
+          "reason": "disappeared"
+        },
+        {
+          "object": "LayoutNGBlockFlow (relative positioned) DIV",
+          "rect": [108, 8, 100, 100],
+          "reason": "chunk appeared"
+        },
+        {
+          "object": "LayoutNGBlockFlow DIV",
+          "rect": [8, 8, 100, 100],
+          "reason": "appeared"
+        },
+        {
+          "object": "LayoutNGBlockFlow DIV",
+          "rect": [8, 8, 100, 100],
+          "reason": "chunk disappeared"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [108, 8, 4, 19],
+          "reason": "disappeared"
+        },
+        {
+          "object": "LayoutNGBlockFlow HTML",
+          "rect": [8, 8, 4, 19],
+          "reason": "chunk appeared"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-4-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-4-expected.txt
new file mode 100644
index 0000000..d72a00c
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-4-expected.txt
@@ -0,0 +1,54 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='keep' class='item'",
+          "rect": [408, 88, 100, 100],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='to_remove' class='item'",
+          "rect": [408, 88, 100, 100],
+          "reason": "disappeared"
+        },
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='keep' class='item'",
+          "rect": [208, 88, 100, 100],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [408, 88, 4, 19],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [408, 88, 4, 19],
+          "reason": "disappeared"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [208, 88, 4, 19],
+          "reason": "geometry"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-expected.txt
new file mode 100644
index 0000000..b77f7ab
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/crbug-371640-expected.txt
@@ -0,0 +1,54 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='keep' class='item'",
+          "rect": [348, 88, 100, 100],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='to_remove' class='item'",
+          "rect": [348, 88, 100, 100],
+          "reason": "disappeared"
+        },
+        {
+          "object": "NGPhysicalBoxFragment LayoutNGBlockFlow DIV id='keep' class='item'",
+          "rect": [88, 88, 100, 100],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [348, 88, 4, 19],
+          "reason": "geometry"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [348, 88, 4, 19],
+          "reason": "disappeared"
+        },
+        {
+          "object": "NGPhysicalTextFragment '\u00A0'",
+          "rect": [88, 88, 4, 19],
+          "reason": "geometry"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-continuations-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-continuations-expected.txt
new file mode 100644
index 0000000..7f64661
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-continuations-expected.txt
@@ -0,0 +1,29 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPhysicalBoxFragment LayoutInline SPAN id='outer'",
+          "rect": [7, 87, 88, 22],
+          "reason": "disappeared"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-enable-continuations-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-enable-continuations-expected.txt
new file mode 100644
index 0000000..b6d45e8
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-enable-continuations-expected.txt
@@ -0,0 +1,29 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPhysicalBoxFragment LayoutInline SPAN id='outer'",
+          "rect": [7, 87, 88, 22],
+          "reason": "appeared"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-continuation-move-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-continuation-move-expected.txt
new file mode 100644
index 0000000..1ad77aa
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-continuation-move-expected.txt
@@ -0,0 +1,44 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPhysicalBoxFragment LayoutInline SPAN",
+          "rect": [207, 231, 102, 102],
+          "reason": "outline"
+        },
+        {
+          "object": "NGPhysicalBoxFragment LayoutInline SPAN",
+          "rect": [7, 231, 102, 102],
+          "reason": "outline"
+        },
+        {
+          "object": "LayoutNGBlockFlow (relative positioned) DIV id='block'",
+          "rect": [208, 232, 100, 100],
+          "reason": "geometry"
+        },
+        {
+          "object": "LayoutNGBlockFlow (relative positioned) DIV id='block'",
+          "rect": [8, 232, 100, 100],
+          "reason": "geometry"
+        }
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-inline-continuation-move-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-inline-continuation-move-expected.txt
index c6f68e11..a000591 100644
--- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-inline-continuation-move-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/outline/focus-ring-on-inline-continuation-move-expected.txt
@@ -20,12 +20,12 @@
         {
           "object": "NGPhysicalBoxFragment LayoutInline SPAN",
           "rect": [7, 7, 102, 106],
-          "reason": "geometry"
+          "reason": "outline"
         },
         {
           "object": "NGPhysicalBoxFragment LayoutInline SPAN",
           "rect": [7, 87, 102, 102],
-          "reason": "geometry"
+          "reason": "outline"
         },
         {
           "object": "LayoutNGBlockFlow (relative positioned) DIV id='block'",
diff --git a/third_party/blink/web_tests/http/tests/event-timing/resources/slow-image.php b/third_party/blink/web_tests/http/tests/event-timing/resources/slow-image.php
deleted file mode 100644
index b0c0020b..0000000
--- a/third_party/blink/web_tests/http/tests/event-timing/resources/slow-image.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-// Sleep for 500ms to delay onload.
-usleep(500000);
-header('Cache-Control: no-cache, must-revalidate');
-header('Location: data:image/gif;base64,R0lGODlhAQABAJAAAMjIyAAAACwAAAAAAQABAAACAgQBADs%3D');
-?>
diff --git a/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream-expected.txt b/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream-expected.txt
new file mode 100644
index 0000000..76b3a24
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+FAIL window.postMessage should be able to transfer a WritableStream Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type.
+FAIL a locked WritableStream should not be transferable assert_throws: postMessage should throw function "() => postMessage(ws, '*', [ws])" threw object "TypeError: Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type." that is not a DOMException DataCloneError: property "code" is equal to undefined, expected 25
+FAIL window.postMessage should be able to transfer a {readable, writable} pair Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream.html b/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream.html
new file mode 100644
index 0000000..5695eba3
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/streams/transferable/writable-stream.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(t => {
+  const orig = new WritableStream();
+  const promise = new Promise(resolve => {
+    addEventListener('message', t.step_func(evt => {
+      const transferred = evt.data;
+      assert_equals(transferred.constructor, WritableStream,
+                    'transferred should be a WritableStream in this realm');
+      assert_true(transferred instanceof WritableStream,
+                  'instanceof check should pass');
+
+      // Perform a brand-check on |transferred|.
+      const writer = WritableStream.prototype.getWriter.call(transferred);
+      resolve();
+    }), {once: true});
+  });
+  postMessage(orig, '*', [orig]);
+  assert_true(orig.locked, 'the original stream should be locked');
+  return promise;
+}, 'window.postMessage should be able to transfer a WritableStream');
+
+test(() => {
+  const ws = new WritableStream();
+  const writer = ws.getWriter();
+  assert_throws('DataCloneError', () => postMessage(ws, '*', [ws]),
+                'postMessage should throw');
+}, 'a locked WritableStream should not be transferable');
+
+promise_test(t => {
+  const {writable, readable} = new TransformStream();
+  const promise = new Promise(resolve => {
+    addEventListener('message', t.step_func(async evt => {
+      const {writable, readable} = evt.data;
+      const reader = readable.getReader();
+      const writer = writable.getWriter();
+      const writerPromises = Promise.all([
+        writer.write('hi'),
+        writer.close(),
+      ]);
+      const {value, done} = await reader.read();
+      assert_false(done, 'we should not be done');
+      assert_equals(value, 'hi', 'chunk should have been delivered');
+      const readResult = await reader.read();
+      assert_true(readResult.done, 'readable should be closed');
+      await writerPromises;
+      resolve();
+    }), {once: true});
+  });
+  postMessage({writable, readable}, '*', [writable, readable]);
+  return promise;
+}, 'window.postMessage should be able to transfer a {readable, writable} pair');
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Attr-expected.txt b/third_party/blink/web_tests/platform/fuchsia/external/wpt/custom-elements/reactions/Attr-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/custom-elements/reactions/Attr-expected.txt
rename to third_party/blink/web_tests/platform/fuchsia/external/wpt/custom-elements/reactions/Attr-expected.txt
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/reactions/Selection-expected.txt b/third_party/blink/web_tests/platform/fuchsia/external/wpt/custom-elements/reactions/Selection-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/custom-elements/reactions/Selection-expected.txt
rename to third_party/blink/web_tests/platform/fuchsia/external/wpt/custom-elements/reactions/Selection-expected.txt
diff --git a/third_party/blink/web_tests/virtual/transferable-streams/http/tests/streams/transferable/writable-stream-expected.txt b/third_party/blink/web_tests/virtual/transferable-streams/http/tests/streams/transferable/writable-stream-expected.txt
new file mode 100644
index 0000000..b70f957
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/transferable-streams/http/tests/streams/transferable/writable-stream-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS window.postMessage should be able to transfer a WritableStream
+PASS a locked WritableStream should not be transferable
+PASS window.postMessage should be able to transfer a {readable, writable} pair
+Harness: the test ran to completion.
+
diff --git a/third_party/feed/BUILD.gn b/third_party/feed/BUILD.gn
index d2b7f0c0..e8f7719 100644
--- a/third_party/feed/BUILD.gn
+++ b/third_party/feed/BUILD.gn
@@ -43,6 +43,9 @@
 
 android_resources("sharedstream_contextmenumanager_resources") {
   resource_dirs = [ "src/src/main/java/com/google/android/libraries/feed/sharedstream/contextmenumanager/res" ]
+  deps = [
+    ":sharedstream_resources",
+  ]
   custom_package =
       "com.google.android.libraries.feed.sharedstream.contextmenumanager"
 }
diff --git a/third_party/feed/README.chromium b/third_party/feed/README.chromium
index 29c8b2a..1304ba2 100644
--- a/third_party/feed/README.chromium
+++ b/third_party/feed/README.chromium
@@ -2,7 +2,7 @@
 Short name: feed
 URL: https://chromium.googlesource.com/feed
 Version: 0
-Revision: 23d32902a8bd6f4d55dea6a46fff43325c61b532
+Revision: 5eaab0ec4f162c4f8d7901e14333127b16bcb7ac
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index b89916fe..efe27434 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,9 +1,9 @@
 Name: harfbuzz-ng
 Short Name: harfbuzz-ng
 URL: http://harfbuzz.org
-Version: 2.1.1
-Date: 20181126
-Revision: 574d888c8a409295a952361a39c8e83a52a0fc3d
+Version: 2.1.3-182
+Date: 20181129
+Revision: e0307de818ad1f70ef96938642bda61d7a62532a
 Security Critical: yes
 License: MIT
 License File: src/COPYING
@@ -12,18 +12,14 @@
 This is harfbuzz-ng, a new implementation of harfbuzz with a different
 API from the old one.
 
-This copy of harfbuzz is updated by putting the new commit hash matching one in
-https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz/ to the
-top level DEPS file. When upgrading, check in ther HarfBuzz repository whether
-files have been added or removed in upstream and whether the BUILD.gn file needs
-to be updated to reflect that or whether the files can be added to the exception
-lis below.
+This copy of harfbuzz is usually updated by running
+    $ third_party/harfbuzz-ng/roll-harfbuzz.sh
+from your Chromium ./src directory.
 
-Example:
-    $ cd ~/dev/harfbuzz/
-    $ git diff --diff-filter=A --stat 1.8.3..1.8.7
-
-Replace 1.8.3 and 1.8.7 with the respective revision hashes for your roll CL.
+This should update your checkout by putting the new upstream HarfBuzz ToT commit
+hash top level DEPS file. In cases added or deleted files have been detected in
+HarfBuzz' src directory, a step in the script will fail and you should edit the
+BUILD.gn file accordingly and continue the roll manually.
 
 Chromium-local cherry picks or patches can be done by pushing new branches to
 refs/heads/chromium/ of [1]. The set of HarfBuzz OWNERS has write rights to this
diff --git a/third_party/harfbuzz-ng/roll-harfbuzz.sh b/third_party/harfbuzz-ng/roll-harfbuzz.sh
new file mode 100755
index 0000000..670930a
--- /dev/null
+++ b/third_party/harfbuzz-ng/roll-harfbuzz.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+rolldeps() {
+  STEP="roll-deps" &&
+  REVIEWERS=$(grep -E -v "^$|#" third_party/harfbuzz-ng/OWNERS | paste -s -d,) &&
+  roll-dep -r "${REVIEWERS}" --roll-to origin/upstream/master "$@" src/third_party/harfbuzz-ng/src/
+}
+
+updatereadme() {
+  STEP="update README.chromium" &&
+  HBVERSION=$(git -C third_party/harfbuzz-ng/src/ describe --long) &&
+  HBCOMMIT=$(git -C third_party/harfbuzz-ng/src/ rev-parse HEAD) &&
+  HBDATE=$(date "+%Y%m%d")
+  sed -i'' -e "s/^Version: .*\$/Version: ${HBVERSION%-*}/" third_party/harfbuzz-ng/README.chromium &&
+  sed -i'' -e "s/^Revision: .*\$/Revision: ${HBCOMMIT}/" third_party/harfbuzz-ng/README.chromium &&
+  sed -i'' -e "s/^Date: .*\$/Date: ${HBDATE}/" third_party/harfbuzz-ng/README.chromium &&
+  git add third_party/harfbuzz-ng/README.chromium
+}
+
+previousrev() {
+  STEP="original revision" &&
+  PREVIOUS_HARFBUZZ_REV=$(git grep "'harfbuzz_revision':" HEAD~1 -- DEPS | grep -Eho "[0-9a-fA-F]{32}")
+}
+
+check_added_deleted_files() {
+  STEP="Check for added or deleted files since last HarfBuzz revision" &&
+  previousrev &&
+  ADDED_FILES=$(git -C third_party/harfbuzz-ng/src/ diff --diff-filter=A --name-only ${PREVIOUS_HARFBUZZ_REV} -- src/ | paste -s -d,) &&
+  DELETED_FILES=$(git -C third_party/harfbuzz-ng/src/ diff --diff-filter=D --name-only ${PREVIOUS_HARFBUZZ_REV} -- src/ | paste -s -d,) &&
+  if [ -n "$ADDED_FILES" ]; then echo "Added files detected: " $ADDED_FILES; fi &&
+  if [ -n "$DELETED_FILES" ]; then echo "Deleted files detected" $DELETED_FILES; fi &&
+  if [ -n "$ADDED_FILES" ] || [ -n "$DELETED_FILES" ]; then echo -e "\nPlease update src/third_party/harfbuzz-ng/BUILD.gn before continuing."; fi
+}
+
+commit() {
+  STEP="commit" &&
+  git commit --quiet --amend --no-edit
+}
+
+rolldeps "$@" &&
+updatereadme &&
+check_added_deleted_files &&
+commit ||
+{ echo "Failed step ${STEP}"; exit 1; }
diff --git a/tools/android/io_benchmark/compression_benchmark.cc b/tools/android/io_benchmark/compression_benchmark.cc
index 6e46544a..00ed41d 100644
--- a/tools/android/io_benchmark/compression_benchmark.cc
+++ b/tools/android/io_benchmark/compression_benchmark.cc
@@ -17,63 +17,75 @@
 
 namespace {
 
-void LogThroughputAndLatency(size_t size,
-                             int repeats,
+void LogThroughputAndLatency(size_t chunk_size,
+                             size_t chunk_count,
                              base::TimeTicks tick,
                              base::TimeTicks tock) {
-  size_t total_size = size * repeats;
+  size_t total_size = chunk_size * chunk_count;
   double elapsed_us = (tock - tick).InMicrosecondsF();
   double throughput = total_size / elapsed_us;
-  double latency_us = elapsed_us / repeats;
+  double latency_us = elapsed_us / chunk_count;
   LOG(INFO) << "  Throughput = " << throughput << "MB/s";
-  LOG(INFO) << "  Latency (size = " << size << ") = " << latency_us << "us";
-  LOG(INFO) << size << "," << throughput << "," << latency_us;
+  LOG(INFO) << "  Latency (size = " << chunk_size << ") = " << latency_us
+            << "us";
+  LOG(INFO) << "AS_CSV=" << chunk_size << "," << throughput << ","
+            << latency_us;
+}
+
+void CompressChunks(const std::string& contents,
+                    size_t chunk_size,
+                    bool snappy,
+                    std::vector<std::string>* compressed_chunks) {
+  CHECK(compressed_chunks);
+  size_t chunk_count = contents.size() / chunk_size;
+
+  for (size_t i = 0; i < chunk_count; ++i) {
+    std::string compressed;
+    base::StringPiece input(contents.c_str() + i * chunk_size, chunk_size);
+    if (snappy)
+      CHECK(snappy::Compress(input.data(), input.size(), &compressed));
+    else
+      CHECK(compression::GzipCompress(input, &compressed));
+
+    compressed_chunks->push_back(compressed);
+  }
 }
 
 void BenchmarkDecompression(const std::string& contents,
-                            int repeats,
+                            size_t chunk_size,
                             bool snappy) {
-  std::string compressed;
-  if (snappy) {
-    snappy::Compress(contents.c_str(), contents.size(), &compressed);
-  } else {
-    CHECK(compression::GzipCompress(contents, &compressed));
-  }
+  std::vector<std::string> compressed_chunks;
+  CompressChunks(contents, chunk_size, snappy, &compressed_chunks);
 
   auto tick = base::TimeTicks::Now();
-  for (int i = 0; i < repeats; ++i) {
+  for (const auto& chunk : compressed_chunks) {
     std::string uncompressed;
     if (snappy) {
-      snappy::Uncompress(compressed.c_str(), compressed.size(), &uncompressed);
+      snappy::Uncompress(chunk.c_str(), chunk.size(), &uncompressed);
     } else {
-      CHECK(compression::GzipUncompress(compressed, &uncompressed));
+      CHECK(compression::GzipUncompress(chunk, &uncompressed));
     }
   }
   auto tock = base::TimeTicks::Now();
 
-  LogThroughputAndLatency(contents.size(), repeats, tick, tock);
+  LogThroughputAndLatency(chunk_size, compressed_chunks.size(), tick, tock);
 }
 
 void BenchmarkCompression(const std::string& contents,
-                          int repeats,
+                          size_t chunk_size,
                           bool snappy) {
-  size_t compressed_size = 0;
   auto tick = base::TimeTicks::Now();
-  for (int i = 0; i < repeats; ++i) {
-    std::string compressed;
-    if (snappy) {
-      compressed_size =
-          snappy::Compress(contents.c_str(), contents.size(), &compressed);
-    } else {
-      CHECK(compression::GzipCompress(contents, &compressed));
-      compressed_size = compressed.size();
-    }
-  }
+  std::vector<std::string> compressed_chunks;
+  CompressChunks(contents, chunk_size, snappy, &compressed_chunks);
   auto tock = base::TimeTicks::Now();
 
+  size_t compressed_size = 0;
+  for (const auto& compressed_chunk : compressed_chunks)
+    compressed_size += compressed_chunk.size();
+
   double ratio = contents.size() / static_cast<double>(compressed_size);
   LOG(INFO) << "  Compression ratio = " << ratio;
-  LogThroughputAndLatency(contents.size(), repeats, tick, tock);
+  LogThroughputAndLatency(chunk_size, compressed_chunks.size(), tick, tock);
 }
 
 }  // namespace
@@ -90,18 +102,24 @@
   std::string contents;
   CHECK(base::ReadFileToString(path, &contents));
 
+  // Make sure we have at least 40MiB.
   constexpr size_t kPageSize = 1 << 12;
+  constexpr size_t target_size = 40 * 1024 * 1024;
+  std::string repeated_contents;
+  size_t repeats = target_size / contents.size() + 1;
+
+  repeated_contents.reserve(repeats * contents.size());
+  for (size_t i = 0; i < repeats; ++i)
+    repeated_contents.append(contents);
+
   for (bool use_snappy : {false, true}) {
     LOG(INFO) << "\n\n\n\n" << (use_snappy ? "Snappy" : "Gzip");
-    for (size_t size = kPageSize; size < contents.size() * 2; size *= 2) {
-      size_t actual_size = std::min(contents.size(), size);
-      std::string data = contents.substr(0, actual_size);
-      LOG(INFO) << "Size = " << actual_size;
+    for (size_t size = kPageSize; size < contents.size(); size *= 2) {
+      LOG(INFO) << "Size = " << size;
       LOG(INFO) << "Compression";
-      BenchmarkCompression(data, (10 * 1024 * kPageSize) / actual_size,
-                           use_snappy);  // 40MiB.
+      BenchmarkCompression(repeated_contents, size, use_snappy);
       LOG(INFO) << "Decompression";
-      BenchmarkDecompression(data, 100, use_snappy);
+      BenchmarkDecompression(repeated_contents, size, use_snappy);
     }
   }
   return 0;
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index f612e6c..8b762dc 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -347,7 +347,7 @@
     return
 
   gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin')
-  GNUWIN_VERSION = '8'
+  GNUWIN_VERSION = '9'
   GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp')
   if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION:
     print 'GNU Win tools already up to date.'
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 807fcb7..8b73798 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -492,10 +492,10 @@
     },
 
     'chromium.webrtc': {
-      'Android Builder': 'android_debug_static_bot_arm64',
+      'WebRTC Chromium Android Builder': 'android_debug_static_bot_arm64',
       'WebRTC Chromium Linux Builder': 'gpu_tests_release_bot',
-      'Mac Builder': 'gpu_tests_release_bot',
-      'Win Builder': 'release_bot_x86_minimal_symbols_no_com_init_hooks_with_codecs',
+      'WebRTC Chromium Mac Builder': 'gpu_tests_release_bot',
+      'WebRTC Chromium Win Builder': 'release_bot_x86_minimal_symbols_no_com_init_hooks_with_codecs',
     },
 
     'chromium.webrtc.fyi': {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8acff09..ac69d28 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -20881,6 +20881,9 @@
   <int value="2642" label="FlexboxSingleLineAlignContent"/>
   <int value="2643" label="SignedExchangeInnerResponseInMainFrame"/>
   <int value="2644" label="SignedExchangeInnerResponseInSubFrame"/>
+  <int value="2645" label="CSSSelectorNotWithValidList"/>
+  <int value="2646" label="CSSSelectorNotWithInvalidList"/>
+  <int value="2647" label="CSSSelectorNotWithPartiallyValidList"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
@@ -34049,6 +34052,7 @@
   <int value="3" label="Shutdown in foreground; no log; with memory warning"/>
   <int value="4" label="Shutdown in foreground; with log; with memory warning"/>
   <int value="5" label="First launch after upgrade"/>
+  <int value="6" label="Shutdown in foreground, main thread not responding"/>
 </enum>
 
 <enum name="MobileSessionStartAction">
@@ -54075,6 +54079,13 @@
   <int value="3" label="Desktop Aura"/>
 </enum>
 
+<enum name="WindowOcclusionState">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="Visible"/>
+  <int value="2" label="Occluded"/>
+  <int value="3" label="Hidden"/>
+</enum>
+
 <enum name="WindowOpenDisposition">
   <int value="0" label="Unknown"/>
   <int value="1" label="Current Tab"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 64b3d4ac..e78e53c 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -8336,7 +8336,25 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="Autofill.WalletAddresses" units="addresses"
+    expires_after="2019-06-01">
+<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
+
+  <owner>sebsg@chromium.org</owner>
+  <owner>jkrcal@chromium.org</owner>
+  <summary>
+    The number of Wallet addresses that were added to Chrome or removed from
+    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
+    the Sync server. Recorded only if both the user had previously non-empty
+    data set locally and the new data set is also non-empty (to rule out initial
+    sync and wiping out data).
+  </summary>
+</histogram>
+
 <histogram name="Autofill.WalletAddressesAdded" units="addresses">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by Autofill.WalletAddresses.Added.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -8349,6 +8367,10 @@
 </histogram>
 
 <histogram name="Autofill.WalletAddressesAddedOrRemoved" units="addresses">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by
+    Autofill.WalletAddresses.AddedOrRemoved.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -8362,6 +8384,9 @@
 </histogram>
 
 <histogram name="Autofill.WalletAddressesRemoved" units="addresses">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by Autofill.WalletAddresses.Removed.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -8373,7 +8398,25 @@
   </details>
 </histogram>
 
+<histogram base="true" name="Autofill.WalletCards" units="credit cards"
+    expires_after="2019-06-01">
+<!-- Name completed by histogram_suffixes name="AutofillWalletCardsDiff" -->
+
+  <owner>sebsg@chromium.org</owner>
+  <owner>jkrcal@chromium.org</owner>
+  <summary>
+    The number of Wallet credit cards that were added to Chrome or removed from
+    Chrome via Sync. Recorded when receiving an AUTOFILL_WALLET_DATA update from
+    the Sync server. Recorded only if both the user had previously non-empty
+    data set locally and the new data set is also non-empty (to rule out initial
+    sync and wiping out data).
+  </summary>
+</histogram>
+
 <histogram name="Autofill.WalletCardsAdded" units="credit cards">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by Autofill.WalletCards.Added.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -8386,6 +8429,9 @@
 </histogram>
 
 <histogram name="Autofill.WalletCardsAddedOrRemoved" units="credit cards">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by Autofill.WalletCards.AddedOrRemoved.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -8399,6 +8445,9 @@
 </histogram>
 
 <histogram name="Autofill.WalletCardsRemoved" units="credit cards">
+  <obsolete>
+    Deprecated as of 11/2018, replaced by Autofill.WalletCards.Removed.
+  </obsolete>
   <owner>sebsg@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>
@@ -35770,6 +35819,19 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="Gaia.AuthFetcher.ListAccounts.NetErrorCodes.Retry"
+    enum="NetErrorCodes" expires_after="2019-08-30">
+  <owner>droger@chromium.org</owner>
+  <owner>msarda@chromium.org</owner>
+<!-- Name completed by histogram_suffixes name="GaiaListAccountsRetry" -->
+
+  <summary>
+    Reports the network error code for requests to the ListAccounts Gaia
+    endpoint. There are suffixes for individual tries (0 is the initial request,
+    and 1-8 are retries).
+  </summary>
+</histogram>
+
 <histogram name="Gaia.AuthFetcher.ListAccounts.ProcessUptime.Error" units="ms"
     expires_after="2019-08-30">
   <owner>droger@chromium.org</owner>
@@ -42093,6 +42155,17 @@
   </summary>
 </histogram>
 
+<histogram name="IOS.MainThreadFreezeDetection.RecoveredAfter" units="ms"
+    expires_after="2019-11-30">
+  <owner>olivierrobin@chromium.org</owner>
+  <summary>
+    The time during which main thread was not responding. 0 if application was
+    killed before recovering. Logged after an action posted on the main thread
+    is not executed immediately. The histogram is sent when the task is finally
+    executed or on next application startup.
+  </summary>
+</histogram>
+
 <histogram name="IOS.NTP.Impression" enum="IOSNTPImpression">
   <owner>gambard@chromium.org</owner>
   <summary>
@@ -43933,6 +44006,33 @@
   </summary>
 </histogram>
 
+<histogram name="ManualFallback.VisibleSuggestions.OpenCreditCards"
+    units="Suggestions" expires_after="2019-12-31">
+  <owner>javierrobles@chromium.org</owner>
+  <summary>
+    Tracks the number of autofill suggestions present when the user taps on the
+    credit card button in manual fallback.
+  </summary>
+</histogram>
+
+<histogram name="ManualFallback.VisibleSuggestions.OpenPasswords"
+    units="Suggestions" expires_after="2019-12-31">
+  <owner>javierrobles@chromium.org</owner>
+  <summary>
+    Tracks the number of password suggestions present when the user taps on the
+    password button in manual fallback.
+  </summary>
+</histogram>
+
+<histogram name="ManualFallback.VisibleSuggestions.OpenProfiles"
+    units="Suggestions" expires_after="2019-12-31">
+  <owner>javierrobles@chromium.org</owner>
+  <summary>
+    Tracks the number of autofill suggestions present when the user taps on the
+    profiles (address) button in manual fallback.
+  </summary>
+</histogram>
+
 <histogram name="Media.AcceleratedCompositingActive" enum="BooleanSuccess">
   <obsolete>
     Deprecated as of July 21, 2014.
@@ -126250,6 +126350,15 @@
   </summary>
 </histogram>
 
+<histogram name="WindowOcclusionChanged" enum="WindowOcclusionState"
+    expires_after="2019-12-02">
+  <owner>davidbienvenu@chromium.org</owner>
+  <owner>fdoray@chromium.org</owner>
+  <summary>
+    A top level window's occlusion state. Recorded each time the state changes.
+  </summary>
+</histogram>
+
 <histogram name="Windows.ComputeNativeWindowOcclusionTime" units="microseconds">
   <owner>fdoray@chromium.org</owner>
   <summary>
@@ -127470,6 +127579,12 @@
   <affected-histogram name="Autofill.UploadEvent"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="AutofillWalletCardsDiff" separator=".">
+  <suffix name="Added" label="Added"/>
+  <suffix name="AddedOrRemoved" label="Added or removed"/>
+  <suffix name="Removed" label="Removed"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="BackgroundFetchDatabaseStorageErrors" separator=".">
   <suffix name="CleanupTask" label="CleanupTask"/>
   <suffix name="CreateMetadataTask" label="CreateMetadata DatabaseTask"/>
@@ -130331,6 +130446,19 @@
   <affected-histogram name="PLT.PT_StartToFinish"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="GaiaListAccountsRetry" separator="_">
+  <suffix name="0" label="Inital request"/>
+  <suffix name="1" label="1st retry"/>
+  <suffix name="2" label="2nd retry"/>
+  <suffix name="3" label="3rd retry"/>
+  <suffix name="4" label="4th retry"/>
+  <suffix name="5" label="5th retry"/>
+  <suffix name="6" label="6th retry"/>
+  <suffix name="7" label="7th retry"/>
+  <suffix name="8" label="8th retry"/>
+  <affected-histogram name="Gaia.AuthFetcher.ListAccounts.NetErrorCodes.Retry"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="GeolocationSettingsDialogSource" separator=".">
   <suffix name="DSE" label="Default search engine"/>
   <suffix name="NonDSE" label="Non-default search engine"/>
diff --git a/ui/aura/window.h b/ui/aura/window.h
index f0cca07..010edc9 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -96,20 +96,23 @@
     STACK_ABOVE,
     STACK_BELOW
   };
+
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
   enum class OcclusionState {
     // The window's occlusion state isn't tracked (Window::TrackOcclusionState)
     // or hasn't been computed yet.
-    UNKNOWN,
+    UNKNOWN = 0,
     // The window or one of its descendants IsVisible() [1] and:
     // - Its bounds aren't completely covered by fully opaque windows [2], or,
     // - Its transform, bounds or opacity is animated.
-    VISIBLE,
+    VISIBLE = 1,
     // The window or one of its descendants IsVisible() [1], but they all:
     // - Have bounds completely covered by fully opaque windows [2], and,
     // - Have no transform, bounds or opacity animation.
-    OCCLUDED,
+    OCCLUDED = 2,
     // The window is not IsVisible() [1].
-    HIDDEN,
+    HIDDEN = 3,
     // [1] A window can only be IsVisible() if all its parent are IsVisible().
     // [2] A window is "fully opaque" if:
     // - It's visible (IsVisible()).
@@ -122,6 +125,7 @@
     //
     // TODO(fdoray): A window that clips its children shouldn't be VISIBLE just
     // because it has an animated child.
+    kMaxValue = HIDDEN,
   };
 
   typedef std::vector<Window*> Windows;
diff --git a/ui/aura/window_occlusion_tracker.cc b/ui/aura/window_occlusion_tracker.cc
index 4e6cb1b..f7e4fbbb 100644
--- a/ui/aura/window_occlusion_tracker.cc
+++ b/ui/aura/window_occlusion_tracker.cc
@@ -6,6 +6,7 @@
 
 #include "base/auto_reset.h"
 #include "base/containers/adapters.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "third_party/skia/include/core/SkRect.h"
 #include "third_party/skia/include/core/SkRegion.h"
@@ -714,6 +715,8 @@
 
 void WindowOcclusionTracker::OnOcclusionStateChanged(
     WindowTreeHost* host,
-    aura::Window::OcclusionState new_state) {}
+    aura::Window::OcclusionState new_state) {
+  UMA_HISTOGRAM_ENUMERATION("WindowOcclusionChanged", new_state);
+}
 
 }  // namespace aura
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index 370391b..ee11c97 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -212,6 +212,23 @@
                'SIZE_TB',
                'SIZE_PB'];
 
+  // TODO(crbug.com/909997): remove this if clause when translations are fixed.
+  if (window.postProcessedLoadTimeData_ !== true) {
+    const language = loadTimeData.getString('language');
+
+    // Replace invalid Hindi SIZE units translations, crbug.com/908767.
+    if (language === 'hi') {
+      loadTimeData.overrideValues({
+        'SIZE_KB': '$1 केबी',
+        'SIZE_MB': '$1 एमबी',
+      });
+    }
+
+    if (typeof language === 'string') {
+      window.postProcessedLoadTimeData_ = true;
+    }
+  }
+
   // Minimum values for the units above.
   var STEPS = [0,
                Math.pow(2, 10),
diff --git a/ui/file_manager/integration_tests/file_manager/crostini.js b/ui/file_manager/integration_tests/file_manager/crostini.js
index bf70c95..f2c69b4 100644
--- a/ui/file_manager/integration_tests/file_manager/crostini.js
+++ b/ui/file_manager/integration_tests/file_manager/crostini.js
@@ -1,50 +1,33 @@
 // Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 'use strict';
 
-testcase.mountCrostini = function() {
+testcase.mountCrostini = async function() {
   const fakeLinuxFiles = '#directory-tree [root-type-icon="crostini"]';
   const realLinxuFiles = '#directory-tree [volume-type-icon="crostini"]';
-  let appId;
 
-  StepsRunner.run([
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []);
-    },
-    // Add entries to crostini volume, but do not mount.
-    function(results) {
-      appId = results.windowId;
-      addEntries(['crostini'], BASIC_CROSTINI_ENTRY_SET, this.next);
-    },
-    // Linux files fake root is shown.
-    function() {
-      remoteCall.waitForElement(appId, fakeLinuxFiles).then(this.next);
-    },
-    // Mount crostini, and ensure real root and files are shown.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fakeLinuxFiles]);
-      remoteCall.waitForElement(appId, realLinxuFiles).then(this.next);
-    },
-    function() {
-      const files = TestEntryInfo.getExpectedRows(BASIC_CROSTINI_ENTRY_SET);
-      remoteCall.waitForFiles(appId, files).then(this.next);
-    },
-    // Unmount and ensure fake root is shown.
-    function() {
-      // Unmount and ensure fake root is shown.
-      remoteCall.callRemoteTestUtil('unmount', null, ['crostini']);
-      remoteCall.waitForElement(appId, fakeLinuxFiles).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.hello], []);
+
+  // Add entries to crostini volume, but do not mount.
+  await addEntries(['crostini'], BASIC_CROSTINI_ENTRY_SET);
+
+  // Linux files fake root is shown.
+  await remoteCall.waitForElement(appId, fakeLinuxFiles);
+
+  // Mount crostini, and ensure real root and files are shown.
+  remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fakeLinuxFiles]);
+  await remoteCall.waitForElement(appId, realLinxuFiles);
+  const files = TestEntryInfo.getExpectedRows(BASIC_CROSTINI_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Unmount and ensure fake root is shown.
+  remoteCall.callRemoteTestUtil('unmount', null, ['crostini']);
+  await remoteCall.waitForElement(appId, fakeLinuxFiles);
 };
 
-testcase.sharePathWithCrostini = function() {
+testcase.sharePathWithCrostini = async function() {
   const fakeLinuxFiles = '#directory-tree [root-type-icon="crostini"]';
   const realLinuxFiles = '#directory-tree [volume-type-icon="crostini"]';
   const downloads = '#directory-tree [volume-type-icon="downloads"]';
@@ -53,50 +36,33 @@
       '[command="#share-with-linux"]:not([hidden]):not([disabled])';
   const menuNoShareWithLinux = '#file-context-menu:not([hidden]) ' +
       '[command="#share-with-linux"][hidden][disabled="disabled"]';
-  let appId;
 
-  StepsRunner.run([
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []);
-    },
-    // Ensure fake Linux files root is shown.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.waitForElement(appId, fakeLinuxFiles).then(this.next);
-    },
-    // Mount crostini, and ensure real root is shown.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fakeLinuxFiles]);
-      remoteCall.waitForElement(appId, realLinuxFiles).then(this.next);
-    },
-    // Go back to downloads, wait for photos dir to be shown.
-    function(results) {
-      remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [downloads]);
-      remoteCall.waitForElement(appId, photos).then(this.next);
-    },
-    // Right-click 'photos' directory, ensure 'Share with Linux' is shown.
-    function(results) {
-      remoteCall.callRemoteTestUtil('fakeMouseRightClick', appId, [photos]);
-      remoteCall.waitForElement(appId, menuShareWithLinux).then(this.next);
-    },
-    // Click on 'Share with Linux', ensure menu is closed.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId,
-          ['#file-context-menu [command="#share-with-linux"]'], this.next);
-      remoteCall.waitForElement(appId, '#file-context-menu[hidden]')
-          .then(this.next);
-    },
-    // Right-click 'photos' directory, ensure 'Share with Linux' is not shown.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseRightClick', appId, ['#file-list [file-name="photos"'],
-          this.next);
-      remoteCall.waitForElement(appId, menuNoShareWithLinux).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.photos], []);
+
+  // Ensure fake Linux files root is shown.
+  await remoteCall.waitForElement(appId, fakeLinuxFiles);
+
+  // Mount crostini, and ensure real root is shown.
+  remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fakeLinuxFiles]);
+  await remoteCall.waitForElement(appId, realLinuxFiles);
+
+  // Go back to downloads, wait for photos dir to be shown.
+  remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [downloads]);
+  await remoteCall.waitForElement(appId, photos);
+
+  // Right-click 'photos' directory, ensure 'Share with Linux' is shown.
+  remoteCall.callRemoteTestUtil('fakeMouseRightClick', appId, [photos]);
+  await remoteCall.waitForElement(appId, menuShareWithLinux);
+
+  // Click on 'Share with Linux', ensure menu is closed.
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId,
+      ['#file-context-menu [command="#share-with-linux"]']);
+  await remoteCall.waitForElement(appId, '#file-context-menu[hidden]');
+
+  // Right-click 'photos' directory, ensure 'Share with Linux' is not shown.
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseRightClick', appId, ['#file-list [file-name="photos"']);
+  await remoteCall.waitForElement(appId, menuNoShareWithLinux);
 };
diff --git a/ui/file_manager/integration_tests/file_manager/install_linux_package_dialog.js b/ui/file_manager/integration_tests/file_manager/install_linux_package_dialog.js
index bd57286b..3c6e764a 100644
--- a/ui/file_manager/integration_tests/file_manager/install_linux_package_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/install_linux_package_dialog.js
@@ -1,99 +1,69 @@
 // Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 'use strict';
 
-testcase.installLinuxPackageDialog = function() {
+testcase.installLinuxPackageDialog = async function() {
   const fake = '#directory-tree .tree-item [root-type-icon="crostini"]';
   const real = '#directory-tree .tree-item [volume-type-icon="crostini"]';
+
   // The dialog has an INSTALL and OK button, both as .cr-dialog-ok, but only
   // one is visible at a time.
   const dialog = '#install-linux-package-dialog';
   const okButton = dialog + ' .cr-dialog-ok:not([hidden])';
 
-  let appId;
 
-  StepsRunner.run([
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Add entries to crostini volume, but do not mount.
-    function(results) {
-      appId = results.windowId;
-      addEntries(['crostini'], [ENTRIES.debPackage], this.next);
-    },
-    // Linux files fake root is shown.
-    function() {
-      remoteCall.waitForElement(appId, fake).then(this.next);
-    },
-    // Mount crostini, and ensure real root and files are shown.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fake]);
-      remoteCall.waitForElement(appId, real).then(this.next);
-    },
-    function() {
-      const files = TestEntryInfo.getExpectedRows([ENTRIES.debPackage]);
-      remoteCall.waitForFiles(appId, files).then(this.next);
-    },
-    // Open the deb package.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, [ENTRIES.debPackage.targetPath], this.next);
-    },
-    // Ensure package install dialog is shown.
-    function() {
-      remoteCall.waitForElement(appId, dialog).then(this.next);
-    },
-    function() {
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'queryAllElements', appId,
-                ['.install-linux-package-details-frame'])
-            .then(function(elements) {
-              // The details are in separate divs on multiple lines, which the
-              // test api returns as a single string. These values come from
-              // fake_cicerone_client.cc.
-              return elements[0] &&
-                  elements[0].text ==
-                      ('Details' +
-                       'Application: Fake Package' +
-                       'Version: 1.0' +
-                       'Description: A package that is fake') ||
-                  pending('Waiting for installation to start.');
-            });
-      }).then(this.next);
-    },
-    // Begin installation.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [okButton], this.next);
-    },
-    // Wait for the installation to start (under test, we use a fake D-Bus
-    // client, so it doesn't actually install anything).
-    function() {
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil('queryAllElements', appId, ['.cr-dialog-text'])
-            .then(function(elements) {
-              return elements[0] &&
-                  elements[0].text == 'Installation successfully started.' ||
-                  pending('Waiting for installation to start.');
-            });
-      }).then(this.next);
-    },
-    // Dismiss dialog
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [okButton], this.next);
-    },
-    // Ensure dialog closes
-    function() {
-      remoteCall.waitForElementLost(appId, dialog).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  const {appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS, null);
+
+  // Add entries to crostini volume, but do not mount.
+  await addEntries(['crostini'], [ENTRIES.debPackage]);
+
+  // Linux files fake root is shown.
+  await remoteCall.waitForElement(appId, fake);
+
+  // Mount crostini, and ensure real root and files are shown.
+  remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [fake]);
+  await remoteCall.waitForElement(appId, real);
+  const files = TestEntryInfo.getExpectedRows([ENTRIES.debPackage]);
+  await remoteCall.waitForFiles(appId, files);
+
+  // Open the deb package.
+  await remoteCall.callRemoteTestUtil(
+      'openFile', appId, [ENTRIES.debPackage.targetPath]);
+
+  // Ensure package install dialog is shown.
+  await remoteCall.waitForElement(appId, dialog);
+  await repeatUntil(async () => {
+    const elements = await remoteCall.callRemoteTestUtil(
+        'queryAllElements', appId, ['.install-linux-package-details-frame']);
+    // The details are in separate divs on multiple lines, which the test api
+    // returns as a single string. These values come from
+    // fake_cicerone_client.cc.
+    return elements[0] &&
+        elements[0].text ==
+            ('Details' +
+             'Application: Fake Package' +
+             'Version: 1.0' +
+             'Description: A package that is fake') ||
+        pending('Waiting for installation to start.');
+  });
+
+  // Begin installation.
+  await remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [okButton]);
+
+  // Wait for the installation to start (under test, we use a fake D-Bus
+  // client, so it doesn't actually install anything).
+  await repeatUntil(async () => {
+    const elements = await remoteCall.callRemoteTestUtil(
+        'queryAllElements', appId, ['.cr-dialog-text']);
+    return elements[0] &&
+        elements[0].text == 'Installation successfully started.' ||
+        pending('Waiting for installation to start.');
+  });
+
+  // Dismiss dialog
+  await remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [okButton]);
+
+  // Ensure dialog closes
+  await remoteCall.waitForElementLost(appId, dialog);
 };
diff --git a/ui/file_manager/integration_tests/file_manager/launcher_search.js b/ui/file_manager/integration_tests/file_manager/launcher_search.js
index 5e526c38..20cafd16 100644
--- a/ui/file_manager/integration_tests/file_manager/launcher_search.js
+++ b/ui/file_manager/integration_tests/file_manager/launcher_search.js
@@ -1,7 +1,6 @@
 // Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 /**
  * @fileoverview Tests for interface we expose to Launcher app's search feature.
  */
@@ -13,50 +12,33 @@
 /**
  * Tests opening an image using the Launcher app's search feature.
  */
-testcase.launcherOpenSearchResult = function() {
-  let galleryAppId;
+testcase.launcherOpenSearchResult = async function() {
   const imageName = ENTRIES.desktop.nameText;
-  StepsRunner.run([
-    // Create an image file in Drive.
-    function() {
-      addEntries(['drive'], [ENTRIES.desktop]).then(this.next);
-    },
-    // Get the image file URL.
-    function() {
-      remoteCall
-          .callRemoteTestUtil(
-              'getFilesUnderVolume', null, ['drive', [imageName]])
-          .then(this.next);
-    },
-    // Request Files app to open the image URL.
-    // This emulates the Launcher interaction with Files app.
-    function(fileURLs) {
-      chrome.test.assertEq(1, fileURLs.length);
-      remoteCall.callRemoteTestUtil(
-          'launcherSearchOpenResult', null, [fileURLs[0]], this.next);
-    },
-    // Files app opens Gallery for images, so check Gallery app has been
-    // launched.
-    function() {
-      galleryApp.waitForWindow('gallery.html').then(this.next);
-    },
-    // Check the image is displayed.
-    function(windowId) {
-      galleryAppId = windowId;
-      const imageNameNoExtension = imageName.split('.')[0];
-      galleryApp.waitForSlideImage(galleryAppId, 0, 0, imageNameNoExtension)
-          .then(this.next);
-    },
-    // Check that the previous step succeeded.
-    function(imageElement) {
-      chrome.test.assertTrue(
-          !!imageElement, 'Failed to find the slide image element');
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
-};
 
+  // Create an image file in Drive.
+  await addEntries(['drive'], [ENTRIES.desktop]);
+
+  // Get the image file URL.
+  const fileURLs = await remoteCall.callRemoteTestUtil(
+      'getFilesUnderVolume', null, ['drive', [imageName]]);
+
+  // Request Files app to open the image URL.
+  // This emulates the Launcher interaction with Files app.
+  chrome.test.assertEq(1, fileURLs.length);
+  await remoteCall.callRemoteTestUtil(
+      'launcherSearchOpenResult', null, [fileURLs[0]]);
+
+  // Files app opens Gallery for images, so check Gallery app has been
+  // launched.
+  const galleryAppId = await galleryApp.waitForWindow('gallery.html');
+
+  // Check the image is displayed.
+  const imageNameNoExtension = imageName.split('.')[0];
+
+  // Check: the slide image element should appear.
+  chrome.test.assertTrue(
+      !!await galleryApp.waitForSlideImage(
+          galleryAppId, 0, 0, imageNameNoExtension),
+      'Failed to find the slide image element');
+};
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/my_files.js b/ui/file_manager/integration_tests/file_manager/my_files.js
index fc7bc54..0d9d9dcac 100644
--- a/ui/file_manager/integration_tests/file_manager/my_files.js
+++ b/ui/file_manager/integration_tests/file_manager/my_files.js
@@ -1,13 +1,10 @@
 // Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 /**
  * Tests if MyFiles is displayed when flag is true.
  */
-testcase.showMyFiles = function() {
-  let appId;
-
+testcase.showMyFiles = async function() {
   const expectedElementLabels = [
     'Recent: FakeItem',
     'My files: EntryListItem',
@@ -20,113 +17,74 @@
     'Offline: SubDirectoryItem',
   ];
 
-  StepsRunner.run([
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Get the directory tree elements.
-    function(results) {
-      appId = results.windowId;
-      const dirTreeQuery = ['#directory-tree [dir-type]'];
-      remoteCall.callRemoteTestUtil('queryAllElements', appId, dirTreeQuery)
-          .then(this.next);
-    },
-    // Check tree elements for the correct order and label/element type.
-    function(elements) {
-      var visibleElements = [];
-      for (let element of elements) {
-        if (!element.hidden) {  // Ignore hidden elements.
-          visibleElements.push(
-              element.attributes['entry-label'] + ': ' +
-              element.attributes['dir-type']);
-        }
-      }
-      chrome.test.assertEq(expectedElementLabels, visibleElements);
-      this.next();
-    },
-    // Select Downloads folder.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'selectVolume', appId, ['downloads'], this.next);
-    },
-    // Get the breadcrumbs elements.
-    function() {
-      const breadcrumbsQuery = ['#location-breadcrumbs .breadcrumb-path'];
-      remoteCall.callRemoteTestUtil(
-          'queryAllElements', appId, breadcrumbsQuery, this.next);
-    },
-    // Check that My Files is displayed on breadcrumbs.
-    function(breadcrumbs) {
-      const expectedBreadcrumbs = 'My files > Downloads';
-      const resultBreadscrubms =
-          breadcrumbs.map(crumb => crumb.text).join(' > ');
-      chrome.test.assertEq(expectedBreadcrumbs, resultBreadscrubms);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
+
+  // Get the directory tree elements.
+  const dirTreeQuery = ['#directory-tree [dir-type]'];
+  const elements = await remoteCall.callRemoteTestUtil(
+      'queryAllElements', appId, dirTreeQuery);
+
+  // Check tree elements for the correct order and label/element type.
+  var visibleElements = [];
+  for (let element of elements) {
+    if (!element.hidden) {  // Ignore hidden elements.
+      visibleElements.push(
+          element.attributes['entry-label'] + ': ' +
+          element.attributes['dir-type']);
+    }
+  }
+  chrome.test.assertEq(expectedElementLabels, visibleElements);
+
+  // Select Downloads folder.
+  await remoteCall.callRemoteTestUtil('selectVolume', appId, ['downloads']);
+
+  // Get the breadcrumbs elements.
+  const breadcrumbsQuery = ['#location-breadcrumbs .breadcrumb-path'];
+  const breadcrumbs = await remoteCall.callRemoteTestUtil(
+      'queryAllElements', appId, breadcrumbsQuery);
+
+  // Check that My Files is displayed on breadcrumbs.
+  const expectedBreadcrumbs = 'My files > Downloads';
+  const resultBreadscrubms = breadcrumbs.map(crumb => crumb.text).join(' > ');
+  chrome.test.assertEq(expectedBreadcrumbs, resultBreadscrubms);
 };
 
 /**
  * Tests search button hidden when selected My Files.
  */
-testcase.hideSearchButton = function() {
-  let appId;
+testcase.hideSearchButton = async function() {
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
 
-  StepsRunner.run([
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Select Downloads folder.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'selectVolume', appId, ['downloads'], this.next);
-    },
-    // Get the search button element.
-    function(result) {
-      chrome.test.assertTrue(result);
-      const buttonQuery = ['#search-button'];
-      remoteCall.callRemoteTestUtil(
-          'queryAllElements', appId, buttonQuery, this.next);
-    },
-    // Check that search button is visible on Downloads.
-    function(buttonElements) {
-      chrome.test.assertEq(1, buttonElements.length);
-      chrome.test.assertFalse(buttonElements[0].hidden);
-      this.next();
-    },
-    // Select My Files folder.
-    function() {
-      const myFilesQuery = '#directory-tree [entry-label="My files"]';
-      const isDriveQuery = false;
-      remoteCall.callRemoteTestUtil(
-          'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery],
-          this.next);
-    },
-    // Get the search button element.
-    function(result) {
-      chrome.test.assertTrue(result);
-      const buttonQuery = ['#search-button'];
-      remoteCall.callRemoteTestUtil(
-          'queryAllElements', appId, buttonQuery, this.next);
-    },
-    // Check that search button is hidden on My Files.
-    function(buttonElements) {
-      chrome.test.assertEq(1, buttonElements.length);
-      chrome.test.assertTrue(buttonElements[0].hidden);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Select Downloads folder.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectVolume', appId, ['downloads']));
+
+  // Get the search button element.
+  const buttonQuery = ['#search-button'];
+  let buttonElements = await remoteCall.callRemoteTestUtil(
+      'queryAllElements', appId, buttonQuery);
+
+  // Check that search button is visible on Downloads.
+  chrome.test.assertEq(1, buttonElements.length);
+  chrome.test.assertFalse(buttonElements[0].hidden);
+
+  // Select My Files folder.
+  const myFilesQuery = '#directory-tree [entry-label="My files"]';
+  const isDriveQuery = false;
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery]));
+
+  // Get the search button element.
+  buttonElements = await remoteCall.callRemoteTestUtil(
+      'queryAllElements', appId, buttonQuery);
+
+  // Check that search button is hidden on My Files.
+  chrome.test.assertEq(1, buttonElements.length);
+  chrome.test.assertTrue(buttonElements[0].hidden);
 };
 
 /**
@@ -137,99 +95,61 @@
  * DirectoryTree expects NavigationModelItem to be the same instance through
  * updates.
  */
-testcase.directoryTreeRefresh = function() {
-  let appId;
+testcase.directoryTreeRefresh = async function() {
   const USB_VOLUME_QUERY = '#directory-tree [volume-type-icon="removable"]';
-  StepsRunner.run([
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Mount a USB volume.
-    function(results) {
-      appId = results.windowId;
-      sendTestMessage({name: 'mountFakeUsb'}).then(this.next);
-    },
-    // Wait for the USB volume to mount.
-    function() {
-      remoteCall.waitForElement(appId, USB_VOLUME_QUERY).then(this.next);
-    },
-    // Select Downloads folder.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'selectVolume', appId, ['downloads'], this.next);
-    },
-    function(result) {
-      chrome.test.assertTrue(result);
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
+
+  // Mount a USB volume.
+  await sendTestMessage({name: 'mountFakeUsb'});
+
+  // Wait for the USB volume to mount.
+  await remoteCall.waitForElement(appId, USB_VOLUME_QUERY);
+
+  // Select Downloads folder.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectVolume', appId, ['downloads']));
 };
 
 /**
  * Tests My Files displaying Downloads on file list (RHS) and opening Downloads
  * from file list.
  */
-testcase.myFilesDisplaysAndOpensEntries = function() {
-  let appId;
-  StepsRunner.run([
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Select My Files folder.
-    function(results) {
-      appId = results.windowId;
-      const myFilesQuery = '#directory-tree [entry-label="My files"]';
-      const isDriveQuery = false;
-      remoteCall.callRemoteTestUtil(
-          'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery],
-          this.next);
-    },
-    // Wait for file list to display Downloads and Crostini.
-    function(result) {
-      chrome.test.assertTrue(result);
-      const downloadsRow = ['Downloads', '--', 'Folder'];
-      const playFilesRow = ['Play files', '--', 'Folder'];
-      const crostiniRow = ['Linux files', '--', 'Folder'];
-      remoteCall
-          .waitForFiles(
-              appId, [downloadsRow, playFilesRow, crostiniRow],
-              {ignoreFileSize: true, ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Double click on Download on file list.
-    function() {
-      const downloadsFileListQuery = '#file-list [file-name="Downloads"]';
-      remoteCall
-          .callRemoteTestUtil(
-              'fakeMouseDoubleClick', appId, [downloadsFileListQuery])
-          .then(this.next);
-    },
-    // Wait for file list to Downloads' content.
-    function() {
-      remoteCall
-          .waitForFiles(
-              appId, [ENTRIES.beautiful.getExpectedRow()],
-              {ignoreFileSize: true, ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Get the selected navigation tree item.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'getSelectedTreeItem', appId, [], this.next);
-    },
-    // Get the selected navigation tree item.
-    function(result) {
-      chrome.test.assertEq('Downloads', result);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+testcase.myFilesDisplaysAndOpensEntries = async function() {
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
+
+  // Select My Files folder.
+  const myFilesQuery = '#directory-tree [entry-label="My files"]';
+  const isDriveQuery = false;
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery]));
+
+  // Wait for file list to display Downloads and Crostini.
+  const downloadsRow = ['Downloads', '--', 'Folder'];
+  const playFilesRow = ['Play files', '--', 'Folder'];
+  const crostiniRow = ['Linux files', '--', 'Folder'];
+  await remoteCall.waitForFiles(
+      appId, [downloadsRow, playFilesRow, crostiniRow],
+      {ignoreFileSize: true, ignoreLastModifiedTime: true});
+
+  // Double click on Download on file list.
+  const downloadsFileListQuery = '#file-list [file-name="Downloads"]';
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseDoubleClick', appId, [downloadsFileListQuery]);
+
+  // Wait for file list to Downloads' content.
+  await remoteCall.waitForFiles(
+      appId, [ENTRIES.beautiful.getExpectedRow()],
+      {ignoreFileSize: true, ignoreLastModifiedTime: true});
+
+  // Get the selected navigation tree item.
+  chrome.test.assertEq(
+      'Downloads',
+      await remoteCall.callRemoteTestUtil('getSelectedTreeItem', appId, []));
 };
 
 /**
@@ -238,8 +158,7 @@
  * If it doesn't update its children recursively it can cause directory tree to
  * not show or hide sub-folders crbug.com/864453.
  */
-testcase.myFilesUpdatesChildren = function() {
-  let appId;
+testcase.myFilesUpdatesChildren = async function() {
   const downloadsQuery = '#directory-tree [entry-label="Downloads"]';
   const hiddenFolder = new TestEntryInfo({
     type: EntryType.DIRECTORY,
@@ -249,183 +168,129 @@
     sizeText: '--',
     typeText: 'Folder'
   });
-  StepsRunner.run([
-    // Add a hidden folder.
-    function() {
-      // It can't be added via setupAndWaitUntilReady, because it isn't
-      // displayed and that function waits all entries to be displayed.
-      addEntries(['local'], [hiddenFolder], this.next);
-    },
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Select Downloads folder.
-    function(results) {
-      appId = results.windowId;
-      const isDriveQuery = false;
-      remoteCall.callRemoteTestUtil(
-          'selectInDirectoryTree', appId, [downloadsQuery, isDriveQuery],
-          this.next);
-    },
-    // Wait for gear menu to be displayed.
-    function() {
-      remoteCall.waitForElement(appId, '#gear-button').then(this.next);
-    },
-    // Open the gear menu by clicking the gear button.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, ['#gear-button'], this.next);
-    },
-    // Wait for menu to not be hidden.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForElement(appId, '#gear-menu:not([hidden])')
-          .then(this.next);
-    },
-    // Wait for menu item to appear.
-    function(result) {
-      remoteCall
-          .waitForElement(
-              appId, '#gear-menu-toggle-hidden-files:not([disabled])')
-          .then(this.next);
-    },
-    // Wait for menu item to appear.
-    function(result) {
-      remoteCall
-          .waitForElement(
-              appId, '#gear-menu-toggle-hidden-files:not([checked])')
-          .then(this.next);
-    },
-    // Click the menu item.
-    function(results) {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, ['#gear-menu-toggle-hidden-files'],
-          this.next);
-    },
-    // Check the hidden folder to be displayed in RHS.
-    function(result) {
-      remoteCall
-          .waitForFiles(
-              appId,
-              TestEntryInfo.getExpectedRows([hiddenFolder, ENTRIES.beautiful]),
-              {ignoreFileSize: true, ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Check the hidden folder to be displayed in LHS.
-    function() {
-      // Children of Downloads and named ".hidden-folder".
-      const hiddenFolderTreeQuery = downloadsQuery +
-          ' .tree-children .tree-item[entry-label=".hidden-folder"]';
-      remoteCall.waitForElement(appId, hiddenFolderTreeQuery).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+
+  // Add a hidden folder.
+  // It can't be added via setupAndWaitUntilReady, because it isn't
+  // displayed and that function waits all entries to be displayed.
+  await addEntries(['local'], [hiddenFolder]);
+
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
+
+  // Select Downloads folder.
+  const isDriveQuery = false;
+  await remoteCall.callRemoteTestUtil(
+      'selectInDirectoryTree', appId, [downloadsQuery, isDriveQuery]);
+
+  // Wait for gear menu to be displayed.
+  await remoteCall.waitForElement(appId, '#gear-button');
+
+  // Open the gear menu by clicking the gear button.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['#gear-button']));
+
+  // Wait for menu to not be hidden.
+  await remoteCall.waitForElement(appId, '#gear-menu:not([hidden])');
+
+  // Wait for menu item to appear.
+  await remoteCall.waitForElement(
+      appId, '#gear-menu-toggle-hidden-files:not([disabled])');
+
+  // Wait for menu item to appear.
+  await remoteCall.waitForElement(
+      appId, '#gear-menu-toggle-hidden-files:not([checked])');
+
+  // Click the menu item.
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['#gear-menu-toggle-hidden-files']);
+
+  // Check the hidden folder to be displayed in RHS.
+  await remoteCall.waitForFiles(
+      appId, TestEntryInfo.getExpectedRows([hiddenFolder, ENTRIES.beautiful]),
+      {ignoreFileSize: true, ignoreLastModifiedTime: true});
+
+  // Check the hidden folder to be displayed in LHS.
+  // Children of Downloads and named ".hidden-folder".
+  const hiddenFolderTreeQuery = downloadsQuery +
+      ' .tree-children .tree-item[entry-label=".hidden-folder"]';
+  await remoteCall.waitForElement(appId, hiddenFolderTreeQuery);
 };
 
 /**
  * Check naming a folder after navigating inside MyFiles using file list (RHS).
  * crbug.com/889636.
  */
-testcase.myFilesFolderRename = function() {
-  let appId;
+testcase.myFilesFolderRename = async function() {
   const textInput = '#file-list .table-row[renaming] input.rename';
-  StepsRunner.run([
-    // Open Files app on local Downloads.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []);
-    },
-    // Select "My files" folder via directory tree.
-    function(result) {
-      appId = result.windowId;
-      const myFilesQuery = '#directory-tree [entry-label="My files"]';
-      const isDriveQuery = false;
-      remoteCall.callRemoteTestUtil(
-          'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery],
-          this.next);
-    },
-    // Wait for Downloads to load.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'selectInDirectoryTree failed');
-      const expectedRows = [
-        ['Downloads', '--', 'Folder'],
-        ['Play files', '--', 'Folder'],
-        ['Linux files', '--', 'Folder'],
-      ];
-      remoteCall
-          .waitForFiles(
-              appId, expectedRows,
-              {ignoreFileSize: true, ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Select Downloads via file list.
-    function() {
-      const downloads = ['Downloads'];
-      remoteCall.callRemoteTestUtil('selectFile', appId, downloads)
-          .then(result => {
-            chrome.test.assertTrue(!!result, 'selectFile failed');
-            this.next();
-          });
-    },
-    // Open Downloads via file list.
-    function() {
-      const fileListItem = '#file-list .table-row';
-      const key = [fileListItem, 'Enter', false, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key).then(this.next);
-    },
-    // Wait for Downloads to load.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeKeyDown failed');
-      remoteCall.waitForFiles(appId, [ENTRIES.photos.getExpectedRow()])
-          .then(this.next);
-    },
-    // Select photos via file list.
-    function() {
-      const folder = ['photos'];
-      remoteCall.callRemoteTestUtil('selectFile', appId, folder)
-          .then(result => {
-            chrome.test.assertTrue(!!result, 'selectFile failed');
-            this.next();
-          });
-    },
-    // Press Ctrl+Enter for start renaming.
-    function() {
-      const fileListItem = '#file-list .table-row';
-      const key = [fileListItem, 'Enter', true, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key).then(this.next);
-    },
-    // Wait for input for renaming to appear.
-    function(result) {
-      chrome.test.assertTrue(result, 'fakeKeyDown ctrl+Enter failed');
-      // Check: the renaming text input should be shown in the file list.
-      remoteCall.waitForElement(appId, textInput).then(this.next);
-    },
-    // Type new name.
-    function() {
-      remoteCall.callRemoteTestUtil('inputText', appId, [textInput, 'new name'])
-          .then(this.next);
-    },
-    // Send Enter key to the text input.
-    function() {
-      const key = [textInput, 'Enter', false, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key).then(this.next);
-    },
-    // Wait for new name to appear on the file list.
-    function(result) {
-      chrome.test.assertTrue(result, 'fakeKeyDown failed');
-      const expectedRows = [['new name', '--', 'Folder', '']];
-      remoteCall
-          .waitForFiles(
-              appId, expectedRows,
-              {ignoreFileSize: true, ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+
+  // Open Files app on local Downloads.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.photos], []);
+
+  // Select "My files" folder via directory tree.
+  const myFilesQuery = '#directory-tree [entry-label="My files"]';
+  const isDriveQuery = false;
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'selectInDirectoryTree', appId, [myFilesQuery, isDriveQuery]),
+      'selectInDirectoryTree failed');
+
+  // Wait for Downloads to load.
+  const expectedRows = [
+    ['Downloads', '--', 'Folder'],
+    ['Play files', '--', 'Folder'],
+    ['Linux files', '--', 'Folder'],
+  ];
+  await remoteCall.waitForFiles(
+      appId, expectedRows,
+      {ignoreFileSize: true, ignoreLastModifiedTime: true});
+
+  // Select Downloads via file list.
+  const downloads = ['Downloads'];
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, downloads),
+      'selectFile failed');
+
+  // Open Downloads via file list.
+  const fileListItem = '#file-list .table-row';
+  const key = [fileListItem, 'Enter', false, false, false];
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key),
+      'fakeKeyDown failed');
+
+  // Wait for Downloads to load.
+  await remoteCall.waitForFiles(appId, [ENTRIES.photos.getExpectedRow()]);
+
+  // Select photos via file list.
+  const folder = ['photos'];
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, folder),
+      'selectFile failed');
+
+  // Press Ctrl+Enter for start renaming.
+  const key2 = [fileListItem, 'Enter', true, false, false];
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key2),
+      'fakeKeyDown ctrl+Enter failed');
+
+  // Wait for input for renaming to appear.
+  // Check: the renaming text input should be shown in the file list.
+  await remoteCall.waitForElement(appId, textInput);
+
+  // Type new name.
+  await remoteCall.callRemoteTestUtil(
+      'inputText', appId, [textInput, 'new name']);
+
+  // Send Enter key to the text input.
+  const key3 = [textInput, 'Enter', false, false, false];
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key3),
+      'fakeKeyDown failed');
+
+  // Wait for new name to appear on the file list.
+  const expectedRows2 = [['new name', '--', 'Folder', '']];
+  await remoteCall.waitForFiles(
+      appId, expectedRows2,
+      {ignoreFileSize: true, ignoreLastModifiedTime: true});
 };
diff --git a/ui/file_manager/integration_tests/file_manager/open_audio_files.js b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
index 1dd52c0..e3cc31e 100644
--- a/ui/file_manager/integration_tests/file_manager/open_audio_files.js
+++ b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
@@ -14,19 +14,18 @@
  * @return {Promise<Object>} Promise to be fulfilled with a track details
  *     object containing {title:string, artist:string}.
  */
-function getTrackText(audioAppId, track) {
+async function getTrackText(audioAppId, track) {
   const titleElement = audioPlayerApp.callRemoteTestUtil(
       'deepQueryAllElements', audioAppId,
       [trackListQuery(track + ' > .data > .data-title')]);
   const artistElement = audioPlayerApp.callRemoteTestUtil(
       'deepQueryAllElements', audioAppId,
       [trackListQuery(track + ' > .data > .data-artist')]);
-  return Promise.all([titleElement, artistElement]).then((data) => {
-    return {
-      title: data[0][0] && data[0][0].text,
-      artist: data[1][0] && data[1][0].text
-    };
-  });
+  const [title, artist] = await Promise.all([titleElement, artistElement]);
+  return {
+    title: title[0] && title[0].text,
+    artist: artist[0] && artist[0].text,
+  };
 }
 
 /**
@@ -87,95 +86,57 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioOpenClose(path) {
-  let appId;
-  let audioAppId;
-
+async function audioOpenClose(path) {
   const track = [ENTRIES.beautiful];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add an audio file to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, track, track);
-    },
-    // Open an audio file from |path|.
-    function(result) {
-      appId = result.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Close the Audio Player window.
-    function() {
-      audioPlayerApp.closeWindowAndWait(audioAppId).then(this.next);
-    },
-    // Check: Audio Player window should close.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'Failed to close audio window');
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add an audio file to Downloads and Drive.
+  const {appId} = await setupAndWaitUntilReady(null, path, null, track, track);
+
+  // Open an audio file from |path|.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Close the Audio Player window.
+  chrome.test.assertTrue(
+      !!await audioPlayerApp.closeWindowAndWait(audioAppId),
+      'Failed to close audio window');
 }
 
 /**
  * Tests an audio file opened from Downloads 1) auto-plays and 2) has the
  * correct track and artist details.
  */
-function audioOpenTrackDownloads() {
-  let appId;
-  let audioAppId;
-
+async function audioOpenTrackDownloads() {
   const track = [ENTRIES.beautiful];
 
-  StepsRunner.run([
-    // Open Files.App on Downloads, add an audio file to Downloads.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next, track, []);
-    },
-    // Open an audio file from Downloads.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Check: track 0 should be active.
-    function() {
-      getTrackText(audioAppId, '.track[index="0"][active]').then(this.next);
-    },
-    // Check: track 0 should have the correct title and artist.
-    function(song) {
-      chrome.test.assertEq('Beautiful Song', song.title);
-      chrome.test.assertEq('Unknown Artist', song.artist);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on Downloads, add an audio file to Downloads.
+  const {appId} =
+      await setupAndWaitUntilReady(null, RootPath.DOWNLOADS, null, track, []);
+
+  // Open an audio file from Downloads.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Check: track 0 should be active.
+  let song = await getTrackText(audioAppId, '.track[index="0"][active]');
+
+  // Check: track 0 should have the correct title and artist.
+  chrome.test.assertEq('Beautiful Song', song.title);
+  chrome.test.assertEq('Unknown Artist', song.artist);
 }
 
 /**
@@ -183,81 +144,55 @@
  * track and artist details. Tests the same when another Drive audio track is
  * opened from Files app.
  */
-function audioOpenMultipleTracksDrive() {
-  let appId;
-  let audioAppId;
-
+async function audioOpenMultipleTracksDrive() {
   const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded];
 
-  StepsRunner.run([
-    // Open Files.App on Drive, add the audio files to Drive.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DRIVE, this.next, [], tracks);
-    },
-    // Open an audio file from Drive.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Check: track 0 should be active.
-    function() {
-      getTrackText(audioAppId, '.track[index="0"][active]').then(this.next);
-    },
-    // Check: track 0 should have the correct title and artist.
-    function(song) {
-      chrome.test.assertEq('Beautiful Song', song.title);
-      chrome.test.assertEq('Unknown Artist', song.artist);
-      this.next();
-    },
-    // Check: track 1 should be inactive.
-    function() {
-      const inactive = trackListQuery('.track[index="1"]:not([active])');
-      audioPlayerApp.waitForElement(audioAppId, inactive).then(this.next);
-    },
-    // Open another audio file from Drive.
-    function(element) {
-      chrome.test.assertTrue(!!element);
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['newly added file.ogg'], this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(result) {
-      chrome.test.assertTrue(result);
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Check: track 1 should be active.
-    function() {
-      getTrackText(audioAppId, '.track[index="1"][active]').then(this.next);
-    },
-    // Check: track 1 should have the correct title and artist.
-    function(song) {
-      chrome.test.assertEq('newly added file', song.title);
-      chrome.test.assertEq('Unknown Artist', song.artist);
-      this.next();
-    },
-    // Check: track 0 should be inactive.
-    function() {
-      const inactive = trackListQuery('.track[index="0"]:not([active])');
-      audioPlayerApp.waitForElement(audioAppId, inactive).then(this.next);
-    },
-    function(element) {
-      chrome.test.assertTrue(!!element);
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on Drive, add the audio files to Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, RootPath.DRIVE, null, [], tracks);
+
+  // Open an audio file from Drive.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Check: track 0 should be active.
+  let song = await getTrackText(audioAppId, '.track[index="0"][active]');
+
+  // Check: track 0 should have the correct title and artist.
+  chrome.test.assertEq('Beautiful Song', song.title);
+  chrome.test.assertEq('Unknown Artist', song.artist);
+
+  // Check: track 1 should be inactive.
+  const inactive = trackListQuery('.track[index="1"]:not([active])');
+  chrome.test.assertTrue(
+      !!await audioPlayerApp.waitForElement(audioAppId, inactive));
+
+  // Open another audio file from Drive.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['newly added file.ogg']));
+
+  // Check: Audio Player should automatically play the file.
+  const playFile2 = audioPlayingQuery('newly added file.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile2);
+
+  // Check: track 1 should be active.
+  song = await getTrackText(audioAppId, '.track[index="1"][active]');
+
+  // Check: track 1 should have the correct title and artist.
+  chrome.test.assertEq('newly added file', song.title);
+  chrome.test.assertEq('Unknown Artist', song.artist);
+
+  // Check: track 0 should be inactive.
+  const inactive2 = trackListQuery('.track[index="0"]:not([active])');
+  chrome.test.assertTrue(
+      !!await audioPlayerApp.waitForElement(audioAppId, inactive2));
 }
 
 /**
@@ -266,53 +201,33 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioAutoAdvance(path) {
-  let appId;
-  let audioAppId;
-
+async function audioAutoAdvance(path) {
   const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add audio files to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, tracks, tracks);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Leap forward in time.
-    function() {
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing.
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // When it ends, Audio Player should play the next file (advance).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add audio files to Downloads and Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, path, null, tracks, tracks);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing.
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // When it ends, Audio Player should play the next file (advance).
+  const playFile2 = audioPlayingQuery('newly added file.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile2);
 }
 
 /**
@@ -320,62 +235,40 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioRepeatAllModeSingleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioRepeatAllModeSingleFile(path) {
   const track = [ENTRIES.beautiful];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add an audio file to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, track, track);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Click the repeat button for repeat-all.
-    function() {
-      const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Leap forward in time.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should replay it (repeat-all).
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      const repeats = playFile + '[playcount="1"]';
-      audioPlayerApp.waitForElement(audioAppId, repeats).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add an audio file to Downloads and Drive.
+  const {appId} = await setupAndWaitUntilReady(null, path, null, track, track);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Click the repeat button for repeat-all.
+  const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton]),
+      'Failed to click the repeat button');
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should replay it (repeat-all).
+  const repeats = playFile + '[playcount="1"]';
+  await audioPlayerApp.waitForElement(audioAppId, repeats);
 }
 
 /**
@@ -383,54 +276,33 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioNoRepeatModeSingleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioNoRepeatModeSingleFile(path) {
   const track = [ENTRIES.beautiful];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add an audio file to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, track, track);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Leap forward in time.
-    function() {
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should stop playing.
-    function() {
-      const playStop = 'audio-player[playcount="1"]:not([playing])';
-      audioPlayerApp.waitForElement(audioAppId, playStop).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add an audio file to Downloads and Drive.
+  const {appId} = await setupAndWaitUntilReady(null, path, null, track, track);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should stop playing.
+  const playStop = 'audio-player[playcount="1"]:not([playing])';
+  await audioPlayerApp.waitForElement(audioAppId, playStop);
 }
 
 /**
@@ -438,69 +310,47 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioRepeatOneModeSingleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioRepeatOneModeSingleFile(path) {
   const track = [ENTRIES.beautiful];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add an audio file to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, track, track);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['Beautiful Song.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Click the repeat button for repeat-all.
-    function() {
-      const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Click the repeat button again for repeat-once.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      const repeatButton = controlPanelQuery(['repeat-button', '.repeat-all']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Leap forward in time.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should replay it (repeat-once).
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      const repeats = playFile + '[playcount="1"]';
-      audioPlayerApp.waitForElement(audioAppId, repeats).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add an audio file to Downloads and Drive.
+  const {appId} = await setupAndWaitUntilReady(null, path, null, track, track);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['Beautiful Song.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Click the repeat button for repeat-all.
+  const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton]),
+      'Failed to click the repeat button');
+
+  // Click the repeat button again for repeat-once.
+  const repeatButton2 = controlPanelQuery(['repeat-button', '.repeat-all']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton2]),
+      'Failed to click the repeat button');
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should replay it (repeat-once).
+  const repeats = playFile + '[playcount="1"]';
+  await audioPlayerApp.waitForElement(audioAppId, repeats);
 }
 
 /**
@@ -508,71 +358,47 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioRepeatAllModeMultipleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioRepeatAllModeMultipleFile(path) {
   const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add audio files to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, tracks, tracks);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['newly added file.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Click the repeat button for repeat-all.
-    function() {
-      const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Leap forward in time.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should play the next file.
-    function() {
-      const playFile = audioPlayingQuery('Beautiful Song.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Leap forward in time.
-    function() {
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // When it ends, Audio Player should replay the first file (repeat-all).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add audio files to Downloads and Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, path, null, tracks, tracks);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['newly added file.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('newly added file.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Click the repeat button for repeat-all.
+  const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton]),
+      'Failed to click the repeat button');
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should play the next file.
+  const playFile2 = audioPlayingQuery('Beautiful Song.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile2);
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // When it ends, Audio Player should replay the first file (repeat-all).
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
 }
 
 /**
@@ -580,54 +406,34 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioNoRepeatModeMultipleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioNoRepeatModeMultipleFile(path) {
   const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add audio files to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, tracks, tracks);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['newly added file.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Leap forward in time.
-    function() {
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should stop playing.
-    function() {
-      const playStop = 'audio-player[playcount="1"]:not([playing])';
-      audioPlayerApp.waitForElement(audioAppId, playStop).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add audio files to Downloads and Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, path, null, tracks, tracks);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['newly added file.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('newly added file.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should stop playing.
+  const playStop = 'audio-player[playcount="1"]:not([playing])';
+  await audioPlayerApp.waitForElement(audioAppId, playStop);
 }
 
 /**
@@ -635,113 +441,91 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function audioRepeatOneModeMultipleFile(path) {
-  let appId;
-  let audioAppId;
-
+async function audioRepeatOneModeMultipleFile(path) {
   const tracks = [ENTRIES.beautiful, ENTRIES.newlyAdded];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add audio files to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, tracks, tracks);
-    },
-    // Open an audio file.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['newly added file.ogg'], this.next);
-    },
-    // Wait for the Audio Player window.
-    function(result) {
-      chrome.test.assertTrue(result);
-      audioPlayerApp.waitForWindow('audio_player.html').then(this.next);
-    },
-    // Check: Audio Player should automatically play the file.
-    function(windowId) {
-      audioAppId = windowId;
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      audioPlayerApp.waitForElement(audioAppId, playFile).then(this.next);
-    },
-    // Click the repeat button for repeat-all.
-    function() {
-      const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Click the repeat button again for repeat-once.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      const repeatButton = controlPanelQuery(['repeat-button', '.repeat-all']);
-      audioPlayerApp.callRemoteTestUtil(
-          'fakeMouseClick', audioAppId, [repeatButton], this.next);
-    },
-    // Leap forward in time.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to click the repeat button');
-      audioTimeLeapForward(audioAppId);
-      this.next();
-    },
-    // Check: the same file should still be playing (non-repeated).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      const initial = playFile + '[playcount="0"]';
-      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
-    },
-    // When it ends, Audio Player should replay it (repeat-once).
-    function() {
-      const playFile = audioPlayingQuery('newly added file.ogg');
-      const repeats = playFile + '[playcount="1"]';
-      audioPlayerApp.waitForElement(audioAppId, repeats).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add audio files to Downloads and Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, path, null, tracks, tracks);
+
+  // Open an audio file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, ['newly added file.ogg']));
+
+  // Wait for the Audio Player window.
+  const audioAppId = await audioPlayerApp.waitForWindow('audio_player.html');
+
+  // Check: Audio Player should automatically play the file.
+  const playFile = audioPlayingQuery('newly added file.ogg');
+  await audioPlayerApp.waitForElement(audioAppId, playFile);
+
+  // Click the repeat button for repeat-all.
+  const repeatButton = controlPanelQuery(['repeat-button', '.no-repeat']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton]),
+      'Failed to click the repeat button');
+
+  // Click the repeat button again for repeat-once.
+  const repeatButton2 = controlPanelQuery(['repeat-button', '.repeat-all']);
+  chrome.test.assertTrue(
+      await audioPlayerApp.callRemoteTestUtil(
+          'fakeMouseClick', audioAppId, [repeatButton2]),
+      'Failed to click the repeat button');
+
+  // Leap forward in time.
+  audioTimeLeapForward(audioAppId);
+
+  // Check: the same file should still be playing (non-repeated).
+  const initial = playFile + '[playcount="0"]';
+  await audioPlayerApp.waitForElement(audioAppId, initial);
+
+  // When it ends, Audio Player should replay it (repeat-once).
+  const repeats = playFile + '[playcount="1"]';
+  await audioPlayerApp.waitForElement(audioAppId, repeats);
 }
 
 testcase.audioOpenCloseDownloads = function() {
-  audioOpenClose(RootPath.DOWNLOADS);
+  return audioOpenClose(RootPath.DOWNLOADS);
 };
 
 testcase.audioOpenCloseDrive = function() {
-  audioOpenClose(RootPath.DRIVE);
+  return audioOpenClose(RootPath.DRIVE);
 };
 
 testcase.audioOpenDownloads = function() {
-  audioOpenTrackDownloads();
+  return audioOpenTrackDownloads();
 };
 
 testcase.audioOpenDrive = function() {
-  audioOpenMultipleTracksDrive();
+  return audioOpenMultipleTracksDrive();
 };
 
 testcase.audioAutoAdvanceDrive = function() {
-  audioAutoAdvance(RootPath.DRIVE);
+  return audioAutoAdvance(RootPath.DRIVE);
 };
 
 testcase.audioRepeatAllModeSingleFileDrive = function() {
-  audioRepeatAllModeSingleFile(RootPath.DRIVE);
+  return audioRepeatAllModeSingleFile(RootPath.DRIVE);
 };
 
 testcase.audioNoRepeatModeSingleFileDrive = function() {
-  audioNoRepeatModeSingleFile(RootPath.DRIVE);
+  return audioNoRepeatModeSingleFile(RootPath.DRIVE);
 };
 
 testcase.audioRepeatOneModeSingleFileDrive = function() {
-  audioRepeatOneModeSingleFile(RootPath.DRIVE);
+  return audioRepeatOneModeSingleFile(RootPath.DRIVE);
 };
 
 testcase.audioRepeatAllModeMultipleFileDrive = function() {
-  audioRepeatAllModeMultipleFile(RootPath.DRIVE);
+  return audioRepeatAllModeMultipleFile(RootPath.DRIVE);
 };
 
 testcase.audioNoRepeatModeMultipleFileDrive = function() {
-  audioNoRepeatModeMultipleFile(RootPath.DRIVE);
+  return audioNoRepeatModeMultipleFile(RootPath.DRIVE);
 };
 
 testcase.audioRepeatOneModeMultipleFileDrive = function() {
-  audioRepeatOneModeMultipleFile(RootPath.DRIVE);
+  return audioRepeatOneModeMultipleFile(RootPath.DRIVE);
 };
-
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/open_image_files.js b/ui/file_manager/integration_tests/file_manager/open_image_files.js
index 98d080cc..bbcf597 100644
--- a/ui/file_manager/integration_tests/file_manager/open_image_files.js
+++ b/ui/file_manager/integration_tests/file_manager/open_image_files.js
@@ -11,46 +11,25 @@
  *
  * @param {string} path Directory path (Downloads or Drive).
  */
-function imageOpen(path) {
-  let appId;
-  let galleryAppId;
+async function imageOpen(path) {
+  // Open Files.App on |path|, add image3 to Downloads and Drive.
+  const {appId} = await setupAndWaitUntilReady(
+      null, path, null, [ENTRIES.image3], [ENTRIES.image3]);
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add image3 to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(
-          null, path, this.next, [ENTRIES.image3], [ENTRIES.image3]);
-    },
-    // Open the image file in Files app.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, [ENTRIES.image3.targetPath], this.next);
-    },
-    // Check: the Gallery window should open.
-    function(result) {
-      chrome.test.assertTrue(result);
-      galleryApp.waitForWindow('gallery.html').then(this.next);
-    },
-    // Check: the image should appear in the Gallery window.
-    function(windowId) {
-      galleryAppId = windowId;
-      galleryApp.waitForSlideImage(
-          galleryAppId, 640, 480, 'image3').then(this.next);
-    },
-    // Close the Gallery window.
-    function() {
-      galleryApp.closeWindowAndWait(galleryAppId).then(this.next);
-    },
-    // Check: the Gallery window should close.
-    function(result) {
-      chrome.test.assertTrue(result, 'Failed to close Gallery window');
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open the image file in Files app.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, [ENTRIES.image3.targetPath]));
+
+  // Check: the Gallery window should open.
+  const galleryAppId = await galleryApp.waitForWindow('gallery.html');
+
+  // Check: the image should appear in the Gallery window.
+  await galleryApp.waitForSlideImage(galleryAppId, 640, 480, 'image3');
+
+  // Close the Gallery window.
+  chrome.test.assertTrue(
+      await galleryApp.closeWindowAndWait(galleryAppId),
+      'Failed to close Gallery window');
 }
 
 /**
@@ -59,80 +38,57 @@
  *
  * @param {string} path Directory path (Downloads or Drive).
  */
-function imageOpenGalleryOpen(path) {
-  let appId;
-  let galleryAppId;
-
+async function imageOpenGalleryOpen(path) {
   const testImages = [ENTRIES.image3, ENTRIES.desktop];
 
-  StepsRunner.run([
-    // Open Files.App on |path|, add test images to Downloads and Drive.
-    function() {
-      setupAndWaitUntilReady(null, path, this.next, testImages, testImages);
-    },
-    // Open an image file in Files app.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, [ENTRIES.image3.targetPath], this.next);
-    },
-    // Wait a11y-msg to have some text.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForElement(appId, '#a11y-msg:not(:empty)').then(this.next);
-    },
-    // Fetch A11y messages.
-    function() {
-      remoteCall.callRemoteTestUtil('getA11yAnnounces', appId, [])
-          .then(this.next);
-    },
-    // Check that opening the file was announced to screen reader.
-    function(a11yMessages) {
-      chrome.test.assertTrue(a11yMessages instanceof Array);
-      chrome.test.assertEq(1, a11yMessages.length);
-      chrome.test.assertEq('Opening file image3.jpg.', a11yMessages[0]);
-      this.next();
-    },
-    // Check: the Gallery window should open.
-    function() {
-      galleryApp.waitForWindow('gallery.html').then(this.next);
-    },
-    // Check: the image should appear in the Gallery window.
-    function(windowId) {
-      galleryAppId = windowId;
-      galleryApp.waitForSlideImage(
-          galleryAppId, 640, 480, 'image3').then(this.next);
-    },
-    // Now open a different image file in Files app.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, [ENTRIES.desktop.targetPath], this.next);
-    },
-    // Check: the new image should appear in the Gallery window.
-    function() {
-      galleryApp.waitForSlideImage(
-          galleryAppId, 800, 600, 'My Desktop Background').then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files.App on |path|, add test images to Downloads and Drive.
+  const {appId} =
+      await setupAndWaitUntilReady(null, path, null, testImages, testImages);
+
+  // Open an image file in Files app.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'openFile', appId, [ENTRIES.image3.targetPath]));
+
+  // Wait a11y-msg to have some text.
+  await remoteCall.waitForElement(appId, '#a11y-msg:not(:empty)');
+
+  // Fetch A11y messages.
+  const a11yMessages =
+      await remoteCall.callRemoteTestUtil('getA11yAnnounces', appId, []);
+
+  // Check that opening the file was announced to screen reader.
+  chrome.test.assertTrue(a11yMessages instanceof Array);
+  chrome.test.assertEq(1, a11yMessages.length);
+  chrome.test.assertEq('Opening file image3.jpg.', a11yMessages[0]);
+
+  // Check: the Gallery window should open.
+  const galleryAppId = await galleryApp.waitForWindow('gallery.html');
+
+  // Check: the image should appear in the Gallery window.
+  await galleryApp.waitForSlideImage(galleryAppId, 640, 480, 'image3');
+
+  // Now open a different image file in Files app.
+  await remoteCall.callRemoteTestUtil(
+      'openFile', appId, [ENTRIES.desktop.targetPath]);
+
+  // Check: the new image should appear in the Gallery window.
+  await galleryApp.waitForSlideImage(
+      galleryAppId, 800, 600, 'My Desktop Background');
 }
 
 testcase.imageOpenDownloads = function() {
-  imageOpen(RootPath.DOWNLOADS);
+  return imageOpen(RootPath.DOWNLOADS);
 };
 
 testcase.imageOpenDrive = function() {
-  imageOpen(RootPath.DRIVE);
+  return imageOpen(RootPath.DRIVE);
 };
 
 testcase.imageOpenGalleryOpenDownloads = function() {
-  imageOpenGalleryOpen(RootPath.DOWNLOADS);
+  return imageOpenGalleryOpen(RootPath.DOWNLOADS);
 };
 
 testcase.imageOpenGalleryOpenDrive = function() {
-  imageOpenGalleryOpen(RootPath.DRIVE);
+  return imageOpenGalleryOpen(RootPath.DRIVE);
 };
-
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/open_video_files.js b/ui/file_manager/integration_tests/file_manager/open_video_files.js
index 2622a23d..f530483 100644
--- a/ui/file_manager/integration_tests/file_manager/open_video_files.js
+++ b/ui/file_manager/integration_tests/file_manager/open_video_files.js
@@ -1,7 +1,6 @@
 // Copyright 2014 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.
-
 'use strict';
 
 (function() {
@@ -13,16 +12,12 @@
  */
 function waitForPlaying(filename) {
   var caller = getCaller();
-  return repeatUntil(function() {
-    return videoPlayerApp.callRemoteTestUtil('isPlaying',
-                                             null,
-                                             [filename]).
-        then(function(result) {
-          if (result)
-            return true;
-          return pending(
-              caller, 'Window with the prefix %s is not found.', filename);
-        });
+  return repeatUntil(async () => {
+    if (await videoPlayerApp.callRemoteTestUtil(
+            'isPlaying', null, [filename])) {
+      return true;
+    }
+    return pending(caller, 'Window with the prefix %s is not found.', filename);
   });
 }
 
@@ -32,47 +27,26 @@
  *
  * @param {string} path Directory path to be tested.
  */
-function videoOpen(path) {
-  var appId;
-  StepsRunner.run([
-    function() {
-      setupAndWaitUntilReady(null, path, this.next);
-    },
-    function(results) {
-      appId = results.windowId;
-      // Select the song.
-      remoteCall.callRemoteTestUtil(
-          'openFile', appId, ['world.ogv'], this.next);
-    },
-    function(result) {
-      chrome.test.assertTrue(result);
-      // Wait for the video player.
-      waitForPlaying('world.ogv').then(this.next);
-    },
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.callRemoteTestUtil(
-          'getErrorCount', null, [], this.next);
-    },
-    function(errorCount) {
-      chrome.test.assertEq(errorCount, 0);
-      videoPlayerApp.callRemoteTestUtil(
-          'getErrorCount', null, [], this.next);
-    },
-    function(errorCount) {
-      chrome.test.assertEq(errorCount, 0);
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+async function videoOpen(path) {
+  const {appId} = await setupAndWaitUntilReady(null, path, null);
+
+  // Open the video.
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('openFile', appId, ['world.ogv']));
+
+  // Wait for the video to start playing.
+  chrome.test.assertTrue(await waitForPlaying('world.ogv'));
+
+  chrome.test.assertEq(
+      0, await videoPlayerApp.callRemoteTestUtil('getErrorCount', null, []));
 }
 
 // Exports test functions.
 testcase.videoOpenDrive = function() {
-  videoOpen(RootPath.DRIVE);
+  return videoOpen(RootPath.DRIVE);
 };
 
 testcase.videoOpenDownloads = function() {
-  videoOpen(RootPath.DOWNLOADS);
+  return videoOpen(RootPath.DOWNLOADS);
 };
-
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index c2ff272..be7f7ac 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -1,18 +1,16 @@
 // Copyright 2016 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 'use strict';
 
 /**
- * Returns an array of steps that opens the Quick View dialog on a given file
- * |name|. The file must be present in the Files app file list.
+ * Opens the Quick View dialog on a given file |name|. The file must be present
+ * in the Files app file list.
  *
  * @param {string} appId Files app windowId.
  * @param {string} name File name.
- * @return {!Array<function>}
  */
-function openQuickViewSteps(appId, name) {
+async function openQuickView(appId, name) {
   let caller = getCaller();
 
   function checkQuickViewElementsDisplayBlock(elements) {
@@ -22,39 +20,33 @@
     return;
   }
 
-  return [
-    // Select file |name| in the file list.
-    function() {
-      remoteCall.callRemoteTestUtil('selectFile', appId, [name], this.next);
-    },
-    // Press the space key.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'selectFile failed');
-      const space = ['#file-list', ' ', false, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, space, this.next);
-    },
-    // Check: the Quick View element should be shown.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeKeyDown failed');
-      repeatUntil(function() {
-        const elements = ['#quick-view', '#dialog[open]'];
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [elements, ['display']])
-            .then(checkQuickViewElementsDisplayBlock);
-      }).then(this.next);
-    },
-  ];
+  // Select file |name| in the file list.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [name]),
+      'selectFile failed');
+
+  // Press the space key.
+  const space = ['#file-list', ' ', false, false, false];
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, space),
+      'fakeKeyDown failed');
+
+  // Check: the Quick View element should be shown.
+  await repeatUntil(async () => {
+    const elements = ['#quick-view', '#dialog[open]'];
+    return checkQuickViewElementsDisplayBlock(
+        await remoteCall.callRemoteTestUtil(
+            'deepQueryAllElements', appId, [elements, ['display']]));
+  });
 }
 
 /**
- * Assuming that Quick View is currently open per the openQuickViewSteps above,
- * returns an array of steps that closes the Quick View dialog.
+ * Assuming that Quick View is currently open per openQuickView above, closes
+ * the Quick View dialog.
  *
  * @param {string} appId Files app windowId.
- * @return {!Array<function>}
  */
-function closeQuickViewSteps(appId) {
+async function closeQuickView(appId) {
   let caller = getCaller();
 
   function checkQuickViewElementsDisplayNone(elements) {
@@ -64,306 +56,192 @@
     return;
   }
 
-  return [
-    // Click on Quick View to close it.
-    function() {
-      const panelElements = ['#quick-view', '#contentPanel'];
-      remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [panelElements])
-          .then(this.next);
-    },
-    // Check: the Quick View element should not be shown.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      repeatUntil(function() {
-        const elements = ['#quick-view', '#dialog:not([open])'];
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [elements, ['display']])
-            .then(checkQuickViewElementsDisplayNone);
-      }).then(this.next);
-    },
-  ];
+  // Click on Quick View to close it.
+  const panelElements = ['#quick-view', '#contentPanel'];
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [panelElements]),
+      'fakeMouseClick failed');
+
+  // Check: the Quick View element should not be shown.
+  await repeatUntil(async () => {
+    const elements = ['#quick-view', '#dialog:not([open])'];
+    return checkQuickViewElementsDisplayNone(
+        await remoteCall.callRemoteTestUtil(
+            'deepQueryAllElements', appId, [elements, ['display']]));
+  });
 }
 
 /**
  * Tests opening Quick View on a local downloads file.
  */
-testcase.openQuickView = function() {
-  let appId;
+testcase.openQuickView = async function() {
+  // Open Files app on Downloads containing ENTRIES.hello.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.hello], []);
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.hello.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
 };
 
 /**
  * Tests opening then closing Quick View on a local downloads file.
  */
-testcase.closeQuickView = function() {
-  let appId;
+testcase.closeQuickView = async function() {
+  // Open Files app on Downloads containing ENTRIES.hello.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.hello], []);
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.hello.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Close Quick View.
-    function() {
-      StepsRunner.run(closeQuickViewSteps(appId)).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
+
+  // Close Quick View.
+  await closeQuickView(appId);
 };
 
 /**
  * Tests opening Quick View on a Drive file.
  */
-testcase.openQuickViewDrive = function() {
-  let appId;
+testcase.openQuickViewDrive = async function() {
+  // Open Files app on Drive containing ENTRIES.hello.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DRIVE, null, [], [ENTRIES.hello]);
 
-  StepsRunner.run([
-    // Open Files app on Drive containing ENTRIES.hello.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DRIVE, this.next, [], [ENTRIES.hello]);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
 };
 
 /**
  * Tests opening Quick View on a USB file.
  */
-testcase.openQuickViewUsb = function() {
-  let appId;
-
+testcase.openQuickViewUsb = async function() {
   const USB_VOLUME_QUERY = '#directory-tree [volume-type-icon="removable"]';
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.photos.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []);
-    },
-    // Mount a USB volume.
-    function(results) {
-      appId = results.windowId;
-      sendTestMessage({name: 'mountFakeUsb'}).then(this.next);
-    },
-    // Wait for the USB volume to mount.
-    function() {
-      remoteCall.waitForElement(appId, USB_VOLUME_QUERY).then(this.next);
-    },
-    // Click to open the USB volume.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [USB_VOLUME_QUERY], this.next);
-    },
-    // Check: the USB files should appear in the file list.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET);
-      remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Open a USB file in Quick View.
-    function() {
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.photos.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.photos], []);
+
+  // Mount a USB volume.
+  await sendTestMessage({name: 'mountFakeUsb'});
+
+  // Wait for the USB volume to mount.
+  await remoteCall.waitForElement(appId, USB_VOLUME_QUERY);
+
+  // Click to open the USB volume.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [USB_VOLUME_QUERY]),
+      'fakeMouseClick failed');
+
+  // Check: the USB files should appear in the file list.
+  const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
+
+  // Open a USB file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
 };
 
 /**
  * Tests opening Quick View on an MTP file.
  */
-testcase.openQuickViewMtp = function() {
-  let appId;
-
+testcase.openQuickViewMtp = async function() {
   const MTP_VOLUME_QUERY = '#directory-tree [volume-type-icon="mtp"]';
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.photos.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []);
-    },
-    // Mount a non-empty MTP volume.
-    function(results) {
-      appId = results.windowId;
-      sendTestMessage({name: 'mountFakeMtp'}).then(this.next);
-    },
-    // Wait for the MTP volume to mount.
-    function() {
-      remoteCall.waitForElement(appId, MTP_VOLUME_QUERY).then(this.next);
-    },
-    // Click to open the MTP volume.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [MTP_VOLUME_QUERY], this.next);
-    },
-    // Check: the MTP files should appear in the file list.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET);
-      remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Open an MTP file in Quick View.
-    function() {
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.photos.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.photos], []);
+
+  // Mount a non-empty MTP volume.
+  await sendTestMessage({name: 'mountFakeMtp'});
+
+  // Wait for the MTP volume to mount.
+  await remoteCall.waitForElement(appId, MTP_VOLUME_QUERY);
+
+  // Click to open the MTP volume.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [MTP_VOLUME_QUERY]),
+      'fakeMouseClick failed');
+
+  // Check: the MTP files should appear in the file list.
+  const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
+
+  // Open an MTP file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
 };
 
 /**
  * Tests opening Quick View on a Crostini file.
  */
-testcase.openQuickViewCrostini = function() {
-  let appId;
-
+testcase.openQuickViewCrostini = async function() {
   const fakeLinuxFiles = '#directory-tree [root-type-icon="crostini"]';
   const realLinuxFiles = '#directory-tree [volume-type-icon="crostini"]';
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.photos.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []);
-    },
-    // Check: the fake Linux files icon should be shown.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.waitForElement(appId, fakeLinuxFiles).then(this.next);
-    },
-    // Add files to the Crostini volume.
-    function() {
-      addEntries(['crostini'], BASIC_CROSTINI_ENTRY_SET, this.next);
-    },
-    // Click the fake Linux files icon to mount the Crostini volume.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [fakeLinuxFiles], this.next);
-    },
-    // Check: the Crostini volume icon should appear.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      remoteCall.waitForElement(appId, realLinuxFiles).then(this.next);
-    },
-    // Check: the Crostini files should appear in the file list.
-    function() {
-      const files = TestEntryInfo.getExpectedRows(BASIC_CROSTINI_ENTRY_SET);
-      remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Open a Crostini file in Quick View.
-    function() {
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.photos.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.photos], []);
+
+  // Check: the fake Linux files icon should be shown.
+  await remoteCall.waitForElement(appId, fakeLinuxFiles);
+
+  // Add files to the Crostini volume.
+  await addEntries(['crostini'], BASIC_CROSTINI_ENTRY_SET);
+
+  // Click the fake Linux files icon to mount the Crostini volume.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [fakeLinuxFiles]),
+      'fakeMouseClick failed');
+
+  // Check: the Crostini volume icon should appear.
+  await remoteCall.waitForElement(appId, realLinuxFiles);
+
+  // Check: the Crostini files should appear in the file list.
+  const files = TestEntryInfo.getExpectedRows(BASIC_CROSTINI_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
+
+  // Open a Crostini file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
 };
 
 /**
  * Tests opening Quick View on an Android file.
  */
-testcase.openQuickViewAndroid = function() {
-  let appId;
+testcase.openQuickViewAndroid = async function() {
+  // Open Files app on Android files.
+  const appId = await openNewWindow(null, RootPath.ANDROID_FILES);
 
-  StepsRunner.run([
-    // Open Files app on Android files.
-    function() {
-      openNewWindow(null, RootPath.ANDROID_FILES).then(this.next);
-    },
-    // Add files to the Android files volume.
-    function(result) {
-      appId = result;
-      const entrySet = BASIC_ANDROID_ENTRY_SET.concat([ENTRIES.documentsText]);
-      addEntries(['android_files'], entrySet, this.next);
-    },
-    // Wait for the file list to appear.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForElement(appId, '#file-list').then(this.next);
-    },
-    // Check: the basic Android file set should appear in the file list.
-    function() {
-      const files = TestEntryInfo.getExpectedRows(BASIC_ANDROID_ENTRY_SET);
-      remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Navigate to the Android files '/Documents' directory.
-    function() {
-      remoteCall
-          .navigateWithDirectoryTree(
-              appId, '/Documents', 'My files/Play files', 'android_files')
-          .then(this.next);
-    },
-    // Check: the 'android.txt' file should appear in the file list.
-    function() {
-      const files = [ENTRIES.documentsText.getExpectedRow()];
-      remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true})
-          .then(this.next);
-    },
-    // Open the Android file in Quick View.
-    function() {
-      const documentsFileName = ENTRIES.documentsText.nameText;
-      const openSteps = openQuickViewSteps(appId, documentsFileName);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Add files to the Android files volume.
+  const entrySet = BASIC_ANDROID_ENTRY_SET.concat([ENTRIES.documentsText]);
+  await addEntries(['android_files'], entrySet);
+
+  // Wait for the file list to appear.
+  await remoteCall.waitForElement(appId, '#file-list');
+
+  // Check: the basic Android file set should appear in the file list.
+  let files = TestEntryInfo.getExpectedRows(BASIC_ANDROID_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
+
+  // Navigate to the Android files '/Documents' directory.
+  await remoteCall.navigateWithDirectoryTree(
+      appId, '/Documents', 'My files/Play files', 'android_files');
+
+  // Check: the 'android.txt' file should appear in the file list.
+  files = [ENTRIES.documentsText.getExpectedRow()];
+  await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
+
+  // Open the Android file in Quick View.
+  const documentsFileName = ENTRIES.documentsText.nameText;
+  await openQuickView(appId, documentsFileName);
 };
 
 /**
  * Tests opening Quick View and scrolling its <webview> which contains a tall
  * text document.
  */
-testcase.openQuickViewScrollText = function() {
+testcase.openQuickViewScrollText = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The text <webview> resides in the #quick-view shadow DOM, as a child of
@@ -373,85 +251,61 @@
 
   function scrollQuickViewTextBy(y) {
     const doScrollBy = `window.scrollBy(0,${y})`;
-    return remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, doScrollBy]);
+    return remoteCall.callRemoteTestUtil(
+        'deepExecuteScriptInWebView', appId, [webView, doScrollBy]);
   }
 
-  function checkQuickViewTextScrollY(scrollY) {
+  async function checkQuickViewTextScrollY(scrollY) {
     if (!scrollY || Number(scrollY.toString()) <= 200) {
       console.log('checkQuickViewTextScrollY: scrollY '.concat(scrollY));
-      return scrollQuickViewTextBy(100).then(() => {
-        return pending(caller, 'Waiting for Quick View to scroll.');
-      });
+      await scrollQuickViewTextBy(100);
+      return pending(caller, 'Waiting for Quick View to scroll.');
     }
   }
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.tallText.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.tallText], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.tallText.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-      function checkWebViewTextLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || !elements[0].attributes.src)
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewTextLoaded);
-      }).then(this.next);
-    },
-    // Get the Quick View <webview> scrollY.
-    function() {
-      const getScrollY = 'window.scrollY';
-      remoteCall
-          .callRemoteTestUtil(
-              'deepExecuteScriptInWebView', appId, [webView, getScrollY])
-          .then(this.next);
-    },
-    // Check: the initial <webview> scrollY should be 0.
-    function(scrollY) {
-      chrome.test.assertEq('0', scrollY.toString());
-      this.next();
-    },
-    // Scroll the <webview> and verify that it scrolled.
-    function() {
-      repeatUntil(function() {
-        const getScrollY = 'window.scrollY';
-        return remoteCall
-          .callRemoteTestUtil(
-              'deepExecuteScriptInWebView', appId, [webView, getScrollY])
-          .then(checkQuickViewTextScrollY);
-      }).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.tallText.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.tallText], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.tallText.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewTextLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || !elements[0].attributes.src)
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewTextLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the Quick View <webview> scrollY.
+  const getScrollY = 'window.scrollY';
+  await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getScrollY]);
+
+  // Check: the initial <webview> scrollY should be 0.
+  chrome.test.assertEq('0', scrollY.toString());
+
+  // Scroll the <webview> and verify that it scrolled.
+  await repeatUntil(async () => {
+    const getScrollY = 'window.scrollY';
+    return checkQuickViewTextScrollY(await remoteCall.callRemoteTestUtil(
+        'deepExecuteScriptInWebView', appId, [webView, getScrollY]));
+  });
 };
 
 /**
  * Tests opening Quick View on a text document to verify that the background
  * color of the <webview> root (html) element is solid white.
  */
-testcase.openQuickViewBackgroundColorText = function() {
+testcase.openQuickViewBackgroundColorText = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The text <webview> resides in the #quick-view shadow DOM, as a child of
@@ -459,61 +313,42 @@
    */
   const webView = ['#quick-view', '#dialog[open] webview.text-content'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.tallText.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.tallText], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.tallText.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-      function checkWebViewTextLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || !elements[0].attributes.src)
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewTextLoaded);
-      }).then(this.next);
-    },
-    // Get the <webview> root (html) element backgroundColor style.
-    function() {
-      const getBackgroundStyle =
-          'window.getComputedStyle(document.documentElement).backgroundColor';
-      remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle])
-        .then(this.next);
-    },
-    // Check: the <webview> root backgroundColor should be solid white.
-    function(backgroundColor) {
-      chrome.test.assertEq('rgb(255, 255, 255)', backgroundColor[0]);
-      this.next();
-    },
-    function(results) {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.tallText.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.tallText], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.tallText.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewTextLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || !elements[0].attributes.src)
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewTextLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the <webview> root (html) element backgroundColor style.
+  const getBackgroundStyle =
+      'window.getComputedStyle(document.documentElement).backgroundColor';
+  const backgroundColor = await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle]);
+
+  // Check: the <webview> root backgroundColor should be solid white.
+  chrome.test.assertEq('rgb(255, 255, 255)', backgroundColor[0]);
 };
 
 /**
  * Tests opening Quick View containing a PDF document.
  */
-testcase.openQuickViewPdf = function() {
+testcase.openQuickViewPdf = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The PDF <webview> resides in the #quick-view shadow DOM, as a child of
@@ -521,69 +356,50 @@
    */
   const webView = ['#quick-view', '#dialog[open] webview.content'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.tallPdf.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.tallPdf], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.tallPdf.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-      function checkWebViewPdfLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || !elements[0].attributes.src)
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewPdfLoaded);
-      }).then(this.next);
-    },
-    // Get the <webview> embed type attribute.
-    function() {
-      function checkPdfEmbedType(type) {
-        let haveElements = Array.isArray(type) && type.length === 1;
-        if (!haveElements || !type[0].toString().includes('pdf'))
-          return pending(caller, 'Waiting for plugin <embed> type.');
-        return type[0];
-      }
-      repeatUntil(function() {
-        const getType = 'window.document.querySelector("embed").type';
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepExecuteScriptInWebView', appId, [webView, getType])
-            .then(checkPdfEmbedType);
-      }).then(this.next);
-    },
-    // Check: the <webview> embed type should be PDF mime type.
-    function(type) {
-      chrome.test.assertEq('application/pdf', type);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.tallPdf.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.tallPdf], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.tallPdf.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewPdfLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || !elements[0].attributes.src)
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewPdfLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the <webview> embed type attribute.
+  function checkPdfEmbedType(type) {
+    let haveElements = Array.isArray(type) && type.length === 1;
+    if (!haveElements || !type[0].toString().includes('pdf'))
+      return pending(caller, 'Waiting for plugin <embed> type.');
+    return type[0];
+  }
+  const type = await repeatUntil(async () => {
+    const getType = 'window.document.querySelector("embed").type';
+    return checkPdfEmbedType(await remoteCall.callRemoteTestUtil(
+        'deepExecuteScriptInWebView', appId, [webView, getType]));
+  });
+
+  // Check: the <webview> embed type should be PDF mime type.
+  chrome.test.assertEq('application/pdf', type);
 };
 
 /**
  * Tests opening Quick View and scrolling its <webview> which contains a tall
  * html document.
  */
-testcase.openQuickViewScrollHtml = function() {
+testcase.openQuickViewScrollHtml = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The <webview> resides in the <files-safe-media type="html"> shadow DOM,
@@ -593,76 +409,53 @@
 
   function scrollQuickViewHtmlBy(y) {
     const doScrollBy = `window.scrollBy(0,${y})`;
-    return remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, doScrollBy]);
+    return remoteCall.callRemoteTestUtil(
+        'deepExecuteScriptInWebView', appId, [webView, doScrollBy]);
   }
 
-  function checkQuickViewHtmlScrollY(scrollY) {
+  async function checkQuickViewHtmlScrollY(scrollY) {
     if (!scrollY || Number(scrollY.toString()) <= 200) {
       console.log('checkQuickViewHtmlScrollY: scrollY '.concat(scrollY));
-      return scrollQuickViewHtmlBy(100).then(() => {
-        return pending(caller, 'Waiting for Quick View to scroll.');
-      });
+      await scrollQuickViewHtmlBy(100);
+      return pending(caller, 'Waiting for Quick View to scroll.');
     }
   }
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.tallHtml.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.tallHtml], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.tallHtml.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-      function checkWebViewHtmlLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || elements[0].attributes.loaded !== '')
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewHtmlLoaded);
-      }).then(this.next);
-    },
-    // Get the Quick View <webview> scrollY.
-    function() {
-      const getScrollY = 'window.scrollY';
-      remoteCall
-          .callRemoteTestUtil(
-              'deepExecuteScriptInWebView', appId, [webView, getScrollY])
-          .then(this.next);
-    },
-    // Check: the initial <webview> scrollY should be 0.
-    function(scrollY) {
-      chrome.test.assertEq('0', scrollY.toString());
-      this.next();
-    },
-    // Scroll the <webview> and verify that it scrolled.
-    function() {
-      repeatUntil(function() {
-        const getScrollY = 'window.scrollY';
-        return remoteCall
-          .callRemoteTestUtil(
-              'deepExecuteScriptInWebView', appId, [webView, getScrollY])
-          .then(checkQuickViewHtmlScrollY);
-      }).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.tallHtml.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.tallHtml], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.tallHtml.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewHtmlLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || elements[0].attributes.loaded !== '')
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewHtmlLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the Quick View <webview> scrollY.
+  const getScrollY = 'window.scrollY';
+  await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getScrollY]);
+
+  // Check: the initial <webview> scrollY should be 0.
+  chrome.test.assertEq('0', scrollY.toString());
+
+  // Scroll the <webview> and verify that it scrolled.
+  await repeatUntil(async () => {
+    const getScrollY = 'window.scrollY';
+    return checkQuickViewHtmlScrollY(await remoteCall.callRemoteTestUtil(
+        'deepExecuteScriptInWebView', appId, [webView, getScrollY]));
+  });
 };
 
 /**
@@ -670,9 +463,8 @@
  * color of the <files-safe-media type="html"> that contains the <webview> is
  * solid white.
  */
-testcase.openQuickViewBackgroundColorHtml = function() {
+testcase.openQuickViewBackgroundColorHtml = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The <webview> resides in the <files-safe-media type="html"> shadow DOM,
@@ -681,53 +473,37 @@
    */
   const fileSafeMedia = ['#quick-view', 'files-safe-media[type="html"]'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.tallHtml.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.tallHtml], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.tallHtml.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Get the <files-safe-media type='html'> backgroundColor style.
-    function() {
-      function getFileSafeMediaBackgroundColor(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || !elements[0].styles.backgroundColor)
-          return pending(caller, 'Waiting for <file-safe-media> element.');
-        return elements[0].styles.backgroundColor;
-      }
-      repeatUntil(function() {
-        const styles = ['display', 'backgroundColor'];
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [fileSafeMedia, styles])
-            .then(getFileSafeMediaBackgroundColor);
-      }).then(this.next);
-    },
-    // Check: the <files-safe-media> backgroundColor should be solid white.
-    function(backgroundColor) {
-      chrome.test.assertEq('rgb(255, 255, 255)', backgroundColor);
-      this.next();
-    },
-    function(results) {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.tallHtml.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.tallHtml], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.tallHtml.nameText);
+
+  // Get the <files-safe-media type='html'> backgroundColor style.
+  function getFileSafeMediaBackgroundColor(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || !elements[0].styles.backgroundColor)
+      return pending(caller, 'Waiting for <file-safe-media> element.');
+    return elements[0].styles.backgroundColor;
+  }
+  const backgroundColor = await repeatUntil(async () => {
+    const styles = ['display', 'backgroundColor'];
+    return getFileSafeMediaBackgroundColor(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [fileSafeMedia, styles]));
+  });
+
+  // Check: the <files-safe-media> backgroundColor should be solid white.
+  chrome.test.assertEq('rgb(255, 255, 255)', backgroundColor);
 };
 
 /**
  * Tests opening Quick View containing an audio file.
  */
-testcase.openQuickViewAudio = function() {
+testcase.openQuickViewAudio = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The <webview> resides in the <files-safe-media type="audio"> shadow DOM,
@@ -735,61 +511,42 @@
    */
   const webView = ['#quick-view', 'files-safe-media[type="audio"]', 'webview'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.beautiful song.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.beautiful], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.beautiful.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-     function checkWebViewAudioLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || elements[0].attributes.loaded !== '')
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewAudioLoaded);
-      }).then(this.next);
-    },
-    // Get the <webview> document.body backgroundColor style.
-    function() {
-      const getBackgroundStyle =
-          'window.getComputedStyle(document.body).backgroundColor';
-      remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle])
-        .then(this.next);
-    },
-    // Check: the <webview> body backgroundColor should be transparent black.
-    function(backgroundColor) {
-      chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.beautiful song.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.beautiful], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.beautiful.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewAudioLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || elements[0].attributes.loaded !== '')
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewAudioLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the <webview> document.body backgroundColor style.
+  const getBackgroundStyle =
+      'window.getComputedStyle(document.body).backgroundColor';
+  const backgroundColor = await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle]);
+
+  // Check: the <webview> body backgroundColor should be transparent black.
+  chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
 };
 
 /**
  * Tests opening Quick View containing an image.
  */
-testcase.openQuickViewImage = function() {
+testcase.openQuickViewImage = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The <webview> resides in the <files-safe-media type="image"> shadow DOM,
@@ -797,61 +554,42 @@
    */
   const webView = ['#quick-view', 'files-safe-media[type="image"]', 'webview'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.smallJpeg.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.smallJpeg], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.smallJpeg.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-      function checkWebViewImageLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || elements[0].attributes.loaded !== '')
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewImageLoaded);
-      }).then(this.next);
-    },
-    // Get the <webview> document.body backgroundColor style.
-    function() {
-      const getBackgroundStyle =
-          'window.getComputedStyle(document.body).backgroundColor';
-      remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle])
-        .then(this.next);
-    },
-    // Check: the <webview> body backgroundColor should be transparent black.
-    function(backgroundColor) {
-      chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.smallJpeg.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.smallJpeg], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.smallJpeg.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewImageLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || elements[0].attributes.loaded !== '')
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewImageLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the <webview> document.body backgroundColor style.
+  const getBackgroundStyle =
+      'window.getComputedStyle(document.body).backgroundColor';
+  const backgroundColor = await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle]);
+
+  // Check: the <webview> body backgroundColor should be transparent black.
+  chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
 };
 
 /**
  * Tests opening Quick View containing a video.
  */
-testcase.openQuickViewVideo = function() {
+testcase.openQuickViewVideo = async function() {
   const caller = getCaller();
-  let appId;
 
   /**
    * The <webview> resides in the <files-safe-media type="video"> shadow DOM,
@@ -859,153 +597,99 @@
    */
   const webView = ['#quick-view', 'files-safe-media[type="video"]', 'webview'];
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.world video.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.world], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.world.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Wait for the Quick View <webview> to load and display its content.
-    function() {
-     function checkWebViewVideoLoaded(elements) {
-        let haveElements = Array.isArray(elements) && elements.length === 1;
-        if (haveElements)
-          haveElements = elements[0].styles.display.includes('block');
-        if (!haveElements || elements[0].attributes.loaded !== '')
-          return pending(caller, 'Waiting for <webview> to load.');
-        return;
-      }
-      repeatUntil(function() {
-        return remoteCall
-            .callRemoteTestUtil(
-                'deepQueryAllElements', appId, [webView, ['display']])
-            .then(checkWebViewVideoLoaded);
-      }).then(this.next);
-    },
-    // Get the <webview> document.body backgroundColor style.
-    function() {
-      const getBackgroundStyle =
-          'window.getComputedStyle(document.body).backgroundColor';
-      remoteCall
-        .callRemoteTestUtil(
-            'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle])
-        .then(this.next);
-    },
-    // Check: the <webview> body backgroundColor should be transparent black.
-    function(backgroundColor) {
-      chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.world video.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.world], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.world.nameText);
+
+  // Wait for the Quick View <webview> to load and display its content.
+  function checkWebViewVideoLoaded(elements) {
+    let haveElements = Array.isArray(elements) && elements.length === 1;
+    if (haveElements)
+      haveElements = elements[0].styles.display.includes('block');
+    if (!haveElements || elements[0].attributes.loaded !== '')
+      return pending(caller, 'Waiting for <webview> to load.');
+    return;
+  }
+  await repeatUntil(async () => {
+    return checkWebViewVideoLoaded(await remoteCall.callRemoteTestUtil(
+        'deepQueryAllElements', appId, [webView, ['display']]));
+  });
+
+  // Get the <webview> document.body backgroundColor style.
+  const getBackgroundStyle =
+      'window.getComputedStyle(document.body).backgroundColor';
+  const backgroundColor = await remoteCall.callRemoteTestUtil(
+      'deepExecuteScriptInWebView', appId, [webView, getBackgroundStyle]);
+
+  // Check: the <webview> body backgroundColor should be transparent black.
+  chrome.test.assertEq('rgba(0, 0, 0, 0)', backgroundColor[0]);
 };
 
 /**
  * Tests close/open metadata info via Enter key.
  */
-testcase.pressEnterOnInfoBoxToOpenClose = function() {
+testcase.pressEnterOnInfoBoxToOpenClose = async function() {
   const infoButton = ['#quick-view', '#metadata-button'];
   const key = [infoButton, 'Enter', false, false, false];
   const infoShown = ['#quick-view', '#contentPanel[metadata-box-active]'];
   const infoHidden =
       ['#quick-view', '#contentPanel:not([metadata-box-active])'];
 
-  let appId;
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.hello.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []);
-    },
-    // Open the file in Quick View.
-    function(results) {
-      appId = results.windowId;
-      const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText);
-      StepsRunner.run(openSteps).then(this.next);
-    },
-    // Press Enter on info button to close metadata box.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next);
-    },
-    // Info should be hidden.
-    function() {
-      remoteCall.waitForElement(appId, infoHidden).then(this.next);
-    },
-    // Press Enter on info button to open metadata box.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next);
-    },
-    // Info should be shown.
-    function() {
-      remoteCall.waitForElement(appId, infoShown).then(this.next);
-    },
-    // Close Quick View.
-    function() {
-      StepsRunner.run(closeQuickViewSteps(appId)).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Open Files app on Downloads containing ENTRIES.hello.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.hello], []);
+
+  // Open the file in Quick View.
+  await openQuickView(appId, ENTRIES.hello.nameText);
+
+  // Press Enter on info button to close metadata box.
+  await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key);
+
+  // Info should be hidden.
+  await remoteCall.waitForElement(appId, infoHidden);
+
+  // Press Enter on info button to open metadata box.
+  await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key);
+
+  // Info should be shown.
+  await remoteCall.waitForElement(appId, infoShown);
+
+  // Close Quick View.
+  await closeQuickView(appId);
 };
 
 /**
  * Tests that Quick View doesn't open with multiple files selected.
  */
-testcase.cantOpenQuickViewWithMultipleFiles = function() {
-  let appId;
+testcase.cantOpenQuickViewWithMultipleFiles = async function() {
+  // Open Files app on Downloads containing ENTRIES.hello and ENTRIES.world.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, [ENTRIES.hello, ENTRIES.world], []);
 
-  StepsRunner.run([
-    // Open Files app on Downloads containing ENTRIES.hello and ENTRIES.world.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello, ENTRIES.world],
-          []);
-    },
-    // Select all 2 files.
-    function(results) {
-      appId = results.windowId;
+  // Select all 2 files.
+  const ctrlA = ['#file-list', 'a', true, false, false];
+  await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, ctrlA);
 
-      const ctrlA = ['#file-list', 'a', true, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, ctrlA, this.next);
-    },
-    // Wait for the files to be selected.
-    function() {
-      remoteCall
-          .waitForElement(
-              appId,
-              '#cancel-selection-button-wrapper:not([hidden]):not([disabled])')
-          .then(this.next);
-    },
-    // Attempt to open Quick View via its keyboard shortcut.
-    function() {
-      const space = ['#file-list', ' ', false, false, false];
-      remoteCall.callRemoteTestUtil('fakeKeyDown', appId, space, this.next);
-    },
-    // Wait for it to possibly open.
-    function() {
-      window.setTimeout(this.next, 500);
-    },
-    // Check Quick View hasn't opened.
-    function() {
-      return remoteCall
-          .callRemoteTestUtil(
-              'deepQueryAllElements', appId, [['#quick-view', '#dialog[open]']])
-          .then(this.next);
-    },
-    function(result) {
-      chrome.test.assertEq([], result);
+  // Wait for the files to be selected.
+  await remoteCall.waitForElement(
+      appId, '#cancel-selection-button-wrapper:not([hidden]):not([disabled])');
 
-      checkIfNoErrorsOccured(this.next);
-    },
-  ]);
+  // Attempt to open Quick View via its keyboard shortcut.
+  const space = ['#file-list', ' ', false, false, false];
+  await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, space);
+
+  // Wait for it to possibly open.
+  await new Promise((resolve) => {
+    window.setTimeout(resolve, 500);
+  });
+
+  // Check Quick View hasn't opened.
+  chrome.test.assertEq(
+      [],
+      await remoteCall.callRemoteTestUtil(
+          'deepQueryAllElements', appId, [['#quick-view', '#dialog[open]']]));
 };
diff --git a/ui/file_manager/integration_tests/file_manager/restore_geometry.js b/ui/file_manager/integration_tests/file_manager/restore_geometry.js
index 074d363..e0b6c40 100644
--- a/ui/file_manager/integration_tests/file_manager/restore_geometry.js
+++ b/ui/file_manager/integration_tests/file_manager/restore_geometry.js
@@ -7,101 +7,60 @@
 /**
  * Tests restoring window geometry of the Files app.
  */
-testcase.restoreGeometry = function() {
-  var appId;
-  var appId2;
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Resize the window to minimal dimensions.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil(
-          'resizeWindow', appId, [640, 480], this.next);
-    },
-    // Check the current window's size.
-    function() {
-      remoteCall.waitForWindowGeometry(appId, 640, 480).then(this.next);
-    },
-    // Enlarge the window by 10 pixels.
-    function(result) {
-      remoteCall.callRemoteTestUtil(
-          'resizeWindow', appId, [650, 490], this.next);
-    },
-    // Check the current window's size.
-    function() {
-      remoteCall.waitForWindowGeometry(appId, 650, 490).then(this.next);
-    },
-    // Open another window, where the current view is restored.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Check the next window's size.
-    function(results) {
-      appId2 = results.windowId;
-      remoteCall.waitForWindowGeometry(appId2, 650, 490).then(this.next);
-    },
-    // Check for errors.
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+testcase.restoreGeometry = async function() {
+  // Set up Files app.
+  let {appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS);
+
+  // Resize the window to minimal dimensions.
+  await remoteCall.callRemoteTestUtil('resizeWindow', appId, [640, 480]);
+
+  // Check the current window's size.
+  await remoteCall.waitForWindowGeometry(appId, 640, 480);
+
+  // Enlarge the window by 10 pixels.
+  await remoteCall.callRemoteTestUtil('resizeWindow', appId, [650, 490]);
+
+  // Check the current window's size.
+  await remoteCall.waitForWindowGeometry(appId, 650, 490);
+
+  // Open another window, where the current view is restored.
+  ({appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS));
+
+  // Check the next window's size.
+  await remoteCall.waitForWindowGeometry(appId, 650, 490);
 };
 
 /**
  * Tests restoring a maximized Files app window.
  */
-testcase.restoreGeometryMaximized = function() {
-  var appId;
-  var appId2;
+testcase.restoreGeometryMaximized = async function() {
   var caller = getCaller();
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Maximize the window
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil('maximizeWindow', appId, [], this.next);
-    },
-    // Check that the first window is maximized.
-    function() {
-      return repeatUntil(function() {
-        return remoteCall.callRemoteTestUtil('isWindowMaximized', appId, [])
-            .then(function(isMaximized) {
-              if (isMaximized)
-                return true;
-              else
-                return pending(caller, 'Waiting window maximized...');
-            });
-      }).then(this.next);
-    },
-    // Close the window.
-    function() {
-      remoteCall.closeWindowAndWait(appId).then(this.next);
-    },
-    // Open a Files app window again.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Check that the newly opened window is maximized initially.
-    function(results) {
-      appId2 = results.windowId;
-      return repeatUntil(function() {
-        return remoteCall.callRemoteTestUtil('isWindowMaximized', appId2, [])
-            .then(function(isMaximized) {
-              if (isMaximized)
-                return true;
-              else
-                return pending(caller, 'Waiting window maximized...');
-            });
-      }).then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
+
+  // Set up Files app.
+  let {appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS);
+
+  // Maximize the window
+  await remoteCall.callRemoteTestUtil('maximizeWindow', appId, []);
+
+  // Check that the first window is maximized.
+  await repeatUntil(async function() {
+    if (await remoteCall.callRemoteTestUtil('isWindowMaximized', appId, [])) {
+      return true;
     }
-  ]);
+    return pending(caller, 'Waiting window maximized...');
+  });
+
+  // Close the window.
+  await remoteCall.closeWindowAndWait(appId);
+
+  // Open a Files app window again.
+  ({appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS));
+
+  // Check that the newly opened window is maximized initially.
+  await repeatUntil(async function() {
+    if (await remoteCall.callRemoteTestUtil('isWindowMaximized', appId, [])) {
+      return true;
+    }
+    return pending(caller, 'Waiting window maximized...');
+  });
 };
diff --git a/ui/file_manager/integration_tests/file_manager/restore_prefs.js b/ui/file_manager/integration_tests/file_manager/restore_prefs.js
index dc013fb..8d7ed9b4 100644
--- a/ui/file_manager/integration_tests/file_manager/restore_prefs.js
+++ b/ui/file_manager/integration_tests/file_manager/restore_prefs.js
@@ -7,8 +7,7 @@
 /**
  * Tests restoring the sorting order.
  */
-testcase.restoreSortColumn = function() {
-  var appId;
+testcase.restoreSortColumn = async function() {
   var EXPECTED_FILES = TestEntryInfo.getExpectedRows([
     ENTRIES.photos,     // 'photos' (directory)
     ENTRIES.world,      // 'world.ogv', 59943 bytes
@@ -16,104 +15,57 @@
     ENTRIES.desktop,    // 'My Desktop Background.png', 272 bytes
     ENTRIES.hello,      // 'hello.txt', 51 bytes
   ]);
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Sort by name.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.callRemoteTestUtil('fakeMouseClick',
-                                    appId,
-                                    ['.table-header-cell:nth-of-type(1)'],
-                                    this.next);
-    },
-    // Check the sorted style of the header.
-    function() {
-      remoteCall.waitForElement(appId, '.table-header-sort-image-asc').
-          then(this.next);
-    },
-    // Sort by size (in descending order).
-    function() {
-      remoteCall.callRemoteTestUtil('fakeMouseClick',
-                                    appId,
-                                    ['.table-header-cell:nth-of-type(2)'],
-                                    this.next);
-    },
-    // Check the sorted style of the header.
-    function() {
-      remoteCall.waitForElement(appId, '.table-header-sort-image-desc').
-          then(this.next);
-    },
-    // Check the sorted files.
-    function() {
-      remoteCall.waitForFiles(appId, EXPECTED_FILES, {orderCheck: true}).
-          then(this.next);
-    },
-    // Open another window, where the sorted column should be restored.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Check the sorted style of the header.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.waitForElement(appId, '.table-header-sort-image-desc').
-          then(this.next);
-    },
-    // Check the sorted files.
-    function() {
-      remoteCall.waitForFiles(appId, EXPECTED_FILES, {orderCheck: true}).
-          then(this.next);
-    },
-    // Check the error.
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+
+  // Set up Files app.
+  let {appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS);
+
+  // Sort by name.
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['.table-header-cell:nth-of-type(1)']);
+
+  // Check the sorted style of the header.
+  await remoteCall.waitForElement(appId, '.table-header-sort-image-asc');
+
+  // Sort by size (in descending order).
+  await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['.table-header-cell:nth-of-type(2)']);
+
+  // Check the sorted style of the header.
+  await remoteCall.waitForElement(appId, '.table-header-sort-image-desc');
+
+  // Check the sorted files.
+  await remoteCall.waitForFiles(appId, EXPECTED_FILES, {orderCheck: true});
+
+  // Open another window, where the sorted column should be restored.
+  ({appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS));
+
+  // Check the sorted style of the header.
+  await remoteCall.waitForElement(appId, '.table-header-sort-image-desc');
+
+  // Check the sorted files.
+  await remoteCall.waitForFiles(appId, EXPECTED_FILES, {orderCheck: true});
 };
 
 /**
  * Tests restoring the current view (the file list or the thumbnail grid).
  */
-testcase.restoreCurrentView = function() {
-  var appId;
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Check the initial view.
-    function(results) {
-      appId = results.windowId;
-      remoteCall.waitForElement(appId, '.thumbnail-grid[hidden]').
-          then(this.next);
-    },
-    // Change the current view.
-    function() {
-      remoteCall.callRemoteTestUtil('fakeMouseClick',
-                                    appId,
-                                    ['#view-button'],
-                                    this.next);
-    },
-    // Check the new current view.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForElement(appId, '.detail-table[hidden]').
-          then(this.next);
-    },
-    // Open another window, where the current view is restored.
-    function() {
-      openNewWindow(null, RootPath.DOWNLOADS, this.next);
-    },
-    // Check the current view.
-    function(inAppId) {
-      appId = inAppId;
-      remoteCall.waitForElement(appId, '.detail-table[hidden]').then(this.next);
-    },
-    // Check the error.
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+testcase.restoreCurrentView = async function() {
+  // Set up Files app.
+  const {appId} = await setupAndWaitUntilReady(null, RootPath.DOWNLOADS);
+
+  // Check the initial view.
+  await remoteCall.waitForElement(appId, '.thumbnail-grid[hidden]');
+
+  // Change the current view.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['#view-button']));
+
+  // Check the new current view.
+  await remoteCall.waitForElement(appId, '.detail-table[hidden]');
+
+  // Open another window, where the current view is restored.
+  const appId2 = await openNewWindow(null, RootPath.DOWNLOADS);
+
+  // Check the current view.
+  await remoteCall.waitForElement(appId2, '.detail-table[hidden]');
 };
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
index 872cab6..e4418e5 100644
--- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -11,92 +11,59 @@
  * @param {!string} url Expected URL for the browser to visit.
  * @param {!string|undefined} teamDrive If set, the team drive to switch to.
  */
-function shareWithOthersExpectBrowserURL(path, url, teamDrive = undefined) {
-  let appId;
+async function shareWithOthersExpectBrowserURL(
+    path, url, teamDrive = undefined) {
+  // Open Files app on Drive.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DRIVE, null, [],
+      BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
 
-  StepsRunner.run([
-    // Open Files app on Drive.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DRIVE, this.next, [],
-          BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
-    },
-    // Navigate to the specified team drive if one is specified.
-    function(results) {
-      appId = results.windowId;
-      if (teamDrive === undefined) {
-        this.next();
-        return;
-      }
-      remoteCall
-          .navigateWithDirectoryTree(
-              appId,
-              teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
-              'Team Drives', 'drive')
-          .then(this.next);
-    },
-    // Wait for the file list to update if we navigated.
-    function() {
-      if (teamDrive === undefined) {
-        this.next();
-        return;
-      }
-      remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length)
-          .then(this.next);
-    },
-    // Select the given |path|.
-    function() {
-      remoteCall.callRemoteTestUtil('selectFile', appId, [path], this.next);
-    },
-    // Wait for the entry to be selected.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'selectFile failed');
-      remoteCall.waitForElement(appId, '.table-row[selected]').then(this.next);
-    },
-    // Wait for the share button to appear.
-    function() {
-      remoteCall.waitForElement(appId, '#share-menu-button:not([disabled])')
-          .then(this.next);
-    },
-    // Click the share button to open share menu.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, ['#share-menu-button'], this.next);
-    },
-    // Check: the "Share with others" menu item should be shown enabled.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      const shareMenuItem =
-          '#share-menu:not([hidden]) [command="#share"]:not([disabled])';
-      remoteCall.waitForElement(appId, shareMenuItem).then(this.next);
-    },
-    // Click the "Share with others" menu item.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      const shareWithOthers = '#share-menu [command="#share"]:not([disabled])';
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseClick', appId, [shareWithOthers], this.next);
-    },
-    // Wait for the share menu to disappear.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      remoteCall.waitForElement(appId, '#share-menu[hidden]').then(this.next);
-    },
-    // Wait for the browser window to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil('getLastVisitedURL', appId, [], this.next);
-    },
-    // Check: the browser navigated to the expected URL.
-    function(visitedUrl) {
-      chrome.test.assertEq(url, visitedUrl);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Navigate to the specified team drive if one is specified.
+  if (teamDrive !== undefined) {
+    await remoteCall.navigateWithDirectoryTree(
+        appId, teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
+        'Team Drives', 'drive');
+
+    // Wait for the file list to update.
+    await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
+  }
+
+  // Select the given |path|.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
+      'selectFile failed');
+
+  // Wait for the entry to be selected.
+  await remoteCall.waitForElement(appId, '.table-row[selected]');
+
+  // Wait for the share button to appear.
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '#share-menu-button:not([disabled])'));
+
+  // Click the share button to open share menu.
+  chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['#share-menu-button']));
+
+  // Check: the "Share with others" menu item should be shown enabled.
+  const shareMenuItem =
+      '#share-menu:not([hidden]) [command="#share"]:not([disabled])';
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElement(appId, shareMenuItem));
+
+  // Click the "Share with others" menu item.
+  const shareWithOthers = '#share-menu [command="#share"]:not([disabled])';
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseClick', appId, [shareWithOthers]),
+      'fakeMouseClick failed');
+
+  // Wait for the share menu to disappear.
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElement(appId, '#share-menu[hidden]'));
+
+  // Wait for the browser window to appear and navigate to the expected URL.
+  chrome.test.assertEq(
+      url, await remoteCall.callRemoteTestUtil('getLastVisitedURL', appId, []));
 }
 
 /**
@@ -106,97 +73,61 @@
  * @param {!string} url Expected URL for the browser to visit.
  * @param {!string|undefined} teamDrive If set, the team drive to switch to.
  */
-function manageWithDriveExpectBrowserURL(path, url, teamDrive = undefined) {
-  let appId;
+async function manageWithDriveExpectBrowserURL(
+    path, url, teamDrive = undefined) {
+  // Open Files app on Drive.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DRIVE, null, [],
+      BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
 
-  StepsRunner.run([
-    // Open Files app on Drive.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DRIVE, this.next, [],
-          BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
-    },
-    // Navigate to the specified team drive if one is specified.
-    function(results) {
-      appId = results.windowId;
-      if (teamDrive === undefined) {
-        this.next();
-        return;
-      }
-      remoteCall
-          .navigateWithDirectoryTree(
-              appId,
-              teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
-              'Team Drives', 'drive')
-          .then(this.next);
-    },
-    // Wait for the file list to update if we navigated.
-    function() {
-      if (teamDrive === undefined) {
-        this.next();
-        return;
-      }
-      remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length)
-          .then(this.next);
-    },
-    // Select the given |path|.
-    function() {
-      remoteCall.callRemoteTestUtil('selectFile', appId, [path], this.next);
-    },
-    // Wait for the entry to be selected.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'selectFile failed');
-      remoteCall.waitForElement(appId, '.table-row[selected]').then(this.next);
-    },
-    // Right-click the selected entry.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseRightClick', appId, ['.table-row[selected]'], this.next);
-    },
-    // Wait for the context menu to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      remoteCall.waitForElement(appId, '#file-context-menu:not([hidden])')
-          .then(this.next);
-    },
-    // Wait for the "Manage in Drive" menu item to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall
-          .waitForElement(
-              appId,
-              '[command="#manage-in-drive"]:not([hidden]):not([disabled])')
-          .then(this.next);
-    },
-    // Click the "Manage in Drive" menu item.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
+  // Navigate to the specified team drive if one is specified.
+  if (teamDrive !== undefined) {
+    await remoteCall.navigateWithDirectoryTree(
+        appId, teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`,
+        'Team Drives', 'drive');
+
+    // Wait for the file list to update.
+    await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
+  }
+
+  // Select the given |path|.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
+      'selectFile failed');
+
+  // Wait for the entry to be selected.
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElement(appId, '.table-row[selected]'));
+
+  // Right-click the selected entry.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseRightClick', appId, ['.table-row[selected]']),
+      'fakeMouseClick failed');
+
+  // Wait for the context menu to appear.
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '#file-context-menu:not([hidden])'));
+
+  // Wait for the "Manage in Drive" menu item to appear.
+
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '[command="#manage-in-drive"]:not([hidden]):not([disabled])'));
+
+  // Click the "Manage in Drive" menu item.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
           'fakeMouseClick', appId,
-          ['[command="#manage-in-drive"]:not([hidden]):not([disabled])'],
-          this.next);
-    },
-    // Wait for the context menu to disappear.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      remoteCall.waitForElement(appId, '#file-context-menu[hidden]')
-          .then(this.next);
-    },
-    // Wait for the browser window to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil('getLastVisitedURL', appId, [], this.next);
-    },
-    // Check: the browser navigated to the expected URL.
-    function(visitedUrl) {
-      chrome.test.assertEq(url, visitedUrl);
-      this.next();
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+          ['[command="#manage-in-drive"]:not([hidden]):not([disabled])']),
+      'fakeMouseClick failed');
+
+  // Wait for the context menu to disappear.
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElement(appId, '#file-context-menu[hidden]'));
+
+  // Wait for the browser window to appear and navigate to the expected URL.
+  chrome.test.assertEq(
+      url, await remoteCall.callRemoteTestUtil('getLastVisitedURL', appId, []));
 }
 
 /**
@@ -204,7 +135,7 @@
  */
 testcase.shareFileDrive = function() {
   const URL = 'https://file_alternate_link/world.ogv?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL('world.ogv', URL);
+  return shareWithOthersExpectBrowserURL('world.ogv', URL);
 };
 
 /**
@@ -212,7 +143,7 @@
  */
 testcase.shareDirectoryDrive = function() {
   const URL = 'https://folder_alternate_link/photos?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL('photos', URL);
+  return shareWithOthersExpectBrowserURL('photos', URL);
 };
 
 /**
@@ -221,7 +152,7 @@
 testcase.shareHostedFileDrive = function() {
   const URL =
       'https://document_alternate_link/Test%20Document?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL('Test Document.gdoc', URL);
+  return shareWithOthersExpectBrowserURL('Test Document.gdoc', URL);
 };
 
 /**
@@ -229,7 +160,7 @@
  */
 testcase.manageFileDrive = function() {
   const URL = 'https://file_alternate_link/world.ogv';
-  manageWithDriveExpectBrowserURL('world.ogv', URL);
+  return manageWithDriveExpectBrowserURL('world.ogv', URL);
 };
 
 /**
@@ -237,7 +168,7 @@
  */
 testcase.manageDirectoryDrive = function() {
   const URL = 'https://folder_alternate_link/photos';
-  manageWithDriveExpectBrowserURL('photos', URL);
+  return manageWithDriveExpectBrowserURL('photos', URL);
 };
 
 /**
@@ -245,7 +176,7 @@
  */
 testcase.manageHostedFileDrive = function() {
   const URL = 'https://document_alternate_link/Test%20Document';
-  manageWithDriveExpectBrowserURL('Test Document.gdoc', URL);
+  return manageWithDriveExpectBrowserURL('Test Document.gdoc', URL);
 };
 
 /**
@@ -254,69 +185,51 @@
 testcase.shareFileTeamDrive = function() {
   const URL =
       'https://file_alternate_link/teamDriveAFile.txt?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL('teamDriveAFile.txt', URL, 'Team Drive A');
+  return shareWithOthersExpectBrowserURL(
+      'teamDriveAFile.txt', URL, 'Team Drive A');
 };
 
 /**
  * Tests that sharing a directory in a team drive is not allowed.
  */
-testcase.shareDirectoryTeamDrive = function() {
-  let appId;
+testcase.shareDirectoryTeamDrive = async function() {
   const teamDrive = 'Team Drive A';
   const path = 'teamDriveADirectory';
 
-  StepsRunner.run([
-    // Open Files app on Drive.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DRIVE, this.next, [],
-          BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
-    },
-    // Navigate to the team drive.
-    function(results) {
-      appId = results.windowId;
-      remoteCall
-          .navigateWithDirectoryTree(
-              appId, `/team_drives/${teamDrive}`, 'Team Drives', 'drive')
-          .then(this.next);
-    },
-    // Wait for the file list to update.
-    function() {
-      remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length)
-          .then(this.next);
-    },
-    // Select the given |path|.
-    function() {
-      remoteCall.callRemoteTestUtil('selectFile', appId, [path], this.next);
-    },
-    // Wait for the entry to be selected.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'selectFile failed');
-      remoteCall.waitForElement(appId, '.table-row[selected]').then(this.next);
-    },
-    // Right-click the selected entry.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseRightClick', appId, ['.table-row[selected]'], this.next);
-    },
-    // Wait for the context menu to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result, 'fakeMouseClick failed');
-      remoteCall.waitForElement(appId, '#file-context-menu:not([hidden])')
-          .then(this.next);
-    },
-    // Wait for the "Share" menu item to appear.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall
-          .waitForElement(appId, '[command="#share"]:not([hidden])[disabled]')
-          .then(this.next);
-    },
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+  // Open Files app on Drive.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DRIVE, null, [],
+      BASIC_DRIVE_ENTRY_SET.concat(TEAM_DRIVE_ENTRY_SET));
+
+  // Navigate to the team drive.
+  await remoteCall.navigateWithDirectoryTree(
+      appId, `/team_drives/${teamDrive}`, 'Team Drives', 'drive');
+
+  // Wait for the file list to update.
+  await remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length);
+
+  // Select the given |path|.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('selectFile', appId, [path]),
+      'selectFile failed');
+
+  // Wait for the entry to be selected.
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElement(appId, '.table-row[selected]'));
+
+  // Right-click the selected entry.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil(
+          'fakeMouseRightClick', appId, ['.table-row[selected]']),
+      'fakeMouseClick failed');
+
+  // Wait for the context menu to appear.
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '#file-context-menu:not([hidden])'));
+
+  // Wait for the "Share" menu item to appear.
+  await remoteCall.waitForElement(
+      appId, '[command="#share"]:not([hidden])[disabled]');
 };
 
 /**
@@ -325,7 +238,7 @@
 testcase.shareHostedFileTeamDrive = function() {
   const URL =
       'https://document_alternate_link/teamDriveAHostedDoc?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL(
+  return shareWithOthersExpectBrowserURL(
       'teamDriveAHostedDoc.gdoc', URL, 'Team Drive A');
 };
 
@@ -334,7 +247,8 @@
  */
 testcase.manageFileTeamDrive = function() {
   const URL = 'https://file_alternate_link/teamDriveAFile.txt';
-  manageWithDriveExpectBrowserURL('teamDriveAFile.txt', URL, 'Team Drive A');
+  return manageWithDriveExpectBrowserURL(
+      'teamDriveAFile.txt', URL, 'Team Drive A');
 };
 
 /**
@@ -342,7 +256,8 @@
  */
 testcase.manageDirectoryTeamDrive = function() {
   const URL = 'https://folder_alternate_link/teamDriveADirectory';
-  manageWithDriveExpectBrowserURL('teamDriveADirectory', URL, 'Team Drive A');
+  return manageWithDriveExpectBrowserURL(
+      'teamDriveADirectory', URL, 'Team Drive A');
 };
 
 /**
@@ -350,7 +265,7 @@
  */
 testcase.manageHostedFileTeamDrive = function() {
   const URL = 'https://document_alternate_link/teamDriveAHostedDoc';
-  manageWithDriveExpectBrowserURL(
+  return manageWithDriveExpectBrowserURL(
       'teamDriveAHostedDoc.gdoc', URL, 'Team Drive A');
 };
 
@@ -359,7 +274,7 @@
  */
 testcase.manageTeamDrive = function() {
   const URL = 'https://folder_alternate_link/Team%20Drive%20A';
-  manageWithDriveExpectBrowserURL('Team Drive A', URL, '');
+  return manageWithDriveExpectBrowserURL('Team Drive A', URL, '');
 };
 
 /**
@@ -368,5 +283,5 @@
 testcase.shareTeamDrive = function() {
   const URL =
       'https://folder_alternate_link/Team%20Drive%20A?userstoinvite=%22%22';
-  shareWithOthersExpectBrowserURL('Team Drive A', URL, '');
+  return shareWithOthersExpectBrowserURL('Team Drive A', URL, '');
 };
diff --git a/ui/file_manager/integration_tests/file_manager/suggest_app_dialog.js b/ui/file_manager/integration_tests/file_manager/suggest_app_dialog.js
index c4371ca..630719f 100644
--- a/ui/file_manager/integration_tests/file_manager/suggest_app_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/suggest_app_dialog.js
@@ -7,107 +7,68 @@
 /**
  * Tests sharing a file on Drive
  */
-testcase.suggestAppDialog = function() {
-  var appId;
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      sendTestMessage({name: 'getCwsWidgetContainerMockUrl'}).then(this.next);
-    },
-    // Override the container URL with the mock.
-    function(json) {
-      var data = JSON.parse(json);
+testcase.suggestAppDialog = async function() {
+  // Fetch the mock CWS page data.
+  const data =
+      JSON.parse(await sendTestMessage({name: 'getCwsWidgetContainerMockUrl'}));
 
-      var appState = {
-        suggestAppsDialogState: {
-          overrideCwsContainerUrlForTest: data.url,
-          overrideCwsContainerOriginForTest: data.origin
-        }
-      };
-      setupAndWaitUntilReady(appState, RootPath.DRIVE, this.next);
-    },
-    function(results) {
-      appId = results.windowId;
-
-      remoteCall.callRemoteTestUtil(
-          'selectFile', appId, ['unsupported.foo'], this.next);
-    },
-    // Double-click the file.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.callRemoteTestUtil(
-          'fakeMouseDoubleClick',
-          appId,
-          ['#file-list li.table-row[selected] .filename-label span'],
-          this.next);
-    },
-    // Wait for the widget is loaded.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForElement(appId, '#suggest-app-dialog webview[src]').
-          then(this.next);
-    },
-    // Wait for the widget is initialized.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.waitForElement(
-          appId, '.cws-widget-spinner-layer:not(.cws-widget-show-spinner)').
-          then(this.next);
-    },
-    // Override task APIs for test.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'overrideTasks',
-          appId,
-          [[
-            {
-              driveApp: false,
-              iconUrl: 'chrome://theme/IDR_DEFAULT_FAVICON',  // Dummy icon
-              isDefault: true,
-              taskId: 'dummytaskid|drive|open-with',
-              title: 'The dummy task for test'
-            }
-          ]],
-          this.next);
-    },
-    // Override installWebstoreItem API for test.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'overrideInstallWebstoreItemApi',
-          appId,
-          [
-            'DUMMY_ITEM_ID_FOR_TEST',  // Same ID in cws_container_mock/main.js.
-            null  // Success
-          ],
-          this.next);
-    },
-    // Initiate an installation from the widget.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.callRemoteTestUtil(
-          'executeScriptInWebView',
-          appId,
-          ['#suggest-app-dialog webview',
-           'document.querySelector("button").click()'],
-          this.next);
-    },
-    // Wait until the installation is finished and the dialog is closed.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.waitForElementLost(appId, '#suggest-app-dialog').
-          then(this.next);
-    },
-    // Wait until the task is executed.
-    function(result) {
-      chrome.test.assertTrue(!!result);
-      remoteCall.waitUntilTaskExecutes(appId, 'dummytaskid|drive|open-with').
-          then(this.next);
-    },
-    // Check error
-    function() {
-      checkIfNoErrorsOccured(this.next);
+  // Override the container URL with the mock.
+  var appState = {
+    suggestAppsDialogState: {
+      overrideCwsContainerUrlForTest: data.url,
+      overrideCwsContainerOriginForTest: data.origin
     }
-  ]);
+  };
+
+  // Set up File Manager.
+  const {appId} = await setupAndWaitUntilReady(appState, RootPath.DRIVE);
+
+  // Select a file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectFile', appId, ['unsupported.foo']));
+
+  // Double-click the file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'fakeMouseDoubleClick', appId,
+      ['#file-list li.table-row[selected] .filename-label span']));
+
+  // Wait until the widget is loaded.
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '#suggest-app-dialog webview[src]'));
+
+  // Wait until the widget is initialized.
+  chrome.test.assertTrue(!!await remoteCall.waitForElement(
+      appId, '.cws-widget-spinner-layer:not(.cws-widget-show-spinner)'));
+
+  // Override task APIs for test.
+  chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
+      'overrideTasks', appId, [[{
+        driveApp: false,
+        iconUrl: 'chrome://theme/IDR_DEFAULT_FAVICON',  // Dummy icon
+        isDefault: true,
+        taskId: 'dummytaskid|drive|open-with',
+        title: 'The dummy task for test'
+      }]]));
+
+  // Override installWebstoreItem API for test.
+  chrome.test.assertTrue(!!remoteCall.callRemoteTestUtil(
+      'overrideInstallWebstoreItemApi', appId,
+      [
+        'DUMMY_ITEM_ID_FOR_TEST',  // Same ID in cws_container_mock/main.js.
+        null                       // Success
+      ]));
+
+  // Initiate an installation from the widget.
+  chrome.test.assertTrue(
+      !!await remoteCall.callRemoteTestUtil('executeScriptInWebView', appId, [
+        '#suggest-app-dialog webview',
+        'document.querySelector("button").click()'
+      ]));
+
+  // Wait until the installation is finished and the dialog is closed.
+  chrome.test.assertTrue(
+      !!await remoteCall.waitForElementLost(appId, '#suggest-app-dialog'));
+
+  // Wait until the task is executed.
+  await remoteCall.waitUntilTaskExecutes(appId, 'dummytaskid|drive|open-with');
 };
diff --git a/ui/file_manager/integration_tests/file_manager/transfer.js b/ui/file_manager/integration_tests/file_manager/transfer.js
index 5270b2b..07fc429 100644
--- a/ui/file_manager/integration_tests/file_manager/transfer.js
+++ b/ui/file_manager/integration_tests/file_manager/transfer.js
@@ -103,9 +103,7 @@
  * Test function to copy from the specified source to the specified destination.
  * @param {TransferInfo} transferInfo Options for the transfer.
  */
-function transferBetweenVolumes(transferInfo) {
-  let appId;
-
+async function transferBetweenVolumes(transferInfo) {
   let srcContents;
   if (transferInfo.source.isTeamDrive) {
     srcContents =
@@ -142,144 +140,93 @@
       TEAM_DRIVE_ENTRY_SET :
       BASIC_DRIVE_ENTRY_SET;
 
-  StepsRunner.run([
-    // Set up File Manager.
-    function() {
-      setupAndWaitUntilReady(
-          null, RootPath.DOWNLOADS, this.next, localFiles, driveFiles);
-    },
-    // Expand Drive root if either src or dst is within Drive.
-    function(results) {
-      appId = results.windowId;
-      if (transferInfo.source.isTeamDrive ||
-          transferInfo.destination.isTeamDrive) {
-        // Select + expand + wait for its content.
-        remoteCall
-            .callRemoteTestUtil('selectFolderInTree', appId, ['Google Drive'])
-            .then(result => {
-              chrome.test.assertTrue(result);
-              return remoteCall.callRemoteTestUtil(
-                  'expandSelectedFolderInTree', appId, []);
-            })
-            .then(result => {
-              chrome.test.assertTrue(result);
-              return remoteCall.waitForFiles(appId, myDriveContent);
-            })
-            .then(this.next);
-      } else {
-        // If isn't drive source, just move on.
-        this.next();
-      }
-    },
-    // Select the source volume.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          transferInfo.source.isTeamDrive ? 'selectTeamDrive' : 'selectVolume',
-          appId, [transferInfo.source.volumeName], this.next);
-    },
-    // Wait for the expected files to appear in the file list.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForFiles(appId, srcContents).then(this.next);
-    },
-    // Focus the file list.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'focus', appId, ['#file-list:not([hidden])'], this.next);
-    },
-    // Select the source file.
-    function() {
-      remoteCall.callRemoteTestUtil(
-          'selectFile', appId, [transferInfo.fileToTransfer.nameText],
-          this.next);
-    },
-    // Copy the file.
-    function(result) {
-      chrome.test.assertTrue(result);
-      let transferCommand = transferInfo.isMove ? 'move' : 'copy';
-      remoteCall.callRemoteTestUtil(
-          'execCommand', appId, [transferCommand], this.next);
-    },
-    // Select the destination volume.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.callRemoteTestUtil(
-          transferInfo.destination.isTeamDrive ? 'selectTeamDrive' :
-                                                 'selectVolume',
-          appId, [transferInfo.destination.volumeName], this.next);
-    },
-    // Wait for the expected files to appear in the file list.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForFiles(appId, dstContents).then(this.next);
-    },
-    // Paste the file.
-    function() {
-      remoteCall.callRemoteTestUtil('execCommand', appId, ['paste'], this.next);
-    },
-    // Wait for a dialog if one is expected, or just continue.
-    function(result) {
-      chrome.test.assertTrue(result);
-      // If we're expecting a confirmation dialog, confirm that it is shown.
-      if (transferInfo.expectedDialogText !== undefined) {
-        return remoteCall.waitForElement(appId, '.cr-dialog-container.shown')
-            .then(this.next);
-      } else {
-        setTimeout(this.next, 0);
-      }
-    },
-    // Click OK if the dialog appears.
-    function(element) {
-      if (transferInfo.expectedDialogText !== undefined) {
-        chrome.test.assertEq(transferInfo.expectedDialogText, element.text);
-        // Press OK button.
-        remoteCall
-            .callRemoteTestUtil(
-                'fakeMouseClick', appId, ['button.cr-dialog-ok'])
-            .then(this.next);
-      } else {
-        this.next();
-      }
-    },
-    // Wait for the file list to change, if the test is expected to pass.
-    function(result) {
-      if (transferInfo.expectedDialogText !== undefined) {
-        chrome.test.assertTrue(result);
-      }
+  // Open files app.
+  const {appId} = await setupAndWaitUntilReady(
+      null, RootPath.DOWNLOADS, null, localFiles, driveFiles);
 
-      const dstContentsAfterPaste = dstContents.slice();
-      var ignoreFileSize =
-          transferInfo.source.volumeName == 'drive_shared_with_me' ||
-          transferInfo.source.volumeName == 'drive_offline' ||
-          transferInfo.destination.volumeName == 'drive_shared_with_me' ||
-          transferInfo.destination.volumeName == 'drive_offline';
+  // Expand Drive root if either src or dst is within Drive.
+  if (transferInfo.source.isTeamDrive || transferInfo.destination.isTeamDrive) {
+    // Select + expand + wait for its content.
+    chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+        'selectFolderInTree', appId, ['Google Drive']));
+    chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+        'expandSelectedFolderInTree', appId, []));
+    await remoteCall.waitForFiles(appId, myDriveContent);
+  }
 
-      // If we expected the transfer to succeed, add the pasted file to the list
-      // of expected rows.
-      if (!transferInfo.expectFailure) {
-        var pasteFile = transferInfo.fileToTransfer.getExpectedRow();
-        // Check if we need to add (1) to the filename, in the case of a
-        // duplicate file.
-        for (var i = 0; i < dstContentsAfterPaste.length; i++) {
-          if (dstContentsAfterPaste[i][0] === pasteFile[0]) {
-            // Replace the last '.' in filename with ' (1).'.
-            // e.g. 'my.note.txt' -> 'my.note (1).txt'
-            pasteFile[0] = pasteFile[0].replace(/\.(?=[^\.]+$)/, ' (1).');
-            break;
-          }
-        }
-        dstContentsAfterPaste.push(pasteFile);
+  // Select the source volume.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      transferInfo.source.isTeamDrive ? 'selectTeamDrive' : 'selectVolume',
+      appId, [transferInfo.source.volumeName]));
+
+  // Wait for the expected files to appear in the file list.
+  await remoteCall.waitForFiles(appId, srcContents);
+
+  // Focus the file list.
+  await remoteCall.callRemoteTestUtil(
+      'focus', appId, ['#file-list:not([hidden])']);
+
+  // Select the source file.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'selectFile', appId, [transferInfo.fileToTransfer.nameText]));
+
+  // Copy the file.
+  let transferCommand = transferInfo.isMove ? 'move' : 'copy';
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'execCommand', appId, [transferCommand]));
+
+  // Select the destination volume.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      transferInfo.destination.isTeamDrive ? 'selectTeamDrive' : 'selectVolume',
+      appId, [transferInfo.destination.volumeName]));
+
+  // Wait for the expected files to appear in the file list.
+  await remoteCall.waitForFiles(appId, dstContents);
+
+  // Paste the file.
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('execCommand', appId, ['paste']));
+
+  // If we're expecting a confirmation dialog, confirm that it is shown.
+  if (transferInfo.expectedDialogText !== undefined) {
+    const {text} =
+        await remoteCall.waitForElement(appId, '.cr-dialog-container.shown');
+    chrome.test.assertEq(transferInfo.expectedDialogText, text);
+
+    // Press OK button.
+    chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+        'fakeMouseClick', appId, ['button.cr-dialog-ok']));
+  }
+
+  // Wait for the file list to change, if the test is expected to pass.
+  const dstContentsAfterPaste = dstContents.slice();
+  var ignoreFileSize =
+      transferInfo.source.volumeName == 'drive_shared_with_me' ||
+      transferInfo.source.volumeName == 'drive_offline' ||
+      transferInfo.destination.volumeName == 'drive_shared_with_me' ||
+      transferInfo.destination.volumeName == 'drive_offline';
+
+  // If we expected the transfer to succeed, add the pasted file to the list
+  // of expected rows.
+  if (!transferInfo.expectFailure) {
+    var pasteFile = transferInfo.fileToTransfer.getExpectedRow();
+    // Check if we need to add (1) to the filename, in the case of a
+    // duplicate file.
+    for (var i = 0; i < dstContentsAfterPaste.length; i++) {
+      if (dstContentsAfterPaste[i][0] === pasteFile[0]) {
+        // Replace the last '.' in filename with ' (1).'.
+        // e.g. 'my.note.txt' -> 'my.note (1).txt'
+        pasteFile[0] = pasteFile[0].replace(/\.(?=[^\.]+$)/, ' (1).');
+        break;
       }
-      remoteCall.waitForFiles(appId, dstContentsAfterPaste, {
-        ignoreFileSize: ignoreFileSize,
-        ignoreLastModifiedTime: true
-      }).then(this.next);
-    },
-    // Check the last contents of file list.
-    function() {
-      checkIfNoErrorsOccured(this.next);
     }
-  ]);
+    dstContentsAfterPaste.push(pasteFile);
+  }
+
+  // Check the last contents of file list.
+  await remoteCall.waitForFiles(
+      appId, dstContentsAfterPaste,
+      {ignoreFileSize: ignoreFileSize, ignoreLastModifiedTime: true});
 }
 
 /**
@@ -322,7 +269,7 @@
  * Tests copying from Drive to Downloads.
  */
 testcase.transferFromDriveToDownloads = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.hello,
     source: TRANSFER_LOCATIONS.drive,
     destination: TRANSFER_LOCATIONS.downloads,
@@ -333,7 +280,7 @@
  * Tests copying from Downloads to Drive.
  */
 testcase.transferFromDownloadsToDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.hello,
     source: TRANSFER_LOCATIONS.downloads,
     destination: TRANSFER_LOCATIONS.drive,
@@ -344,7 +291,7 @@
  * Tests copying from Drive shared with me to Downloads.
  */
 testcase.transferFromSharedToDownloads = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.testSharedDocument,
     source: TRANSFER_LOCATIONS.sharedWithMe,
     destination: TRANSFER_LOCATIONS.downloads,
@@ -355,7 +302,7 @@
  * Tests copying from Drive shared with me to Drive.
  */
 testcase.transferFromSharedToDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.testSharedDocument,
     source: TRANSFER_LOCATIONS.sharedWithMe,
     destination: TRANSFER_LOCATIONS.drive,
@@ -366,7 +313,7 @@
  * Tests copying from Drive offline to Downloads.
  */
 testcase.transferFromOfflineToDownloads = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.testDocument,
     source: TRANSFER_LOCATIONS.driveOffline,
     destination: TRANSFER_LOCATIONS.downloads,
@@ -377,7 +324,7 @@
  * Tests copying from Drive offline to Drive.
  */
 testcase.transferFromOfflineToDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.testDocument,
     source: TRANSFER_LOCATIONS.driveOffline,
     destination: TRANSFER_LOCATIONS.drive,
@@ -388,7 +335,7 @@
  * Tests copying from a Team Drive to Drive.
  */
 testcase.transferFromTeamDriveToDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.teamDriveAFile,
     source: TRANSFER_LOCATIONS.driveTeamDriveA,
     destination: TRANSFER_LOCATIONS.driveWithTeamDriveEntries,
@@ -399,7 +346,7 @@
  * Tests copying from Drive to a Team Drive.
  */
 testcase.transferFromDriveToTeamDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.hello,
     source: TRANSFER_LOCATIONS.driveWithTeamDriveEntries,
     destination: TRANSFER_LOCATIONS.driveTeamDriveA,
@@ -413,7 +360,7 @@
  * Tests copying from a Team Drive to Downloads.
  */
 testcase.transferFromTeamDriveToDownloads = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.teamDriveAFile,
     source: TRANSFER_LOCATIONS.driveTeamDriveA,
     destination: TRANSFER_LOCATIONS.downloads,
@@ -426,7 +373,7 @@
  * Drive.
  */
 testcase.transferHostedFileFromTeamDriveToDownloads = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.teamDriveAHostedFile,
     source: TRANSFER_LOCATIONS.driveTeamDriveA,
     destination: TRANSFER_LOCATIONS.driveWithTeamDriveEntries,
@@ -438,7 +385,7 @@
  * Tests copying from Downloads to a Team Drive.
  */
 testcase.transferFromDownloadsToTeamDrive = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.hello,
     source: TRANSFER_LOCATIONS.downloads,
     destination: TRANSFER_LOCATIONS.driveTeamDriveA,
@@ -452,7 +399,7 @@
  * Tests copying between Team Drives.
  */
 testcase.transferBetweenTeamDrives = function() {
-  transferBetweenVolumes(new TransferInfo({
+  return transferBetweenVolumes(new TransferInfo({
     fileToTransfer: ENTRIES.teamDriveBFile,
     source: TRANSFER_LOCATIONS.driveTeamDriveB,
     destination: TRANSFER_LOCATIONS.driveTeamDriveA,
diff --git a/ui/file_manager/integration_tests/file_manager/traverse.js b/ui/file_manager/integration_tests/file_manager/traverse.js
index 05a031f4..859673c 100644
--- a/ui/file_manager/integration_tests/file_manager/traverse.js
+++ b/ui/file_manager/integration_tests/file_manager/traverse.js
@@ -8,63 +8,40 @@
  * Test utility for traverse tests.
  * @param {string} path Root path to be traversed.
  */
-function traverseDirectories(path) {
-  var appId;
-  StepsRunner.run([
-    // Set up File Manager. Do not add initial files.
-    function() {
-      openNewWindow(null, path, this.next);
-    },
-    // Check the initial view.
-    function(inAppId) {
-      appId = inAppId;
-      remoteCall.waitForElement(appId, '#detail-table').then(this.next);
-    },
-    function() {
-      addEntries(['local', 'drive'], NESTED_ENTRY_SET, this.next);
-    },
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForFiles(appId, [ENTRIES.directoryA.getExpectedRow()]).
-          then(this.next);
-    },
-    // Open the directory
-    function() {
-      remoteCall.callRemoteTestUtil('openFile', appId, ['A'], this.next);
-    },
-    // Check the contents of current directory.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForFiles(appId, [ENTRIES.directoryB.getExpectedRow()]).
-          then(this.next);
-    },
-    // Open the directory
-    function() {
-      remoteCall.callRemoteTestUtil('openFile', appId, ['B'], this.next);
-    },
-    // Check the contents of current directory.
-    function(result) {
-      chrome.test.assertTrue(result);
-      remoteCall.waitForFiles(appId, [ENTRIES.directoryC.getExpectedRow()]).
-          then(this.next);
-    },
-    // Check the error.
-    function() {
-      checkIfNoErrorsOccured(this.next);
-    }
-  ]);
+async function traverseDirectories(path) {
+  // Set up File Manager. Do not add initial files.
+  const appId = await openNewWindow(null, path);
+
+  // Check the initial view.
+  await remoteCall.waitForElement(appId, '#detail-table');
+  await addEntries(['local', 'drive'], NESTED_ENTRY_SET);
+  await remoteCall.waitForFiles(appId, [ENTRIES.directoryA.getExpectedRow()]);
+
+  // Open the directory
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('openFile', appId, ['A']));
+
+  // Check the contents of current directory.
+  await remoteCall.waitForFiles(appId, [ENTRIES.directoryB.getExpectedRow()]);
+
+  // Open the directory
+  chrome.test.assertTrue(
+      await remoteCall.callRemoteTestUtil('openFile', appId, ['B']));
+
+  // Check the contents of current directory.
+  await remoteCall.waitForFiles(appId, [ENTRIES.directoryC.getExpectedRow()]);
 }
 
 /**
  * Tests to traverse local directories.
  */
 testcase.traverseDownloads = function() {
-  traverseDirectories(RootPath.DOWNLOADS);
+  return traverseDirectories(RootPath.DOWNLOADS);
 };
 
 /**
  * Tests to traverse drive directories.
  */
 testcase.traverseDrive = function() {
-  traverseDirectories(RootPath.DRIVE);
+  return traverseDirectories(RootPath.DRIVE);
 };
diff --git a/ui/ozone/common/linux/BUILD.gn b/ui/ozone/common/linux/BUILD.gn
index 3e95929..2bf3481 100644
--- a/ui/ozone/common/linux/BUILD.gn
+++ b/ui/ozone/common/linux/BUILD.gn
@@ -7,18 +7,29 @@
 
 assert(ozone_platform_gbm || ozone_platform_wayland)
 
-source_set("linux") {
+source_set("drm") {
   sources = [
     "drm_util_linux.cc",
     "drm_util_linux.h",
+  ]
+
+  deps = [
+    "//base:base",
+    "//build/config/linux/libdrm",
+    "//ui/gfx:buffer_types",
+  ]
+}
+
+source_set("gbm") {
+  sources = [
     "gbm_buffer.h",
     "gbm_device.h",
     "gbm_wrapper.cc",
   ]
 
   deps = [
+    ":drm",
     "//base:base",
-    "//build/config/linux/libdrm",
     "//third_party/minigbm",
     "//ui/gfx:buffer_types",
     "//ui/gfx:memory_buffer",
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index 490835ced..5af8744 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -3,8 +3,8 @@
 # found in the LICENSE file.
 
 import("//build/config/linux/pkg_config.gni")
-import("//ui/ozone/ozone.gni")
 import("//gpu/vulkan/features.gni")
+import("//ui/ozone/ozone.gni")
 
 visibility = [ "//ui/ozone/*" ]
 
@@ -144,7 +144,8 @@
     "//ui/gl",
     "//ui/ozone:ozone_base",
     "//ui/ozone/common",
-    "//ui/ozone/common/linux",
+    "//ui/ozone/common/linux:drm",
+    "//ui/ozone/common/linux:gbm",
     "//ui/ozone/public/interfaces",
     "//ui/platform_window",
   ]
@@ -191,7 +192,8 @@
     "//ui/gfx",
     "//ui/ozone:platform",
     "//ui/ozone/common",
-    "//ui/ozone/common/linux",
+    "//ui/ozone/common/linux:drm",
+    "//ui/ozone/common/linux:gbm",
   ]
 
   if (drm_commit_properties_on_page_flip) {
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index 4578b80..d3d30fc8 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -113,7 +113,7 @@
     "//ui/gfx/geometry",
     "//ui/ozone:ozone_base",
     "//ui/ozone/common",
-    "//ui/ozone/common/linux",
+    "//ui/ozone/common/linux:drm",
     "//ui/ozone/public/interfaces/wayland:wayland_interfaces",
     "//ui/platform_window",
     "//ui/platform_window/platform_window_handler",
@@ -136,9 +136,8 @@
 
     deps += [
       "//build/config/linux/libdrm",
-      "//third_party/minigbm",
       "//ui/gfx:memory_buffer",
-      "//ui/ozone/common/linux",
+      "//ui/ozone/common/linux:gbm",
     ]
   }
 
diff --git a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h
index f06f9b9a..7c3d072 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h
+++ b/ui/ozone/platform/wayland/gpu/wayland_connection_proxy.h
@@ -15,7 +15,7 @@
 #include "ui/ozone/public/interfaces/wayland/wayland_connection.mojom.h"
 
 #if defined(WAYLAND_GBM)
-#include "ui/ozone/common/linux/gbm_device.h"
+#include "ui/ozone/common/linux/gbm_device.h"  // nogncheck
 #endif
 
 struct wl_shm;
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 39675a2..a1868f5 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -59,6 +59,8 @@
     "../views_bridge_mac/bridged_native_widget_impl.h",
     "../views_bridge_mac/native_widget_mac_nswindow.h",
     "../views_bridge_mac/window_touch_bar_delegate.h",
+    "accessibility/ax_event_manager.h",
+    "accessibility/ax_event_observer.h",
     "accessibility/ax_virtual_view.h",
     "accessibility/view_accessibility.h",
     "accessibility/view_accessibility_utils.h",
@@ -266,6 +268,8 @@
     # TODO(ccameron): Move these sources to the views_bridge_mac component
     "../views_bridge_mac/bridged_native_widget_impl.mm",
     "../views_bridge_mac/native_widget_mac_nswindow.mm",
+    "accessibility/ax_event_manager.cc",
+    "accessibility/ax_event_observer.cc",
     "accessibility/ax_virtual_view.cc",
     "accessibility/view_accessibility.cc",
     "accessibility/view_accessibility_utils.cc",
diff --git a/ui/views/accessibility/ax_event_manager.cc b/ui/views/accessibility/ax_event_manager.cc
new file mode 100644
index 0000000..7e1fd0f
--- /dev/null
+++ b/ui/views/accessibility/ax_event_manager.cc
@@ -0,0 +1,36 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/accessibility/ax_event_manager.h"
+
+#include "base/no_destructor.h"
+#include "ui/views/accessibility/ax_event_observer.h"
+
+namespace views {
+
+AXEventManager::AXEventManager() = default;
+
+AXEventManager::~AXEventManager() = default;
+
+// static
+AXEventManager* AXEventManager::Get() {
+  static base::NoDestructor<AXEventManager> instance;
+  return instance.get();
+}
+
+void AXEventManager::AddObserver(AXEventObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void AXEventManager::RemoveObserver(AXEventObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void AXEventManager::NotifyViewEvent(views::View* view,
+                                     ax::mojom::Event event_type) {
+  for (AXEventObserver& observer : observers_)
+    observer.OnViewEvent(view, event_type);
+}
+
+}  // namespace views
diff --git a/ui/views/accessibility/ax_event_manager.h b/ui/views/accessibility/ax_event_manager.h
new file mode 100644
index 0000000..6eef3ef
--- /dev/null
+++ b/ui/views/accessibility/ax_event_manager.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
+#define UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/views/views_export.h"
+
+namespace views {
+
+class AXEventObserver;
+class View;
+
+// AXEventManager allows observation of accessibility events for all views.
+class VIEWS_EXPORT AXEventManager {
+ public:
+  AXEventManager();
+  ~AXEventManager();
+
+  // Returns the singleton instance.
+  static AXEventManager* Get();
+
+  void AddObserver(AXEventObserver* observer);
+  void RemoveObserver(AXEventObserver* observer);
+
+  // Notifies observers of an accessibility event. |view| must not be null.
+  void NotifyViewEvent(views::View* view, ax::mojom::Event event_type);
+
+ private:
+  base::ObserverList<AXEventObserver> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(AXEventManager);
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
diff --git a/ui/views/accessibility/ax_event_observer.cc b/ui/views/accessibility/ax_event_observer.cc
new file mode 100644
index 0000000..cc1db79
--- /dev/null
+++ b/ui/views/accessibility/ax_event_observer.cc
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/accessibility/ax_event_observer.h"
+
+namespace views {
+
+AXEventObserver::AXEventObserver() = default;
+
+AXEventObserver::~AXEventObserver() = default;
+
+}  // namespace views
diff --git a/ui/views/accessibility/ax_event_observer.h b/ui/views/accessibility/ax_event_observer.h
new file mode 100644
index 0000000..5fc3c812
--- /dev/null
+++ b/ui/views/accessibility/ax_event_observer.h
@@ -0,0 +1,28 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
+#define UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
+
+#include "base/observer_list_types.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/views/views_export.h"
+
+namespace views {
+
+class View;
+
+// AXEventObserver is notified for accessibility events on all views.
+class VIEWS_EXPORT AXEventObserver : public base::CheckedObserver {
+ public:
+  virtual void OnViewEvent(views::View* view, ax::mojom::Event event_type) = 0;
+
+ protected:
+  AXEventObserver();
+  ~AXEventObserver() override;
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
index 76471d1f..0f796ad1 100644
--- a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
+++ b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
@@ -13,6 +13,8 @@
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/accessibility/ax_aura_obj_cache.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
+#include "ui/views/accessibility/ax_event_manager.h"
+#include "ui/views/accessibility/ax_event_observer.h"
 #include "ui/views/accessibility/ax_widget_obj_wrapper.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
@@ -178,13 +180,16 @@
   void OnBlur() override { SetVisible(false); }
 };
 
-class AxTestViewsDelegate : public TestViewsDelegate {
+class TestAXEventObserver : public AXEventObserver {
  public:
-  AxTestViewsDelegate() = default;
-  ~AxTestViewsDelegate() override = default;
+  TestAXEventObserver() { AXEventManager::Get()->AddObserver(this); }
 
-  void NotifyAccessibilityEvent(View* view,
-                                ax::mojom::Event event_type) override {
+  ~TestAXEventObserver() override {
+    AXEventManager::Get()->RemoveObserver(this);
+  }
+
+  // AXEventObserver:
+  void OnViewEvent(View* view, ax::mojom::Event event_type) override {
     AXAuraObjCache* ax = AXAuraObjCache::GetInstance();
     std::vector<AXAuraObjWrapper*> out_children;
     AXAuraObjWrapper* ax_obj = ax->GetOrCreate(view->GetWidget());
@@ -192,24 +197,17 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(AxTestViewsDelegate);
+  DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
 };
 
-class ViewAccessibilityTest : public ViewsTestBase {
- public:
-  ViewAccessibilityTest() = default;
-  ~ViewAccessibilityTest() override = default;
-  void SetUp() override {
-    std::unique_ptr<TestViewsDelegate> views_delegate(
-        new AxTestViewsDelegate());
-    set_views_delegate(std::move(views_delegate));
-    ViewsTestBase::SetUp();
-  }
-};
+using ViewAccessibilityTest = ViewsTestBase;
 
 // Check if the destruction of the widget ends successfully if |view|'s
 // visibility changed during destruction.
 TEST_F(ViewAccessibilityTest, LayoutCalledInvalidateRootView) {
+  // TODO: Construct a real AutomationManagerAura rather than using this
+  // observer to simulate it.
+  TestAXEventObserver observer;
   std::unique_ptr<Widget> widget(new Widget);
   Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
   params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
diff --git a/ui/views/controls/slider_unittest.cc b/ui/views/controls/slider_unittest.cc
index 08f4dda4..96900eb 100644
--- a/ui/views/controls/slider_unittest.cc
+++ b/ui/views/controls/slider_unittest.cc
@@ -18,8 +18,9 @@
 #include "ui/events/gesture_event_details.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/events/test/event_generator.h"
+#include "ui/views/accessibility/ax_event_manager.h"
+#include "ui/views/accessibility/ax_event_observer.h"
 #include "ui/views/test/slider_test_api.h"
-#include "ui/views/test/test_views_delegate.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
@@ -118,6 +119,28 @@
   last_drag_ended_epoch_ = ++last_event_epoch_;
 }
 
+class TestAXEventObserver : public views::AXEventObserver {
+ public:
+  TestAXEventObserver() { views::AXEventManager::Get()->AddObserver(this); }
+
+  ~TestAXEventObserver() override {
+    views::AXEventManager::Get()->RemoveObserver(this);
+  }
+
+  bool value_changed() const { return value_changed_; }
+
+  // views::AXEventObserver:
+  void OnViewEvent(views::View* view, ax::mojom::Event event_type) override {
+    if (event_type == ax::mojom::Event::kValueChanged)
+      value_changed_ = true;
+  }
+
+ private:
+  bool value_changed_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
+};
+
 }  // namespace
 
 namespace views {
@@ -125,22 +148,8 @@
 // Base test fixture for Slider tests.
 class SliderTest : public views::ViewsTestBase {
  public:
-  class SliderTestViewsDelegate : public views::TestViewsDelegate {
-   public:
-    bool has_value_changed() { return has_value_changed_; }
-
-   private:
-    void NotifyAccessibilityEvent(View* view,
-                                  ax::mojom::Event event_type) override {
-      if (event_type == ax::mojom::Event::kValueChanged)
-        has_value_changed_ = true;
-    }
-
-    bool has_value_changed_ = false;
-  };
-
-  SliderTest();
-  ~SliderTest() override;
+  SliderTest() = default;
+  ~SliderTest() override = default;
 
  protected:
   Slider* slider() {
@@ -169,43 +178,26 @@
     return event_generator_.get();
   }
 
-  SliderTestViewsDelegate* delegate() { return delegate_; }
-
  private:
   // The Slider to be tested.
-  Slider* slider_;
+  Slider* slider_ = nullptr;
   // A simple SliderListener test double.
   TestSliderListener slider_listener_;
   // Stores the default locale at test setup so it can be restored
   // during test teardown.
   std::string default_locale_;
   // The maximum x value within the bounds of the slider.
-  int max_x_;
+  int max_x_ = 0;
   // The maximum y value within the bounds of the slider.
-  int max_y_;
+  int max_y_ = 0;
   // The widget container for the slider being tested.
-  views::Widget* widget_;
+  views::Widget* widget_ = nullptr;
   // An event generator.
   std::unique_ptr<ui::test::EventGenerator> event_generator_;
-  // A TestViewsDelegate that intercepts accessibility notifications. Weak.
-  SliderTestViewsDelegate* delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(SliderTest);
 };
 
-SliderTest::SliderTest()
-    : slider_(NULL),
-      default_locale_(),
-      max_x_(0),
-      max_y_(0),
-      delegate_(new SliderTestViewsDelegate()) {
-  std::unique_ptr<views::TestViewsDelegate> delegate(delegate_);
-  set_views_delegate(std::move(delegate));
-}
-
-SliderTest::~SliderTest() {
-}
-
 void SliderTest::SetUp() {
   views::ViewsTestBase::SetUp();
 
@@ -401,7 +393,8 @@
 // Verifies the correct SliderListener events are raised for an accessible
 // slider.
 TEST_F(SliderTest, SliderRaisesA11yEvents) {
-  EXPECT_FALSE(delegate()->has_value_changed());
+  TestAXEventObserver observer;
+  EXPECT_FALSE(observer.value_changed());
 
   // First, detach/reattach the slider without setting value.
   // Temporarily detach the slider.
@@ -410,18 +403,18 @@
 
   // Re-attachment should cause nothing to get fired.
   root_view->AddChildView(slider());
-  EXPECT_FALSE(delegate()->has_value_changed());
+  EXPECT_FALSE(observer.value_changed());
 
   // Now, set value before reattaching.
   root_view->RemoveChildView(slider());
 
   // Value changes won't trigger accessibility events before re-attachment.
   slider()->SetValue(22);
-  EXPECT_FALSE(delegate()->has_value_changed());
+  EXPECT_FALSE(observer.value_changed());
 
   // Re-attachment should trigger the value change.
   root_view->AddChildView(slider());
-  EXPECT_TRUE(delegate()->has_value_changed());
+  EXPECT_TRUE(observer.value_changed());
 }
 
 #endif  // !defined(OS_MACOSX) || defined(USE_AURA)
diff --git a/ui/views/mus/ax_remote_host.cc b/ui/views/mus/ax_remote_host.cc
index 89ea463..527cfd8fe 100644
--- a/ui/views/mus/ax_remote_host.cc
+++ b/ui/views/mus/ax_remote_host.cc
@@ -18,6 +18,7 @@
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
+#include "ui/views/accessibility/ax_event_manager.h"
 #include "ui/views/mus/ax_tree_source_mus.h"
 #include "ui/views/mus/mus_client.h"
 #include "ui/views/view.h"
@@ -30,6 +31,7 @@
 namespace views {
 
 AXRemoteHost::AXRemoteHost() {
+  AXEventManager::Get()->AddObserver(this);
   AXAuraObjCache::GetInstance()->SetDelegate(this);
 }
 
@@ -37,6 +39,7 @@
   if (widget_)
     StopMonitoringWidget();
   AXAuraObjCache::GetInstance()->SetDelegate(nullptr);
+  AXEventManager::Get()->RemoveObserver(this);
 }
 
 void AXRemoteHost::Init(service_manager::Connector* connector) {
@@ -98,19 +101,6 @@
   tree_source_.reset();
 }
 
-void AXRemoteHost::HandleEvent(View* view, ax::mojom::Event event_type) {
-  CHECK(view);
-
-  if (!enabled_)
-    return;
-
-  // Can return null for views without a widget.
-  AXAuraObjWrapper* aura_obj = AXAuraObjCache::GetInstance()->GetOrCreate(view);
-  if (!aura_obj)
-    return;
-  SendEvent(aura_obj, event_type);
-}
-
 void AXRemoteHost::OnAutomationEnabled(bool enabled) {
   if (enabled)
     Enable();
@@ -170,6 +160,19 @@
   SendEvent(aura_obj, event_type);
 }
 
+void AXRemoteHost::OnViewEvent(View* view, ax::mojom::Event event_type) {
+  CHECK(view);
+
+  if (!enabled_)
+    return;
+
+  // Can return null for views without a widget.
+  AXAuraObjWrapper* aura_obj = AXAuraObjCache::GetInstance()->GetOrCreate(view);
+  if (!aura_obj)
+    return;
+  SendEvent(aura_obj, event_type);
+}
+
 void AXRemoteHost::FlushForTesting() {
   ax_host_ptr_.FlushForTesting();
 }
diff --git a/ui/views/mus/ax_remote_host.h b/ui/views/mus/ax_remote_host.h
index bb432ba..f9db944 100644
--- a/ui/views/mus/ax_remote_host.h
+++ b/ui/views/mus/ax_remote_host.h
@@ -15,6 +15,7 @@
 #include "ui/accessibility/mojom/ax_host.mojom.h"
 #include "ui/display/display_observer.h"
 #include "ui/views/accessibility/ax_aura_obj_cache.h"
+#include "ui/views/accessibility/ax_event_observer.h"
 #include "ui/views/mus/mus_export.h"
 #include "ui/views/widget/widget_observer.h"
 
@@ -40,7 +41,8 @@
 class VIEWS_MUS_EXPORT AXRemoteHost : public ax::mojom::AXRemoteHost,
                                       public WidgetObserver,
                                       public display::DisplayObserver,
-                                      public AXAuraObjCache::Delegate {
+                                      public AXAuraObjCache::Delegate,
+                                      public AXEventObserver {
  public:
   AXRemoteHost();
   ~AXRemoteHost() override;
@@ -56,9 +58,6 @@
   void StartMonitoringWidget(Widget* widget);
   void StopMonitoringWidget();
 
-  // Handles an event fired upon a |view|.
-  void HandleEvent(View* view, ax::mojom::Event event_type);
-
   // ax::mojom::AXRemoteHost:
   void OnAutomationEnabled(bool enabled) override;
   void PerformAction(const ui::AXActionData& action) override;
@@ -76,6 +75,9 @@
   void OnEvent(AXAuraObjWrapper* aura_obj,
                ax::mojom::Event event_type) override;
 
+  // AXEventObserver:
+  void OnViewEvent(View* view, ax::mojom::Event event_type) override;
+
   void FlushForTesting();
   Widget* widget_for_testing() { return widget_; }
 
diff --git a/ui/views/mus/ax_remote_host_unittest.cc b/ui/views/mus/ax_remote_host_unittest.cc
index 1d099ef1..934dcfe3 100644
--- a/ui/views/mus/ax_remote_host_unittest.cc
+++ b/ui/views/mus/ax_remote_host_unittest.cc
@@ -117,8 +117,9 @@
   remote->InitForTesting(service->CreateInterfacePtr());
   remote->FlushForTesting();
   // Install the AXRemoteHost on MusClient so it monitors Widget creation.
+  AXRemoteHost* remote_raw = remote.get();
   MusClientTestApi::SetAXRemoteHost(std::move(remote));
-  return MusClient::Get()->ax_remote_host();
+  return remote_raw;
 }
 
 std::unique_ptr<Widget> CreateTestWidget() {
@@ -193,7 +194,7 @@
 
   // Create a view that is not yet associated with the widget.
   views::View view;
-  remote->HandleEvent(&view, ax::mojom::Event::kLocationChanged);
+  remote->OnViewEvent(&view, ax::mojom::Event::kLocationChanged);
   // No crash.
 }
 
diff --git a/ui/views/mus/mus_client.h b/ui/views/mus/mus_client.h
index 71b18f7c..143637135 100644
--- a/ui/views/mus/mus_client.h
+++ b/ui/views/mus/mus_client.h
@@ -115,8 +115,6 @@
 
   aura::WindowTreeClient* window_tree_client() { return window_tree_client_; }
 
-  AXRemoteHost* ax_remote_host() { return ax_remote_host_.get(); }
-
   // Creates DesktopNativeWidgetAura with DesktopWindowTreeHostMus. This is
   // set as the factory function used for creating NativeWidgets when a
   //  NativeWidget has not been explicitly set.
diff --git a/ui/views/mus/mus_views_delegate.cc b/ui/views/mus/mus_views_delegate.cc
index e383ac00..55e5a77 100644
--- a/ui/views/mus/mus_views_delegate.cc
+++ b/ui/views/mus/mus_views_delegate.cc
@@ -4,7 +4,6 @@
 
 #include "ui/views/mus/mus_views_delegate.h"
 
-#include "ui/views/mus/ax_remote_host.h"
 #include "ui/views/mus/mus_client.h"
 
 namespace views {
@@ -13,10 +12,4 @@
 
 MusViewsDelegate::~MusViewsDelegate() = default;
 
-void MusViewsDelegate::NotifyAccessibilityEvent(View* view,
-                                                ax::mojom::Event event_type) {
-  if (MusClient::Get()->ax_remote_host())
-    MusClient::Get()->ax_remote_host()->HandleEvent(view, event_type);
-}
-
 }  // namespace views
diff --git a/ui/views/mus/mus_views_delegate.h b/ui/views/mus/mus_views_delegate.h
index b7d55503..d74ac42 100644
--- a/ui/views/mus/mus_views_delegate.h
+++ b/ui/views/mus/mus_views_delegate.h
@@ -12,15 +12,12 @@
 
 namespace views {
 
+// TODO(jamescook): Move the LayoutProvider and delete this class.
 class VIEWS_MUS_EXPORT MusViewsDelegate : public ViewsDelegate {
  public:
   MusViewsDelegate();
   ~MusViewsDelegate() override;
 
-  // ViewsDelegate:
-  void NotifyAccessibilityEvent(View* view,
-                                ax::mojom::Event event_type) override;
-
  private:
   LayoutProvider layout_provider_;
 
diff --git a/ui/views/view.cc b/ui/views/view.cc
index da506368..b2429b98 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -44,6 +44,7 @@
 #include "ui/gfx/skia_util.h"
 #include "ui/gfx/transform.h"
 #include "ui/native_theme/native_theme.h"
+#include "ui/views/accessibility/ax_event_manager.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/background.h"
 #include "ui/views/border.h"
@@ -52,7 +53,6 @@
 #include "ui/views/layout/layout_manager.h"
 #include "ui/views/view_observer.h"
 #include "ui/views/view_tracker.h"
-#include "ui/views/views_delegate.h"
 #include "ui/views/views_switches.h"
 #include "ui/views/widget/native_widget_private.h"
 #include "ui/views/widget/root_view.h"
@@ -1451,8 +1451,7 @@
 
 void View::NotifyAccessibilityEvent(ax::mojom::Event event_type,
                                     bool send_native_event) {
-  if (ViewsDelegate::GetInstance())
-    ViewsDelegate::GetInstance()->NotifyAccessibilityEvent(this, event_type);
+  AXEventManager::Get()->NotifyViewEvent(this, event_type);
 
   if (send_native_event && GetWidget())
     GetViewAccessibility().NotifyAccessibilityEvent(event_type);
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc
index 68ac0732..7252607 100644
--- a/ui/views/views_delegate.cc
+++ b/ui/views/views_delegate.cc
@@ -61,9 +61,6 @@
   return false;
 }
 
-void ViewsDelegate::NotifyAccessibilityEvent(View* view,
-                                             ax::mojom::Event event_type) {}
-
 void ViewsDelegate::NotifyMenuItemFocused(const base::string16& menu_name,
                                           const base::string16& menu_item_name,
                                           int item_index,
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h
index ab1ccc50..1a66e7d 100644
--- a/ui/views/views_delegate.h
+++ b/ui/views/views_delegate.h
@@ -17,7 +17,6 @@
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
-#include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/views/views_export.h"
@@ -37,7 +36,6 @@
 
 class NativeWidget;
 class NonClientFrameView;
-class View;
 class Widget;
 
 #if defined(USE_AURA)
@@ -125,10 +123,6 @@
                                        gfx::Rect* bounds,
                                        ui::WindowShowState* show_state) const;
 
-  // Handles an event on a |view|. The |view| must not be null.
-  virtual void NotifyAccessibilityEvent(View* view,
-                                        ax::mojom::Event event_type);
-
   // For accessibility, notify the delegate that a menu item was focused
   // so that alternate feedback (speech / magnified text) can be provided.
   virtual void NotifyMenuItemFocused(const base::string16& menu_name,