diff --git a/DEPS b/DEPS
index 085a136..f23a29d 100644
--- a/DEPS
+++ b/DEPS
@@ -105,11 +105,11 @@
   # 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': 'a391c72a20574053a00e05848aa7460d30d7b649',
+  'skia_revision': '1354048c8fa885b83e414532c011d710590d6b46',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'f474ca1de96cc8d320e15f0e79fa7630673a3946',
+  'v8_revision': 'a7788c48cc8143a4cfe35f8f993c6cbde5f7adbe',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -117,7 +117,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': '7e585118fe827063e715c3741c3f43c4dd677ec2',
+  'angle_revision': '8fbd9d96e68b5a74a49737c8a8549cbe9d556fc9',
   # 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.
@@ -125,7 +125,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '551478a9b8be146edaf4bcc7639ed77752d1650f',
+  'swiftshader_revision': '6a990f8b1a930336eee5b2af2319fae11b967d4e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -165,7 +165,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '9eaedb7fa00f7b1c3bba87eeb82f75e7a147f8d2',
+  'catapult_revision': '27380b171e3fd0073d475e0fb628fe8850571d06',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -913,7 +913,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '9bda2ab7df0acdbc528dc8cba46bc5e6c3f9e276',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '68eaa07bdfa03c38a6ec74091382829097d3f68e',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1035,7 +1035,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a5c263cc63ffc2cc189b5214074c8792067c1853',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'd497e6bd6b6520d08ff5e2df3a50a46d8c9f9b6e',
+    Var('webrtc_git') + '/src.git' + '@' + '1208cbb3ec07c6740fd2f651169fafff94e1e041',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 4db81ae..881ccbd 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -837,6 +837,8 @@
     "task/sequence_manager/thread_controller.h",
     "task/sequence_manager/thread_controller_impl.cc",
     "task/sequence_manager/thread_controller_impl.h",
+    "task/sequence_manager/thread_controller_with_message_pump_impl.cc",
+    "task/sequence_manager/thread_controller_with_message_pump_impl.h",
     "task/sequence_manager/time_domain.cc",
     "task/sequence_manager/time_domain.h",
     "task/sequence_manager/work_queue.cc",
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc
index 856370a5..05a3896 100644
--- a/base/files/file_util_unittest.cc
+++ b/base/files/file_util_unittest.cc
@@ -3189,19 +3189,11 @@
 
   data = "temp";
   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 2));
-#if defined(OS_ANDROID)
-  EXPECT_EQ("Pr", data);
-#else
-  EXPECT_EQ("pr", data);
-#endif
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("pr", data));
 
   data = "temp";
   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, &data, 4));
-#if defined(OS_ANDROID)
-  EXPECT_EQ("Proc", data);
-#else
-  EXPECT_EQ("proc", data);
-#endif
+  EXPECT_TRUE(EqualsCaseInsensitiveASCII("proc", data));
 
   EXPECT_FALSE(ReadFileToStringWithMaxSize(file_path, nullptr, 4));
 }
diff --git a/base/fuchsia/default_job.cc b/base/fuchsia/default_job.cc
index 366b14f6..c26aeb34 100644
--- a/base/fuchsia/default_job.cc
+++ b/base/fuchsia/default_job.cc
@@ -4,7 +4,7 @@
 
 #include "base/fuchsia/default_job.h"
 
-#include <zircon/process.h>
+#include <zircon/types.h>
 
 #include "base/logging.h"
 
@@ -12,16 +12,16 @@
 
 namespace {
 zx_handle_t g_job = ZX_HANDLE_INVALID;
-}  // namespace
-
-zx_handle_t GetDefaultJob() {
-  if (g_job == ZX_HANDLE_INVALID)
-    return zx_job_default();
-  return g_job;
 }
 
-void SetDefaultJob(ScopedZxHandle job) {
-  DCHECK_EQ(ZX_HANDLE_INVALID, g_job);
+zx::unowned_job GetDefaultJob() {
+  if (g_job == ZX_HANDLE_INVALID)
+    return zx::job::default_job();
+  return zx::unowned_job(g_job);
+}
+
+void SetDefaultJob(zx::job job) {
+  DCHECK_EQ(g_job, ZX_HANDLE_INVALID);
   g_job = job.release();
 }
 
diff --git a/base/fuchsia/default_job.h b/base/fuchsia/default_job.h
index f5f5c3a..9417f1c3 100644
--- a/base/fuchsia/default_job.h
+++ b/base/fuchsia/default_job.h
@@ -5,17 +5,18 @@
 #ifndef BASE_FUCHSIA_DEFAULT_JOB_H_
 #define BASE_FUCHSIA_DEFAULT_JOB_H_
 
+#include <lib/zx/job.h>
+
 #include "base/base_export.h"
-#include "base/fuchsia/scoped_zx_handle.h"
 
 namespace base {
 
 // Gets and sets the job object used for creating new child processes,
 // and looking them up by their process IDs.
-// zx_job_default() will be returned if no job is explicitly set here.
+// zx::job::default_job() will be returned if no job is explicitly set here.
 // Only valid handles may be passed to SetDefaultJob().
-BASE_EXPORT zx_handle_t GetDefaultJob();
-BASE_EXPORT void SetDefaultJob(ScopedZxHandle job);
+BASE_EXPORT zx::unowned_job GetDefaultJob();
+BASE_EXPORT void SetDefaultJob(zx::job job);
 
 }  // namespace base
 
diff --git a/base/json/json_reader_fuzzer.cc b/base/json/json_reader_fuzzer.cc
index a8490da..5e69940 100644
--- a/base/json/json_reader_fuzzer.cc
+++ b/base/json/json_reader_fuzzer.cc
@@ -5,9 +5,6 @@
 #include "base/json/json_reader.h"
 #include "base/values.h"
 
-int error_code, error_line, error_column;
-std::string error_message;
-
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size < 2)
@@ -21,6 +18,9 @@
   base::StringPiece input_string(input.get(), size - 1);
 
   const int options = data[size - 1];
+
+  int error_code, error_line, error_column;
+  std::string error_message;
   base::JSONReader::ReadAndReturnError(input_string, options, &error_code,
                                        &error_message, &error_line,
                                        &error_column);
diff --git a/base/json/string_escape_fuzzer.cc b/base/json/string_escape_fuzzer.cc
index e44bd4fe..f430411 100644
--- a/base/json/string_escape_fuzzer.cc
+++ b/base/json/string_escape_fuzzer.cc
@@ -6,8 +6,6 @@
 
 #include <memory>
 
-std::string escaped_string;
-
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size < 2)
@@ -22,6 +20,7 @@
   memcpy(input.get(), data, actual_size_char8);
 
   base::StringPiece input_string(input.get(), actual_size_char8);
+  std::string escaped_string;
   base::EscapeJSONString(input_string, put_in_quotes, &escaped_string);
 
   // Test for wide-strings if available size is even.
@@ -31,6 +30,7 @@
   size_t actual_size_char16 = actual_size_char8 / 2;
   base::StringPiece16 input_string16(
       reinterpret_cast<base::char16*>(input.get()), actual_size_char16);
+  escaped_string.clear();
   base::EscapeJSONString(input_string16, put_in_quotes, &escaped_string);
 
   return 0;
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc
index ef582e62..7f7a00d 100644
--- a/base/process/launch_fuchsia.cc
+++ b/base/process/launch_fuchsia.cc
@@ -8,9 +8,9 @@
 #include <lib/fdio/namespace.h>
 #include <lib/fdio/spawn.h>
 #include <lib/fdio/util.h>
+#include <lib/zx/job.h>
 #include <stdint.h>
 #include <unistd.h>
-#include <zircon/process.h>
 #include <zircon/processargs.h>
 
 #include "base/command_line.h"
@@ -120,9 +120,10 @@
   }
 
   // Determine the job under which to launch the new process.
-  zx_handle_t job = options.job_handle != ZX_HANDLE_INVALID ? options.job_handle
-                                                            : GetDefaultJob();
-  DCHECK_NE(ZX_HANDLE_INVALID, job);
+  zx::unowned_job job = options.job_handle != ZX_HANDLE_INVALID
+                            ? zx::unowned_job(options.job_handle)
+                            : GetDefaultJob();
+  DCHECK(job->is_valid());
 
   // Construct an |argv| array of C-strings from the supplied std::strings.
   std::vector<const char*> argv_cstr;
@@ -203,9 +204,9 @@
   // case of failure, so we avoid unnecessarily initializing it here.
   char error_message[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
   zx_status_t status = fdio_spawn_etc(
-      job, spawn_flags, argv_cstr[0], argv_cstr.data(), new_environ.get(),
-      spawn_actions.size(), spawn_actions.data(), process_handle.receive(),
-      error_message);
+      job->get(), spawn_flags, argv_cstr[0], argv_cstr.data(),
+      new_environ.get(), spawn_actions.size(), spawn_actions.data(),
+      process_handle.receive(), error_message);
 
   // fdio_spawn_etc() will close all handles specified in add-handle actions,
   // regardless of whether it succeeds or fails, so release our copies.
diff --git a/base/process/process_fuchsia.cc b/base/process/process_fuchsia.cc
index 709e654..89fb40d 100644
--- a/base/process/process_fuchsia.cc
+++ b/base/process/process_fuchsia.cc
@@ -4,6 +4,7 @@
 
 #include "base/process/process.h"
 
+#include <lib/zx/process.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
 
@@ -49,15 +50,15 @@
     return Current();
 
   // While a process with object id |pid| might exist, the job returned by
-  // zx_job_default() might not contain it, so this call can fail.
-  ScopedZxHandle handle;
-  zx_status_t status = zx_object_get_child(
-      GetDefaultJob(), pid, ZX_RIGHT_SAME_RIGHTS, handle.receive());
+  // zx::job::default_job() might not contain it, so this call can fail.
+  zx::process process;
+  zx_status_t status =
+      GetDefaultJob()->get_child(pid, ZX_RIGHT_SAME_RIGHTS, &process);
   if (status != ZX_OK) {
     ZX_DLOG(ERROR, status) << "zx_object_get_child";
     return Process();
   }
-  return Process(handle.release());
+  return Process(process.release());
 }
 
 // static
diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h
index 0ef40140..53953060 100644
--- a/base/task/sequence_manager/thread_controller.h
+++ b/base/task/sequence_manager/thread_controller.h
@@ -53,6 +53,7 @@
   // scheduled delayed work. Can only be called from the main sequence.
   // NOTE: DelayTillNextTask might return a different value as it also takes
   // immediate work into account.
+  // TODO(kraynov): Remove |lazy_now| parameter.
   virtual void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) = 0;
 
   // Sets the sequenced task source from which to take tasks after
diff --git a/base/task/sequence_manager/thread_controller_impl.h b/base/task/sequence_manager/thread_controller_impl.h
index 1c1dc11c..794feefb 100644
--- a/base/task/sequence_manager/thread_controller_impl.h
+++ b/base/task/sequence_manager/thread_controller_impl.h
@@ -23,6 +23,7 @@
 namespace sequence_manager {
 namespace internal {
 
+// TODO(kraynov): Rename to ThreadControllerWithMessageLoopImpl.
 class BASE_EXPORT ThreadControllerImpl : public ThreadController,
                                          public RunLoop::NestingObserver {
  public:
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
new file mode 100644
index 0000000..fbed88b
--- /dev/null
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -0,0 +1,205 @@
+// 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 "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
+
+#include "base/auto_reset.h"
+#include "base/message_loop/message_pump_default.h"
+#include "base/time/tick_clock.h"
+#include "base/trace_event/trace_event.h"
+
+namespace base {
+namespace sequence_manager {
+namespace internal {
+
+ThreadControllerWithMessagePumpImpl::ThreadControllerWithMessagePumpImpl(
+    TickClock* time_source)
+    : main_thread_id_(PlatformThread::CurrentId()),
+      pump_(new MessagePumpDefault()),
+      time_source_(time_source) {
+  RunLoop::RegisterDelegateForCurrentThread(this);
+}
+
+ThreadControllerWithMessagePumpImpl::~ThreadControllerWithMessagePumpImpl() {
+  // Destructors of RunLoop::Delegate and ThreadTaskRunnerHandle
+  // will do all the clean-up.
+}
+
+ThreadControllerWithMessagePumpImpl::MainThreadOnly::MainThreadOnly() = default;
+
+ThreadControllerWithMessagePumpImpl::MainThreadOnly::~MainThreadOnly() =
+    default;
+
+void ThreadControllerWithMessagePumpImpl::SetSequencedTaskSource(
+    SequencedTaskSource* task_source) {
+  DCHECK(task_source);
+  DCHECK(!main_thread_only().task_source);
+  main_thread_only().task_source = task_source;
+}
+
+void ThreadControllerWithMessagePumpImpl::SetWorkBatchSize(
+    int work_batch_size) {
+  DCHECK_GE(work_batch_size, 1);
+  main_thread_only().batch_size = work_batch_size;
+}
+
+void ThreadControllerWithMessagePumpImpl::WillQueueTask(
+    PendingTask* pending_task) {
+  task_annotator_.WillQueueTask("ThreadController::Task", pending_task);
+}
+
+void ThreadControllerWithMessagePumpImpl::ScheduleWork() {
+  // Continuation will be posted if necessary.
+  if (RunsTasksInCurrentSequence() && is_doing_work())
+    return;
+
+  pump_->ScheduleWork();
+}
+
+void ThreadControllerWithMessagePumpImpl::SetNextDelayedDoWork(
+    LazyNow* lazy_now,
+    TimeTicks run_time) {
+  if (main_thread_only().next_delayed_work == run_time)
+    return;
+  main_thread_only().next_delayed_work = run_time;
+
+  if (run_time == TimeTicks::Max())
+    return;
+
+  // Continuation will be posted if necessary.
+  if (is_doing_work())
+    return;
+
+  // |lazy_now| will be removed in this method soon.
+  DCHECK_LT(time_source_->NowTicks(), run_time);
+  pump_->ScheduleDelayedWork(run_time);
+}
+
+const TickClock* ThreadControllerWithMessagePumpImpl::GetClock() {
+  return time_source_;
+}
+
+bool ThreadControllerWithMessagePumpImpl::RunsTasksInCurrentSequence() {
+  return main_thread_id_ == PlatformThread::CurrentId();
+}
+
+void ThreadControllerWithMessagePumpImpl::SetDefaultTaskRunner(
+    scoped_refptr<SingleThreadTaskRunner> task_runner) {
+  main_thread_only().thread_task_runner_handle =
+      std::make_unique<ThreadTaskRunnerHandle>(task_runner);
+}
+
+void ThreadControllerWithMessagePumpImpl::RestoreDefaultTaskRunner() {
+  // There's no default task runner unlike with the MessageLoop.
+  main_thread_only().thread_task_runner_handle.reset();
+}
+
+void ThreadControllerWithMessagePumpImpl::AddNestingObserver(
+    RunLoop::NestingObserver* observer) {
+  DCHECK_LE(main_thread_only().run_depth, 1);
+  DCHECK(!main_thread_only().nesting_observer);
+  DCHECK(observer);
+  main_thread_only().nesting_observer = observer;
+}
+
+void ThreadControllerWithMessagePumpImpl::RemoveNestingObserver(
+    RunLoop::NestingObserver* observer) {
+  DCHECK_EQ(main_thread_only().nesting_observer, observer);
+  main_thread_only().nesting_observer = nullptr;
+}
+
+bool ThreadControllerWithMessagePumpImpl::DoWork() {
+  DCHECK(main_thread_only().task_source);
+  bool task_ran = false;
+
+  {
+    AutoReset<int> do_work_scope(&main_thread_only().do_work_depth,
+                                 main_thread_only().do_work_depth + 1);
+
+    for (int i = 0; i < main_thread_only().batch_size; i++) {
+      Optional<PendingTask> task = main_thread_only().task_source->TakeTask();
+      if (!task)
+        break;
+
+      TRACE_TASK_EXECUTION("ThreadController::Task", *task);
+      task_annotator_.RunTask("ThreadController::Task", &*task);
+      task_ran = true;
+
+      main_thread_only().task_source->DidRunTask();
+
+      if (main_thread_only().quit_do_work) {
+        // When Quit() is called we must stop running the batch because
+        // caller expects per-task granularity.
+        main_thread_only().quit_do_work = false;
+        return true;
+      }
+    }
+  }  // DoWorkScope.
+
+  LazyNow lazy_now(time_source_);
+  TimeDelta do_work_delay =
+      main_thread_only().task_source->DelayTillNextTask(&lazy_now);
+  DCHECK_GE(do_work_delay, TimeDelta());
+  // Schedule a continuation.
+  if (do_work_delay.is_zero()) {
+    // Need to run new work immediately.
+    pump_->ScheduleWork();
+  } else if (do_work_delay != TimeDelta::Max()) {
+    SetNextDelayedDoWork(&lazy_now, lazy_now.Now() + do_work_delay);
+  } else {
+    SetNextDelayedDoWork(&lazy_now, TimeTicks::Max());
+  }
+
+  return task_ran;
+}
+
+bool ThreadControllerWithMessagePumpImpl::DoDelayedWork(
+    TimeTicks* next_run_time) {
+  // Delayed work is getting processed in DoWork().
+  return false;
+}
+
+bool ThreadControllerWithMessagePumpImpl::DoIdleWork() {
+  // RunLoop::Delegate knows whether we called Run() or RunUntilIdle().
+  if (ShouldQuitWhenIdle())
+    Quit();
+  return false;
+}
+
+void ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed) {
+  // No system messages are being processed by this class.
+  DCHECK(application_tasks_allowed);
+
+  // We already have a MessagePump::Run() running, so we're in a nested RunLoop.
+  if (main_thread_only().run_depth > 0 && main_thread_only().nesting_observer)
+    main_thread_only().nesting_observer->OnBeginNestedRunLoop();
+
+  {
+    AutoReset<int> run_scope(&main_thread_only().run_depth,
+                             main_thread_only().run_depth + 1);
+    // MessagePump::Run() blocks until Quit() called, but previously started
+    // Run() calls continue to block.
+    pump_->Run(this);
+  }
+
+  // We'll soon continue to run an outer MessagePump::Run() loop.
+  if (main_thread_only().run_depth > 0 && main_thread_only().nesting_observer)
+    main_thread_only().nesting_observer->OnExitNestedRunLoop();
+}
+
+void ThreadControllerWithMessagePumpImpl::Quit() {
+  // Interrupt a batch of work.
+  if (is_doing_work())
+    main_thread_only().quit_do_work = true;
+  // If we're in a nested RunLoop, continuation will be posted if necessary.
+  pump_->Quit();
+}
+
+void ThreadControllerWithMessagePumpImpl::EnsureWorkScheduled() {
+  ScheduleWork();
+}
+
+}  // namespace internal
+}  // namespace sequence_manager
+}  // namespace base
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
new file mode 100644
index 0000000..c19a2e8
--- /dev/null
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
@@ -0,0 +1,109 @@
+// 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 BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_
+#define BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_
+
+#include "base/debug/task_annotator.h"
+#include "base/message_loop/message_pump.h"
+#include "base/task/sequence_manager/sequenced_task_source.h"
+#include "base/task/sequence_manager/thread_controller.h"
+#include "base/threading/platform_thread.h"
+#include "base/threading/thread_task_runner_handle.h"
+
+namespace base {
+namespace sequence_manager {
+namespace internal {
+
+// EXPERIMENTAL ThreadController implementation which doesn't use
+// MessageLoop or a task runner to schedule their DoWork calls.
+// See https://crbug.com/828835.
+class BASE_EXPORT ThreadControllerWithMessagePumpImpl
+    : public ThreadController,
+      public MessagePump::Delegate,
+      public RunLoop::Delegate {
+ public:
+  explicit ThreadControllerWithMessagePumpImpl(TickClock* time_source);
+  ~ThreadControllerWithMessagePumpImpl() override;
+
+  // ThreadController implementation:
+  void SetSequencedTaskSource(SequencedTaskSource* task_source) override;
+  void SetWorkBatchSize(int work_batch_size) override;
+  void WillQueueTask(PendingTask* pending_task) override;
+  void ScheduleWork() override;
+  void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) override;
+  const TickClock* GetClock() override;
+  bool RunsTasksInCurrentSequence() override;
+  void SetDefaultTaskRunner(
+      scoped_refptr<SingleThreadTaskRunner> task_runner) override;
+  void RestoreDefaultTaskRunner() override;
+  void AddNestingObserver(RunLoop::NestingObserver* observer) override;
+  void RemoveNestingObserver(RunLoop::NestingObserver* observer) override;
+
+ private:
+  friend class DoWorkScope;
+  friend class RunScope;
+
+  // MessagePump::Delegate implementation.
+  bool DoWork() override;
+  bool DoDelayedWork(TimeTicks* next_run_time) override;
+  bool DoIdleWork() override;
+
+  // RunLoop::Delegate implementation.
+  void Run(bool application_tasks_allowed) override;
+  void Quit() override;
+  void EnsureWorkScheduled() override;
+
+  struct MainThreadOnly {
+    MainThreadOnly();
+    ~MainThreadOnly();
+
+    SequencedTaskSource* task_source = nullptr;            // Not owned.
+    RunLoop::NestingObserver* nesting_observer = nullptr;  // Not owned.
+    std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle;
+
+    // Next delayed DoWork time for scheduling de-duplication purpose.
+    TimeTicks next_delayed_work;
+
+    // Indicates that we should yield DoWork ASAP.
+    bool quit_do_work = false;
+
+    // Number of tasks processed in a single DoWork invocation.
+    int batch_size = 1;
+
+    // Number of RunLoop layers currently running.
+    int run_depth = 0;
+
+    // Number of DoWork running, but only the inner-most one can take tasks.
+    // Must be equal to |run_depth| or |run_depth - 1|.
+    int do_work_depth = 0;
+  };
+
+  MainThreadOnly& main_thread_only() {
+    DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+    return main_thread_only_;
+  }
+
+  // Returns true if there's a DoWork running on the inner-most nesting layer.
+  bool is_doing_work() const {
+    DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+    return main_thread_only_.do_work_depth == main_thread_only_.run_depth &&
+           main_thread_only_.do_work_depth != 0;
+  }
+
+  MainThreadOnly main_thread_only_;
+  const PlatformThreadId main_thread_id_;
+  std::unique_ptr<MessagePump> pump_;
+  debug::TaskAnnotator task_annotator_;
+  TickClock* time_source_;  // Not owned.
+
+  THREAD_CHECKER(main_thread_checker_);
+  DISALLOW_COPY_AND_ASSIGN(ThreadControllerWithMessagePumpImpl);
+};
+
+}  // namespace internal
+}  // namespace sequence_manager
+}  // namespace base
+
+#endif  // BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc
index a686b21..ddd9a4dc 100644
--- a/base/test/launcher/test_launcher.cc
+++ b/base/test/launcher/test_launcher.cc
@@ -321,8 +321,7 @@
   DCHECK(!new_options.job_handle);
 
   zx::job job_handle;
-  zx_status_t result =
-      zx::job::create(*zx::unowned<zx::job>(GetDefaultJob()), 0, &job_handle);
+  zx_status_t result = zx::job::create(*GetDefaultJob(), 0, &job_handle);
   ZX_CHECK(ZX_OK == result, result) << "zx_job_create";
   new_options.job_handle = job_handle.get();
 #endif  // defined(OS_FUCHSIA)
@@ -401,7 +400,8 @@
     AutoLock lock(*GetLiveProcessesLock());
 
 #if defined(OS_FUCHSIA)
-    CHECK_EQ(job_handle.kill(), ZX_OK);
+    zx_status_t status = job_handle.kill();
+    ZX_CHECK(status == ZX_OK, status);
 #elif defined(OS_POSIX)
     if (exit_code != 0) {
       // On POSIX, in case the test does not exit cleanly, either due to a crash
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 99ad70f..ea32525 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -694,7 +694,6 @@
       "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockBrowserKeyboardInterface.java",
       "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrCoreVersionCheckerImpl.java",
       "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrDaydreamApi.java",
-      "javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java",
       "javatests/src/org/chromium/chrome/browser/vr_shell/nfc_apk/SimNfcActivity.java",
       "javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java",
       "javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java",
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index d40c3097..ab23dfc 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -449,18 +449,6 @@
                 {{ self.mhtml_view_intent_shared_filter_with_mime_body() }}
             </intent-filter>
         </activity-alias>
-        <activity android:name="org.chromium.chrome.browser.vr.CustomTabVrActivity"
-            android:theme="@style/VrSupportTheme"
-            android:screenOrientation="landscape"
-            android:enableVrMode="@string/gvr_vr_mode_component"
-            android:taskAffinity=""
-            android:persistableMode="persistNever"
-            android:autoRemoveFromRecents="false"
-            {{ self.chrome_activity_common() }}
-            {{ self.supports_video_persistence() }}
-        >
-            {{ self.supports_vr() }}
-        </activity>
         {% endif %}
 
         <!-- ChromeTabbedActivity related -->
diff --git a/chrome/android/java/res_vr/values-v17/vr_styles.xml b/chrome/android/java/res_vr/values-v17/vr_styles.xml
index 881d486..dacfdb1 100644
--- a/chrome/android/java/res_vr/values-v17/vr_styles.xml
+++ b/chrome/android/java/res_vr/values-v17/vr_styles.xml
@@ -4,17 +4,6 @@
      found in the LICENSE file. -->
 
 <resources xmlns:tools="http://schemas.android.com/tools">
-    <!-- The theme to use when starting Chrome in VR mode.-->
-    <style name="VrSupportTheme" parent="MainTheme">
-       <!-- Android shows a preview window to give the user immediate feedback that the
-            app launched. The default behavior with this preview window is to show system
-            UI (e.g. navigation bars), which looks jarring if the user already has their
-            headset on. We disable the preview window feature when starting Chrome in VR
-            mode.
-       -->
-      <item name="android:windowDisablePreview">true</item>
-      <item name="android:windowBackground">@android:color/black</item>
-    </style>
     <style name="VrSupportThemeLauncher" parent="@android:style/Theme.NoDisplay">
       <item name="android:windowDisablePreview">true</item>
       <item name="android:windowBackground">@android:color/black</item>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 94114c4..0052fc12 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1780,13 +1780,13 @@
             if (shouldCloseTab) {
                 recordBackPressedUma(
                         "Minimized and closed tab", BackPressedResult.MINIMIZED_TAB_CLOSED);
-                mActivityStopMetrics.setStopReason(ActivityStopMetrics.STOP_REASON_BACK_BUTTON);
+                mActivityStopMetrics.setStopReason(ActivityStopMetrics.StopReason.BACK_BUTTON);
                 sendToBackground(currentTab);
                 return true;
             } else {
                 recordBackPressedUma(
                         "Minimized, kept tab", BackPressedResult.MINIMIZED_NO_TAB_CLOSED);
-                mActivityStopMetrics.setStopReason(ActivityStopMetrics.STOP_REASON_BACK_BUTTON);
+                mActivityStopMetrics.setStopReason(ActivityStopMetrics.StopReason.BACK_BUTTON);
                 sendToBackground(null);
                 return true;
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
index ec9295b..906ac21 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -16,7 +16,6 @@
 import android.os.Bundle;
 import android.os.StrictMode;
 import android.support.annotation.IntDef;
-import android.support.annotation.Nullable;
 import android.support.customtabs.CustomTabsIntent;
 import android.support.customtabs.CustomTabsSessionToken;
 import android.support.customtabs.TrustedWebUtils;
@@ -43,7 +42,6 @@
 import org.chromium.chrome.browser.upgrade.UpgradeActivity;
 import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.util.IntentUtils;
-import org.chromium.chrome.browser.vr.CustomTabVrActivity;
 import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
 import org.chromium.chrome.browser.webapps.ActivityAssigner;
 import org.chromium.chrome.browser.webapps.WebappActivity;
@@ -149,22 +147,7 @@
         recordIntentMetrics();
 
         mIsVrIntent = VrIntentUtils.isVrIntent(mIntent);
-        boolean isCustomTabIntent = (!mIsVrIntent && isCustomTabIntent(mIntent))
-                || (mIsVrIntent && VrIntentUtils.isCustomTabVrIntent(mIntent));
-        mIsCustomTabIntent = isCustomTabIntent;
-    }
-
-    /**
-     * Returns the options that should be used to start an activity.
-     */
-    @Nullable
-    private Bundle getStartActivityIntentOptions() {
-        Bundle options = null;
-        if (mIsVrIntent) {
-            // These options hide the 2D screenshot while we prepare for VR rendering.
-            options = VrIntentUtils.getVrIntentOptions(mActivity);
-        }
-        return options;
+        mIsCustomTabIntent = isCustomTabIntent(mIntent);
     }
 
     /**
@@ -335,11 +318,7 @@
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                 // Force a new document L+ to ensure the proper task/stack creation.
                 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
-                if (VrIntentUtils.isCustomTabVrIntent(intent)) {
-                    newIntent.setClassName(context, CustomTabVrActivity.class.getName());
-                } else {
-                    newIntent.setClassName(context, SeparateTaskCustomTabActivity.class.getName());
-                }
+                newIntent.setClassName(context, SeparateTaskCustomTabActivity.class.getName());
             } else {
                 int activityIndex =
                         ActivityAssigner.instance(ActivityAssigner.SEPARATE_TASK_CCT_NAMESPACE)
@@ -376,7 +355,7 @@
         // Allow disk writes during startActivity() to avoid strict mode violations on some
         // Samsung devices, see https://crbug.com/796548.
         try (StrictModeContext smc = StrictModeContext.allowDiskWrites()) {
-            mActivity.startActivity(launchIntent, getStartActivityIntentOptions());
+            mActivity.startActivity(launchIntent, null);
         }
     }
 
@@ -396,7 +375,6 @@
         WebappActivity.addWebappInfo(info.id(), info);
         Intent launchIntent = WebappLauncherActivity.createWebappLaunchIntent(info, false);
         launchIntent.putExtras(mIntent.getExtras());
-        launchIntent.setFlags(launchIntent.getFlags() | mIntent.getFlags());
 
         mActivity.startActivity(launchIntent);
         return true;
@@ -436,7 +414,8 @@
         // This system call is often modified by OEMs and not actionable. http://crbug.com/619646.
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
         try {
-            mActivity.startActivity(newIntent, getStartActivityIntentOptions());
+            Bundle options = mIsVrIntent ? VrIntentUtils.getVrIntentOptions(mActivity) : null;
+            mActivity.startActivity(newIntent, options);
         } catch (SecurityException ex) {
             if (isContentScheme) {
                 Toast.makeText(mActivity,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java
index 66882fa..b6c1bdec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java
@@ -95,12 +95,13 @@
     }
 
     // Installation states.
+    @IntDef({InstallState.NOT_INSTALLED, InstallState.INSTALLING, InstallState.INSTALLED})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({INSTALL_STATE_NOT_INSTALLED, INSTALL_STATE_INSTALLING, INSTALL_STATE_INSTALLED})
-    public @interface InstallState {}
-    public static final int INSTALL_STATE_NOT_INSTALLED = 0;
-    public static final int INSTALL_STATE_INSTALLING = 1;
-    public static final int INSTALL_STATE_INSTALLED = 2;
+    public @interface InstallState {
+        int NOT_INSTALLED = 0;
+        int INSTALLING = 1;
+        int INSTALLED = 2;
+    }
 
     private static final String TAG = "cr_InstallerDelegate";
     private static final long DEFAULT_MS_BETWEEN_RUNS = TimeUnit.SECONDS.toMillis(1);
@@ -206,15 +207,8 @@
      * @param packageName Name of the package to check.
      */
     public @InstallState int determineInstallState(String packageName) {
-        if (mIsRunning) {
-            return INSTALL_STATE_INSTALLING;
-        }
-
-        if (isInstalled(packageName)) {
-            return INSTALL_STATE_INSTALLED;
-        }
-
-        return INSTALL_STATE_NOT_INSTALLED;
+        if (mIsRunning) return InstallState.INSTALLING;
+        return isInstalled(packageName) ? InstallState.INSTALLED : InstallState.NOT_INSTALLED;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
index 6f074cb..aadcbe6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
@@ -9,6 +9,7 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Region;
+import android.support.annotation.IntDef;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
@@ -22,6 +23,9 @@
 import org.chromium.content_public.browser.GestureStateListener;
 import org.chromium.content_public.browser.WebContents;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * View that slides up from the bottom of the page and slides away as the user scrolls the page.
  * Meant to be tacked onto the {@link org.chromium.content_public.browser.WebContents}'s view and
@@ -42,9 +46,13 @@
     private static final float VERTICAL_FLING_SHOW_THRESHOLD = 0.2f;
     private static final float VERTICAL_FLING_HIDE_THRESHOLD = 0.9f;
 
-    private static final int GESTURE_NONE = 0;
-    private static final int GESTURE_SCROLLING = 1;
-    private static final int GESTURE_FLINGING = 2;
+    @IntDef({Gesture.NONE, Gesture.SCROLLING, Gesture.FLINGING})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface Gesture {
+        int NONE = 0;
+        int SCROLLING = 1;
+        int FLINGING = 2;
+    }
 
     private static final long ANIMATION_DURATION_MS = 250;
 
@@ -58,7 +66,7 @@
     private final Interpolator mInterpolator;
 
     /** Tracks whether the user is scrolling or flinging. */
-    private int mGestureState;
+    private @Gesture int mGestureState;
 
     /** Animation currently being used to translate the View. */
     private Animator mCurrentAnimation;
@@ -86,7 +94,7 @@
     public SwipableOverlayView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mGestureStateListener = createGestureStateListener();
-        mGestureState = GESTURE_NONE;
+        mGestureState = Gesture.NONE;
         mLayoutChangeListener = createLayoutChangeListener();
         mInterpolator = new DecelerateInterpolator(1.0f);
 
@@ -162,7 +170,7 @@
         int currentParentHeight = getParent() == null ? 0 : ((View) getParent()).getHeight();
         if (mParentHeight != currentParentHeight) {
             mParentHeight = currentParentHeight;
-            mGestureState = GESTURE_NONE;
+            mGestureState = Gesture.NONE;
             if (mCurrentAnimation != null) mCurrentAnimation.end();
         }
 
@@ -193,13 +201,13 @@
             public void onFlingStartGesture(int scrollOffsetY, int scrollExtentY) {
                 if (!isAllowedToAutoHide() || !cancelCurrentAnimation()) return;
                 resetInternalScrollState(scrollOffsetY, scrollExtentY);
-                mGestureState = GESTURE_FLINGING;
+                mGestureState = Gesture.FLINGING;
             }
 
             @Override
             public void onFlingEndGesture(int scrollOffsetY, int scrollExtentY) {
-                if (mGestureState != GESTURE_FLINGING) return;
-                mGestureState = GESTURE_NONE;
+                if (mGestureState != Gesture.FLINGING) return;
+                mGestureState = Gesture.NONE;
 
                 updateTranslation(scrollOffsetY, scrollExtentY);
 
@@ -222,13 +230,13 @@
                 if (!isAllowedToAutoHide() || !cancelCurrentAnimation()) return;
                 resetInternalScrollState(scrollOffsetY, scrollExtentY);
                 mLastScrollOffsetY = scrollOffsetY;
-                mGestureState = GESTURE_SCROLLING;
+                mGestureState = Gesture.SCROLLING;
             }
 
             @Override
             public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
-                if (mGestureState != GESTURE_SCROLLING) return;
-                mGestureState = GESTURE_NONE;
+                if (mGestureState != Gesture.SCROLLING) return;
+                mGestureState = Gesture.NONE;
 
                 updateTranslation(scrollOffsetY, scrollExtentY);
 
@@ -245,7 +253,7 @@
                 }
 
                 // This function is called for both fling and scrolls.
-                if (mGestureState == GESTURE_NONE || !cancelCurrentAnimation()
+                if (mGestureState == Gesture.NONE || !cancelCurrentAnimation()
                         || isIndependentlyAnimating()) {
                     return;
                 }
@@ -351,7 +359,7 @@
         mCurrentAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mGestureState = GESTURE_NONE;
+                mGestureState = Gesture.NONE;
                 mCurrentAnimation = null;
                 mIsBeingDisplayedForFirstTime = false;
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index 4a3e89a0d..7302df7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -381,7 +381,7 @@
 
             if (!(caller instanceof Activity)) freIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             if (isVrIntent) {
-                freIntent = VrIntentUtils.setupVrFreIntent(caller, intent, freIntent);
+                freIntent = VrIntentUtils.setupVrFreIntent(caller, freIntent);
             }
             IntentUtils.safeStartActivity(caller, freIntent);
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java
index d83a8a1..4702261 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java
@@ -45,7 +45,7 @@
         mAppTitle = appTitle;
         mAppData = data;
         mAppUrl = null;
-        mInstallState = InstallerDelegate.INSTALL_STATE_NOT_INSTALLED;
+        mInstallState = InstallerDelegate.InstallState.NOT_INSTALLED;
     }
 
     // Banner for web apps.
@@ -54,7 +54,7 @@
         mAppTitle = appTitle;
         mAppData = null;
         mAppUrl = url;
-        mInstallState = InstallerDelegate.INSTALL_STATE_NOT_INSTALLED;
+        mInstallState = InstallerDelegate.InstallState.NOT_INSTALLED;
     }
 
     @Override
@@ -116,7 +116,7 @@
 
     @Override
     public void onButtonClicked(boolean isPrimaryButton) {
-        if (isPrimaryButton && mInstallState == InstallerDelegate.INSTALL_STATE_INSTALLING) {
+        if (isPrimaryButton && mInstallState == InstallerDelegate.InstallState.INSTALLING) {
             setControlsEnabled(true);
             updateButton();
             return;
@@ -138,11 +138,11 @@
         String accessibilityText = null;
         boolean enabled = true;
         Context context = getContext();
-        if (mInstallState == InstallerDelegate.INSTALL_STATE_NOT_INSTALLED) {
+        if (mInstallState == InstallerDelegate.InstallState.NOT_INSTALLED) {
             text = mAppData.installButtonText();
             accessibilityText = context.getString(
                     R.string.app_banner_view_native_app_install_accessibility, text);
-        } else if (mInstallState == InstallerDelegate.INSTALL_STATE_INSTALLING) {
+        } else if (mInstallState == InstallerDelegate.InstallState.INSTALLING) {
             text = context.getString(R.string.app_banner_installing);
             mButton.announceForAccessibility(text);
             enabled = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java
index c895e03..cfda96c4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/AbstractMediaRouteController.java
@@ -178,8 +178,8 @@
     // There are times when the player state shown to user (e.g. just after pressing the pause
     // button) should update before we receive an update from the Chromecast, so we have to track
     // two player states.
-    private PlayerState mRemotePlayerState = PlayerState.FINISHED;
-    private PlayerState mDisplayedPlayerState = PlayerState.FINISHED;
+    private @PlayerState int mRemotePlayerState = PlayerState.FINISHED;
+    private @PlayerState int mDisplayedPlayerState = PlayerState.FINISHED;
     private boolean mRoutesAvailable;
     private final Set<UiListener> mUiListeners;
     private boolean mWatchingRouteSelection;
@@ -291,12 +291,12 @@
         return mMediaStateListener;
     }
 
-    public final PlayerState getRemotePlayerState() {
+    public final @PlayerState int getRemotePlayerState() {
         return mRemotePlayerState;
     }
 
     @Override
-    public final PlayerState getDisplayedPlayerState() {
+    public final @PlayerState int getDisplayedPlayerState() {
         return mDisplayedPlayerState;
     }
 
@@ -529,7 +529,8 @@
 
     @VisibleForTesting
     void setPlayerStateForMediaItemState(int state) {
-        PlayerState playerState = PlayerState.STOPPED;
+        @PlayerState
+        int playerState = PlayerState.STOPPED;
         switch (state) {
             case MediaItemStatus.PLAYBACK_STATE_BUFFERING:
                 playerState = PlayerState.LOADING;
@@ -569,28 +570,28 @@
     protected void updateState(int state) {
         Log.d(TAG, "updateState oldState: %s player state: %s", mRemotePlayerState, state);
 
-        PlayerState oldState = mRemotePlayerState;
+        @PlayerState
+        int oldState = mRemotePlayerState;
         setPlayerStateForMediaItemState(state);
 
         Log.d(TAG, "updateState newState: %s", mRemotePlayerState);
 
         if (oldState != mRemotePlayerState) {
             setDisplayedPlayerState(mRemotePlayerState);
-
             switch (mRemotePlayerState) {
-                case PLAYING:
+                case PlayerState.PLAYING:
                     onCasting();
                     break;
-                case PAUSED:
+                case PlayerState.PAUSED:
                     onCasting();
                     break;
-                case FINISHED:
+                case PlayerState.FINISHED:
                     release();
                     break;
-                case INVALIDATED:
+                case PlayerState.INVALIDATED:
                     clearItemState();
                     break;
-                case ERROR:
+                case PlayerState.ERROR:
                     sendErrorToListeners(CastMediaControlIntent.ERROR_CODE_REQUEST_FAILED);
                     release();
                     break;
@@ -600,7 +601,7 @@
         }
     }
 
-    protected void setDisplayedPlayerState(PlayerState state) {
+    protected void setDisplayedPlayerState(@PlayerState int state) {
         mDisplayedPlayerState = state;
         for (UiListener listener : mUiListeners) {
             listener.onPlaybackStateChanged(mDisplayedPlayerState);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java
index f140ff5..3b091fc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/CastNotificationControl.java
@@ -45,7 +45,7 @@
     protected MediaRouteController mMediaRouteController;
     private MediaNotificationInfo.Builder mNotificationBuilder;
     private Context mContext;
-    private PlayerState mState;
+    private @PlayerState int mState;
     private String mTitle = "";
     private AudioManager mAudioManager;
 
@@ -115,15 +115,15 @@
         mMediaRouteController.removeUiListener(this);
     }
 
-    public void show(PlayerState initialState) {
+    public void show(@PlayerState int initialState) {
         mMediaRouteController.addUiListener(this);
         // TODO(aberent): investigate why this is necessary, and whether we are handling
         // it correctly. Also add code to restore it when Chrome is resumed.
         mAudioManager.requestAudioFocus(this, AudioManager.USE_DEFAULT_STREAM_TYPE,
                 AudioManager.AUDIOFOCUS_GAIN);
         Intent contentIntent = new Intent(mContext, ExpandedControllerActivity.class);
-        contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME,
-                MediaNotificationUma.SOURCE_MEDIA_FLING);
+        contentIntent.putExtra(
+                MediaNotificationUma.INTENT_EXTRA_NAME, MediaNotificationUma.Source.MEDIA_FLING);
         mNotificationBuilder = new MediaNotificationInfo.Builder()
                 .setPaused(false)
                 .setPrivate(false)
@@ -176,7 +176,7 @@
 
     // MediaRouteController.UiListener implementation.
     @Override
-    public void onPlaybackStateChanged(PlayerState newState) {
+    public void onPlaybackStateChanged(@PlayerState int newState) {
         if (!mIsShowing
                 && (newState == PlayerState.PLAYING || newState == PlayerState.LOADING
                         || newState == PlayerState.PAUSED)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/DefaultMediaRouteController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/DefaultMediaRouteController.java
index 85e408d..05ac5bd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/DefaultMediaRouteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/DefaultMediaRouteController.java
@@ -97,13 +97,9 @@
             new ApplicationStatus.ApplicationStateListener() {
                 @Override
                 public void onApplicationStateChange(int newState) {
-                    switch (newState) {
-                        // HAS_DESTROYED_ACTIVITIES means all Chrome activities have been destroyed.
-                        case ApplicationState.HAS_DESTROYED_ACTIVITIES:
-                            onActivitiesDestroyed();
-                            break;
-                        default:
-                            break;
+                    // HAS_DESTROYED_ACTIVITIES means all Chrome activities have been destroyed.
+                    if (newState == ApplicationState.HAS_DESTROYED_ACTIVITIES) {
+                        onActivitiesDestroyed();
                     }
                 }
             };
@@ -140,10 +136,7 @@
 
     @Override
     public boolean canPlayMedia(String sourceUrl, String frameUrl) {
-
-        if (mediaRouterInitializationFailed()) return false;
-
-        if (sourceUrl == null) return false;
+        if (mediaRouterInitializationFailed() || sourceUrl == null) return false;
 
         try {
             String scheme = new URI(sourceUrl).getScheme();
@@ -478,8 +471,7 @@
 
         RecordCastAction.castPlayRequested();
 
-        RecordCastAction.remotePlaybackDeviceSelected(
-                RecordCastAction.DEVICE_TYPE_CAST_GENERIC);
+        RecordCastAction.remotePlaybackDeviceSelected(RecordCastAction.DeviceType.CAST_GENERIC);
         installBroadcastReceivers();
 
         if (getMediaStateListener() == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java
index 017c3c65..03398725 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/ExpandedControllerActivity.java
@@ -57,7 +57,7 @@
             if (mMediaRouteController == null) return;
             mMediaRouteController.resume();
             RecordCastAction.recordFullscreenControlsAction(
-                    RecordCastAction.FULLSCREEN_CONTROLS_RESUME,
+                    RecordCastAction.FullScreenControls.RESUME,
                     mMediaRouteController.getMediaStateListener() != null);
         }
 
@@ -66,7 +66,7 @@
             if (mMediaRouteController == null) return;
             mMediaRouteController.pause();
             RecordCastAction.recordFullscreenControlsAction(
-                    RecordCastAction.FULLSCREEN_CONTROLS_PAUSE,
+                    RecordCastAction.FullScreenControls.PAUSE,
                     mMediaRouteController.getMediaStateListener() != null);
         }
 
@@ -87,7 +87,7 @@
             if (mMediaRouteController == null) return;
             mMediaRouteController.seekTo(pos);
             RecordCastAction.recordFullscreenControlsAction(
-                    RecordCastAction.FULLSCREEN_CONTROLS_SEEK,
+                    RecordCastAction.FullScreenControls.SEEK,
                     mMediaRouteController.getMediaStateListener() != null);
         }
 
@@ -289,7 +289,7 @@
     }
 
     @Override
-    public void onPlaybackStateChanged(PlayerState newState) {
+    public void onPlaybackStateChanged(@PlayerState int newState) {
         RemoteVideoInfo videoInfo = new RemoteVideoInfo(mVideoInfo);
         videoInfo.state = newState;
         setVideoInfo(videoInfo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/FullscreenMediaRouteButton.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/FullscreenMediaRouteButton.java
index a2aeca7..376859f5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/FullscreenMediaRouteButton.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/FullscreenMediaRouteButton.java
@@ -61,11 +61,7 @@
         // If the button is being set to visible, first make sure that it can even cast
         // to anything before making it actually visible.
         if (visibility == View.VISIBLE) {
-            if (isEnabled()) {
-                setVisibility(View.VISIBLE);
-            } else {
-                setVisibility(View.GONE);
-            }
+            setVisibility(isEnabled() ? View.VISIBLE : View.GONE);
         } else {
             setVisibility(visibility);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaRouteController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaRouteController.java
index b58b66c..7b07b47 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaRouteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaRouteController.java
@@ -54,7 +54,7 @@
          * Called when the playback state changes (e.g. from Playing to Paused)
          * @param newState the new playback state
          */
-        void onPlaybackStateChanged(PlayerState newState);
+        void onPlaybackStateChanged(@PlayerState int newState);
 
         String getTitle();
 
@@ -152,7 +152,7 @@
          * Called when the Playback state has changed (e.g. from playing to paused)
          * @param newState the new state
          */
-        void onPlaybackStateChanged(PlayerState newState);
+        void onPlaybackStateChanged(@PlayerState int newState);
 
         /**
          * Called when the duration of the currently playing video changes.
@@ -314,7 +314,8 @@
     MediaStateListener getMediaStateListener();
 
     @VisibleForTesting
-    PlayerState getDisplayedPlayerState();
+    @PlayerState
+    int getDisplayedPlayerState();
 
     /**
      * Remove an existing media state listener
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
index 5e4f112..5554415 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.media.remote;
 
 import android.net.Uri;
+import android.support.annotation.IntDef;
 import android.text.TextUtils;
 
 import org.chromium.base.AsyncTask;
@@ -13,6 +14,8 @@
 import org.chromium.base.metrics.RecordHistogram;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.HttpURLConnection;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -27,21 +30,25 @@
  * HEAD request to determine if the URL is redirected.
  */
 public class MediaUrlResolver extends AsyncTask<Void, Void, MediaUrlResolver.Result> {
-
     // Cast.Sender.UrlResolveResult UMA histogram values; must match values of
     // RemotePlaybackUrlResolveResult in histograms.xml. Do not change these values, as they are
     // being used in UMA.
-    private static final int RESOLVE_RESULT_SUCCESS = 0;
-    private static final int RESOLVE_RESULT_MALFORMED_URL = 1;
-    private static final int RESOLVE_RESULT_NO_CORS = 2;
-    private static final int RESOLVE_RESULT_INCOMPATIBLE_CORS = 3;
-    private static final int RESOLVE_RESULT_SERVER_ERROR = 4;
-    private static final int RESOLVE_RESULT_NETWORK_ERROR = 5;
-    private static final int RESOLVE_RESULT_UNSUPPORTED_MEDIA = 6;
-    private static final int RESOLVE_RESULT_HUC_EXCEPTION = 7;
-
-    // Range of histogram.
-    private static final int HISTOGRAM_RESULT_COUNT = 8;
+    @IntDef({ResolveResult.SUCCESS, ResolveResult.MALFORMED_URL, ResolveResult.NO_CORS,
+            ResolveResult.INCOMPATIBLE_CORS, ResolveResult.SERVER_ERROR,
+            ResolveResult.NETWORK_ERROR, ResolveResult.UNSUPPORTED_MEDIA,
+            ResolveResult.HUC_EXCEPTION})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResolveResult {
+        int SUCCESS = 0;
+        int MALFORMED_URL = 1;
+        int NO_CORS = 2;
+        int INCOMPATIBLE_CORS = 3;
+        int SERVER_ERROR = 4;
+        int NETWORK_ERROR = 5;
+        int UNSUPPORTED_MEDIA = 6;
+        int HUC_EXCEPTION = 7;
+        int NUM_ENTRIES = 8;
+    }
 
     // Acceptal response codes for URL resolving request.
     private static final Integer[] SUCCESS_RESPONSE_CODES = {
@@ -110,16 +117,21 @@
     // media/base/container_names.h for the actual enum where these are defined.
     // See https://developers.google.com/cast/docs/media#media-container-formats for the formats
     // supported by Cast devices.
-    private static final int MEDIA_TYPE_UNKNOWN = 0;
-    private static final int MEDIA_TYPE_AAC = 1;
-    private static final int MEDIA_TYPE_HLS = 22;
-    private static final int MEDIA_TYPE_MP3 = 26;
-    private static final int MEDIA_TYPE_MPEG4 = 29;
-    private static final int MEDIA_TYPE_OGG = 30;
-    private static final int MEDIA_TYPE_WAV = 35;
-    private static final int MEDIA_TYPE_WEBM = 36;
-    private static final int MEDIA_TYPE_DASH = 38;
-    private static final int MEDIA_TYPE_SMOOTHSTREAM = 39;
+    @IntDef({MediaType.UNKNOWN, MediaType.AAC, MediaType.HLS, MediaType.MP3, MediaType.MPEG4,
+            MediaType.OGG, MediaType.WAV, MediaType.WEBM, MediaType.DASH, MediaType.SMOOTHSTREAM})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface MediaType {
+        int UNKNOWN = 0;
+        int AAC = 1;
+        int HLS = 22;
+        int MP3 = 26;
+        int MPEG4 = 29;
+        int OGG = 30;
+        int WAV = 35;
+        int WEBM = 36;
+        int DASH = 38;
+        int SMOOTHSTREAM = 39;
+    }
 
     // We don't want to necessarily fetch the whole video but we don't want to miss the CORS header.
     // Assume that 64k should be more than enough to keep all the headers.
@@ -179,17 +191,17 @@
             // If server's response is not valid, don't try to fling the video.
             int responseCode = urlConnection.getResponseCode();
             if (!Arrays.asList(SUCCESS_RESPONSE_CODES).contains(responseCode)) {
-                recordResultHistogram(RESOLVE_RESULT_SERVER_ERROR);
+                recordResultHistogram(ResolveResult.SERVER_ERROR);
                 Log.e(TAG, "Server response is not valid: %d", responseCode);
                 uri = Uri.EMPTY;
             }
         } catch (IOException | IllegalArgumentException e) {
             // IllegalArgumentException for SSL issue (https://b/78588631).
-            recordResultHistogram(RESOLVE_RESULT_NETWORK_ERROR);
+            recordResultHistogram(ResolveResult.NETWORK_ERROR);
             Log.e(TAG, "Failed to fetch the final url", e);
             uri = Uri.EMPTY;
         } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
-            recordResultHistogram(RESOLVE_RESULT_HUC_EXCEPTION);
+            recordResultHistogram(ResolveResult.HUC_EXCEPTION);
             Log.e(TAG, "Threading issue with HUC, see https://crbug.com/754480", e);
             uri = Uri.EMPTY;
         } catch (RuntimeException e) {
@@ -212,7 +224,7 @@
 
     private boolean canPlayMedia(Uri uri, Map<String, List<String>> headers) {
         if (uri == null || uri.equals(Uri.EMPTY)) {
-            recordResultHistogram(RESOLVE_RESULT_MALFORMED_URL);
+            recordResultHistogram(ResolveResult.MALFORMED_URL);
             return false;
         }
 
@@ -221,7 +233,7 @@
             List<String> corsData = headers.get(CORS_HEADER_NAME);
             if (corsData.isEmpty() || (!corsData.get(0).equals("*")
                     && !corsData.get(0).equals(CHROMECAST_ORIGIN))) {
-                recordResultHistogram(RESOLVE_RESULT_INCOMPATIBLE_CORS);
+                recordResultHistogram(ResolveResult.INCOMPATIBLE_CORS);
                 return false;
             }
         } else if (isEnhancedMedia(uri)) {
@@ -230,48 +242,47 @@
             // Clank assumes that if CORS is set for the manifest it's set for everything but
             // it not necessary always true. See b/19138712
             Log.d(TAG, "HLS stream without CORS header: %s", uri);
-            recordResultHistogram(RESOLVE_RESULT_NO_CORS);
+            recordResultHistogram(ResolveResult.NO_CORS);
             return false;
         }
 
-        if (getMediaType(uri) == MEDIA_TYPE_UNKNOWN) {
+        if (getMediaType(uri) == MediaType.UNKNOWN) {
             Log.d(TAG, "Unsupported media container format: %s", uri);
-            recordResultHistogram(RESOLVE_RESULT_UNSUPPORTED_MEDIA);
+            recordResultHistogram(ResolveResult.UNSUPPORTED_MEDIA);
             return false;
         }
 
-        recordResultHistogram(RESOLVE_RESULT_SUCCESS);
+        recordResultHistogram(ResolveResult.SUCCESS);
         return true;
     }
 
     private boolean isEnhancedMedia(Uri uri) {
         int mediaType = getMediaType(uri);
-        return mediaType == MEDIA_TYPE_HLS
-                || mediaType == MEDIA_TYPE_DASH
-                || mediaType == MEDIA_TYPE_SMOOTHSTREAM;
+        return mediaType == MediaType.HLS || mediaType == MediaType.DASH
+                || mediaType == MediaType.SMOOTHSTREAM;
     }
 
     @VisibleForTesting
-    void recordResultHistogram(int result) {
-        RecordHistogram.recordEnumeratedHistogram("Cast.Sender.UrlResolveResult", result,
-                HISTOGRAM_RESULT_COUNT);
+    void recordResultHistogram(@ResolveResult int result) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Cast.Sender.UrlResolveResult", result, ResolveResult.NUM_ENTRIES);
     }
 
-    static int getMediaType(Uri uri) {
+    static @MediaType int getMediaType(Uri uri) {
         String path = uri.getPath();
 
-        if (path == null) return MEDIA_TYPE_UNKNOWN;
+        if (path == null) return MediaType.UNKNOWN;
 
         path = path.toLowerCase(Locale.US);
-        if (path.endsWith(".m3u8")) return MEDIA_TYPE_HLS;
-        if (path.endsWith(".mp4")) return MEDIA_TYPE_MPEG4;
-        if (path.endsWith(".mpd")) return MEDIA_TYPE_DASH;
-        if (path.endsWith(".ism")) return MEDIA_TYPE_SMOOTHSTREAM;
-        if (path.endsWith(".m4a") || path.endsWith(".aac")) return MEDIA_TYPE_AAC;
-        if (path.endsWith(".mp3")) return MEDIA_TYPE_MP3;
-        if (path.endsWith(".wav")) return MEDIA_TYPE_WAV;
-        if (path.endsWith(".webm")) return MEDIA_TYPE_WEBM;
-        if (path.endsWith(".ogg")) return MEDIA_TYPE_OGG;
-        return MEDIA_TYPE_UNKNOWN;
+        if (path.endsWith(".m3u8")) return MediaType.HLS;
+        if (path.endsWith(".mp4")) return MediaType.MPEG4;
+        if (path.endsWith(".mpd")) return MediaType.DASH;
+        if (path.endsWith(".ism")) return MediaType.SMOOTHSTREAM;
+        if (path.endsWith(".m4a") || path.endsWith(".aac")) return MediaType.AAC;
+        if (path.endsWith(".mp3")) return MediaType.MP3;
+        if (path.endsWith(".wav")) return MediaType.WAV;
+        if (path.endsWith(".webm")) return MediaType.WEBM;
+        if (path.endsWith(".ogg")) return MediaType.OGG;
+        return MediaType.UNKNOWN;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java
index 2122183..e08861f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java
@@ -4,38 +4,48 @@
 
 package org.chromium.chrome.browser.media.remote;
 
+import android.support.annotation.IntDef;
+
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.rappor.RapporServiceBridge;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Record statistics on interesting cast events and actions.
  */
 @JNINamespace("remote_media")
 public class RecordCastAction {
-
     // UMA histogram values for the device types the user could select.
     // Keep in sync with the enum in uma_record_action.cc
-    public static final int DEVICE_TYPE_CAST_GENERIC = 0;
-    public static final int DEVICE_TYPE_CAST_YOUTUBE = 1;
-    public static final int DEVICE_TYPE_NON_CAST_YOUTUBE = 2;
-    public static final int DEVICE_TYPE_COUNT = 3;
+    @IntDef({DeviceType.CAST_GENERIC, DeviceType.CAST_YOUTUBE, DeviceType.NON_CAST_YOUTUBE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeviceType {
+        int CAST_GENERIC = 0;
+        int CAST_YOUTUBE = 1;
+        int NON_CAST_YOUTUBE = 2;
+        int NUM_ENTRIES = 3;
+    }
 
     // UMA histogram values for the fullscreen controls the user could tap.
     // Keep in sync with the MediaCommand enum in histograms.xml
-    public static final int FULLSCREEN_CONTROLS_RESUME = 0;
-    public static final int FULLSCREEN_CONTROLS_PAUSE = 1;
-    public static final int FULLSCREEN_CONTROLS_SEEK = 2;
-    public static final int FULLSCREEN_CONTROLS_COUNT = 3;
+    @IntDef({FullScreenControls.RESUME, FullScreenControls.PAUSE, FullScreenControls.SEEK})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FullScreenControls {
+        int RESUME = 0;
+        int PAUSE = 1;
+        int SEEK = 2;
+        int NUM_ENTRIES = 3;
+    }
 
     /**
      * Record the type of cast receiver we to which we are casting.
      * @param playerType the type of cast receiver.
      */
-    public static void remotePlaybackDeviceSelected(int playerType) {
-        assert playerType >= 0
-                && playerType < RecordCastAction.DEVICE_TYPE_COUNT;
+    public static void remotePlaybackDeviceSelected(@RecordCastAction.DeviceType int playerType) {
         if (LibraryLoader.getInstance().isInitialized())
             nativeRecordRemotePlaybackDeviceSelected(playerType);
     }
@@ -117,12 +127,12 @@
 
         if (isMediaElementAlive) {
             RecordHistogram.recordEnumeratedHistogram(
-                    "Cast.Sender.FullscreenControlsActionWithMediaElement",
-                    action, FULLSCREEN_CONTROLS_COUNT);
+                    "Cast.Sender.FullscreenControlsActionWithMediaElement", action,
+                    FullScreenControls.NUM_ENTRIES);
         } else {
             RecordHistogram.recordEnumeratedHistogram(
-                    "Cast.Sender.FullscreenControlsActionWithoutMediaElement",
-                    action, FULLSCREEN_CONTROLS_COUNT);
+                    "Cast.Sender.FullscreenControlsActionWithoutMediaElement", action,
+                    FullScreenControls.NUM_ENTRIES);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
index 70db9813..1290c58 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
@@ -81,7 +81,7 @@
         }
 
         @Override
-        public void onPlaybackStateChanged(PlayerState newState) {
+        public void onPlaybackStateChanged(@PlayerState int newState) {
             if (mNativeRemoteMediaPlayerBridge == 0) return;
             if (newState == PlayerState.FINISHED || newState == PlayerState.INVALIDATED) {
                 nativeOnPlaybackFinished(mNativeRemoteMediaPlayerBridge);
@@ -360,7 +360,6 @@
         mCookies = cookies;
         mRouteController.checkIfPlayableRemotely(mOriginalSourceUrl, mOriginalFrameUrl, cookies,
                 mUserAgent, new MediaRouteController.MediaValidationCallback() {
-
                     @Override
                     public void onResult(
                             boolean isPlayable, String revisedSourceUrl, String revisedFrameUrl) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerController.java
index 3fb5d57..2008e75 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerController.java
@@ -278,8 +278,7 @@
     }
 
     @Override
-    public void onPlaybackStateChanged(PlayerState newState) {
-    }
+    public void onPlaybackStateChanged(@PlayerState int newState) {}
 
     @Override
     public void onError(int error, String errorMessage) {
@@ -344,5 +343,4 @@
     static RemoteMediaPlayerController getIfExists() {
         return sInstance;
     }
-
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java
index cfe299c..f4030cf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteVideoInfo.java
@@ -4,38 +4,38 @@
 
 package org.chromium.chrome.browser.media.remote;
 
+import android.support.annotation.IntDef;
 import android.text.TextUtils;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Exposes information about the current video to the external clients.
  */
 public class RemoteVideoInfo {
-
     /**
      * This lists all the states that the remote video can be in.
      */
-    public enum PlayerState {
+    @IntDef({PlayerState.STOPPED, PlayerState.LOADING, PlayerState.PLAYING, PlayerState.PAUSED,
+            PlayerState.ERROR, PlayerState.INVALIDATED, PlayerState.FINISHED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlayerState {
         /** The remote player is currently stopped. */
-        STOPPED,
-
+        int STOPPED = 0;
         /** The remote player is buffering this video. */
-        LOADING,
-
+        int LOADING = 1;
         /** The remote player is playing this video. */
-        PLAYING,
-
+        int PLAYING = 2;
         /** The remote player is paused. */
-        PAUSED,
-
+        int PAUSED = 3;
         /** The remote player is in an error state. */
-        ERROR,
-
+        int ERROR = 4;
         /** The remote player has been replaced by another player (so the current session has
          * finished) */
-        INVALIDATED,
-
+        int INVALIDATED = 5;
         /** The remote video has completed playing. */
-        FINISHED
+        int FINISHED = 6;
     }
 
     /**
@@ -49,7 +49,7 @@
     /**
      * The current state of the video
      */
-    public PlayerState state;
+    public @PlayerState int state;
     /**
      * The last known position in the video
      */
@@ -68,7 +68,7 @@
      * @param currentTimeMillis
      * @param errorMessage
      */
-    public RemoteVideoInfo(String title, long durationMillis, PlayerState state,
+    public RemoteVideoInfo(String title, long durationMillis, @PlayerState int state,
             long currentTimeMillis, String errorMessage) {
         this.title = title;
         this.durationMillis = durationMillis;
@@ -88,12 +88,8 @@
 
     @Override
     public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof RemoteVideoInfo)) {
-            return false;
-        }
+        if (obj == this) return true;
+        if (!(obj instanceof RemoteVideoInfo)) return false;
 
         RemoteVideoInfo other = (RemoteVideoInfo) obj;
         return durationMillis == other.durationMillis
@@ -110,7 +106,7 @@
         result = 31 * result + (int) currentTimeMillis;
         result = 31 * result + (int) (currentTimeMillis >> 32);
         result = 31 * result + (title == null ? 0 : title.hashCode());
-        result = 31 * result + (state == null ? 0 : state.hashCode());
+        result = 31 * result + state;
         result = 31 * result + (errorMessage == null ? 0 : errorMessage.hashCode());
         return result;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java
index 174d9be..a5010a30d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/CastSessionImpl.java
@@ -133,7 +133,7 @@
         Intent contentIntent = Tab.createBringTabToFrontIntent(tabId);
         if (contentIntent != null) {
             contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME,
-                    MediaNotificationUma.SOURCE_PRESENTATION);
+                    MediaNotificationUma.Source.PRESENTATION);
         }
         mNotificationBuilder =
                 new MediaNotificationInfo.Builder()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
index 3e9926d..c684de6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -211,7 +211,7 @@
                 Intent contentIntent = Tab.createBringTabToFrontIntent(mTab.getId());
                 if (contentIntent != null) {
                     contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME,
-                            MediaNotificationUma.SOURCE_MEDIA);
+                            MediaNotificationUma.Source.MEDIA);
                 }
 
                 if (mFallbackTitle == null) mFallbackTitle = sanitizeMediaTitle(mTab.getTitle());
@@ -420,17 +420,18 @@
      *               {@link MediaNotificationListener} interface.
      * @return the corresponding histogram value.
      */
-    public static int convertMediaActionSourceToUMA(int source) {
+    public static @MediaSessionUMA.MediaSessionActionSource int convertMediaActionSourceToUMA(
+            int source) {
         if (source == MediaNotificationListener.ACTION_SOURCE_MEDIA_NOTIFICATION) {
-            return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_MEDIA_NOTIFICATION;
+            return MediaSessionUMA.MediaSessionActionSource.MEDIA_NOTIFICATION;
         } else if (source == MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION) {
-            return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_MEDIA_SESSION;
+            return MediaSessionUMA.MediaSessionActionSource.MEDIA_SESSION;
         } else if (source == MediaNotificationListener.ACTION_SOURCE_HEADSET_UNPLUG) {
-            return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_HEADSET_UNPLUG;
+            return MediaSessionUMA.MediaSessionActionSource.HEADSET_UNPLUG;
         }
 
         assert false;
-        return MediaSessionUMA.MEDIA_SESSION_ACTION_SOURCE_MAX;
+        return MediaSessionUMA.MediaSessionActionSource.NUM_ENTRIES;
     }
 
     private Activity getActivityFromTab(Tab tab) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityStopMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityStopMetrics.java
index 2c1b266b..515293f4a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityStopMetrics.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityStopMetrics.java
@@ -17,36 +17,28 @@
  * Tracks metrics caused by a particular Activity stopping.
  */
 public class ActivityStopMetrics {
+    // NUM_ENTRIES is intentionally included into @IntDef.
+    @IntDef({StopReason.UNKNOWN, StopReason.BACK_BUTTON,
+            StopReason.OTHER_CHROME_ACTIVITY_IN_FOREGROUND, StopReason.NUM_ENTRIES})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        STOP_REASON_UNKNOWN,
-        STOP_REASON_BACK_BUTTON,
-        STOP_REASON_OTHER_CHROME_ACTIVITY_IN_FOREGROUND,
-        STOP_REASON_COUNT
-    })
-    public @interface StopReason{}
+    public @interface StopReason {
+        /** Activity stopped for unknown reasons. */
+        int UNKNOWN = 0;
+        /** Activity stopped after the user hit the back button. */
+        int BACK_BUTTON = 1;
+        // Obsolete -- Activity stopped after the user hit the close/return UI button.
+        // int RETURN_BUTTON = 2;
+        // Obsolete --  Activity stopped because it launched a {@link CustomTabActivity} on top of
+        //              itself.
+        // int CUSTOM_TAB_STARTED = 3;
+        // Obsolete -- Activity stopped because its child {@link CustomTabActivity} stopped itself.
+        // int CUSTOM_TAB_STOPPED = 4;
+        /** Activity stopped because another of Chrome Activities came into focus. */
+        int OTHER_CHROME_ACTIVITY_IN_FOREGROUND = 5;
 
-    /** Activity stopped for unknown reasons. */
-    public static final int STOP_REASON_UNKNOWN = 0;
-
-    /** Activity stopped after the user hit the back button. */
-    public static final int STOP_REASON_BACK_BUTTON = 1;
-
-    // Obsolete -- Activity stopped after the user hit the close/return UI button.
-    // public static final int STOP_REASON_RETURN_BUTTON = 2;
-
-    // Obsolete --  Activity stopped because it launched a {@link CustomTabActivity} on top of
-    //              itself.
-    // public static final int STOP_REASON_CUSTOM_TAB_STARTED = 3;
-
-    // Obsolete -- Activity stopped because its child {@link CustomTabActivity} stopped itself.
-    // public static final int STOP_REASON_CUSTOM_TAB_STOPPED = 4;
-
-    /** Activity stopped because another of Chrome Activities came into focus. */
-    public static final int STOP_REASON_OTHER_CHROME_ACTIVITY_IN_FOREGROUND = 5;
-
-    /** Boundary.  Shouldn't ever be passed to the metrics service. */
-    public static final int STOP_REASON_COUNT = 6;
+        /** Boundary. Shouldn't ever be passed to the metrics service. */
+        int NUM_ENTRIES = 6;
+    }
 
     /** Name of the histogram that will be recorded. */
     private static final String HISTOGRAM_NAME = "Android.Activity.ChromeTabbedActivity.StopReason";
@@ -58,7 +50,7 @@
      * Constructs an {@link ActivityStopMetrics} instance.
      */
     public ActivityStopMetrics() {
-        mStopReason = STOP_REASON_COUNT;
+        mStopReason = StopReason.NUM_ENTRIES;
     }
 
     /**
@@ -66,16 +58,17 @@
      * @param parent Activity that owns this {@link ActivityStopMetrics} instance.
      */
     public void onStopWithNative(Activity parent) {
-        if (mStopReason == STOP_REASON_COUNT) {
+        if (mStopReason == StopReason.NUM_ENTRIES) {
             if (parent != ApplicationStatus.getLastTrackedFocusedActivity()
                     && ApplicationStatus.hasVisibleActivities()) {
-                mStopReason = STOP_REASON_OTHER_CHROME_ACTIVITY_IN_FOREGROUND;
+                mStopReason = StopReason.OTHER_CHROME_ACTIVITY_IN_FOREGROUND;
             } else {
-                mStopReason = STOP_REASON_UNKNOWN;
+                mStopReason = StopReason.UNKNOWN;
             }
         }
-        RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_NAME, mStopReason, STOP_REASON_COUNT);
-        mStopReason = STOP_REASON_COUNT;
+        RecordHistogram.recordEnumeratedHistogram(
+                HISTOGRAM_NAME, mStopReason, StopReason.NUM_ENTRIES);
+        mStopReason = StopReason.NUM_ENTRIES;
     }
 
     /**
@@ -83,7 +76,7 @@
      * @param reason Reason the Activity was stopped (see {@link StopReason}).
      */
     public void setStopReason(@StopReason int reason) {
-        if (mStopReason != STOP_REASON_COUNT) return;
+        if (mStopReason != StopReason.NUM_ENTRIES) return;
         mStopReason = reason;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java
index c78f144..e322c60 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java
@@ -28,7 +28,6 @@
  * Records the behavior metrics after an ACTION_MAIN intent is received.
  */
 public class MainIntentBehaviorMetrics implements ApplicationStatus.ActivityStateListener {
-
     private static final long BACKGROUND_TIME_24_HOUR_MS = 86400000;
     private static final long BACKGROUND_TIME_12_HOUR_MS = 43200000;
     private static final long BACKGROUND_TIME_6_HOUR_MS = 21600000;
@@ -36,14 +35,17 @@
 
     static final long TIMEOUT_DURATION_MS = 10000;
 
+    @IntDef({MainIntentActionType.CONTINUATION, MainIntentActionType.FOCUS_OMNIBOX,
+            MainIntentActionType.SWITCH_TABS, MainIntentActionType.NTP_CREATED,
+            MainIntentActionType.BACKGROUNDED})
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({CONTINUATION, FOCUS_OMNIBOX, SWITCH_TABS, NTP_CREATED, BACKGROUNDED})
-    @interface MainIntentActionType {}
-    static final int CONTINUATION = 0;
-    static final int FOCUS_OMNIBOX = 1;
-    static final int SWITCH_TABS = 2;
-    static final int NTP_CREATED = 3;
-    static final int BACKGROUNDED = 4;
+    @interface MainIntentActionType {
+        int CONTINUATION = 0;
+        int FOCUS_OMNIBOX = 1;
+        int SWITCH_TABS = 2;
+        int NTP_CREATED = 3;
+        int BACKGROUNDED = 4;
+    }
 
     // Min and max values (in minutes) for the buckets in the duration histograms.
     private static final int DURATION_HISTOGRAM_MIN = 5;
@@ -73,7 +75,7 @@
         mTimeoutRunnable = new Runnable() {
             @Override
             public void run() {
-                recordUserBehavior(CONTINUATION);
+                recordUserBehavior(MainIntentActionType.CONTINUATION);
             }
         };
     }
@@ -110,12 +112,13 @@
             @Override
             public void didAddTab(Tab tab, @TabLaunchType int type) {
                 if (type == TabLaunchType.FROM_RESTORE) return;
-                if (NewTabPage.isNTPUrl(tab.getUrl())) recordUserBehavior(NTP_CREATED);
+                if (NewTabPage.isNTPUrl(tab.getUrl()))
+                    recordUserBehavior(MainIntentActionType.NTP_CREATED);
             }
 
             @Override
             public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {
-                recordUserBehavior(SWITCH_TABS);
+                recordUserBehavior(MainIntentActionType.SWITCH_TABS);
             }
         };
     }
@@ -133,13 +136,13 @@
      * Signal that the omnibox received focus.
      */
     public void onOmniboxFocused() {
-        recordUserBehavior(FOCUS_OMNIBOX);
+        recordUserBehavior(MainIntentActionType.FOCUS_OMNIBOX);
     }
 
     @Override
     public void onActivityStateChange(Activity activity, int newState) {
         if (newState == ActivityState.STOPPED || newState == ActivityState.DESTROYED) {
-            recordUserBehavior(BACKGROUNDED);
+            recordUserBehavior(MainIntentActionType.BACKGROUNDED);
         }
     }
 
@@ -168,15 +171,15 @@
 
     private String getHistogramNameForBehavior(@MainIntentActionType int behavior) {
         switch (behavior) {
-            case CONTINUATION:
+            case MainIntentActionType.CONTINUATION:
                 return "FirstUserAction.BackgroundTime.MainIntent.Continuation";
-            case FOCUS_OMNIBOX:
+            case MainIntentActionType.FOCUS_OMNIBOX:
                 return "FirstUserAction.BackgroundTime.MainIntent.Omnibox";
-            case SWITCH_TABS:
+            case MainIntentActionType.SWITCH_TABS:
                 return "FirstUserAction.BackgroundTime.MainIntent.SwitchTabs";
-            case NTP_CREATED:
+            case MainIntentActionType.NTP_CREATED:
                 return "FirstUserAction.BackgroundTime.MainIntent.NtpCreated";
-            case BACKGROUNDED:
+            case MainIntentActionType.BACKGROUNDED:
                 return "FirstUserAction.BackgroundTime.MainIntent.Backgrounded";
             default:
                 return null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaNotificationUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaNotificationUma.java
index d13b46f2..698b242 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaNotificationUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaNotificationUma.java
@@ -7,23 +7,31 @@
 import static org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample;
 
 import android.content.Intent;
+import android.support.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Helper class to record which kind of media notifications does the user click to go back to
  * Chrome.
  */
 public class MediaNotificationUma {
-    public static final int SOURCE_INVALID = -1;
-    public static final int SOURCE_MEDIA = 0;
-    public static final int SOURCE_PRESENTATION = 1;
-    public static final int SOURCE_MEDIA_FLING = 2;
-    public static final int SOURCE_MAX = 3;
+    @IntDef({Source.INVALID, Source.MEDIA, Source.PRESENTATION, Source.MEDIA_FLING})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Source {
+        int INVALID = -1;
+        int MEDIA = 0;
+        int PRESENTATION = 1;
+        int MEDIA_FLING = 2;
+        int NUM_ENTRIES = 3;
+    }
 
     public static final String INTENT_EXTRA_NAME =
             "org.chromium.chrome.browser.metrics.MediaNotificationUma.EXTRA_CLICK_SOURCE";
 
     private static final EnumeratedHistogramSample sClickSourceHistogram =
-            new EnumeratedHistogramSample("Media.Notification.Click", SOURCE_MAX);
+            new EnumeratedHistogramSample("Media.Notification.Click", Source.NUM_ENTRIES);
 
     /**
      * Record the UMA as specified by {@link intent}. The {@link intent} should contain intent extra
@@ -32,8 +40,9 @@
      */
     public static void recordClickSource(Intent intent) {
         if (intent == null) return;
-        int source = intent.getIntExtra(INTENT_EXTRA_NAME, SOURCE_INVALID);
-        if (source == SOURCE_INVALID || source >= SOURCE_MAX) return;
+        @Source
+        int source = intent.getIntExtra(INTENT_EXTRA_NAME, Source.INVALID);
+        if (source == Source.INVALID || source >= Source.NUM_ENTRIES) return;
         sClickSourceHistogram.record(source);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaSessionUMA.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaSessionUMA.java
index 239e2f2c..76cd25c9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaSessionUMA.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MediaSessionUMA.java
@@ -4,33 +4,41 @@
 
 package org.chromium.chrome.browser.metrics;
 
+import android.support.annotation.IntDef;
+
 import org.chromium.base.metrics.RecordHistogram;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Centralizes UMA data collection for Android-specific MediaSession features.
  */
 public class MediaSessionUMA {
     // MediaSessionAction defined in tools/metrics/histograms/histograms.xml.
-    public static final int MEDIA_SESSION_ACTION_SOURCE_MEDIA_NOTIFICATION = 0;
-    public static final int MEDIA_SESSION_ACTION_SOURCE_MEDIA_SESSION = 1;
-    public static final int MEDIA_SESSION_ACTION_SOURCE_HEADSET_UNPLUG = 2;
-    public static final int MEDIA_SESSION_ACTION_SOURCE_MAX = 3;
+    @IntDef({MediaSessionActionSource.MEDIA_NOTIFICATION, MediaSessionActionSource.MEDIA_SESSION,
+            MediaSessionActionSource.HEADSET_UNPLUG})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MediaSessionActionSource {
+        int MEDIA_NOTIFICATION = 0;
+        int MEDIA_SESSION = 1;
+        int HEADSET_UNPLUG = 2;
 
-    public static void recordPlay(int action) {
-        assert action >= 0 && action < MEDIA_SESSION_ACTION_SOURCE_MAX;
-        RecordHistogram.recordEnumeratedHistogram("Media.Session.Play", action,
-                MEDIA_SESSION_ACTION_SOURCE_MAX);
+        int NUM_ENTRIES = 3;
     }
 
-    public static void recordPause(int action) {
-        assert action >= 0 && action < MEDIA_SESSION_ACTION_SOURCE_MAX;
-        RecordHistogram.recordEnumeratedHistogram("Media.Session.Pause", action,
-                MEDIA_SESSION_ACTION_SOURCE_MAX);
+    public static void recordPlay(@MediaSessionActionSource int action) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Media.Session.Play", action, MediaSessionActionSource.NUM_ENTRIES);
     }
 
-    public static void recordStop(int action) {
-        assert action >= 0 && action < MEDIA_SESSION_ACTION_SOURCE_MAX;
-        RecordHistogram.recordEnumeratedHistogram("Media.Session.Stop", action,
-                MEDIA_SESSION_ACTION_SOURCE_MAX);
+    public static void recordPause(@MediaSessionActionSource int action) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Media.Session.Pause", action, MediaSessionActionSource.NUM_ENTRIES);
+    }
+
+    public static void recordStop(@MediaSessionActionSource int action) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Media.Session.Stop", action, MediaSessionActionSource.NUM_ENTRIES);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/OmniboxStartupMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/OmniboxStartupMetrics.java
index 75b3084..71b41b38 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/OmniboxStartupMetrics.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/OmniboxStartupMetrics.java
@@ -15,6 +15,8 @@
 import org.chromium.content_public.browser.BrowserStartupController;
 import org.chromium.content_public.browser.WebContents;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -25,6 +27,7 @@
     // Since these values are persisted to logs, they should never be renumbered nor reused.
     @IntDef({StartupState.PRE_NATIVE_INITIALIZATION, StartupState.POST_NATIVE_INITIALIZATION,
             StartupState.POST_FIRST_MEANINGFUL_PAINT, StartupState.POST_FIRST_PAGELOAD_FINISHED})
+    @Retention(RetentionPolicy.SOURCE)
     public @interface StartupState {
         // This is the state of startup before native has been loaded
         int PRE_NATIVE_INITIALIZATION = 0;
@@ -37,7 +40,7 @@
         // This is after the first page has been loaded completely.
         int POST_FIRST_PAGELOAD_FINISHED = 3;
 
-        int COUNT = 4;
+        int NUM_ENTRIES = 4;
     }
 
     private static final int MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 1000;
@@ -90,7 +93,6 @@
     }
 
     private void updateStartupState(@StartupState int newState) {
-        assert newState < StartupState.COUNT;
         // Should not go backwards in startup state
         if (newState < mCurrentStartupState) return;
         mCurrentStartupState = newState;
@@ -137,7 +139,7 @@
             String activityName = mActivity.getClass().getSimpleName();
             RecordHistogram.recordEnumeratedHistogram(
                     "MobileStartup.ToolbarFirstFocusStartupState." + activityName,
-                    mUrlBarFocusedStartupState, StartupState.COUNT);
+                    mUrlBarFocusedStartupState, StartupState.NUM_ENTRIES);
 
             RecordHistogram.recordCustomTimesHistogram(
                     "MobileStartup.ToolbarFirstFocusTime2." + activityName,
@@ -147,4 +149,4 @@
         }
         destroy();
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
index 6d7a91f..2286de9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
@@ -10,6 +10,7 @@
 import android.os.Environment;
 import android.os.StatFs;
 import android.provider.Settings;
+import android.support.annotation.IntDef;
 import android.text.TextUtils;
 
 import org.chromium.base.AsyncTask;
@@ -22,6 +23,8 @@
 import org.chromium.webapk.lib.common.WebApkConstants;
 
 import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -33,20 +36,28 @@
  */
 public class WebApkUma {
     // This enum is used to back UMA histograms, and should therefore be treated as append-only.
-    // Deprecated: UPDATE_REQUEST_SENT_FIRST_TRY = 0;
-    // Deprecated: UPDATE_REQUEST_SENT_ONSTOP = 1;
-    // Deprecated: UPDATE_REQUEST_SENT_WHILE_WEBAPK_IN_FOREGROUND = 2;
-    public static final int UPDATE_REQUEST_SENT_WHILE_WEBAPK_CLOSED = 3;
-    public static final int UPDATE_REQUEST_SENT_MAX = 4;
+    @IntDef({UpdateRequestSent.WHILE_WEBAPK_CLOSED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UpdateRequestSent {
+        // Deprecated: FIRST_TRY = 0;
+        // Deprecated: ONSTOP = 1;
+        // Deprecated: WHILE_WEBAPK_IN_FOREGROUND = 2;
+        int WHILE_WEBAPK_CLOSED = 3;
+        int NUM_ENTRIES = 4;
+    }
 
     // This enum is used to back UMA histograms, and should therefore be treated as append-only.
     // The queued request times shouldn't exceed three.
-    public static final int UPDATE_REQUEST_QUEUED_ONCE = 0;
-    public static final int UPDATE_REQUEST_QUEUED_TWICE = 1;
-    public static final int UPDATE_REQUEST_QUEUED_THREE_TIMES = 2;
-    public static final int UPDATE_REQUEST_QUEUED_MAX = 3;
+    @IntDef({UpdateRequestQueued.ONCE, UpdateRequestQueued.TWICE, UpdateRequestQueued.THREE_TIMES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UpdateRequestQueued {
+        int ONCE = 0;
+        int TWICE = 1;
+        int THREE_TIMES = 2;
+        int NUM_ENTRIES = 3;
+    }
 
-    // This enum is used to back UMA histograms, and should therefore be treated as append-only.
+    // TODO(yfriedman): Remove once internal repo is updated.
     public static final int GOOGLE_PLAY_INSTALL_SUCCESS = 0;
     public static final int GOOGLE_PLAY_INSTALL_FAILED_NO_DELEGATE = 1;
     public static final int GOOGLE_PLAY_INSTALL_FAILED_TO_CONNECT_TO_SERVICE = 2;
@@ -58,8 +69,6 @@
     public static final int GOOGLE_PLAY_INSTALL_FAILED_DOWNLOAD_ERROR = 8;
     public static final int GOOGLE_PLAY_INSTALL_FAILED_INSTALL_ERROR = 9;
     public static final int GOOGLE_PLAY_INSTALL_FAILED_INSTALL_TIMEOUT = 10;
-    // GOOGLE_PLAY_INSTALL_REQUEST_FAILED_* errors are the error codes shown in the "reason" of
-    // the returned Bundle when calling installPackage() API returns false.
     public static final int GOOGLE_PLAY_INSTALL_REQUEST_FAILED_POLICY_DISABLED = 11;
     public static final int GOOGLE_PLAY_INSTALL_REQUEST_FAILED_UNKNOWN_ACCOUNT = 12;
     public static final int GOOGLE_PLAY_INSTALL_REQUEST_FAILED_NETWORK_ERROR = 13;
@@ -68,12 +77,56 @@
     public static final int GOOGLE_PLAY_INSTALL_RESULT_MAX = 16;
 
     // This enum is used to back UMA histograms, and should therefore be treated as append-only.
-    private static final int PERMISSION_OTHER = 0;
-    private static final int PERMISSION_LOCATION = 1;
-    private static final int PERMISSION_MICROPHONE = 2;
-    private static final int PERMISSION_CAMERA = 3;
-    private static final int PERMISSION_STORAGE = 4;
-    private static final int PERMISSION_COUNT = 5;
+    @IntDef({GooglePlayInstallResult.SUCCESS, GooglePlayInstallResult.FAILED_NO_DELEGATE,
+            GooglePlayInstallResult.FAILED_TO_CONNECT_TO_SERVICE,
+            GooglePlayInstallResult.FAILED_CALLER_VERIFICATION_FAILURE,
+            GooglePlayInstallResult.FAILED_POLICY_VIOLATION,
+            GooglePlayInstallResult.FAILED_API_DISABLED,
+            GooglePlayInstallResult.FAILED_REQUEST_FAILED,
+            GooglePlayInstallResult.FAILED_DOWNLOAD_CANCELLED,
+            GooglePlayInstallResult.FAILED_DOWNLOAD_ERROR,
+            GooglePlayInstallResult.FAILED_INSTALL_ERROR,
+            GooglePlayInstallResult.FAILED_INSTALL_TIMEOUT,
+            GooglePlayInstallResult.REQUEST_FAILED_POLICY_DISABLED,
+            GooglePlayInstallResult.REQUEST_FAILED_UNKNOWN_ACCOUNT,
+            GooglePlayInstallResult.REQUEST_FAILED_NETWORK_ERROR,
+            GooglePlayInstallResult.REQUSET_FAILED_RESOLVE_ERROR,
+            GooglePlayInstallResult.REQUEST_FAILED_NOT_GOOGLE_SIGNED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GooglePlayInstallResult {
+        int SUCCESS = 0;
+        int FAILED_NO_DELEGATE = 1;
+        int FAILED_TO_CONNECT_TO_SERVICE = 2;
+        int FAILED_CALLER_VERIFICATION_FAILURE = 3;
+        int FAILED_POLICY_VIOLATION = 4;
+        int FAILED_API_DISABLED = 5;
+        int FAILED_REQUEST_FAILED = 6;
+        int FAILED_DOWNLOAD_CANCELLED = 7;
+        int FAILED_DOWNLOAD_ERROR = 8;
+        int FAILED_INSTALL_ERROR = 9;
+        int FAILED_INSTALL_TIMEOUT = 10;
+        // REQUEST_FAILED_* errors are the error codes shown in the "reason" of
+        // the returned Bundle when calling installPackage() API returns false.
+        int REQUEST_FAILED_POLICY_DISABLED = 11;
+        int REQUEST_FAILED_UNKNOWN_ACCOUNT = 12;
+        int REQUEST_FAILED_NETWORK_ERROR = 13;
+        int REQUSET_FAILED_RESOLVE_ERROR = 14;
+        int REQUEST_FAILED_NOT_GOOGLE_SIGNED = 15;
+        int NUM_ENTRIES = 16;
+    }
+
+    // This enum is used to back UMA histograms, and should therefore be treated as append-only.
+    @IntDef({Permission.OTHER, Permission.LOCATION, Permission.MICROPHONE, Permission.CAMERA,
+            Permission.STORAGE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Permission {
+        int OTHER = 0;
+        int LOCATION = 1;
+        int MICROPHONE = 2;
+        int CAMERA = 3;
+        int STORAGE = 4;
+        int NUM_ENTRIES = 5;
+    }
 
     public static final String HISTOGRAM_UPDATE_REQUEST_SENT =
             "WebApk.Update.RequestSent";
@@ -97,10 +150,9 @@
      * Records the time point when a request to update a WebAPK is sent to the WebAPK Server.
      * @param type representing when the update request is sent to the WebAPK server.
      */
-    public static void recordUpdateRequestSent(int type) {
-        assert type >= 0 && type < UPDATE_REQUEST_SENT_MAX;
-        RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_UPDATE_REQUEST_SENT,
-                type, UPDATE_REQUEST_SENT_MAX);
+    public static void recordUpdateRequestSent(@UpdateRequestSent int type) {
+        RecordHistogram.recordEnumeratedHistogram(
+                HISTOGRAM_UPDATE_REQUEST_SENT, type, UpdateRequestSent.NUM_ENTRIES);
     }
 
     /**
@@ -108,9 +160,9 @@
      * sending to WebAPK server.
      * @param times representing the times that an update has been queued.
      */
-    public static void recordUpdateRequestQueued(int times) {
-        RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_UPDATE_REQUEST_QUEUED, times,
-                UPDATE_REQUEST_QUEUED_MAX);
+    public static void recordUpdateRequestQueued(@UpdateRequestQueued int times) {
+        RecordHistogram.recordEnumeratedHistogram(
+                HISTOGRAM_UPDATE_REQUEST_QUEUED, times, UpdateRequestQueued.NUM_ENTRIES);
     }
 
     /**
@@ -151,10 +203,9 @@
      * Records whether installing a WebAPK from Google Play succeeded. If not, records the reason
      * that the install failed.
      */
-    public static void recordGooglePlayInstallResult(int result) {
-        assert result >= 0 && result < GOOGLE_PLAY_INSTALL_RESULT_MAX;
-        RecordHistogram.recordEnumeratedHistogram(
-                "WebApk.Install.GooglePlayInstallResult", result, GOOGLE_PLAY_INSTALL_RESULT_MAX);
+    public static void recordGooglePlayInstallResult(@GooglePlayInstallResult int result) {
+        RecordHistogram.recordEnumeratedHistogram("WebApk.Install.GooglePlayInstallResult", result,
+                GooglePlayInstallResult.NUM_ENTRIES);
     }
 
     /** Records the error code if installing a WebAPK via Google Play fails. */
@@ -169,10 +220,9 @@
      * Records whether updating a WebAPK from Google Play succeeded. If not, records the reason
      * that the update failed.
      */
-    public static void recordGooglePlayUpdateResult(int result) {
-        assert result >= 0 && result < GOOGLE_PLAY_INSTALL_RESULT_MAX;
-        RecordHistogram.recordEnumeratedHistogram(
-                "WebApk.Update.GooglePlayUpdateResult", result, GOOGLE_PLAY_INSTALL_RESULT_MAX);
+    public static void recordGooglePlayUpdateResult(@GooglePlayInstallResult int result) {
+        RecordHistogram.recordEnumeratedHistogram("WebApk.Update.GooglePlayUpdateResult", result,
+                GooglePlayInstallResult.NUM_ENTRIES);
     }
 
     /** Records the duration of a WebAPK session (from launch/foreground to background). */
@@ -216,28 +266,28 @@
         for (String permission : permissions) {
             permissionGroups.add(getPermissionGroup(permission));
         }
-        for (Integer permission : permissionGroups) {
+        for (@Permission Integer permission : permissionGroups) {
             RecordHistogram.recordEnumeratedHistogram(
-                    permissionUmaName, permission, PERMISSION_COUNT);
+                    permissionUmaName, permission, Permission.NUM_ENTRIES);
         }
     }
 
-    private static int getPermissionGroup(String permission) {
+    private static @Permission int getPermissionGroup(String permission) {
         if (TextUtils.equals(permission, Manifest.permission.ACCESS_COARSE_LOCATION)
                 || TextUtils.equals(permission, Manifest.permission.ACCESS_FINE_LOCATION)) {
-            return PERMISSION_LOCATION;
+            return Permission.LOCATION;
         }
         if (TextUtils.equals(permission, Manifest.permission.RECORD_AUDIO)) {
-            return PERMISSION_MICROPHONE;
+            return Permission.MICROPHONE;
         }
         if (TextUtils.equals(permission, Manifest.permission.CAMERA)) {
-            return PERMISSION_CAMERA;
+            return Permission.CAMERA;
         }
         if (TextUtils.equals(permission, Manifest.permission.READ_EXTERNAL_STORAGE)
                 || TextUtils.equals(permission, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
-            return PERMISSION_STORAGE;
+            return Permission.STORAGE;
         }
-        return PERMISSION_OTHER;
+        return Permission.OTHER;
     }
 
     /**
@@ -330,10 +380,7 @@
         try {
             File[] files = dir.listFiles();
             if (files == null) return 0;
-
-            for (File file : files) {
-                sizeInByte += getDirectorySizeInByte(file);
-            }
+            for (File file : files) sizeInByte += getDirectorySizeInByte(file);
         } catch (SecurityException e) {
             return 0;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebappUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebappUma.java
index 47c0039d..d1f1dc7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebappUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebappUma.java
@@ -5,10 +5,13 @@
 package org.chromium.chrome.browser.metrics;
 
 import android.os.SystemClock;
+import android.support.annotation.IntDef;
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.webapps.SplashscreenObserver;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -16,23 +19,40 @@
  */
 public class WebappUma implements SplashscreenObserver {
     // SplashscreenColorStatus defined in tools/metrics/histograms/enums.xml.
-    public static final int SPLASHSCREEN_COLOR_STATUS_DEFAULT = 0;
-    public static final int SPLASHSCREEN_COLOR_STATUS_CUSTOM = 1;
-    public static final int SPLASHSCREEN_COLOR_STATUS_MAX = 2;
+    // NUM_ENTRIES is intentionally included into @IntDef.
+    @IntDef({SplashScreenColorStatus.DEFAULT, SplashScreenColorStatus.CUSTOM,
+            SplashScreenColorStatus.NUM_ENTRIES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SplashScreenColorStatus {
+        int DEFAULT = 0;
+        int CUSTOM = 1;
+        int NUM_ENTRIES = 2;
+    }
 
     // SplashscreenHidesReason defined in tools/metrics/histograms/enums.xml.
-    public static final int SPLASHSCREEN_HIDES_REASON_PAINT = 0;
-    public static final int SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED = 1;
-    public static final int SPLASHSCREEN_HIDES_REASON_LOAD_FAILED = 2;
-    public static final int SPLASHSCREEN_HIDES_REASON_CRASH = 3;
-    public static final int SPLASHSCREEN_HIDES_REASON_MAX = 4;
+    @IntDef({SplashScreenHidesReason.PAINT, SplashScreenHidesReason.LOAD_FINISHED,
+            SplashScreenHidesReason.LOAD_FAILED, SplashScreenHidesReason.CRASH})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SplashScreenHidesReason {
+        int PAINT = 0;
+        int LOAD_FINISHED = 1;
+        int LOAD_FAILED = 2;
+        int CRASH = 3;
+        int NUM_ENTRIES = 4;
+    }
 
     // SplashscreenBackgroundColorType defined in tools/metrics/histograms/enums.xml.
-    public static final int SPLASHSCREEN_ICON_TYPE_NONE = 0;
-    public static final int SPLASHSCREEN_ICON_TYPE_FALLBACK = 1;
-    public static final int SPLASHSCREEN_ICON_TYPE_CUSTOM = 2;
-    public static final int SPLASHSCREEN_ICON_TYPE_CUSTOM_SMALL = 3;
-    public static final int SPLASHSCREEN_ICON_TYPE_MAX = 4;
+    // NUM_ENTRIES is intentionally included into @IntDef.
+    @IntDef({SplashScreenIconType.NONE, SplashScreenIconType.FALLBACK, SplashScreenIconType.CUSTOM,
+            SplashScreenIconType.CUSTOM_SMALL, SplashScreenIconType.NUM_ENTRIES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SplashScreenIconType {
+        int NONE = 0;
+        int FALLBACK = 1;
+        int CUSTOM = 2;
+        int CUSTOM_SMALL = 3;
+        int NUM_ENTRIES = 4;
+    }
 
     // Histogram names are defined in tools/metrics/histograms/histograms.xml.
     public static final String HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR =
@@ -48,10 +68,10 @@
     public static final String HISTOGRAM_SPLASHSCREEN_THEMECOLOR =
             "Webapp.Splashscreen.ThemeColor";
 
-    private int mSplashScreenBackgroundColor = SPLASHSCREEN_COLOR_STATUS_MAX;
-    private int mSplashScreenIconType = SPLASHSCREEN_ICON_TYPE_MAX;
+    private int mSplashScreenBackgroundColor = SplashScreenColorStatus.NUM_ENTRIES;
+    private int mSplashScreenIconType = SplashScreenIconType.NUM_ENTRIES;
     private int mSplashScreenIconSize = -1;
-    private int mSplashScreenThemeColor = SPLASHSCREEN_COLOR_STATUS_MAX;
+    private int mSplashScreenThemeColor = SplashScreenColorStatus.NUM_ENTRIES;
     private long mSplashScreenVisibleTime;
 
     private boolean mCommitted;
@@ -70,9 +90,8 @@
      * Records the type of background color on the splash screen.
      * @param type flag representing the type of color.
      */
-    public void recordSplashscreenBackgroundColor(int type) {
+    public void recordSplashscreenBackgroundColor(@SplashScreenColorStatus int type) {
         assert !mCommitted;
-        assert type >= 0 && type < SPLASHSCREEN_COLOR_STATUS_MAX;
         mSplashScreenBackgroundColor = type;
     }
 
@@ -83,10 +102,9 @@
      * @param reason enum representing the reason why the splash screen was hidden.
      */
     @Override
-    public void onSplashscreenHidden(int reason) {
-        assert reason >= 0 && reason < SPLASHSCREEN_HIDES_REASON_MAX;
-        RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_SPLASHSCREEN_HIDES,
-                reason, SPLASHSCREEN_HIDES_REASON_MAX);
+    public void onSplashscreenHidden(@SplashScreenHidesReason int reason) {
+        RecordHistogram.recordEnumeratedHistogram(
+                HISTOGRAM_SPLASHSCREEN_HIDES, reason, SplashScreenHidesReason.NUM_ENTRIES);
 
         assert mSplashScreenVisibleTime != 0;
         RecordHistogram.recordMediumTimesHistogram(HISTOGRAM_SPLASHSCREEN_DURATION,
@@ -97,9 +115,8 @@
      * Records the type of icon on the splash screen.
      * @param type flag representing the type of icon.
      */
-    public void recordSplashscreenIconType(int type) {
+    public void recordSplashscreenIconType(@SplashScreenIconType int type) {
         assert !mCommitted;
-        assert type >= 0 && type < SPLASHSCREEN_ICON_TYPE_MAX;
         mSplashScreenIconType = type;
     }
 
@@ -113,9 +130,8 @@
      * Records the type of theme color on the splash screen.
      * @param type flag representing the type of color.
      */
-    public void recordSplashscreenThemeColor(int type) {
+    public void recordSplashscreenThemeColor(@SplashScreenColorStatus int type) {
         assert !mCommitted;
-        assert type >= 0 && type < SPLASHSCREEN_COLOR_STATUS_MAX;
         mSplashScreenThemeColor = type;
     }
 
@@ -128,31 +144,28 @@
 
         mCommitted = true;
 
-        assert mSplashScreenBackgroundColor != SPLASHSCREEN_COLOR_STATUS_MAX;
+        assert mSplashScreenBackgroundColor != SplashScreenColorStatus.NUM_ENTRIES;
         RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR,
-                mSplashScreenBackgroundColor,
-                SPLASHSCREEN_COLOR_STATUS_MAX);
-        mSplashScreenBackgroundColor = SPLASHSCREEN_COLOR_STATUS_MAX;
+                mSplashScreenBackgroundColor, SplashScreenColorStatus.NUM_ENTRIES);
+        mSplashScreenBackgroundColor = SplashScreenColorStatus.NUM_ENTRIES;
 
-        assert mSplashScreenIconType != SPLASHSCREEN_ICON_TYPE_MAX;
+        assert mSplashScreenIconType != SplashScreenIconType.NUM_ENTRIES;
         RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                mSplashScreenIconType,
-                SPLASHSCREEN_ICON_TYPE_MAX);
+                mSplashScreenIconType, SplashScreenIconType.NUM_ENTRIES);
 
-        if (mSplashScreenIconType == SPLASHSCREEN_ICON_TYPE_NONE) {
+        if (mSplashScreenIconType == SplashScreenIconType.NONE) {
             assert mSplashScreenIconSize == -1;
         } else {
             assert mSplashScreenIconSize >= 0;
             RecordHistogram.recordCount1000Histogram(HISTOGRAM_SPLASHSCREEN_ICON_SIZE,
                     mSplashScreenIconSize);
         }
-        mSplashScreenIconType = SPLASHSCREEN_ICON_TYPE_MAX;
+        mSplashScreenIconType = SplashScreenIconType.NUM_ENTRIES;
         mSplashScreenIconSize = -1;
 
-        assert mSplashScreenThemeColor != SPLASHSCREEN_COLOR_STATUS_MAX;
+        assert mSplashScreenThemeColor != SplashScreenColorStatus.NUM_ENTRIES;
         RecordHistogram.recordEnumeratedHistogram(HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
-                mSplashScreenThemeColor,
-                SPLASHSCREEN_COLOR_STATUS_MAX);
-        mSplashScreenThemeColor = SPLASHSCREEN_COLOR_STATUS_MAX;
+                mSplashScreenThemeColor, SplashScreenColorStatus.NUM_ENTRIES);
+        mSplashScreenThemeColor = SplashScreenColorStatus.NUM_ENTRIES;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java
deleted file mode 100644
index 862b042..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java
+++ /dev/null
@@ -1,45 +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.
-
-package org.chromium.chrome.browser.vr;
-
-import android.content.Intent;
-import android.view.WindowManager;
-
-import org.chromium.chrome.browser.customtabs.SeparateTaskCustomTabActivity;
-import org.chromium.chrome.browser.util.IntentUtils;
-import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
-import org.chromium.chrome.browser.vr_shell.VrShellDelegate;
-
-/**
- * A subclass of SeparateTaskCustomTabActivity created when starting Chrome in VR mode.
- *
- * The main purpose of this activity is to add flexibility to the way Chrome is started when the
- * user's phone is already in their VR headset (e.g, we want to hide the System UI).
- */
-public class CustomTabVrActivity extends SeparateTaskCustomTabActivity {
-    @Override
-    public void preInflationStartup() {
-        assert VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent());
-
-        // Set VR specific window mode.
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-        getWindow().getDecorView().setSystemUiVisibility(VrShellDelegate.VR_SYSTEM_UI_FLAGS);
-
-        super.preInflationStartup();
-    }
-
-    @Override
-    protected boolean isStartedUpCorrectly(Intent intent) {
-        if (!VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(getIntent())) {
-            return false;
-        }
-        return super.isStartedUpCorrectly(intent);
-    }
-
-    @Override
-    protected Intent validateIntent(final Intent intent) {
-        return IntentUtils.sanitizeIntent(intent);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java
index 53e31d23b..df555dd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrFirstRunActivity.java
@@ -82,13 +82,6 @@
     }
 
     private void recordFreHistogram() {
-        // This is the intent that started the activity that triggered the FRE.
-        Intent freCallerIntent = (Intent) IntentUtils.safeGetParcelableExtra(
-                getIntent(), VrIntentUtils.VR_FRE_CALLER_INTENT_EXTRA);
-        if (VrIntentUtils.getHandlerInstance().isTrustedAutopresentIntent(freCallerIntent)) {
-            sFreNotCompleteAutopresentHistogram.record(true);
-        } else {
-            sFreNotCompleteBrowserHistogram.record(true);
-        }
+        sFreNotCompleteBrowserHistogram.record(true);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
index 812196a..4a4e94ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrIntentUtils.java
@@ -13,17 +13,13 @@
 import android.os.Bundle;
 import android.view.Display;
 
-import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.browser.vr.VrMainActivity;
 
 /**
  * Utilities dealing with extracting information about VR intents.
  */
 public class VrIntentUtils {
-    private static final String DAYDREAM_HOME_PACKAGE = "com.google.android.vr.home";
     // The Daydream Home app adds this extra to auto-present intents.
     public static final String AUTOPRESENT_WEVBVR_EXTRA = "browser.vr.AUTOPRESENT_WEBVR";
     public static final String DAYDREAM_CATEGORY = "com.google.intent.category.DAYDREAM";
@@ -38,69 +34,6 @@
             "org.chromium.chrome.browser.vr_shell.ENABLE_TEST_RELUANCH_WORKAROUND";
 
     static final String VR_FRE_INTENT_EXTRA = "org.chromium.chrome.browser.vr_shell.VR_FRE";
-    static final String VR_FRE_CALLER_INTENT_EXTRA =
-            "org.chromium.chrome.browser.vr_shell.VR_FRE_CALLER";
-
-    private static VrIntentHandler sHandlerInstance;
-
-    /**
-     * Handles VR intent checking for VrShellDelegate.
-     * TODO(ymalik): There's no reason for this to be an interface, refactor
-     * into default implementation that tests can override.
-     */
-    public interface VrIntentHandler {
-        /**
-         * Determines whether the given intent is a VR intent from Daydream Home.
-         * @param intent The intent to check
-         * @return Whether the intent is a VR intent and originated from Daydream Home
-         */
-        boolean isTrustedDaydreamIntent(Intent intent);
-
-        /**
-         * Determines whether the given intent is a VR intent that is allowed to auto-present WebVR
-         * content.
-         * @param intent The intent to check
-         * @return Whether the intent should be allowed to auto-present.
-         */
-        boolean isTrustedAutopresentIntent(Intent intent);
-    }
-
-    private static VrIntentHandler createInternalVrIntentHandler() {
-        return new VrIntentHandler() {
-            @Override
-            public boolean isTrustedDaydreamIntent(Intent intent) {
-                return isVrIntent(intent)
-                        && IntentHandler.isIntentFromTrustedApp(intent, DAYDREAM_HOME_PACKAGE);
-            }
-
-            @Override
-            public boolean isTrustedAutopresentIntent(Intent intent) {
-                // Note that all auto-present intents may not have the intent extra because the user
-                // may have an older version of the Daydream app which doesn't add this extra.
-                // This is probably fine because we mostly use isTrustedDaydreamIntent above to
-                // start auto-presentation. We should switch those calls to use this method when
-                // we're sure that most clients have the change.
-                return isTrustedDaydreamIntent(intent)
-                        && IntentUtils.safeGetBooleanExtra(intent, AUTOPRESENT_WEVBVR_EXTRA, false);
-            }
-        };
-    }
-
-    /**
-     * Gets the static VrIntentHandler instance.
-     * @return The VrIntentHandler instance
-     */
-    public static VrIntentHandler getHandlerInstance() {
-        if (sHandlerInstance == null) {
-            sHandlerInstance = createInternalVrIntentHandler();
-        }
-        return sHandlerInstance;
-    }
-
-    @VisibleForTesting
-    public static void setHandlerInstanceForTesting(VrIntentHandler handler) {
-        sHandlerInstance = handler;
-    }
 
     /**
      * @return Whether or not the given intent is a VR-specific intent.
@@ -123,7 +56,7 @@
      */
     public static boolean isLaunchingIntoVr(Activity activity, Intent intent) {
         if (!VrShellDelegate.deviceSupportsVrLaunches()) return false;
-        return isLaunchingIntoVrBrowsing(activity, intent) || isCustomTabVrIntent(intent);
+        return isLaunchingIntoVrBrowsing(activity, intent);
     }
 
     private static boolean isLaunchingIntoVrBrowsing(Activity activity, Intent intent) {
@@ -131,32 +64,18 @@
     }
 
     /**
-     * @return whether the given intent is should open in a Custom Tab.
-     */
-    public static boolean isCustomTabVrIntent(Intent intent) {
-        // TODO(crbug.com/719661): Currently, only Daydream intents open in a CustomTab. We should
-        // probably change this once we figure out core CCT flows in VR.
-        if (intent == null) return false;
-        return IntentHandler.getUrlFromIntent(intent) != null
-                && getHandlerInstance().isTrustedDaydreamIntent(intent);
-    }
-
-    /**
      * This function returns an intent that will launch a VR activity that will prompt the
      * user to take off their headset and forward the freIntent to the standard
      * 2D FRE activity.
      *
-     * @param freCallerIntent The intent that is used to launch the caller.
      * @param freIntent       The intent that will be used to start the first run in 2D mode.
      * @return The intermediate VR activity intent.
      */
-    public static Intent setupVrFreIntent(
-            Context context, Intent freCallerIntent, Intent freIntent) {
+    public static Intent setupVrFreIntent(Context context, Intent freIntent) {
         if (!VrShellDelegate.isVrEnabled()) return freIntent;
         Intent intent = new Intent();
         intent.setClassName(context, VrFirstRunActivity.class.getName());
         intent.addCategory(DAYDREAM_CATEGORY);
-        intent.putExtra(VR_FRE_CALLER_INTENT_EXTRA, new Intent(freCallerIntent));
         intent.putExtra(VR_FRE_INTENT_EXTRA, new Intent(freIntent));
         return intent;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
index 5899897..f397048 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -15,8 +15,7 @@
     /**
      * Performs native VrShell initialization.
      */
-    void initializeNative(boolean forWebVr, boolean webVrAutopresentationExpected, boolean inCct,
-            boolean isStandaloneVrDevice);
+    void initializeNative(boolean forWebVr, boolean inCct, boolean isStandaloneVrDevice);
 
     /**
      * Pauses VrShell.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index f16ed6b7..80c8a6a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -196,13 +196,8 @@
     private boolean mMaybeActivateAfterHeadsetInsertion;
     private Handler mClearMaybeActivateHandler = new Handler();
     private boolean mActivateFromHeadsetInsertion;
-    // Whether or not we should autopresent WebVr. If this is set, it means that a first
-    // party app has asked us to autopresent WebVr content and we're waiting for the WebVr
-    // content to call requestPresent.
-    private boolean mAutopresentWebVr;
     // If set to true, we attempt to enter VR mode when the activity is resumed.
     private boolean mEnterVrOnStartup;
-    private boolean mExitCctOnStartup;
 
     private boolean mInternalIntentUsedToStartVr;
 
@@ -761,10 +756,6 @@
                 || activity instanceof WebappActivity;
     }
 
-    private static boolean activitySupportsAutopresentation(Activity activity) {
-        return activity instanceof ChromeTabbedActivity || activity instanceof CustomTabActivity;
-    }
-
     private static boolean activitySupportsExitFeedback(Activity activity) {
         return activity instanceof ChromeTabbedActivity
                 && ChromeFeatureList.isEnabled(ChromeFeatureList.VR_BROWSING_FEEDBACK);
@@ -1222,7 +1213,6 @@
         if (mActivateFromHeadsetInsertion) {
             assert !mRequestedWebVr;
             assert !mEnterVrOnStartup;
-            assert !mAutopresentWebVr;
         }
         enterVr(mActivateFromHeadsetInsertion);
         if (mActivateFromHeadsetInsertion && mListeningForWebVrActivate) {
@@ -1263,17 +1253,17 @@
         mExitedDueToUnsupportedMode = false;
 
         addVrViews();
-        boolean webVrMode = mRequestedWebVr || tentativeWebVrMode || mAutopresentWebVr;
+        boolean webVrMode = mRequestedWebVr || tentativeWebVrMode;
         // Make sure that assets component is registered when creating native VR shell.
         if (!sRegisteredVrAssetsComponent) {
             registerVrAssetsComponentIfDaydreamUser(isDaydreamCurrentViewer());
         }
-        mVrShell.initializeNative(webVrMode, mAutopresentWebVr,
-                mActivity instanceof CustomTabActivity, getVrClassesWrapper().bootsToVr());
+        mVrShell.initializeNative(webVrMode, mActivity instanceof CustomTabActivity,
+                getVrClassesWrapper().bootsToVr());
         mVrShell.setWebVrModeEnabled(webVrMode);
 
         // We're entering VR, but not in WebVr mode.
-        mVrBrowserUsed = !webVrMode && !mAutopresentWebVr;
+        mVrBrowserUsed = !webVrMode;
 
         // resume needs to be called on GvrLayout after initialization to make sure DON flow works
         // properly.
@@ -1281,7 +1271,7 @@
 
         mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
         removeBlackOverlayView(mActivity);
-        if (!donSuceeded && !mAutopresentWebVr && isDaydreamCurrentViewerInternal()) {
+        if (!donSuceeded && isDaydreamCurrentViewerInternal()) {
             // TODO(mthiesse): This is a VERY dirty hack. We need to know whether or not entering VR
             // will trigger the DON flow, so that we can wait for it to complete before we let the
             // webVR page know that it can present. However, Daydream APIs currently make this
@@ -1333,7 +1323,6 @@
         // we're not in vr.
         assert !mInVr;
         if (USE_HIDE_ANIMATION) mNeedsAnimationCancel = true;
-        mAutopresentWebVr = true;
         mEnterVrOnStartup = true;
 
         // We assume that the user is already in VR mode when launched for auto-presentation.
@@ -1378,23 +1367,7 @@
 
         setVrModeEnabled(mActivity, true);
 
-        // TODO(ymalik): This should use isTrustedAutopresentIntent once the Daydream Home change
-        // that adds the autopresent intent extra rolls out on most devices. This will allow us to
-        // differentiate trusted auto-present intents from other VR intents.
-        if (VrIntentUtils.getHandlerInstance().isTrustedDaydreamIntent(intent)) {
-            if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: autopresent");
-            assert activitySupportsAutopresentation(activity);
-
-            // TODO(mthiesse): This needs to be set here to correctly close the CCT when we early
-            // exit here. We should use a different variable or refactor or something to make this
-            // more clear.
-            mAutopresentWebVr = true;
-            if (!ChromeFeatureList.isEnabled(ChromeFeatureList.WEBVR_AUTOPRESENT_FROM_INTENT)) {
-                onEnterVrUnsupported();
-                return;
-            }
-            onAutopresentIntent();
-        } else if (isVrBrowsingSupported(mActivity)) {
+        if (isVrBrowsingSupported(mActivity)) {
             if (DEBUG_LOGS) Log.i(TAG, "onNewIntentWithNative: vr");
             onVrIntent();
         } else {
@@ -1417,16 +1390,6 @@
                 // call, so enter VR here.
                 handleDonFlowSuccess();
                 runPendingExitVrTask();
-
-                // This is extremely unlikely to happen in practice, but it's theoretically possible
-                // for the page to have loaded and registered an activate handler before this point.
-                // Usually the displayActivate is sent from
-                // VrShellDelegate#setListeningForWebVrActivate.
-                if (mAutopresentWebVr && mListeningForWebVrActivate) {
-                    // Dispatch vrdisplayactivate so that the WebVr page can call requestPresent
-                    // to start presentation.
-                    nativeDisplayActivate(mNativeVrShellDelegate);
-                }
             }
         }
     }
@@ -1521,8 +1484,8 @@
             return false;
 
         // If vr shell is not enabled and this is not a web vr request, then return false.
-        boolean presenting = mRequestedWebVr || mListeningForWebVrActivate
-                || mActivateFromHeadsetInsertion || mAutopresentWebVr;
+        boolean presenting =
+                mRequestedWebVr || mListeningForWebVrActivate || mActivateFromHeadsetInsertion;
         if (!isVrBrowsingEnabled() && !presenting) return false;
         return true;
     }
@@ -1604,20 +1567,12 @@
 
     private void exitWebVRAndClearState() {
         exitWebVRPresent();
-        mAutopresentWebVr = false;
         mRequestedWebVr = false;
     }
 
     @CalledByNative
     /* package */ void exitWebVRPresent() {
         if (!mInVr) return;
-        if (mAutopresentWebVr) {
-            // For autopresent from Daydream home, we do NOT want to show ChromeVR. So if we
-            // ever exit WebVR for whatever reason (navigation, call exitPresent etc), go back to
-            // Daydream home.
-            getVrDaydreamApi().launchVrHomescreen();
-            return;
-        }
 
         if (!isVrBrowsingEnabled()) {
             if (isDaydreamCurrentViewerInternal()) {
@@ -1663,7 +1618,6 @@
         if (!mTestWorkaroundDontCancelVrEntryOnResume) {
             mMaybeActivateAfterHeadsetInsertion = false;
         }
-        if (maybeCloseVrCct()) return;
         if (mNeedsAnimationCancel) {
             // At least on some devices, like the Samsung S8+, a Window animation is run after our
             // Activity is shown that fades between a stale screenshot from before pausing to the
@@ -1798,7 +1752,6 @@
     }
 
     private void onStart() {
-        if (maybeCloseVrCct()) return;
         mMaybeActivateAfterHeadsetInsertion = false;
         mStopped = false;
         if (mDonSucceeded) setWindowModeForVr();
@@ -1823,14 +1776,6 @@
         assert !mCancellingEntryAnimation;
     }
 
-    private boolean maybeCloseVrCct() {
-        if (!mExitCctOnStartup) return false;
-        getVrDaydreamApi().launchVrHomescreen();
-        assert mActivity instanceof CustomTabActivity;
-        ((CustomTabActivity) mActivity).finishAndClose(false);
-        return true;
-    }
-
     private boolean onBackPressedInternal() {
         if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return false;
         cancelPendingVrEntry();
@@ -1853,20 +1798,15 @@
             return true;
         }
 
-        // To avoid taking the user out of VR mode when started for auto-presentation, never show
-        // DOFF and bail to Daydream if we're forced to leave Chrome. We still show DOFF if VR
-        // services are out of date though.
-        if (!mAutopresentWebVr || mShowingDoffForGvrUpdate) {
-            try {
-                if (getVrDaydreamApi().exitFromVr(mActivity, EXIT_VR_RESULT, new Intent())) {
-                    mShowingDaydreamDoff = true;
-                    mDoffOptional = optional;
-                    return true;
-                }
-            } catch (IllegalArgumentException | SecurityException e) {
-                // DOFF calls can unpredictably throw exceptions if VrCore doesn't think Chrome is
-                // the active component, for example.
+        try {
+            if (getVrDaydreamApi().exitFromVr(mActivity, EXIT_VR_RESULT, new Intent())) {
+                mShowingDaydreamDoff = true;
+                mDoffOptional = optional;
+                return true;
             }
+        } catch (IllegalArgumentException | SecurityException e) {
+            // DOFF calls can unpredictably throw exceptions if VrCore doesn't think Chrome is
+            // the active component, for example.
         }
         if (!optional) getVrDaydreamApi().launchVrHomescreen();
         return false;
@@ -1889,7 +1829,6 @@
 
         if (mShowingDoffForGvrUpdate) {
             mShowVrServicesUpdatePrompt = success;
-            handleFinishAutopresentation();
         }
 
         if (success) {
@@ -1921,7 +1860,7 @@
         if (mListeningForWebVrActivate) {
             registerDaydreamIntent(mActivity);
             if (mNeedsAnimationCancel || mCancellingEntryAnimation) return;
-            if (mAutopresentWebVr || mActivateFromHeadsetInsertion) {
+            if (mActivateFromHeadsetInsertion) {
                 // Dispatch vrdisplayactivate so that the WebVr page can call requestPresent
                 // to start presentation.
                 nativeDisplayActivate(mNativeVrShellDelegate);
@@ -1962,9 +1901,6 @@
     protected void shutdownVr(boolean disableVrMode, boolean stayingInChrome) {
         if (DEBUG_LOGS) Log.i(TAG, "shuttdown VR");
         cancelPendingVrEntry();
-        // Ensure shutdownVr runs if we're stopping.
-        if (handleFinishAutopresentation() && !mStopped) return;
-        mAutopresentWebVr = false;
 
         if (!mInVr) return;
         if (mShowingDaydreamDoff) {
@@ -2038,25 +1974,7 @@
         mCloseButtonListener = new Runnable() {
             @Override
             public void run() {
-                boolean startedForAutopresentation = mAutopresentWebVr;
-                // Avoid launching DD home when we shutdown VR.
-                mAutopresentWebVr = false;
-
-                shutdownVr(true /* disableVrMode */,
-                        !startedForAutopresentation /* stayingInChrome */);
-
-                if (!startedForAutopresentation) return;
-
-                // We override the default behavior of the close button because we may stay in
-                // Chrome after exiting VR. This is not true for auto-presented content and we want
-                // to do what Daydream does for other VR apps by default (which is currently to open
-                // 2D launcher). Note that we shutdownVr when Chrome is stopped by this intent.
-                final Intent homeIntent = new Intent(Intent.ACTION_MAIN);
-                homeIntent.addCategory(Intent.CATEGORY_HOME);
-                homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mActivity.startActivity(homeIntent);
-
-                ((CustomTabActivity) mActivity).finishAndClose(false);
+                shutdownVr(true /* disableVrMode */, true /* stayingInChrome */);
             }
         };
         return mCloseButtonListener;
@@ -2067,16 +1985,10 @@
      */
     /* package */ Runnable getVrSettingsButtonListener() {
         if (mSettingsButtonListener != null) return mSettingsButtonListener;
-        final boolean startedForAutopresentation = mAutopresentWebVr;
         mSettingsButtonListener = new Runnable() {
             @Override
             public void run() {
-                // Avoid launching DD home when we shutdown VR.
-                mAutopresentWebVr = false;
-
                 shutdownVr(true /* disableVrMode */, false /* stayingInChrome */);
-
-                if (startedForAutopresentation) mExitCctOnStartup = true;
                 getVrClassesWrapper().launchGvrSettings(mActivity);
             }
         };
@@ -2084,22 +1996,6 @@
     }
 
     /**
-     * Returns true if finishing auto-presentation was handled.
-     */
-    private boolean handleFinishAutopresentation() {
-        // We keep the activity alive when we're returning from DOFF and need to show the GVR update
-        // infobar.
-        boolean willPromptForUpdateOnVrExit = mShowingDoffForGvrUpdate
-                && mShowVrServicesUpdatePrompt != null && mShowVrServicesUpdatePrompt;
-        if (!mAutopresentWebVr || willPromptForUpdateOnVrExit) return false;
-        if (DEBUG_LOGS) Log.i(TAG, "killing activity started for auto-presentation");
-        // Should only autopresent CustomTabActivity for now.
-        assert mActivity instanceof CustomTabActivity;
-        ((CustomTabActivity) mActivity).finishAndClose(false);
-        return true;
-    }
-
-    /**
      * Prompts the user to enter feedback for their VR Browsing experience.
      */
     private void promptForFeedbackIfNeeded(boolean stayingInChrome) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index 73cbb3d..c239bc11 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -340,8 +340,7 @@
 
     @Override
     @TargetApi(Build.VERSION_CODES.N)
-    public void initializeNative(boolean forWebVr, boolean webVrAutopresentationExpected,
-            boolean inCct, boolean isStandaloneVrDevice) {
+    public void initializeNative(boolean forWebVr, boolean inCct, boolean isStandaloneVrDevice) {
         Tab tab = mActivity.getActivityTab();
         if (mActivity.isInOverviewMode() || tab == null) {
             launchNTP();
@@ -384,8 +383,8 @@
                 || mActivity.getWindowAndroid().canRequestPermission(
                            android.Manifest.permission.RECORD_AUDIO);
         boolean supportsRecognition = FeatureUtilities.isRecognitionIntentPresent(mActivity, false);
-        mNativeVrShell = nativeInit(mDelegate, forWebVr, webVrAutopresentationExpected, inCct,
-                !mVrBrowsingEnabled, hasOrCanRequestAudioPermission && supportsRecognition,
+        mNativeVrShell = nativeInit(mDelegate, forWebVr, inCct, !mVrBrowsingEnabled,
+                hasOrCanRequestAudioPermission && supportsRecognition,
                 getGvrApi().getNativeGvrContext(), mReprojectedRendering, displayWidthMeters,
                 displayHeightMeters, dm.widthPixels, dm.heightPixels, pauseContent, lowDensity,
                 isStandaloneVrDevice);
@@ -1254,12 +1253,11 @@
         mUiActivityResultCallback = null;
     }
 
-    private native long nativeInit(VrShellDelegate delegate, boolean forWebVR,
-            boolean webVrAutopresentationExpected, boolean inCct, boolean browsingDisabled,
-            boolean hasOrCanRequestAudioPermission, long gvrApi, boolean reprojectedRendering,
-            float displayWidthMeters, float displayHeightMeters, int displayWidthPixels,
-            int displayHeightPixels, boolean pauseContent, boolean lowDensity,
-            boolean isStandaloneVrDevice);
+    private native long nativeInit(VrShellDelegate delegate, boolean forWebVR, boolean inCct,
+            boolean browsingDisabled, boolean hasOrCanRequestAudioPermission, long gvrApi,
+            boolean reprojectedRendering, float displayWidthMeters, float displayHeightMeters,
+            int displayWidthPixels, int displayHeightPixels, boolean pauseContent,
+            boolean lowDensity, boolean isStandaloneVrDevice);
     private native void nativeSetSurface(long nativeVrShell, Surface surface);
     private native void nativeSwapContents(long nativeVrShell, Tab tab);
     private native void nativeSetAndroidGestureTarget(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
index 1b6fc459..bc23c5f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
@@ -69,7 +69,7 @@
         if (mInstallDelegate == null) {
             notify(WebApkInstallResult.FAILURE);
             WebApkUma.recordGooglePlayInstallResult(
-                    WebApkUma.GOOGLE_PLAY_INSTALL_FAILED_NO_DELEGATE);
+                    WebApkUma.GooglePlayInstallResult.FAILED_NO_DELEGATE);
             return;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
index 78a5662..8edf556d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
@@ -196,7 +196,7 @@
             callback.run();
         };
 
-        WebApkUma.recordUpdateRequestSent(WebApkUma.UPDATE_REQUEST_SENT_WHILE_WEBAPK_CLOSED);
+        WebApkUma.recordUpdateRequestSent(WebApkUma.UpdateRequestSent.WHILE_WEBAPK_CLOSED);
         updateWebApkFromFile(mStorage.getPendingUpdateRequestPath(), callbackRunner);
     }
 
@@ -204,10 +204,10 @@
      * Destroys {@link mFetcher}. In a separate function for the sake of tests.
      */
     protected void destroyFetcher() {
-        if (mFetcher == null) return;
-
-        mFetcher.destroy();
-        mFetcher = null;
+        if (mFetcher != null) {
+            mFetcher.destroy();
+            mFetcher = null;
+        }
     }
 
     /**
@@ -239,18 +239,14 @@
      * True if there has not been any update attempts.
      */
     private boolean shouldCheckIfWebManifestUpdated(WebApkInfo info) {
-        if (!sUpdatesEnabled) {
-            return false;
-        }
+        if (!sUpdatesEnabled) return false;
 
         if (CommandLine.getInstance().hasSwitch(
                     ChromeSwitches.CHECK_FOR_WEB_MANIFEST_UPDATE_ON_STARTUP)) {
             return true;
         }
 
-        if (!info.apkPackageName().startsWith(WEBAPK_PACKAGE_PREFIX)) {
-            return false;
-        }
+        if (!info.apkPackageName().startsWith(WEBAPK_PACKAGE_PREFIX)) return false;
 
         if (isShellApkVersionOutOfDate(info)
                 && WebApkVersion.CURRENT_SHELL_APK_VERSION
@@ -296,13 +292,8 @@
      */
     private static @WebApkUpdateReason int needsUpdate(WebApkInfo oldInfo, WebApkInfo fetchedInfo,
             String primaryIconUrl, String badgeIconUrl) {
-        if (isShellApkVersionOutOfDate(oldInfo)) {
-            return WebApkUpdateReason.OLD_SHELL_APK;
-        }
-
-        if (fetchedInfo == null) {
-            return WebApkUpdateReason.NONE;
-        }
+        if (isShellApkVersionOutOfDate(oldInfo)) return WebApkUpdateReason.OLD_SHELL_APK;
+        if (fetchedInfo == null) return WebApkUpdateReason.NONE;
 
         // We should have computed the Murmur2 hashes for the bitmaps at the primary icon URL and
         // the badge icon for {@link fetchedInfo} (but not the other icon URLs.)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
index e6de000..a97d297 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappSplashScreenController.java
@@ -90,11 +90,11 @@
 
         notifySplashscreenVisible();
         mWebappUma.recordSplashscreenBackgroundColor(webappInfo.hasValidBackgroundColor()
-                        ? WebappUma.SPLASHSCREEN_COLOR_STATUS_CUSTOM
-                        : WebappUma.SPLASHSCREEN_COLOR_STATUS_DEFAULT);
+                        ? WebappUma.SplashScreenColorStatus.CUSTOM
+                        : WebappUma.SplashScreenColorStatus.DEFAULT);
         mWebappUma.recordSplashscreenThemeColor(webappInfo.hasValidThemeColor()
-                        ? WebappUma.SPLASHSCREEN_COLOR_STATUS_CUSTOM
-                        : WebappUma.SPLASHSCREEN_COLOR_STATUS_DEFAULT);
+                        ? WebappUma.SplashScreenColorStatus.CUSTOM
+                        : WebappUma.SplashScreenColorStatus.DEFAULT);
 
         WebappDataStorage storage =
                 WebappRegistry.getInstance().getWebappDataStorage(webappInfo.id());
@@ -125,9 +125,7 @@
         mNativeLoaded = true;
         mCompositorViewHolder = compositorViewHolder;
         tab.addObserver(this);
-        if (mInitializedLayout) {
-            mWebappUma.commitMetrics();
-        }
+        if (mInitializedLayout) mWebappUma.commitMetrics();
     }
 
     @VisibleForTesting
@@ -138,28 +136,27 @@
     @Override
     public void didFirstVisuallyNonEmptyPaint(Tab tab) {
         if (canHideSplashScreen()) {
-            hideSplashScreenOnDrawingFinished(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_PAINT);
+            hideSplashScreenOnDrawingFinished(tab, WebappUma.SplashScreenHidesReason.PAINT);
         }
     }
 
     @Override
     public void onPageLoadFinished(Tab tab) {
         if (canHideSplashScreen()) {
-            hideSplashScreenOnDrawingFinished(
-                    tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FINISHED);
+            hideSplashScreenOnDrawingFinished(tab, WebappUma.SplashScreenHidesReason.LOAD_FINISHED);
         }
     }
 
     @Override
     public void onPageLoadFailed(Tab tab, int errorCode) {
         if (canHideSplashScreen()) {
-            animateHidingSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_LOAD_FAILED);
+            animateHidingSplashScreen(tab, WebappUma.SplashScreenHidesReason.LOAD_FAILED);
         }
     }
 
     @Override
     public void onCrash(Tab tab, boolean sadTabShown) {
-        animateHidingSplashScreen(tab, WebappUma.SPLASHSCREEN_HIDES_REASON_CRASH);
+        animateHidingSplashScreen(tab, WebappUma.SplashScreenHidesReason.CRASH);
     }
 
     @Override
@@ -242,7 +239,7 @@
         int layoutId;
         if (displayIcon == null || displayIcon.getWidth() < minimiumSizeThreshold
                 || (displayIcon == webappInfo.icon() && webappInfo.isIconGenerated())) {
-            mWebappUma.recordSplashscreenIconType(WebappUma.SPLASHSCREEN_ICON_TYPE_NONE);
+            mWebappUma.recordSplashscreenIconType(WebappUma.SplashScreenIconType.NONE);
             layoutId = R.layout.webapp_splash_screen_no_icon;
         } else {
             // The size of the splash screen image determines which layout to use.
@@ -255,13 +252,14 @@
             }
 
             // Record stats about the splash screen.
+            @WebappUma.SplashScreenIconType
             int splashScreenIconType;
             if (splashImage == null) {
-                splashScreenIconType = WebappUma.SPLASHSCREEN_ICON_TYPE_FALLBACK;
+                splashScreenIconType = WebappUma.SplashScreenIconType.FALLBACK;
             } else if (isUsingSmallSplashImage) {
-                splashScreenIconType = WebappUma.SPLASHSCREEN_ICON_TYPE_CUSTOM_SMALL;
+                splashScreenIconType = WebappUma.SplashScreenIconType.CUSTOM_SMALL;
             } else {
-                splashScreenIconType = WebappUma.SPLASHSCREEN_ICON_TYPE_CUSTOM;
+                splashScreenIconType = WebappUma.SplashScreenIconType.CUSTOM;
             }
             mWebappUma.recordSplashscreenIconType(splashScreenIconType);
             mWebappUma.recordSplashscreenIconSize(
@@ -283,9 +281,7 @@
                     ApiCompatibilityUtils.getColor(resources, R.color.webapp_splash_title_light));
         }
 
-        if (mNativeLoaded) {
-            mWebappUma.commitMetrics();
-        }
+        if (mNativeLoaded) mWebappUma.commitMetrics();
     }
 
     /**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index da48bc3..78332cd 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1418,7 +1418,6 @@
   "java/src/org/chromium/chrome/browser/util/PlatformUtil.java",
   "java/src/org/chromium/chrome/browser/util/UrlUtilities.java",
   "java/src/org/chromium/chrome/browser/util/ViewUtils.java",
-  "java/src/org/chromium/chrome/browser/vr/CustomTabVrActivity.java",
   "java/src/org/chromium/chrome/browser/vr/VrMainActivity.java",
   "java/src/org/chromium/chrome/browser/vr_shell/EmptySniffingVrViewContainer.java",
   "java/src/org/chromium/chrome/browser/vr_shell/NoopCanvas.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestRule.java
index 0dac3380..cefc96a6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastTestRule.java
@@ -56,7 +56,7 @@
         public void onError(int errorType, String message) {}
 
         @Override
-        public void onPlaybackStateChanged(final PlayerState newState) {
+        public void onPlaybackStateChanged(final @PlayerState int newState) {
             // Use postOnUiThread to handling the latch until the current UI task has completed,
             // this makes sure that Cast has finished handling the event.
             ThreadUtils.postOnUiThread(new Runnable() {
@@ -79,7 +79,7 @@
         public void onTitleChanged(String title) {}
     }
 
-    private Set<PlayerState> mAwaitedStates;
+    private Set<Integer> mAwaitedStates;
     private CountDownLatch mLatch;
     private EmbeddedTestServer mTestServer;
 
@@ -147,7 +147,7 @@
      * Will deadlock if called on the target's UI thread.
      * @param states
      */
-    public boolean waitForStates(final Set<PlayerState> states, int waitTimeMs) {
+    public boolean waitForStates(final Set<Integer> states, int waitTimeMs) {
         mAwaitedStates = states;
         mLatch = new CountDownLatch(1);
         // Deal with the case where Chrome is already in the desired state
@@ -172,8 +172,8 @@
      * Will deadlock if called on the target's UI thread.
      * @param state
      */
-    public boolean waitForState(final PlayerState state, int waitTimeMs) {
-        Set<PlayerState> states = new HashSet<PlayerState>();
+    public boolean waitForState(final @PlayerState int state, int waitTimeMs) {
+        Set<Integer> states = new HashSet<Integer>();
         states.add(state);
         return waitForStates(states, waitTimeMs);
     }
@@ -297,7 +297,7 @@
     }
 
     public void checkDisconnected() {
-        HashSet<PlayerState> disconnectedStates = new HashSet<PlayerState>();
+        HashSet<Integer> disconnectedStates = new HashSet<Integer>();
         disconnectedStates.add(PlayerState.FINISHED);
         disconnectedStates.add(PlayerState.INVALIDATED);
         waitForStates(disconnectedStates, MAX_VIEW_TIME_MS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
index 3c3f2d5..394457a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
@@ -71,7 +71,7 @@
                 OmniboxTestUtils.toggleUrlBarFocus(urlBar, true);
             }
         });
-        assertMainIntentBehavior(MainIntentBehaviorMetrics.FOCUS_OMNIBOX);
+        assertMainIntentBehavior(MainIntentBehaviorMetrics.MainIntentActionType.FOCUS_OMNIBOX);
     }
 
     @MediumTest
@@ -101,7 +101,7 @@
                 TabModelUtils.setIndex(mActivityTestRule.getActivity().getCurrentTabModel(), 1);
             }
         });
-        assertMainIntentBehavior(MainIntentBehaviorMetrics.SWITCH_TABS);
+        assertMainIntentBehavior(MainIntentBehaviorMetrics.MainIntentActionType.SWITCH_TABS);
     }
 
     @MediumTest
@@ -115,7 +115,7 @@
                 mActivityTestRule.getActivity().finish();
             }
         });
-        assertMainIntentBehavior(MainIntentBehaviorMetrics.BACKGROUNDED);
+        assertMainIntentBehavior(MainIntentBehaviorMetrics.MainIntentActionType.BACKGROUNDED);
     }
 
     @MediumTest
@@ -129,7 +129,7 @@
                 mActivityTestRule.getActivity().getTabCreator(false).launchNTP();
             }
         });
-        assertMainIntentBehavior(MainIntentBehaviorMetrics.NTP_CREATED);
+        assertMainIntentBehavior(MainIntentBehaviorMetrics.MainIntentActionType.NTP_CREATED);
     }
 
     @MediumTest
@@ -138,7 +138,7 @@
         try {
             MainIntentBehaviorMetrics.setTimeoutDurationMsForTesting(500);
             startActivity(true);
-            assertMainIntentBehavior(MainIntentBehaviorMetrics.CONTINUATION);
+            assertMainIntentBehavior(MainIntentBehaviorMetrics.MainIntentActionType.CONTINUATION);
         } finally {
             MainIntentBehaviorMetrics.setTimeoutDurationMsForTesting(
                     MainIntentBehaviorMetrics.TIMEOUT_DURATION_MS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrInputTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrInputTest.java
index 77327f8..d5de6ae 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrInputTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrInputTest.java
@@ -4,14 +4,13 @@
 
 package org.chromium.chrome.browser.vr_shell;
 
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.PAGE_LOAD_TIMEOUT_S;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_TIMEOUT_LONG_MS;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_TIMEOUT_SHORT_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.PAGE_LOAD_TIMEOUT_S;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_TIMEOUT_LONG_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_TIMEOUT_SHORT_MS;
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM;
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_NON_DAYDREAM;
 
-import android.app.Activity;
 import android.os.Build;
 import android.os.SystemClock;
 import android.support.test.filters.LargeTest;
@@ -26,7 +25,6 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
@@ -39,9 +37,7 @@
 import org.chromium.base.test.util.Restriction;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.vr_shell.mock.MockVrDaydreamApi;
-import org.chromium.chrome.browser.vr_shell.mock.MockVrIntentHandler;
 import org.chromium.chrome.browser.vr_shell.rules.VrActivityRestriction;
 import org.chromium.chrome.browser.vr_shell.util.TransitionUtils;
 import org.chromium.chrome.browser.vr_shell.util.VrShellDelegateUtils;
@@ -53,15 +49,12 @@
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content_public.browser.ViewEventSink;
-import org.chromium.content_public.browser.WebContents;
 
-import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * End-to-end tests for sending input while using WebVR and WebXR.
@@ -492,79 +485,6 @@
     }
 
     /**
-     * Verifies that pressing the Daydream controller's 'app' button does not cause the user to exit
-     * WebVR presentation if they entered it via a Deep Link intent.
-     */
-    @Test
-    @MediumTest
-    @CommandLineFlags.Add("enable-features=WebVrAutopresentFromIntent")
-    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
-    public void testAppButtonNoopsWhenDeepLinked() throws InterruptedException, ExecutionException {
-        VrIntentUtils.setHandlerInstanceForTesting(new MockVrIntentHandler(
-                true /* useMockImplementation */, true /* treatIntentsAsTrusted */));
-
-        // Send an autopresent intent, which will open the link in a CCT
-        VrTransitionUtils.sendVrLaunchIntent(
-                VrTestFramework.getFileUrlForHtmlTestFile("test_webvr_autopresent"),
-                true /* autopresent */, true /* avoidRelaunch */);
-
-        // Wait until a CCT is opened due to the intent
-        final AtomicReference<CustomTabActivity> cct = new AtomicReference<CustomTabActivity>();
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                List<WeakReference<Activity>> list = ApplicationStatus.getRunningActivities();
-                for (WeakReference<Activity> ref : list) {
-                    Activity activity = ref.get();
-                    if (activity == null) continue;
-                    if (activity instanceof CustomTabActivity) {
-                        cct.set((CustomTabActivity) activity);
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
-
-        // Wait until the tab is ready
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                if (cct.get().getActivityTab() == null) return false;
-                return !cct.get().getActivityTab().isLoading();
-            }
-        }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
-
-        // Wait for autopresent to kick in
-        WebContents wc = cct.get().getActivityTab().getWebContents();
-        VrTestFramework.waitOnJavaScriptStep(wc);
-        Assert.assertTrue("CCT entered presentation",
-                VrTestFramework.pollJavaScriptBoolean(
-                        "vrDisplay.isPresenting", POLL_TIMEOUT_LONG_MS, wc));
-
-        // Verify that pressing the app button does nothing
-        MockVrDaydreamApi mockApi = new MockVrDaydreamApi();
-        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(mockApi);
-
-        EmulatedVrController controller = new EmulatedVrController(cct.get());
-        controller.pressReleaseAppButton();
-        Assert.assertFalse("App button left Chrome",
-                ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
-                    @Override
-                    public Boolean call() throws Exception {
-                        return mockApi.getExitFromVrCalled()
-                                || mockApi.getLaunchVrHomescreenCalled();
-                    }
-                }));
-        Assert.assertFalse("App button exited WebVR presentation",
-                VrTestFramework.pollJavaScriptBoolean(
-                        "!vrDisplay.isPresenting", POLL_TIMEOUT_SHORT_MS, wc));
-
-        VrTestFramework.endTest(wc);
-        VrShellDelegateUtils.getDelegateInstance().overrideDaydreamApiForTesting(null);
-    }
-
-    /**
      * Tests that focus loss updates synchronously.
      */
     @DisabledTest(message = "crbug.com/859666")
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java
index 0cc7372..398fe5f0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java
@@ -5,16 +5,14 @@
 package org.chromium.chrome.browser.vr_shell;
 
 import static org.chromium.chrome.browser.vr_shell.TestFramework.PAGE_LOAD_TIMEOUT_S;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.PAGE_LOAD_TIMEOUT_S;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_CHECK_INTERVAL_LONG_MS;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_TIMEOUT_LONG_MS;
-import static org.chromium.chrome.browser.vr_shell.VrTestFramework.POLL_TIMEOUT_SHORT_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_CHECK_INTERVAL_LONG_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_TIMEOUT_LONG_MS;
+import static org.chromium.chrome.browser.vr_shell.TestFramework.POLL_TIMEOUT_SHORT_MS;
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_DON_ENABLED;
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM;
 
 import android.annotation.TargetApi;
-import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.os.Build;
@@ -31,7 +29,6 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.ApplicationStatus;
 import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
 import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
 import org.chromium.base.test.params.ParameterSet;
@@ -42,8 +39,6 @@
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.customtabs.CustomTabActivity;
-import org.chromium.chrome.browser.vr_shell.mock.MockVrIntentHandler;
 import org.chromium.chrome.browser.vr_shell.rules.VrActivityRestriction;
 import org.chromium.chrome.browser.vr_shell.util.NfcSimUtils;
 import org.chromium.chrome.browser.vr_shell.util.TransitionUtils;
@@ -53,15 +48,12 @@
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.content_public.browser.WebContents;
 
-import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * End-to-end tests for transitioning between WebVR and WebXR's magic window and
@@ -310,55 +302,6 @@
     }
 
     /**
-     * Tests that an intent from a trusted app such as Daydream Home allows WebVR content
-     * to auto present without the need for a user gesture.
-     */
-    @Test
-    @MediumTest
-    @CommandLineFlags.Add("enable-features=WebVrAutopresentFromIntent")
-    @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
-    public void testTrustedIntentAllowsAutoPresent() throws InterruptedException {
-        VrIntentUtils.setHandlerInstanceForTesting(new MockVrIntentHandler(
-                true /* useMockImplementation */, true /* treatIntentsAsTrusted */));
-
-        // Send an autopresent intent, which will open the link in a CCT
-        VrTransitionUtils.sendVrLaunchIntent(
-                VrTestFramework.getFileUrlForHtmlTestFile("test_webvr_autopresent"),
-                true /* autopresent */, true /* avoidRelaunch */);
-
-        // Wait until a CCT is opened due to the intent
-        final AtomicReference<CustomTabActivity> cct = new AtomicReference<CustomTabActivity>();
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                List<WeakReference<Activity>> list = ApplicationStatus.getRunningActivities();
-                for (WeakReference<Activity> ref : list) {
-                    Activity activity = ref.get();
-                    if (activity == null) continue;
-                    if (activity instanceof CustomTabActivity) {
-                        cct.set((CustomTabActivity) activity);
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
-
-        // Wait until the tab is ready
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                if (cct.get().getActivityTab() == null) return false;
-                return !cct.get().getActivityTab().isLoading();
-            }
-        }, POLL_TIMEOUT_LONG_MS, POLL_CHECK_INTERVAL_SHORT_MS);
-
-        WebContents wc = cct.get().getActivityTab().getWebContents();
-        VrTestFramework.waitOnJavaScriptStep(wc);
-        VrTestFramework.endTest(wc);
-    }
-
-    /**
      * Tests that the omnibox reappears after exiting VR.
      */
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java
deleted file mode 100644
index a87dae8..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/mock/MockVrIntentHandler.java
+++ /dev/null
@@ -1,43 +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.
-
-package org.chromium.chrome.browser.vr_shell.mock;
-
-import android.content.Intent;
-
-import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
-
-/**
- * Mock version of VrIntentHandler for testing.
- */
-public class MockVrIntentHandler implements VrIntentUtils.VrIntentHandler {
-    private boolean mUseMockImplementation;
-    private boolean mTreatIntentsAsTrusted;
-
-    public MockVrIntentHandler(boolean useMockImplementation, boolean treatIntentsAsTrusted) {
-        mUseMockImplementation = useMockImplementation;
-        mTreatIntentsAsTrusted = treatIntentsAsTrusted;
-    }
-
-    @Override
-    public boolean isTrustedDaydreamIntent(Intent intent) {
-        if (mUseMockImplementation) {
-            return mTreatIntentsAsTrusted;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isTrustedAutopresentIntent(Intent intent) {
-        return false;
-    }
-
-    public void setUseMockImplementation(boolean enabled) {
-        mUseMockImplementation = enabled;
-    }
-
-    public void setTreatIntentsAsTrusted(boolean trusted) {
-        mTreatIntentsAsTrusted = trusted;
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenBackgroundColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenBackgroundColorTest.java
index a9ea450..31a6a46 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenBackgroundColorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenBackgroundColorTest.java
@@ -48,6 +48,6 @@
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_CUSTOM));
+                        WebappUma.SplashScreenColorStatus.CUSTOM));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenHomescreenIconTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenHomescreenIconTest.java
index 4c57428..bebcc4af 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenHomescreenIconTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenHomescreenIconTest.java
@@ -62,7 +62,7 @@
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                        WebappUma.SPLASHSCREEN_ICON_TYPE_FALLBACK));
+                        WebappUma.SplashScreenIconType.FALLBACK));
 
         Bitmap icon = ShortcutHelper.decodeBitmapFromString(WebappActivityTestRule.TEST_ICON);
         int sizeInDp = Math.round((float) icon.getWidth()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenIconTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenIconTest.java
index d401e77..a0d224b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenIconTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenIconTest.java
@@ -65,7 +65,7 @@
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                        WebappUma.SPLASHSCREEN_ICON_TYPE_CUSTOM));
+                        WebappUma.SplashScreenIconType.CUSTOM));
 
         Bitmap icon =
                 ShortcutHelper.decodeBitmapFromString(WebappActivityTestRule.TEST_SPLASH_ICON);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java
index d8fe2c7..42c265f7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java
@@ -191,26 +191,26 @@
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_DEFAULT));
+                        WebappUma.SplashScreenColorStatus.DEFAULT));
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_DEFAULT));
+                        WebappUma.SplashScreenColorStatus.DEFAULT));
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                        WebappUma.SPLASHSCREEN_ICON_TYPE_NONE));
+                        WebappUma.SplashScreenIconType.NONE));
 
         // Tests UMA counts.
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_MAX));
+                        WebappUma.SplashScreenColorStatus.NUM_ENTRIES));
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_MAX));
+                        WebappUma.SplashScreenColorStatus.NUM_ENTRIES));
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                        WebappUma.SPLASHSCREEN_ICON_TYPE_MAX));
+                        WebappUma.SplashScreenIconType.NUM_ENTRIES));
 
         // Given that there is no icon, the ICON_SIZE UMA should not be recorded.
         Assert.assertEquals(
@@ -220,7 +220,7 @@
         Assert.assertFalse(hasHistogramEntry(WebappUma.HISTOGRAM_SPLASHSCREEN_DURATION, 3000));
         Assert.assertEquals(0,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_HIDES,
-                        WebappUma.SPLASHSCREEN_HIDES_REASON_MAX));
+                        WebappUma.SplashScreenHidesReason.NUM_ENTRIES));
     }
 
     @Test
@@ -242,18 +242,18 @@
         Assert.assertTrue(hasHistogramEntry(WebappUma.HISTOGRAM_SPLASHSCREEN_DURATION, 10000));
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_HIDES,
-                        WebappUma.SPLASHSCREEN_HIDES_REASON_MAX));
+                        WebappUma.SplashScreenHidesReason.NUM_ENTRIES));
 
         // The other UMA records should not have changed.
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_BACKGROUNDCOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_MAX));
+                        WebappUma.SplashScreenColorStatus.NUM_ENTRIES));
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_MAX));
+                        WebappUma.SplashScreenColorStatus.NUM_ENTRIES));
         Assert.assertEquals(1,
                 getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_TYPE,
-                        WebappUma.SPLASHSCREEN_ICON_TYPE_MAX));
+                        WebappUma.SplashScreenIconType.NUM_ENTRIES));
         Assert.assertEquals(
                 0, getHistogramTotalCountFor(WebappUma.HISTOGRAM_SPLASHSCREEN_ICON_SIZE, 50));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java
index a6fdb29..004c732 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java
@@ -91,6 +91,6 @@
         Assert.assertEquals(1,
                 RecordHistogram.getHistogramValueCountForTesting(
                         WebappUma.HISTOGRAM_SPLASHSCREEN_THEMECOLOR,
-                        WebappUma.SPLASHSCREEN_COLOR_STATUS_CUSTOM));
+                        WebappUma.SplashScreenColorStatus.CUSTOM));
     }
 }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 72fa157..f34c102 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -4231,7 +4231,7 @@
     Unlock
   </message>
   <message name="IDS_AD_UNLOCK_CONFIG_PASSWORD" desc="Admin-facing. Label for unlocking password input field on the Active Directory domain join screen.">
-    Unlocking password
+    Password to unlock
   </message>
   <message name="IDS_AD_UNLOCK_INCORRECT_PASSWORD" desc="Admin-facing. Error that is shown when incorrect unlocking password was entered.">
     Incorrect password
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 138c5237..f4a3344e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -288,8 +288,6 @@
     "component_updater/crl_set_component_installer.h",
     "component_updater/file_type_policies_component_installer.cc",
     "component_updater/file_type_policies_component_installer.h",
-    "component_updater/intervention_policy_database_component_installer.cc",
-    "component_updater/intervention_policy_database_component_installer.h",
     "component_updater/mei_preload_component_installer.cc",
     "component_updater/mei_preload_component_installer.h",
     "component_updater/optimization_hints_component_installer.cc",
@@ -2484,6 +2482,8 @@
       "chrome_browser_field_trials_desktop.h",
       "chrome_process_singleton.cc",
       "chrome_process_singleton.h",
+      "component_updater/intervention_policy_database_component_installer.cc",
+      "component_updater/intervention_policy_database_component_installer.h",
       "custom_handlers/register_protocol_handler_permission_request.cc",
       "custom_handlers/register_protocol_handler_permission_request.h",
       "diagnostics/diagnostics_controller.cc",
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
index 213623b9..6978405 100644
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -528,7 +528,7 @@
   scoped_refptr<MediaStreamCaptureIndicator> indicator =
       MediaCaptureDevicesDispatcher::GetInstance()
           ->GetMediaStreamCaptureIndicator();
-  return indicator->IsBeingMirrored(web_contents);
+  return indicator->IsCapturingDesktop(web_contents);
 }
 
 void JNI_TabWebContentsDelegateAndroid_NotifyStopped(
diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc
index d5a3c30..8aa5e00 100644
--- a/chrome/browser/android/vr/vr_gl_thread.cc
+++ b/chrome/browser/android/vr/vr_gl_thread.cc
@@ -61,33 +61,25 @@
 }
 
 void VrGLThread::Init() {
-  bool keyboard_enabled =
-      !ui_initial_state_.web_vr_autopresentation_expected;
-  if (keyboard_enabled) {
-    keyboard_delegate_ = GvrKeyboardDelegate::Create();
-    text_input_delegate_ = std::make_unique<TextInputDelegate>();
-  }
-  auto* keyboard_delegate =
-      !keyboard_delegate_ ? nullptr : keyboard_delegate_.get();
-  if (!keyboard_delegate)
+  keyboard_delegate_ = GvrKeyboardDelegate::Create();
+  text_input_delegate_ = std::make_unique<TextInputDelegate>();
+  if (!keyboard_delegate_.get())
     ui_initial_state_.needs_keyboard_update = true;
 
   audio_delegate_ = std::make_unique<SoundsManagerAudioDelegate>();
 
-  auto ui = std::make_unique<Ui>(this, this, keyboard_delegate,
+  auto ui = std::make_unique<Ui>(this, this, keyboard_delegate_.get(),
                                  text_input_delegate_.get(),
                                  audio_delegate_.get(), ui_initial_state_);
-  if (keyboard_enabled) {
-    text_input_delegate_->SetRequestFocusCallback(
-        base::BindRepeating(&Ui::RequestFocus, base::Unretained(ui.get())));
-    text_input_delegate_->SetRequestUnfocusCallback(
-        base::BindRepeating(&Ui::RequestUnfocus, base::Unretained(ui.get())));
-    if (keyboard_delegate) {
-      keyboard_delegate_->SetUiInterface(ui.get());
-      text_input_delegate_->SetUpdateInputCallback(
-          base::BindRepeating(&GvrKeyboardDelegate::UpdateInput,
-                              base::Unretained(keyboard_delegate_.get())));
-    }
+  text_input_delegate_->SetRequestFocusCallback(
+      base::BindRepeating(&Ui::RequestFocus, base::Unretained(ui.get())));
+  text_input_delegate_->SetRequestUnfocusCallback(
+      base::BindRepeating(&Ui::RequestUnfocus, base::Unretained(ui.get())));
+  if (keyboard_delegate_.get()) {
+    keyboard_delegate_->SetUiInterface(ui.get());
+    text_input_delegate_->SetUpdateInputCallback(
+        base::BindRepeating(&GvrKeyboardDelegate::UpdateInput,
+                            base::Unretained(keyboard_delegate_.get())));
   }
 
   vr_shell_gl_ = std::make_unique<VrShellGl>(
diff --git a/chrome/browser/android/vr/vr_gl_thread.h b/chrome/browser/android/vr/vr_gl_thread.h
index 4dc2f7fc..b7faebd1 100644
--- a/chrome/browser/android/vr/vr_gl_thread.h
+++ b/chrome/browser/android/vr/vr_gl_thread.h
@@ -171,7 +171,7 @@
   // Both VrInputConnection and VrGlThread are owned by VrShell. In VrShell, we
   // made sure that this input_connection_ is up to date and destroyed after
   // VrGlThread. So it is safe to use raw pointer here.
-  VrInputConnection* input_connection_;
+  VrInputConnection* input_connection_ = nullptr;
 
   // This state is used for initializing vr_shell_gl_.
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc
index 18dbc2c..44e90db 100644
--- a/chrome/browser/android/vr/vr_shell.cc
+++ b/chrome/browser/android/vr/vr_shell.cc
@@ -1335,7 +1335,6 @@
                            const JavaParamRef<jobject>& obj,
                            const JavaParamRef<jobject>& delegate,
                            jboolean for_web_vr,
-                           jboolean web_vr_autopresentation_expected,
                            jboolean in_cct,
                            jboolean browsing_disabled,
                            jboolean has_or_can_request_audio_permission,
@@ -1352,8 +1351,6 @@
   ui_initial_state.browsing_disabled = browsing_disabled;
   ui_initial_state.in_cct = in_cct;
   ui_initial_state.in_web_vr = for_web_vr;
-  ui_initial_state.web_vr_autopresentation_expected =
-      web_vr_autopresentation_expected;
   ui_initial_state.has_or_can_request_audio_permission =
       has_or_can_request_audio_permission;
   ui_initial_state.skips_redraw_when_not_dirty =
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc
index 8a78653..374729f 100644
--- a/chrome/browser/android/vr/vr_shell_gl.cc
+++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -2050,7 +2050,7 @@
 
 void VrShellGl::DrawContentQuad(bool draw_overlay_texture) {
   // Add a 2 pixel border to avoid aliasing issues at the edge of the texture.
-  constexpr float kBorder = 2;
+  constexpr float kBorder = 10;
   TRACE_EVENT0("gpu", "VrShellGl::DrawContentQuad");
   // Don't need face culling, depth testing, blending, etc. Turn it all off.
   glDisable(GL_CULL_FACE);
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 682d3e1..513ce73 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -95,7 +95,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/resource_coordinator/render_process_probe.h"
-#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/sessions/chrome_serialized_navigation_driver.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/tracing/background_tracing_field_trial.h"
@@ -307,6 +306,11 @@
 #endif
 #include "services/service_manager/public/cpp/connector.h"
 
+#if !defined(OS_ANDROID)
+#include "chrome/browser/component_updater/intervention_policy_database_component_installer.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
+#endif
+
 using content::BrowserThread;
 
 namespace {
@@ -594,6 +598,11 @@
   RegisterThirdPartyModuleListComponent(cus);
 #endif  // defined(GOOGLE_CHROME_BUILD)
 #endif  // defined(OS_WIN)
+
+#if !defined(OS_ANDROID)
+  RegisterInterventionPolicyDatabaseComponent(
+      cus, g_browser_process->GetTabManager()->intervention_policy_database());
+#endif
 }
 
 #if !defined(OS_ANDROID)
@@ -1434,9 +1443,9 @@
   for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
     chrome_extra_parts_[i]->PreBrowserStart();
 
-// Start the tab manager here so that we give the most amount of time for the
-// other services to start up before we start adjusting the oom priority.
-#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
+#if !defined(OS_ANDROID)
+  // Start the tab manager here so that we give the most amount of time for the
+  // other services to start up before we start adjusting the oom priority.
   g_browser_process->GetTabManager()->Start();
 #endif
 
diff --git a/chrome/browser/component_updater/intervention_policy_database_component_installer.cc b/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
index 1ffe42c1..1da07b90 100644
--- a/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
+++ b/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
@@ -10,6 +10,7 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
+#include "chrome/browser/resource_coordinator/intervention_policy_database.h"
 #include "components/component_updater/component_updater_paths.h"
 #include "components/component_updater/component_updater_service.h"
 #include "components/crx_file/id_util.h"
@@ -37,6 +38,13 @@
 
 namespace component_updater {
 
+InterventionPolicyDatabaseComponentInstallerPolicy::
+    InterventionPolicyDatabaseComponentInstallerPolicy(
+        resource_coordinator::InterventionPolicyDatabase* database)
+    : database_(database) {
+  DCHECK(database_);
+}
+
 bool InterventionPolicyDatabaseComponentInstallerPolicy::
     SupportsGroupPolicyEnabledComponentUpdates() const {
   return false;
@@ -72,7 +80,10 @@
     const base::Version& version,
     const base::FilePath& install_dir,
     std::unique_ptr<base::DictionaryValue> manifest) {
-  // TODO(sebmarchand): Implement this.
+  DCHECK(database_);
+  database_->InitializeDatabaseWithProtoFile(
+      install_dir.Append(kInterventionPolicyDatabaseBinaryPbFileName), version,
+      std::move(manifest));
 }
 
 base::FilePath
@@ -104,9 +115,11 @@
   return std::vector<std::string>();
 }
 
-void RegisterInterventionPolicyDatabaseComponent(ComponentUpdateService* cus) {
+void RegisterInterventionPolicyDatabaseComponent(
+    ComponentUpdateService* cus,
+    resource_coordinator::InterventionPolicyDatabase* database) {
   std::unique_ptr<ComponentInstallerPolicy> policy(
-      new InterventionPolicyDatabaseComponentInstallerPolicy());
+      new InterventionPolicyDatabaseComponentInstallerPolicy(database));
   auto installer = base::MakeRefCounted<ComponentInstaller>(std::move(policy));
   installer->Register(cus, base::OnceClosure());
 }
diff --git a/chrome/browser/component_updater/intervention_policy_database_component_installer.h b/chrome/browser/component_updater/intervention_policy_database_component_installer.h
index 42279d1..1abe36d 100644
--- a/chrome/browser/component_updater/intervention_policy_database_component_installer.h
+++ b/chrome/browser/component_updater/intervention_policy_database_component_installer.h
@@ -7,6 +7,10 @@
 
 #include "components/component_updater/component_installer.h"
 
+namespace resource_coordinator {
+class InterventionPolicyDatabase;
+}
+
 namespace component_updater {
 
 class ComponentUpdateService;
@@ -17,7 +21,8 @@
 class InterventionPolicyDatabaseComponentInstallerPolicy
     : public ComponentInstallerPolicy {
  public:
-  InterventionPolicyDatabaseComponentInstallerPolicy() = default;
+  InterventionPolicyDatabaseComponentInstallerPolicy(
+      resource_coordinator::InterventionPolicyDatabase* database);
   ~InterventionPolicyDatabaseComponentInstallerPolicy() override = default;
 
  private:
@@ -39,12 +44,16 @@
   update_client::InstallerAttributes GetInstallerAttributes() const override;
   std::vector<std::string> GetMimeTypes() const override;
 
+  resource_coordinator::InterventionPolicyDatabase* database_;
+
   DISALLOW_COPY_AND_ASSIGN(InterventionPolicyDatabaseComponentInstallerPolicy);
 };
 
 // Call once to make the component update service aware of the Intervention
 // Policy Database component.
-void RegisterInterventionPolicyDatabaseComponent(ComponentUpdateService* cus);
+void RegisterInterventionPolicyDatabaseComponent(
+    ComponentUpdateService* cus,
+    resource_coordinator::InterventionPolicyDatabase* database);
 
 }  // namespace component_updater
 
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
index 7f8fb25..6b5dc75 100644
--- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -244,9 +244,12 @@
   EXPECT_CALL(*service, AddObserver(testing::_)).Times(testing::AnyNumber());
   EXPECT_CALL(*service, RemoveObserver(testing::_)).Times(testing::AnyNumber());
 
-  browser_ = new Browser(Browser::CreateParams(profile, true));
-
+  // Note: ProfileSyncService::Initialize must be called ASAP after constructing
+  // the object. In particular, creating the Browser below calls into
+  // ProfileSyncService which is illegal before Initialize() has been called.
   service->Initialize();
+
+  browser_ = new Browser(Browser::CreateParams(profile, true));
 }
 
 void ExtensionSessionsTest::CreateTestExtension() {
diff --git a/chrome/browser/memory/chrome_memory_coordinator_delegate.cc b/chrome/browser/memory/chrome_memory_coordinator_delegate.cc
index 11d8577..12f431f5 100644
--- a/chrome/browser/memory/chrome_memory_coordinator_delegate.cc
+++ b/chrome/browser/memory/chrome_memory_coordinator_delegate.cc
@@ -5,9 +5,13 @@
 #include "chrome/browser/memory/chrome_memory_coordinator_delegate.h"
 
 #include "base/memory/ptr_util.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/resource_coordinator/discard_reason.h"
+
+#if !defined(OS_ANDROID)
 #include "chrome/browser/resource_coordinator/tab_manager.h"
+#endif
 
 namespace memory {
 
diff --git a/chrome/browser/policy/policy_conversions.cc b/chrome/browser/policy/policy_conversions.cc
index c47e6b3..b7a3ca4 100644
--- a/chrome/browser/policy/policy_conversions.cc
+++ b/chrome/browser/policy/policy_conversions.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/policy/profile_policy_connector_factory.h"
 #include "chrome/browser/policy/schema_registry_service.h"
 #include "chrome/browser/policy/schema_registry_service_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/core/common/policy_details.h"
@@ -200,6 +201,8 @@
   if (!context)
     return std::make_unique<base::DictionaryValue>(std::move(all_policies));
 
+  context = chrome::GetBrowserContextRedirectedInIncognito(context);
+
   // Add Chrome policy values.
   auto chrome_policies = std::make_unique<base::DictionaryValue>();
   GetChromePolicyValues(context, chrome_policies.get(), with_user_policies,
diff --git a/chrome/browser/printing/cloud_print/OWNERS b/chrome/browser/printing/cloud_print/OWNERS
index 3a21c291..3b8d2d0 100644
--- a/chrome/browser/printing/cloud_print/OWNERS
+++ b/chrome/browser/printing/cloud_print/OWNERS
@@ -1,5 +1,3 @@
-gene@chromium.org
-scottbyer@chromium.org
-vitalybuka@chromium.org
+file://cloud_print/OWNERS
 
 # COMPONENT: Services>CloudPrint
diff --git a/chrome/browser/profiles/profile_list_desktop_browsertest.cc b/chrome/browser/profiles/profile_list_desktop_browsertest.cc
index 4ebba83..388f58d 100644
--- a/chrome/browser/profiles/profile_list_desktop_browsertest.cc
+++ b/chrome/browser/profiles/profile_list_desktop_browsertest.cc
@@ -21,6 +21,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
 
 namespace {
@@ -86,6 +87,10 @@
       chrome::NOTIFICATION_BROWSER_CLOSED,
       content::Source<Browser>(browser()));
 
+  content::WindowedNotificationObserver system_profile_created_observer(
+      chrome::NOTIFICATION_PROFILE_CREATED,
+      content::NotificationService::AllSources());
+
   EXPECT_FALSE(entry->IsSigninRequired());
   profiles::LockProfile(current_profile);
   window_close_observer.Wait();  // rely on test time-out for failure indication
@@ -94,6 +99,9 @@
   EXPECT_EQ(0u, browser_list->size());
 
   // Signing out brings up the User Manager which we should close before exit.
+  // But the User Manager is shown only when the system profile is created,
+  // which happens asynchronously.
+  system_profile_created_observer.Wait();
   UserManager::Hide();
 }
 
diff --git a/chrome/browser/resource_coordinator/intervention_policy_database.cc b/chrome/browser/resource_coordinator/intervention_policy_database.cc
index 57e6635..3e43def5 100644
--- a/chrome/browser/resource_coordinator/intervention_policy_database.cc
+++ b/chrome/browser/resource_coordinator/intervention_policy_database.cc
@@ -6,6 +6,8 @@
 
 #include "base/files/file_util.h"
 #include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/values.h"
 #include "chrome/browser/resource_coordinator/utils.h"
 
 namespace resource_coordinator {
@@ -37,9 +39,14 @@
 }
 
 void InterventionPolicyDatabase::InitializeDatabaseWithProtoFile(
-    const base::FilePath& proto_location) {
-  base::PostTaskAndReplyWithResult(
-      background_task_runner_.get(), FROM_HERE,
+    const base::FilePath& proto_location,
+    const base::Version& version,
+    std::unique_ptr<base::DictionaryValue> manifest) {
+  // TODO(sebmarchand): Validate the version and the manifest?
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      {base::TaskPriority::BACKGROUND,
+       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()},
       base::BindOnce(
           &InterventionPolicyDatabase::ReadDatabaseFromProtoFileOnSequence,
           proto_location),
diff --git a/chrome/browser/resource_coordinator/intervention_policy_database.h b/chrome/browser/resource_coordinator/intervention_policy_database.h
index 3295250a..5558fde1 100644
--- a/chrome/browser/resource_coordinator/intervention_policy_database.h
+++ b/chrome/browser/resource_coordinator/intervention_policy_database.h
@@ -9,10 +9,14 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/task_scheduler/post_task.h"
+#include "base/version.h"
 #include "chrome/browser/resource_coordinator/intervention_policy_database.pb.h"
 #include "url/origin.h"
 
+namespace base {
+class DictionaryValue;
+}
+
 namespace resource_coordinator {
 
 // Intervention policy database, this should receive data from the
@@ -41,7 +45,10 @@
 
   // Initialize the database with the OriginInterventionsDatabase protobuf
   // stored in |proto_location|.
-  void InitializeDatabaseWithProtoFile(const base::FilePath& proto_location);
+  void InitializeDatabaseWithProtoFile(
+      const base::FilePath& proto_location,
+      const base::Version& version,
+      std::unique_ptr<base::DictionaryValue> manifest);
 
  protected:
   // Map that associates the MD5 hash of an origin to its polices.
@@ -65,12 +72,6 @@
   // The map that stores all the per-origin intervention policies.
   InterventionsMap database_;
 
-  // Used to run all the blocking operations asynchronously.
-  const scoped_refptr<base::SequencedTaskRunner> background_task_runner_ =
-      base::CreateSequencedTaskRunnerWithTraits(
-          {base::TaskPriority::BACKGROUND,
-           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()});
-
   base::WeakPtrFactory<InterventionPolicyDatabase> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(InterventionPolicyDatabase);
diff --git a/chrome/browser/resource_coordinator/intervention_policy_database_unittest.cc b/chrome/browser/resource_coordinator/intervention_policy_database_unittest.cc
index 500ef499..4de7d63 100644
--- a/chrome/browser/resource_coordinator/intervention_policy_database_unittest.cc
+++ b/chrome/browser/resource_coordinator/intervention_policy_database_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
+#include "base/values.h"
 #include "chrome/browser/resource_coordinator/intervention_policy_database.pb.h"
 #include "chrome/browser/resource_coordinator/utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -88,7 +89,8 @@
                                                 OriginInterventions::DEFAULT));
   WriteProtoToFile(proto_path, policy_map);
 
-  GetDatabase()->InitializeDatabaseWithProtoFile(proto_path);
+  GetDatabase()->InitializeDatabaseWithProtoFile(proto_path, base::Version(),
+                                                 nullptr);
 
   WaitForDatabaseToBeInitialized();
 
diff --git a/chrome/browser/resource_coordinator/tab_helper.cc b/chrome/browser/resource_coordinator/tab_helper.cc
index 158e5605..39b3707 100644
--- a/chrome/browser/resource_coordinator/tab_helper.cc
+++ b/chrome/browser/resource_coordinator/tab_helper.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/resource_coordinator/page_signal_receiver.h"
 #include "chrome/browser/resource_coordinator/tab_load_tracker.h"
-#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/resource_coordinator/tab_memory_metrics_reporter.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
@@ -29,6 +28,7 @@
 
 #if !defined(OS_ANDROID)
 #include "chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #endif
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index 7127975f..506003a6 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -188,6 +188,7 @@
   proactive_freeze_discard_params_ =
       GetStaticProactiveTabFreezeAndDiscardParams();
   TabLoadTracker::Get()->AddObserver(this);
+  intervention_policy_database_.reset(new InterventionPolicyDatabase());
 }
 
 TabManager::~TabManager() {
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h
index 8262426c..8208320 100644
--- a/chrome/browser/resource_coordinator/tab_manager.h
+++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -20,6 +20,7 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "chrome/browser/resource_coordinator/discard_reason.h"
+#include "chrome/browser/resource_coordinator/intervention_policy_database.h"
 #include "chrome/browser/resource_coordinator/lifecycle_unit.h"
 #include "chrome/browser/resource_coordinator/lifecycle_unit_observer.h"
 #include "chrome/browser/resource_coordinator/lifecycle_unit_source_observer.h"
@@ -179,6 +180,10 @@
   // non-zero only during session restore.
   int restored_tab_count() const;
 
+  InterventionPolicyDatabase* intervention_policy_database() {
+    return intervention_policy_database_.get();
+  }
+
  private:
   friend class TabManagerStatsCollectorTest;
   friend class TabManagerWithProactiveDiscardExperimentEnabledTest;
@@ -498,6 +503,10 @@
   // session restore.
   std::unique_ptr<TabManagerStatsCollector> stats_collector_;
 
+  // The intervention policy database, should be initialized by
+  // InterventionPolicyDatabaseComponentInstallerPolicy.
+  std::unique_ptr<InterventionPolicyDatabase> intervention_policy_database_;
+
   // Weak pointer factory used for posting delayed tasks.
   base::WeakPtrFactory<TabManager> weak_ptr_factory_;
 
diff --git a/chrome/browser/service_process/OWNERS b/chrome/browser/service_process/OWNERS
index 3a21c291..3b8d2d0 100644
--- a/chrome/browser/service_process/OWNERS
+++ b/chrome/browser/service_process/OWNERS
@@ -1,5 +1,3 @@
-gene@chromium.org
-scottbyer@chromium.org
-vitalybuka@chromium.org
+file://cloud_print/OWNERS
 
 # COMPONENT: Services>CloudPrint
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc
index 5d5ac25e..5755bf8 100644
--- a/chrome/browser/signin/account_consistency_mode_manager.cc
+++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -120,30 +120,35 @@
 }
 
 AccountConsistencyModeManager::AccountConsistencyModeManager(Profile* profile)
-    : profile_(profile) {
+    : profile_(profile),
+      account_consistency_(signin::AccountConsistencyMethod::kDisabled),
+      account_consistency_initialized_(false) {
   DCHECK(profile_);
   DCHECK(!profile_->IsOffTheRecord());
+  account_consistency_ = ComputeAccountConsistencyMethod(profile_);
+
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
-  bool is_ready_for_dice = IsReadyForDiceMigration();
-  AccountConsistencyMethod account_consistency = GetAccountConsistencyMethod();
+  bool is_ready_for_dice = IsReadyForDiceMigration(profile_);
   if (is_ready_for_dice &&
       signin::DiceMethodGreaterOrEqual(
-          account_consistency, AccountConsistencyMethod::kDiceMigration)) {
-    if (account_consistency != AccountConsistencyMethod::kDice)
+          account_consistency_, AccountConsistencyMethod::kDiceMigration)) {
+    if (account_consistency_ != AccountConsistencyMethod::kDice)
       VLOG(1) << "Profile is migrating to Dice";
     profile_->GetPrefs()->SetBoolean(kDiceMigrationCompletePref, true);
-    account_consistency = GetAccountConsistencyMethod();
-    DCHECK_EQ(AccountConsistencyMethod::kDice, account_consistency);
+    account_consistency_ = AccountConsistencyMethod::kDice;
   }
   UMA_HISTOGRAM_ENUMERATION(
       kDiceMigrationStatusHistogram,
-      account_consistency == AccountConsistencyMethod::kDice
+      account_consistency_ == AccountConsistencyMethod::kDice
           ? DiceMigrationStatus::kEnabled
           : (is_ready_for_dice
                  ? DiceMigrationStatus::kDisabledReadyForMigration
                  : DiceMigrationStatus::kDisabledNotReadyForMigration),
       DiceMigrationStatus::kDiceMigrationStatusCount);
 #endif
+
+  DCHECK_EQ(account_consistency_, ComputeAccountConsistencyMethod(profile_));
+  account_consistency_initialized_ = true;
 }
 
 AccountConsistencyModeManager::~AccountConsistencyModeManager() {}
@@ -190,11 +195,11 @@
   prefs->SetBoolean(kDiceMigrationOnStartupPref, migrate);
 }
 
-bool AccountConsistencyModeManager::IsReadyForDiceMigration() {
-  return (profile_->GetProfileType() ==
-          Profile::ProfileType::REGULAR_PROFILE) &&
-         (profile_->IsNewProfile() ||
-          profile_->GetPrefs()->GetBoolean(kDiceMigrationOnStartupPref));
+// static
+bool AccountConsistencyModeManager::IsReadyForDiceMigration(Profile* profile) {
+  return (profile->GetProfileType() == Profile::ProfileType::REGULAR_PROFILE) &&
+         (profile->IsNewProfile() ||
+          profile->GetPrefs()->GetBoolean(kDiceMigrationOnStartupPref));
 }
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
@@ -211,8 +216,26 @@
 
 AccountConsistencyMethod
 AccountConsistencyModeManager::GetAccountConsistencyMethod() {
-  if (profile_->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE) {
-    DCHECK_EQ(Profile::ProfileType::GUEST_PROFILE, profile_->GetProfileType());
+#if defined(OS_CHROMEOS)
+  // TODO(https://crbug.com/860671): ChromeOS should use the cached value.
+  // Changing the value dynamically is not supported.
+  return ComputeAccountConsistencyMethod(profile_);
+#else
+  // The account consistency method should not change during the lifetime of a
+  // profile. We always return the cached value, but still check that it did not
+  // change, in order to detect inconsisent states. See https://crbug.com/860471
+  CHECK(account_consistency_initialized_);
+  CHECK_EQ(ComputeAccountConsistencyMethod(profile_), account_consistency_);
+  return account_consistency_;
+#endif
+}
+
+// static
+signin::AccountConsistencyMethod
+AccountConsistencyModeManager::ComputeAccountConsistencyMethod(
+    Profile* profile) {
+  if (profile->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE) {
+    DCHECK_EQ(Profile::ProfileType::GUEST_PROFILE, profile->GetProfileType());
     return GetMethodForNonRegularProfile();
   }
 
@@ -225,7 +248,7 @@
 
 #if defined(OS_CHROMEOS)
   return (method_value == kAccountConsistencyFeatureMethodMirror ||
-          profile_->GetPrefs()->GetBoolean(
+          profile->GetPrefs()->GetBoolean(
               prefs::kAccountConsistencyMirrorRequired))
              ? AccountConsistencyMethod::kMirror
              : AccountConsistencyMethod::kDisabled;
@@ -258,7 +281,7 @@
   // Legacy supervised users cannot get Dice.
   // TODO(droger): remove this once legacy supervised users are no longer
   // supported.
-  if (profile_->IsLegacySupervised())
+  if (profile->IsLegacySupervised())
     return AccountConsistencyMethod::kDiceFixAuthErrors;
 
   bool can_enable_dice_for_build = ignore_missing_oauth_client_for_testing_ ||
@@ -270,7 +293,7 @@
   }
 
   if (method == AccountConsistencyMethod::kDiceMigration &&
-      profile_->GetPrefs()->GetBoolean(kDiceMigrationCompletePref)) {
+      profile->GetPrefs()->GetBoolean(kDiceMigrationCompletePref)) {
     return AccountConsistencyMethod::kDice;
   }
 
diff --git a/chrome/browser/signin/account_consistency_mode_manager.h b/chrome/browser/signin/account_consistency_mode_manager.h
index 91a771e..d0ecab3c 100644
--- a/chrome/browser/signin/account_consistency_mode_manager.h
+++ b/chrome/browser/signin/account_consistency_mode_manager.h
@@ -81,13 +81,21 @@
   static void SetDiceMigrationOnStartup(PrefService* prefs, bool migrate);
 
   // Returns true if migration can happen on the next startup.
-  bool IsReadyForDiceMigration();
+  static bool IsReadyForDiceMigration(Profile* profile);
 #endif
 
   // Returns the account consistency method for the current profile.
   signin::AccountConsistencyMethod GetAccountConsistencyMethod();
 
+  // Computes the account consistency method for the current profile. This is
+  // only called from the constructor, the account consistency method cannot
+  // change during the lifetime of a profile.
+  static signin::AccountConsistencyMethod ComputeAccountConsistencyMethod(
+      Profile* profile);
+
   Profile* profile_;
+  signin::AccountConsistencyMethod account_consistency_;
+  bool account_consistency_initialized_;
 
   // By default, DICE is not enabled in builds lacking an API key. Set to true
   // for tests.
diff --git a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc
index 89bdd9c..3edfdd39 100644
--- a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc
+++ b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc
@@ -91,7 +91,7 @@
     // Migration does not happen if SetDiceMigrationOnStartup() is not called.
     ScopedAccountConsistencyDiceMigration scoped_dice_migration;
     AccountConsistencyModeManager manager(&profile);
-    EXPECT_FALSE(manager.IsReadyForDiceMigration());
+    EXPECT_FALSE(manager.IsReadyForDiceMigration(&profile));
     EXPECT_NE(signin::AccountConsistencyMethod::kDice,
               manager.GetAccountConsistencyMethod());
   }
@@ -103,7 +103,7 @@
     // Migration does not happen if Dice is not enabled.
     ScopedAccountConsistencyDiceFixAuthErrors scoped_dice_fix_errors;
     AccountConsistencyModeManager manager(&profile);
-    EXPECT_TRUE(manager.IsReadyForDiceMigration());
+    EXPECT_TRUE(manager.IsReadyForDiceMigration(&profile));
     EXPECT_NE(signin::AccountConsistencyMethod::kDice,
               manager.GetAccountConsistencyMethod());
   }
@@ -112,7 +112,7 @@
     // Migration happens.
     ScopedAccountConsistencyDiceMigration scoped_dice_migration;
     AccountConsistencyModeManager manager(&profile);
-    EXPECT_TRUE(manager.IsReadyForDiceMigration());
+    EXPECT_TRUE(manager.IsReadyForDiceMigration(&profile));
     EXPECT_EQ(signin::AccountConsistencyMethod::kDice,
               manager.GetAccountConsistencyMethod());
   }
diff --git a/chrome/browser/sync/test/integration/single_client_user_consents_sync_test.cc b/chrome/browser/sync/test/integration/single_client_user_consents_sync_test.cc
new file mode 100644
index 0000000..7a5d296
--- /dev/null
+++ b/chrome/browser/sync/test/integration/single_client_user_consents_sync_test.cc
@@ -0,0 +1,155 @@
+// 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 <stdint.h>
+
+#include "base/macros.h"
+#include "chrome/browser/consent_auditor/consent_auditor_factory.h"
+#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
+#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
+#include "chrome/browser/sync/test/integration/status_change_checker.h"
+#include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
+#include "chrome/browser/sync/test/integration/sync_test.h"
+#include "components/consent_auditor/consent_auditor.h"
+#include "components/sync/driver/sync_driver_switches.h"
+#include "components/sync/protocol/user_consent_specifics.pb.h"
+
+using consent_auditor::ConsentStatus;
+using consent_auditor::Feature;
+using fake_server::FakeServer;
+using sync_pb::SyncEntity;
+using sync_pb::UserConsentSpecifics;
+
+namespace {
+
+std::string GetAccountId() {
+#if defined(OS_CHROMEOS)
+  // TODO(vitaliii): Unify the two, because it takes ages to debug and
+  // impossible to discover otherwise.
+  return "user@gmail.com";
+#else
+  return "gaia-id-user@gmail.com";
+#endif
+}
+
+class UserConsentEqualityChecker : public SingleClientStatusChangeChecker {
+ public:
+  UserConsentEqualityChecker(
+      browser_sync::ProfileSyncService* service,
+      FakeServer* fake_server,
+      std::vector<UserConsentSpecifics> expected_specifics)
+      : SingleClientStatusChangeChecker(service), fake_server_(fake_server) {
+    for (const UserConsentSpecifics& specifics : expected_specifics) {
+      expected_specifics_.insert(std::pair<int64_t, UserConsentSpecifics>(
+          specifics.confirmation_grd_id(), specifics));
+    }
+  }
+
+  bool IsExitConditionSatisfied() override {
+    std::vector<SyncEntity> entities =
+        fake_server_->GetSyncEntitiesByModelType(syncer::USER_CONSENTS);
+
+    // |entities.size()| is only going to grow, if |entities.size()| ever
+    // becomes bigger then all hope is lost of passing, stop now.
+    EXPECT_GE(expected_specifics_.size(), entities.size());
+
+    if (expected_specifics_.size() > entities.size()) {
+      return false;
+    }
+
+    // Number of events on server matches expected, exit condition can be
+    // satisfied. Let's verify that content matches as well. It is safe to
+    // modify |expected_specifics_|.
+    for (const SyncEntity& entity : entities) {
+      UserConsentSpecifics server_specifics = entity.specifics().user_consent();
+      auto iter =
+          expected_specifics_.find(server_specifics.confirmation_grd_id());
+      EXPECT_TRUE(expected_specifics_.end() != iter);
+      if (expected_specifics_.end() == iter) {
+        return false;
+      };
+      EXPECT_EQ(iter->second.account_id(), server_specifics.account_id());
+      expected_specifics_.erase(iter);
+    }
+
+    return true;
+  }
+
+  std::string GetDebugMessage() const override {
+    return "Waiting server side USER_CONSENTS to match expected.";
+  }
+
+ private:
+  FakeServer* fake_server_;
+  std::multimap<int64_t, UserConsentSpecifics> expected_specifics_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserConsentEqualityChecker);
+};
+
+class SingleClientUserConsentsSyncTest : public SyncTest {
+ public:
+  SingleClientUserConsentsSyncTest() : SyncTest(SINGLE_CLIENT) {
+    DisableVerifier();
+  }
+
+  bool ExpectUserConsents(
+      std::vector<UserConsentSpecifics> expected_specifics) {
+    return UserConsentEqualityChecker(GetSyncService(0), GetFakeServer(),
+                                      expected_specifics)
+        .Wait();
+  }
+
+  void SetSyncUserConsentSeparateTypeFeature(bool value) {
+    SyncTest::feature_list_.InitWithFeatureState(
+        switches::kSyncUserConsentSeparateType, value);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SingleClientUserConsentsSyncTest);
+};
+
+IN_PROC_BROWSER_TEST_F(SingleClientUserConsentsSyncTest,
+                       ShouldSubmitAsSeparateConsentDatatypeWhenEnabled) {
+  SetSyncUserConsentSeparateTypeFeature(true);
+
+  ASSERT_TRUE(SetupSync());
+  ASSERT_EQ(0u, GetFakeServer()
+                    ->GetSyncEntitiesByModelType(syncer::USER_CONSENTS)
+                    .size());
+  consent_auditor::ConsentAuditor* consent_service =
+      ConsentAuditorFactory::GetForProfile(GetProfile(0));
+  UserConsentSpecifics specifics;
+  specifics.set_confirmation_grd_id(1);
+  specifics.set_account_id(GetAccountId());
+  consent_service->RecordGaiaConsent(
+      GetAccountId(), Feature::CHROME_SYNC, /*description_grd_ids=*/{},
+      /*confirmation_grd_id=*/1, ConsentStatus::GIVEN);
+  EXPECT_TRUE(ExpectUserConsents({specifics}));
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SingleClientUserConsentsSyncTest,
+    ShouldPreserveConsentsOnDisableSyncAndResubmitWhenReneabled) {
+  SetSyncUserConsentSeparateTypeFeature(true);
+
+  UserConsentSpecifics specifics;
+  specifics.set_confirmation_grd_id(1);
+  // Account id may be compared to the synced account, thus, we need them to
+  // match.
+  specifics.set_account_id(GetAccountId());
+
+  ASSERT_TRUE(SetupSync());
+  consent_auditor::ConsentAuditor* consent_service =
+      ConsentAuditorFactory::GetForProfile(GetProfile(0));
+  consent_service->RecordGaiaConsent(
+      GetAccountId(), Feature::CHROME_SYNC, /*description_grd_ids=*/{},
+      /*confirmation_grd_id=*/1, ConsentStatus::GIVEN);
+
+  GetClient(0)->StopSyncService(syncer::SyncService::CLEAR_DATA);
+  ASSERT_TRUE(GetClient(0)->StartSyncService());
+
+  EXPECT_TRUE(ExpectUserConsents({specifics}));
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/ash/tab_scrubber.cc b/chrome/browser/ui/ash/tab_scrubber.cc
index 6127037..4b408b0 100644
--- a/chrome/browser/ui/ash/tab_scrubber.cc
+++ b/chrome/browser/ui/ash/tab_scrubber.cc
@@ -47,14 +47,29 @@
 gfx::Point TabScrubber::GetStartPoint(TabStrip* tab_strip,
                                       int index,
                                       TabScrubber::Direction direction) {
-  int initial_tab_offset = Tab::GetPinnedWidth() / 2;
-  // In RTL layouts the tabs are mirrored. We hence use GetMirroredBounds()
-  // which will give us the correct bounds of tabs in RTL layouts as well as
-  // non-RTL layouts (in non-RTL layouts GetMirroredBounds() is the same as
-  // bounds()).
-  gfx::Rect tab_bounds = tab_strip->tab_at(index)->GetMirroredBounds();
-  float x = direction == LEFT ? tab_bounds.x() + initial_tab_offset
-                              : tab_bounds.right() - initial_tab_offset;
+  const Tab* tab = tab_strip->tab_at(index);
+  gfx::Rect tab_bounds = tab->GetMirroredBounds();
+
+  // Start the swipe where the tab contents start/end.  This provides a small
+  // amount of slop inside the tab before a swipe will change tabs.
+  auto contents_insets = Tab::GetContentsInsets();
+  int left = contents_insets.left();
+  int right = contents_insets.right();
+
+  // The contents insets are logical rather than physical, so reverse them for
+  // RTL.
+  if (base::i18n::IsRTL())
+    std::swap(left, right);
+
+  // For very narrow tabs, the contents insets may be too large.  Clamp to the
+  // opposite edges of the tab, which should be at (overlap / 2).
+  gfx::Rect tab_edges = tab_bounds;
+  // For odd overlap values, be conservative and inset both edges rounding up.
+  tab_edges.Inset((Tab::GetOverlap() + 1) / 2, 0);
+  const int x = (direction == LEFT)
+                    ? std::min(tab_bounds.x() + left, tab_edges.right())
+                    : std::max(tab_bounds.right() - right, tab_edges.x());
+
   return gfx::Point(x, tab_bounds.CenterPoint().y());
 }
 
@@ -122,9 +137,6 @@
   // The event's x_offset doesn't change in an RTL layout. Negative value means
   // left, positive means right.
   float x_offset = event->x_offset();
-  int initial_tab_index = highlighted_tab_ == -1
-                              ? browser->tab_strip_model()->active_index()
-                              : highlighted_tab_;
   if (!scrubbing_) {
     BeginScrub(browser, browser_view, x_offset);
   } else if (highlighted_tab_ == -1) {
@@ -136,10 +148,7 @@
 
   UpdateSwipeX(x_offset);
 
-  Tab* initial_tab = tab_strip_->tab_at(initial_tab_index);
-  gfx::Point tab_point(swipe_x_, swipe_y_);
-  views::View::ConvertPointToTarget(tab_strip_, initial_tab, &tab_point);
-  Tab* new_tab = tab_strip_->GetTabAt(initial_tab, tab_point);
+  Tab* new_tab = tab_strip_->GetTabAt(gfx::Point(swipe_x_, swipe_y_));
   if (!new_tab)
     return;
 
diff --git a/chrome/browser/ui/ash/tab_scrubber.h b/chrome/browser/ui/ash/tab_scrubber.h
index 7926745..b14b036 100644
--- a/chrome/browser/ui/ash/tab_scrubber.h
+++ b/chrome/browser/ui/ash/tab_scrubber.h
@@ -33,8 +33,8 @@
   // Returns a the single instance of a TabScrubber.
   static TabScrubber* GetInstance();
 
-  // Returns the virtual position of a swipe starting in the tab at |index|,
-  // base on the |direction|.
+  // Returns the starting position (in tabstrip coordinates) of a swipe starting
+  // in the tab at |index| and traveling in |direction|.
   static gfx::Point GetStartPoint(TabStrip* tab_strip,
                                   int index,
                                   TabScrubber::Direction direction);
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
index 31e67540..425096a 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -431,7 +431,7 @@
 
       {{"https://normal.test/", "https://enforce.test/",
         "https://normal.test/"},
-       ActivationPosition::kMiddle},
+       base::nullopt},
   };
 
   for (const auto& test_case : kTestCases) {
diff --git a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
index 92326c4..c5feb0e 100644
--- a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
@@ -32,7 +32,7 @@
 
 class FakeSMSService : public SMSService {
  public:
-  FakeSMSService() : SMSService(nullptr, nullptr, nullptr) {}
+  FakeSMSService() : SMSService(nullptr, nullptr) {}
   ~FakeSMSService() override {}
   MOCK_METHOD1(QueryPhoneNumber, void(const PhoneNumberCallback&));
   MOCK_METHOD2(SendSMS,
diff --git a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
index b15707bd8..3bdc5db 100644
--- a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_util_unittest.cc
@@ -11,8 +11,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
 #include "chrome/common/chrome_features.h"
@@ -22,12 +21,11 @@
 #include "components/browser_sync/profile_sync_service.h"
 #include "components/browser_sync/test_profile_sync_service.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_manager.h"
+#include "components/signin/core/browser/fake_auth_status_provider.h"
 #include "components/sync/driver/fake_sync_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "google_apis/gaia/oauth2_token_service_delegate.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 
 namespace {
 
@@ -81,8 +79,7 @@
     profile_ = profile_builder.Build();
     sync_service_ = static_cast<TestSyncService*>(
         ProfileSyncServiceFactory::GetForProfile(profile_.get()));
-    mock_signin_ = SigninManagerFactory::GetForProfile(profile_.get());
-    mock_signin_->SetAuthenticatedAccountInfo("test", "test");
+    identity_test_environment_.MakePrimaryAccountAvailable("test@gmail.com");
   }
 
   void TearDown() override {
@@ -97,6 +94,12 @@
 
   Profile* profile() { return profile_.get(); }
 
+  const std::string& account_id() {
+    return identity_test_environment_.identity_manager()
+        ->GetPrimaryAccountInfo()
+        .account_id;
+  }
+
   double GetDoubleNDayOldDate(int days) {
     base::Time time_result =
         base::Time::NowFromSystemTime() - base::TimeDelta::FromDays(days);
@@ -106,8 +109,8 @@
  private:
   TestSyncService* sync_service_ = nullptr;
   content::TestBrowserThreadBundle thread_bundle_;
+  identity::IdentityTestEnvironment identity_test_environment_;
   ScopedTestingLocalState local_state_;
-  SigninManagerBase* mock_signin_ = nullptr;
   std::unique_ptr<TestingProfile> profile_;
   DISALLOW_COPY_AND_ASSIGN(DesktopIOSPromotionUtilTest);
 };
@@ -187,12 +190,9 @@
             ? GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
             : GoogleServiceAuthError::NONE);
 
-    ProfileOAuth2TokenService* token_service =
-        ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
-    token_service->UpdateCredentials("test", "refresh_token");
-    // TODO(https://crbug.com/836212): Do not use the delegate directly, because
-    // it is internal API.
-    token_service->GetDelegate()->UpdateAuthError("test", error);
+    FakeAuthStatusProvider auth_status_provider(
+        SigninErrorControllerFactory::GetForProfile(profile()));
+    auth_status_provider.SetAuthError(account_id(), error);
 
     local_state()->SetBoolean(prefs::kSavePasswordsBubbleIOSPromoDismissed,
                               test_case.is_dismissed);
diff --git a/chrome/browser/ui/desktop_ios_promotion/sms_service.cc b/chrome/browser/ui/desktop_ios_promotion/sms_service.cc
index 7d7ff00..ac16017 100644
--- a/chrome/browser/ui/desktop_ios_promotion/sms_service.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/sms_service.cc
@@ -10,14 +10,14 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/optional.h"
 #include "base/strings/stringprintf.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "google_apis/gaia/oauth2_token_service.h"
 #include "net/base/load_flags.h"
 #include "net/base/url_util.h"
 #include "net/http/http_status_code.h"
 #include "net/http/http_util.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
@@ -40,8 +40,7 @@
 // The maximum number of retries for the URLFetcher requests.
 const size_t kMaxRetries = 1;
 
-class RequestImpl : public SMSService::Request,
-                    private OAuth2TokenService::Consumer {
+class RequestImpl : public SMSService::Request {
  public:
   ~RequestImpl() override {}
 
@@ -57,14 +56,11 @@
  private:
   friend class ::SMSService;
 
-  RequestImpl(OAuth2TokenService* token_service,
-              SigninManagerBase* signin_manager,
+  RequestImpl(identity::IdentityManager* identity_manager,
               scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
               const GURL& url,
               const SMSService::CompletionCallback& callback)
-      : OAuth2TokenService::Consumer("desktop_ios_promotion"),
-        token_service_(token_service),
-        signin_manager_(signin_manager),
+      : identity_manager_(identity_manager),
         url_loader_factory_(std::move(url_loader_factory)),
         url_(url),
         post_data_mime_type_(kPostDataMimeType),
@@ -72,16 +68,19 @@
         auth_retry_count_(0),
         callback_(callback),
         is_pending_(false) {
-    DCHECK(token_service_);
-    DCHECK(signin_manager_);
+    DCHECK(identity_manager_);
     DCHECK(url_loader_factory_);
   }
 
   void Start() override {
     OAuth2TokenService::ScopeSet oauth_scopes;
     oauth_scopes.insert(kDesktopIOSPromotionOAuthScope);
-    token_request_ = token_service_->StartRequest(
-        signin_manager_->GetAuthenticatedAccountId(), oauth_scopes, this);
+    token_fetcher_ =
+        identity_manager_->CreateAccessTokenFetcherForPrimaryAccount(
+            "desktop_ios_promotion", oauth_scopes,
+            base::BindOnce(&RequestImpl::AccessTokenFetchComplete,
+                           base::Unretained(this)),
+            identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate);
     is_pending_ = true;
   }
 
@@ -103,10 +102,9 @@
     if (response_code_ == net::HTTP_UNAUTHORIZED && ++auth_retry_count_ <= 1) {
       OAuth2TokenService::ScopeSet oauth_scopes;
       oauth_scopes.insert(kDesktopIOSPromotionOAuthScope);
-      token_service_->InvalidateAccessToken(
-          signin_manager_->GetAuthenticatedAccountId(), oauth_scopes,
+      identity_manager_->RemoveAccessTokenFromCache(
+          identity_manager_->GetPrimaryAccountInfo().account_id, oauth_scopes,
           access_token_);
-
       access_token_.clear();
       Start();
       return;
@@ -124,11 +122,20 @@
     // members below here.
   }
 
-  // OAuth2TokenService::Consumer interface.
-  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                         const std::string& access_token,
-                         const base::Time& expiration_time) override {
-    token_request_.reset();
+  void AccessTokenFetchComplete(GoogleServiceAuthError error,
+                                std::string access_token) {
+    token_fetcher_.reset();
+
+    if (error.state() != GoogleServiceAuthError::NONE) {
+      is_pending_ = false;
+      UMA_HISTOGRAM_BOOLEAN("DesktopIOSPromotion.OAuthTokenCompletion", false);
+
+      callback_.Run(this, false);
+      // It is valid for the callback to delete |this|, so do not access any
+      // members below here.
+      return;
+    }
+
     DCHECK(!access_token.empty());
     access_token_ = access_token;
 
@@ -187,18 +194,6 @@
                        base::Unretained(this)));
   }
 
-  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                         const GoogleServiceAuthError& error) override {
-    token_request_.reset();
-    is_pending_ = false;
-
-    UMA_HISTOGRAM_BOOLEAN("DesktopIOSPromotion.OAuthTokenCompletion", false);
-
-    callback_.Run(this, false);
-    // It is valid for the callback to delete |this|, so do not access any
-    // members below here.
-  }
-
   void SetPostData(const std::string& post_data) override {
     SetPostDataAndType(post_data, kPostDataMimeType);
   }
@@ -209,8 +204,7 @@
     post_data_mime_type_ = mime_type;
   }
 
-  OAuth2TokenService* token_service_;
-  SigninManagerBase* signin_manager_;
+  identity::IdentityManager* identity_manager_;
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
 
   // The URL of the API endpoint.
@@ -223,7 +217,7 @@
   std::string post_data_mime_type_;
 
   // The OAuth2 access token request.
-  std::unique_ptr<OAuth2TokenService::Request> token_request_;
+  std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_;
 
   // The current OAuth2 access token.
   std::string access_token_;
@@ -255,11 +249,9 @@
 SMSService::Request::~Request() {}
 
 SMSService::SMSService(
-    OAuth2TokenService* token_service,
-    SigninManagerBase* signin_manager,
+    identity::IdentityManager* identity_manager,
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-    : token_service_(token_service),
-      signin_manager_(signin_manager),
+    : identity_manager_(identity_manager),
       url_loader_factory_(std::move(url_loader_factory)),
       weak_ptr_factory_(this) {}
 
@@ -268,8 +260,7 @@
 SMSService::Request* SMSService::CreateRequest(
     const GURL& url,
     const CompletionCallback& callback) {
-  return new RequestImpl(token_service_, signin_manager_, url_loader_factory_,
-                         url, callback);
+  return new RequestImpl(identity_manager_, url_loader_factory_, url, callback);
 }
 
 void SMSService::QueryPhoneNumber(const PhoneNumberCallback& callback) {
diff --git a/chrome/browser/ui/desktop_ios_promotion/sms_service.h b/chrome/browser/ui/desktop_ios_promotion/sms_service.h
index bd9d5d2e..9549185 100644
--- a/chrome/browser/ui/desktop_ios_promotion/sms_service.h
+++ b/chrome/browser/ui/desktop_ios_promotion/sms_service.h
@@ -19,13 +19,14 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "url/gurl.h"
 
+namespace identity {
+class IdentityManager;
+}
+
 namespace network {
 class SharedURLLoaderFactory;
 }
 
-class OAuth2TokenService;
-class SigninManagerBase;
-
 // Provides an API for querying a logged in users's verified phone number,
 // and sending a predetermined promotional SMS to that number.  This class is
 // based heavily on WebHistoryService's implementation to query Google services.
@@ -61,8 +62,7 @@
       PhoneNumberCallback;
   typedef base::Callback<void(Request*, bool success)> CompletionCallback;
 
-  SMSService(OAuth2TokenService* token_service,
-             SigninManagerBase* signin_manager,
+  SMSService(identity::IdentityManager* identity_manager,
              scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
   ~SMSService() override;
 
@@ -88,11 +88,9 @@
   virtual Request* CreateRequest(const GURL& url,
                                  const CompletionCallback& callback);
 
-  // Stores pointer to OAuth2TokenService and SigninManagerBase instance. They
-  // must outlive the SMSService and can be null during
-  // tests.
-  OAuth2TokenService* token_service_;
-  SigninManagerBase* signin_manager_;
+  // Stores pointer to the IdentityManager instance. It must outlive the
+  // SMSService and can be null during tests.
+  identity::IdentityManager* identity_manager_;
 
   // Request context getter to use.
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
diff --git a/chrome/browser/ui/desktop_ios_promotion/sms_service_factory.cc b/chrome/browser/ui/desktop_ios_promotion/sms_service_factory.cc
index ccd28b4..aa34dd4 100644
--- a/chrome/browser/ui/desktop_ios_promotion/sms_service_factory.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/sms_service_factory.cc
@@ -4,8 +4,7 @@
 
 #include "chrome/browser/ui/desktop_ios_promotion/sms_service_factory.h"
 
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/desktop_ios_promotion/sms_service.h"
 #include "components/browser_sync/profile_sync_service.h"
@@ -31,8 +30,7 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
   return new SMSService(
-      ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
-      SigninManagerFactory::GetForProfile(profile),
+      IdentityManagerFactory::GetForProfile(profile),
       content::BrowserContext::GetDefaultStoragePartition(profile)
           ->GetURLLoaderFactoryForBrowserProcess());
 }
@@ -41,8 +39,7 @@
     : BrowserContextKeyedServiceFactory(
           "SMSServiceFactory",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
-  DependsOn(SigninManagerFactory::GetInstance());
+  DependsOn(IdentityManagerFactory::GetInstance());
 }
 
 SMSServiceFactory::~SMSServiceFactory() {}
diff --git a/chrome/browser/ui/desktop_ios_promotion/sms_service_unittest.cc b/chrome/browser/ui/desktop_ios_promotion/sms_service_unittest.cc
index d2fa778..887b5eb 100644
--- a/chrome/browser/ui/desktop_ios_promotion/sms_service_unittest.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/sms_service_unittest.cc
@@ -7,10 +7,9 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
-#include "components/signin/core/browser/fake_signin_manager.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "net/http/http_status_code.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
@@ -23,11 +22,10 @@
 // TestRequest instead of a normal request.
 class TestingSMSService : public SMSService {
  public:
-  explicit TestingSMSService(
-      ProfileOAuth2TokenService* token_service,
-      SigninManagerBase* signin_manager,
+  TestingSMSService(
+      identity::IdentityManager* identity_manager,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-      : SMSService(token_service, signin_manager, url_loader_factory) {}
+      : SMSService(identity_manager, url_loader_factory) {}
 
   ~TestingSMSService() override {}
 
@@ -126,13 +124,10 @@
 class SMSServiceTest : public testing::Test {
  public:
   SMSServiceTest()
-      : signin_client_(nullptr),
-        signin_manager_(&signin_client_, &account_tracker_),
-        test_shared_loader_factory_(
+      : test_shared_loader_factory_(
             base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
                 &test_url_loader_factory_)),
-        sms_service_(&token_service_,
-                     &signin_manager_,
+        sms_service_(identity_test_environment_.identity_manager(),
                      test_shared_loader_factory_) {}
 
   ~SMSServiceTest() override {}
@@ -153,10 +148,7 @@
 
  private:
   base::MessageLoop message_loop_;
-  FakeProfileOAuth2TokenService token_service_;
-  AccountTrackerService account_tracker_;
-  TestSigninClient signin_client_;
-  FakeSigninManagerBase signin_manager_;
+  identity::IdentityTestEnvironment identity_test_environment_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   TestingSMSService sms_service_;
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc
index 2d3d9d1..db69dfd 100644
--- a/chrome/browser/ui/login/login_handler_browsertest.cc
+++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -110,6 +110,7 @@
 
 const char kMultiRealmTestPage[] = "/login/multi_realm.html";
 const int  kMultiRealmTestRealmCount = 2;
+const int kMultiRealmTestAuthRequestsCount = 4;
 
 const char kSingleRealmTestPage[] = "/login/single_realm.html";
 
@@ -475,104 +476,102 @@
 // Test handling of resources that require authentication even though
 // the page they are included on doesn't.  In this case we should only
 // present the minimal number of prompts necessary for successfully
-// displaying the page.  First we check whether cancelling works as
-// expected.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) {
+// displaying the page.
+class MultiRealmLoginPromptBrowserTest : public LoginPromptBrowserTest {
+ public:
+  void TearDownOnMainThread() override {
+    login_prompt_observer_.UnregisterAll();
+    LoginPromptBrowserTest::TearDownOnMainThread();
+  }
+
+  // Load the multi-realm test page, waits for LoginHandlers to be created, then
+  // calls |for_each_realm_func| once for each authentication realm, passing a
+  // LoginHandler for the realm as an argument. The page should stop loading
+  // after that.
+  template <class F>
+  void RunTest(const F& for_each_realm_func);
+
+  NavigationController* GetNavigationController() {
+    return &browser()
+                ->tab_strip_model()
+                ->GetActiveWebContents()
+                ->GetController();
+  }
+
+  LoginPromptBrowserTestObserver* login_prompt_observer() {
+    return &login_prompt_observer_;
+  }
+
+ private:
+  LoginPromptBrowserTestObserver login_prompt_observer_;
+};
+
+template <class F>
+void MultiRealmLoginPromptBrowserTest::RunTest(const F& for_each_realm_func) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  NavigationController* controller = GetNavigationController();
 
-  observer.Register(content::Source<NavigationController>(controller));
+  login_prompt_observer_.Register(
+      content::Source<NavigationController>(controller));
 
   WindowedLoadStopObserver load_stop_waiter(controller, 1);
 
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
+  browser()->OpenURL(OpenURLParams(test_page, Referrer(),
+                                   WindowOpenDisposition::CURRENT_TAB,
+                                   ui::PAGE_TRANSITION_TYPED, false));
 
-  int n_handlers = 0;
+  // Need to have LoginHandlers created for all requests that need
+  // authentication.
+  while (login_prompt_observer_.handlers().size() <
+         kMultiRealmTestAuthRequestsCount)
+    WindowedAuthNeededObserver(controller).Wait();
 
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
+  // Now confirm or cancel auth once per realm.
+  std::set<std::string> seen_realms;
+  for (int i = 0; i < kMultiRealmTestRealmCount; ++i) {
+    auto it = std::find_if(
+        login_prompt_observer_.handlers().begin(),
+        login_prompt_observer_.handlers().end(),
+        [&seen_realms](LoginHandler* handler) {
+          return seen_realms.count(handler->auth_info()->realm) == 0;
+        });
+    ASSERT_TRUE(it != login_prompt_observer_.handlers().end());
+    seen_realms.insert((*it)->auth_info()->realm);
 
-    while (!observer.handlers().empty()) {
-      WindowedAuthCancelledObserver auth_cancelled_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      handler->CancelAuth();
-      auth_cancelled_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
+    for_each_realm_func(*it);
   }
 
   load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_EQ(0, observer.auth_supplied_count());
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_cancelled_count());
 }
 
-// Similar to the MultipleRealmCancellation test above, but tests
-// whether supplying credentials work as exepcted.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmConfirmation) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
+// Checks that cancelling works as expected.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmCancellation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthCancelledObserver waiter(GetNavigationController());
+    handler->CancelAuth();
+    waiter.Wait();
+  });
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  EXPECT_EQ(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_cancelled_count());
+}
 
-  observer.Register(content::Source<NavigationController>(controller));
+// Checks that supplying credentials works as expected.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmConfirmation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthSuppliedObserver waiter(GetNavigationController());
+    SetAuthFor(handler);
+    waiter.Wait();
+  });
 
-  WindowedLoadStopObserver load_stop_waiter(controller, 1);
-  int n_handlers = 0;
-
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
-
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    while (!observer.handlers().empty()) {
-      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      SetAuthFor(handler);
-      auth_supplied_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
-  }
-
-  load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_supplied_count());
-  EXPECT_EQ(0, observer.auth_cancelled_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_EQ(0, login_prompt_observer()->auth_cancelled_count());
 }
 
 // Testing for recovery from an incorrect password for the case where
diff --git a/chrome/browser/ui/login/login_handler_test_utils.cc b/chrome/browser/ui/login/login_handler_test_utils.cc
index a0814c6b..d1c419d7 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.cc
+++ b/chrome/browser/ui/login/login_handler_test_utils.cc
@@ -57,6 +57,10 @@
   registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, source);
 }
 
+void LoginPromptBrowserTestObserver::UnregisterAll() {
+  registrar_.RemoveAll();
+}
+
 WindowedLoadStopObserver::WindowedLoadStopObserver(
     content::NavigationController* controller,
     int notification_count)
diff --git a/chrome/browser/ui/login/login_handler_test_utils.h b/chrome/browser/ui/login/login_handler_test_utils.h
index 8f32a54f..bf277a0 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.h
+++ b/chrome/browser/ui/login/login_handler_test_utils.h
@@ -31,6 +31,7 @@
   void RemoveHandler(LoginHandler* handler);
 
   void Register(const content::NotificationSource& source);
+  void UnregisterAll();
 
   const std::list<LoginHandler*>& handlers() const { return handlers_; }
 
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
index 4a553bdb..d0a8ec9 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
@@ -234,7 +234,15 @@
     network::ResourceResponseHead resource_response;
     resource_response.mime_type = "text/html";
     resource_response.ssl_info = ssl_info;
+
+    mojo::ScopedDataPipeProducerHandle producer;
+    mojo::ScopedDataPipeConsumerHandle consumer;
+    EXPECT_EQ(MOJO_RESULT_OK,
+              mojo::CreateDataPipe(nullptr, &producer, &consumer));
+
     params->client->OnReceiveResponse(resource_response);
+    params->client->OnStartLoadingResponseBody(std::move(consumer));
+
     network::URLLoaderCompletionStatus completion_status;
     completion_status.ssl_info = ssl_info;
     params->client->OnComplete(completion_status);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
index e3a4af6..3861330 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -288,7 +288,7 @@
   if (is_old_style_answer_ || is_rich_suggestion_ || has_tab_match_) {
     separator_view_->SetSize(gfx::Size());
   } else {
-    separator_view_->SetSize(separator_view_->CalculatePreferredSize());
+    separator_view_->SetSize(separator_view_->GetPreferredSize());
   }
 
   if (OmniboxFieldTrial::IsNewAnswerLayoutEnabled() &&
@@ -450,7 +450,7 @@
   icon_view_->SetBounds(child_area.x(), y, icon_view_width, row_height);
   int content_width = content_view_->GetPreferredSize().width();
   int description_width = description_view_->GetPreferredSize().width();
-  gfx::Size separator_size = separator_view_->CalculatePreferredSize();
+  gfx::Size separator_size = separator_view_->GetPreferredSize();
   OmniboxPopupModel::ComputeMatchMaxWidths(
       content_width, separator_size.width(), description_width,
       child_area.width() - text_indent,
diff --git a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
index 823426c4..eef05396 100644
--- a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
+++ b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
@@ -39,6 +39,25 @@
     background->set_blend_mode(SkBlendMode::kSrc);
     SetBackground(std::move(background));
   }
+
+#if !defined(USE_AURA)
+  // For non-Aura platforms, forward mouse events intended for the omnibox to
+  // the Widget owning the omnibox. For Aura platforms, this is done with an
+  // event targeter set up in RoundedOmniboxResultsFrame::AddedToWidget(),
+  // below.
+  void OnMouseEvent(ui::MouseEvent* event) override {
+    views::Widget* omnibox_widget = GetWidget()->GetTopLevelWidgetForNativeView(
+        GetWidget()->GetNativeView());
+    DCHECK_NE(GetWidget(), omnibox_widget);
+    ui::MouseEvent omnibox_event(*event);
+    gfx::Point event_location = event->location();
+    views::View::ConvertPointToScreen(this, &event_location);
+    views::View::ConvertPointFromScreen(omnibox_widget->GetRootView(),
+                                        &event_location);
+    omnibox_event.set_location(event_location);
+    omnibox_widget->OnMouseEvent(&omnibox_event);
+  }
+#endif  // !AURA
 };
 
 // Insets used to position |contents_| within |contents_host_|.
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
index d7937f1..fe2dce1 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
@@ -130,8 +130,6 @@
     constexpr char kSupervisedUser[] = "SupervisedUser";
 
     Browser* target_browser = browser();
-    std::unique_ptr<ScopedAccountConsistency> scoped_account_consistency;
-
     if (name == kSignedIn || name == kManageAccountLink) {
       constexpr char kEmail[] = "verylongemailfortesting@gmail.com";
       AddAccountToProfile(target_browser->profile(), kEmail);
@@ -153,10 +151,7 @@
       EXPECT_TRUE(guest);
       target_browser = chrome::FindAnyBrowser(guest, true);
     }
-    if (name == kManageAccountLink) {
-      scoped_account_consistency = std::make_unique<ScopedAccountConsistency>(
-          signin::AccountConsistencyMethod::kMirror);
-    }
+
     Profile* supervised = nullptr;
     if (name == kSupervisedOwner || name == kSupervisedUser) {
       supervised = SetupProfilesForLock(target_browser->profile());
@@ -521,6 +516,7 @@
 // Shows the |ProfileChooserView| when a supervised user is the active profile.
 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest,
                        MAYBE_InvokeUi_SupervisedUser) {
+  ScopedAccountConsistencyDiceFixAuthErrors scoped_account_consistency;
   ShowAndVerifyUi();
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index 67b1f6c..845a6cf 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -78,6 +78,7 @@
 namespace {
 
 constexpr int kExtraLeftPaddingToBalanceCloseButtonPadding = 2;
+constexpr int kRefreshExtraLeftPaddingToBalanceCloseButtonPadding = 4;
 
 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If
 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal
@@ -101,13 +102,6 @@
 // tabs are very narrow.
 constexpr int kChildClipPadding = 1;
 
-// Under material refresh, the spec for the favicon or title text is 12dips from
-// the left vertical edge of the tab. This edge is in the middle of the tab end
-// cap. The end cap is 16dips, the middle of which is 8dips. This value is the
-// additional spacing that is added from that distance to come up with the
-// spec's 12dips.
-constexpr int kRefreshExtraLeftFavIconPadding = 4;
-
 // Helper functions ------------------------------------------------------------
 
 // Returns the coordinate for an object of size |item_size| centered in a region
@@ -607,7 +601,7 @@
   int extra_padding = 0;
   if (extra_padding_before_content_) {
     extra_padding = MD::IsRefreshUi()
-                        ? kRefreshExtraLeftFavIconPadding
+                        ? kRefreshExtraLeftPaddingToBalanceCloseButtonPadding
                         : kExtraLeftPaddingToBalanceCloseButtonPadding;
   }
 
@@ -803,7 +797,9 @@
       // we don't contain the mouse anymore. We assume the user is clicking
       // quicker than the animation and we should close the tab that falls under
       // the mouse.
-      Tab* closest_tab = controller_->GetTabAt(this, event.location());
+      gfx::Point location_in_parent = event.location();
+      ConvertPointToTarget(this, parent(), &location_in_parent);
+      Tab* closest_tab = controller_->GetTabAt(location_in_parent);
       if (closest_tab)
         controller_->CloseTab(closest_tab, CLOSE_TAB_FROM_MOUSE);
     }
@@ -1022,6 +1018,11 @@
   Layout();
 }
 
+void Tab::FrameColorsChanged() {
+  OnButtonColorMaybeChanged();
+  SchedulePaint();
+}
+
 bool Tab::IsSelected() const {
   return controller_->IsTabSelected(this);
 }
@@ -1104,18 +1105,14 @@
   // Assume the entire region to the left of the alert indicator and/or close
   // buttons is available for click-to-select.  If neither are visible, the
   // entire tab region is available.
-  const int indicator_left =
-      showing_alert_indicator_ ? alert_indicator_button_->x() : width();
+  const int indicator_left = alert_indicator_button_->visible()
+                                 ? alert_indicator_button_->x()
+                                 : width();
   const int close_button_left =
-      showing_close_button_ ? close_button_->x() : width();
+      close_button_->visible() ? close_button_->x() : width();
   return std::min(indicator_left, close_button_left);
 }
 
-void Tab::FrameColorsChanged() {
-  OnButtonColorMaybeChanged();
-  SchedulePaint();
-}
-
 // static
 int Tab::GetMinimumInactiveWidth() {
   if (!MD::IsRefreshUi())
@@ -1184,6 +1181,11 @@
 }
 
 // static
+int Tab::GetDragInset() {
+  return MD::IsRefreshUi() ? GetCornerRadius() : GetTabEndcapWidthForLayout();
+}
+
+// static
 int Tab::GetOverlap() {
   // For refresh, overlap the separators.
   return MD::IsRefreshUi() ? (GetCornerRadius() * 2 + kSeparatorThickness)
@@ -1466,7 +1468,7 @@
                           : close_button_->GetInsets().width());
 
   int extra_padding = MD::IsRefreshUi()
-                          ? kRefreshExtraLeftFavIconPadding
+                          ? kRefreshExtraLeftPaddingToBalanceCloseButtonPadding
                           : kExtraLeftPaddingToBalanceCloseButtonPadding;
 
   const bool is_pinned = data().pinned;
@@ -1546,25 +1548,38 @@
 }
 
 Tab::SeparatorOpacities Tab::GetSeparatorOpacities(bool for_layout) const {
-  if (!MD::IsRefreshUi() || IsActive())
+  if (!MD::IsRefreshUi())
     return SeparatorOpacities();
 
-  // Fade out the trailing separator while this tab or the subsequent tab is
-  // hovered.  If the subsequent tab is active, don't consider its hover
-  // animation value, lest the trailing separator on this tab disappear while
-  // the subsequent tab is being dragged.
-  const float hover_value = hover_controller_.GetAnimationValue();
-  const Tab* subsequent_tab = controller_->GetSubsequentTab(this);
-  const float subsequent_hover =
-      !for_layout && subsequent_tab && !subsequent_tab->IsActive()
-          ? float{subsequent_tab->hover_controller_.GetAnimationValue()}
-          : 0;
-  float trailing_opacity = 1.f - std::max(hover_value, subsequent_hover);
-
-  // The leading separator need not consider the previous tab's hover value,
-  // since if there is a previous tab that's hovered and not being dragged, it
-  // will draw atop this tab.
-  float leading_opacity = 1.f - hover_value;
+  // Something should visually separate tabs from each other and any adjacent
+  // new tab button.  Normally, active and hovered tabs draw distinct shapes
+  // (via different background colors) and thus need no separators, while
+  // background tabs need separators between them.  In single-tab mode, the
+  // active tab has no visible shape and thus needs separators on any side with
+  // an adjacent new tab button.  (The other sides will be faded out below.)
+  float leading_opacity, trailing_opacity;
+  if (controller_->SingleTabMode()) {
+    leading_opacity = trailing_opacity = 1.f;
+  } else if (IsActive()) {
+    leading_opacity = trailing_opacity = 0;
+  } else {
+    // Fade out the trailing separator while this tab or the subsequent tab is

+    // hovered.  If the subsequent tab is active, don't consider its hover

+    // animation value, lest the trailing separator on this tab disappear while

+    // the subsequent tab is being dragged.

+    const float hover_value = hover_controller_.GetAnimationValue();

+    const Tab* subsequent_tab = controller_->GetSubsequentTab(this);

+    const float subsequent_hover =

+        !for_layout && subsequent_tab && !subsequent_tab->IsActive()

+            ? float{subsequent_tab->hover_controller_.GetAnimationValue()}

+            : 0;

+    trailing_opacity = 1.f - std::max(hover_value, subsequent_hover);

+

+    // The leading separator need not consider the previous tab's hover value,

+    // since if there is a previous tab that's hovered and not being dragged, it

+    // will draw atop this tab.

+    leading_opacity = 1.f - hover_value;
+  }
 
   // For the first or last tab in the strip, fade the leading or trailing
   // separator based on the NTB position and how close to the target bounds this
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h
index e02a70a4..50579b14 100644
--- a/chrome/browser/ui/views/tabs/tab.h
+++ b/chrome/browser/ui/views/tabs/tab.h
@@ -130,6 +130,9 @@
   // Called when the alert indicator has changed states.
   void AlertStateChanged();
 
+  // Called when the frame state color changes.
+  void FrameColorsChanged();
+
   // Returns true if the tab is selected.
   bool IsSelected() const;
 
@@ -171,9 +174,6 @@
   // user to click to select/activate the tab.
   int GetWidthOfLargestSelectableRegion() const;
 
-  // Called when the frame state color changes.
-  void FrameColorsChanged();
-
   // Returns the minimum possible width of a single unselected Tab.
   static int GetMinimumInactiveWidth();
 
@@ -211,6 +211,11 @@
   // Returns the insets to use for laying out tab contents.
   static gfx::Insets GetContentsInsets();
 
+  // Returns an offset into the leading edge of the tab which delineates the
+  // "main body" of the tab from the user's perspective; dragging based on this
+  // point feels better than dragging based on the tab's actual leading edge.
+  static int GetDragInset();
+
   // Returns the overlap between adjacent tabs.
   static int GetOverlap();
 
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h
index 07988df..bf820a4 100644
--- a/chrome/browser/ui/views/tabs/tab_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -74,20 +74,24 @@
                                      const gfx::Point& p,
                                      ui::MenuSourceType source_type) = 0;
 
-  // Returns true if |tab| is the active tab. The active tab is the one whose
+  // Returns whether |tab| is the active tab. The active tab is the one whose
   // content is shown in the browser.
   virtual bool IsActiveTab(const Tab* tab) const = 0;
 
-  // Returns true if the specified Tab is selected.
+  // Returns whether |tab| is selected.
   virtual bool IsTabSelected(const Tab* tab) const = 0;
 
-  // Returns true if the specified Tab is pinned.
+  // Returns whether |tab| is pinned.
   virtual bool IsTabPinned(const Tab* tab) const = 0;
 
-  // Returns true if the specified tab is the first or last one visible.
+  // Returns whether |tab| is the first or last one visible.
   virtual bool IsFirstVisibleTab(const Tab* tab) const = 0;
   virtual bool IsLastVisibleTab(const Tab* tab) const = 0;
 
+  // Returns whether the strip is painting in single-tab mode.  This is true in
+  // a subset of the cases where ther is exactly one tab.
+  virtual bool SingleTabMode() const = 0;
+
   // Returns true if the tab is a part of an incognito profile.
   virtual bool IsIncognito() const = 0;
 
@@ -104,10 +108,9 @@
   // Ends dragging a Tab. Returns whether the tab has been destroyed.
   virtual bool EndDrag(EndDragReason reason) = 0;
 
-  // Returns the tab that contains the specified coordinates, in terms of |tab|,
-  // or NULL if there is no tab that contains the specified point.
-  virtual Tab* GetTabAt(Tab* tab,
-                        const gfx::Point& tab_in_tab_coordinates) = 0;
+  // Returns the tab that contains the specified point in tabstrip coordinates,
+  // or null if there is no tab that contains the specified point.
+  virtual Tab* GetTabAt(const gfx::Point& point) = 0;
 
   // Returns the next tab in the model order. Returns nullptr if there
   // isn't another tab beyond the given tab.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 871cc513..5bf8825 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -78,19 +78,6 @@
 
 const int kHorizontalMoveThreshold = 16;  // DIPs.
 
-// The inset within the first dragged tab to use when calculating the "drag
-// insertion point".  If we simply used the x-coordinate of the tab, we'd be
-// calculating based on a point well before where the user considers the tab to
-// "be".  The value here is chosen to "feel good" based on the widths of the tab
-// images and the tab overlap.
-//
-// Note that this must return a value smaller than the midpoint of any tab's
-// width, or else the user won't be able to drag a tab to the left of the first
-// tab in the strip.
-//
-// TODO(pkasting): Maybe this should use Tab::GetOverlap() instead?
-const int kLeadingWidthForDrag = 16;
-
 // Distance from the next/previous stacked before before we consider the tab
 // close enough to trigger moving.
 const int kStackedDistance = 36;
@@ -101,6 +88,12 @@
 // maximized size.
 const int kMaximizedWindowInset = 10;  // DIPs.
 
+// Given the bounds of a dragged tab, return the X coordinate to use for
+// computing where in the strip to insert/move the tab.
+int GetDraggedX(const gfx::Rect& dragged_bounds) {
+  return dragged_bounds.x() + Tab::GetDragInset();
+}
+
 #if defined(OS_CHROMEOS)
 // Returns true if |tab_strip| browser window is snapped.
 bool IsSnapped(const TabStrip* tab_strip) {
@@ -1222,10 +1215,7 @@
 int TabDragController::GetInsertionIndexFrom(const gfx::Rect& dragged_bounds,
                                              int start) const {
   const int last_tab = attached_tabstrip_->tab_count() - 1;
-  // Make the actual "drag insertion point" be just after the leading edge of
-  // the first dragged tab.  This is closer to where the user thinks of the tab
-  // as "starting" than just dragged_bounds.x(), especially with narrow tabs.
-  const int dragged_x = dragged_bounds.x() + kLeadingWidthForDrag;
+  const int dragged_x = GetDraggedX(dragged_bounds);
   if (start < 0 || start > last_tab ||
       dragged_x < attached_tabstrip_->ideal_bounds(start).x())
     return -1;
@@ -1242,10 +1232,7 @@
 int TabDragController::GetInsertionIndexFromReversed(
     const gfx::Rect& dragged_bounds,
     int start) const {
-  // Make the actual "drag insertion point" be just after the leading edge of
-  // the first dragged tab.  This is closer to where the user thinks of the tab
-  // as "starting" than just dragged_bounds.x(), especially with narrow tabs.
-  const int dragged_x = dragged_bounds.x() + kLeadingWidthForDrag;
+  const int dragged_x = GetDraggedX(dragged_bounds);
   if (start < 0 || start >= attached_tabstrip_->tab_count() ||
       dragged_x >= attached_tabstrip_->ideal_bounds(start).right())
     return -1;
@@ -1315,9 +1302,7 @@
   int next_x = attached_tabstrip_->ideal_bounds(index + 1).x();
   int mid_x = std::min(next_x - kStackedDistance,
                        active_x + (next_x - active_x) / 4);
-  // TODO(pkasting): Should this add kLeadingWidthForDrag as
-  // GetInsertionIndexFrom() does?
-  return dragged_bounds.x() >= mid_x;
+  return GetDraggedX(dragged_bounds) >= mid_x;
 }
 
 bool TabDragController::ShouldDragToPreviousStackedTab(
@@ -1332,9 +1317,7 @@
   int previous_x = attached_tabstrip_->ideal_bounds(index - 1).x();
   int mid_x = std::max(previous_x + kStackedDistance,
                        active_x - (active_x - previous_x) / 4);
-  // TODO(pkasting): Should this add kLeadingWidthForDrag as
-  // GetInsertionIndexFrom() does?
-  return dragged_bounds.x() <= mid_x;
+  return GetDraggedX(dragged_bounds) <= mid_x;
 }
 
 int TabDragController::GetInsertionIndexForDraggedBoundsStacked(
@@ -1816,7 +1799,7 @@
       views::View::ConvertPointToWidget(source, &right_edge);
       new_bounds.set_x(point_in_screen.x() - right_edge.x());
       new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0);
-      OffsetX(-(*drag_bounds)[0].x(), drag_bounds);
+      OffsetX(-drag_bounds->front().x(), drag_bounds);
       break;
     }
     default:
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 7f4c489..ddd3d45 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -437,11 +437,6 @@
     tab_at(i)->Layout();
 }
 
-bool TabStrip::SingleTabMode() const {
-  return controller_->IsSingleTabModeAvailable() && tab_count() == 1 &&
-         !tab_at(0)->data().pinned;
-}
-
 bool TabStrip::SizeTabButtonToTopOfTabStrip() {
   // Extend the button to the screen edge in maximized and immersive fullscreen.
   views::Widget* widget = GetWidget();
@@ -982,6 +977,11 @@
   return GetLastVisibleTab() == tab;
 }
 
+bool TabStrip::SingleTabMode() const {
+  return controller_->IsSingleTabModeAvailable() && tab_count() == 1 &&
+         !tab_at(0)->data().pinned;
+}
+
 bool TabStrip::IsIncognito() const {
   // There may be no controller in tests.
   return controller_ && controller_->IsIncognito();
@@ -1068,11 +1068,8 @@
   return started_drag;
 }
 
-Tab* TabStrip::GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) {
-  gfx::Point local_point = tab_in_tab_coordinates;
-  ConvertPointToTarget(tab, this, &local_point);
-
-  views::View* view = GetEventHandlerForPoint(local_point);
+Tab* TabStrip::GetTabAt(const gfx::Point& point) {
+  views::View* view = GetEventHandlerForPoint(point);
   if (!view)
     return nullptr;  // No tab contains the point.
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index 21cfc30..87498b1 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -127,10 +127,6 @@
   // Sets |stacked_layout_| and animates if necessary.
   void SetStackedLayout(bool stacked_layout);
 
-  // Whether the special painting mode for a single tab is enabled. This is only
-  // true if both the mode is available and we have exactly one tab.
-  bool SingleTabMode() const;
-
   // Called when the value of SingleTabMode() changes.
   void SingleTabModeChanged();
 
@@ -243,6 +239,7 @@
   bool IsTabPinned(const Tab* tab) const override;
   bool IsFirstVisibleTab(const Tab* tab) const override;
   bool IsLastVisibleTab(const Tab* tab) const override;
+  bool SingleTabMode() const override;
   bool IsIncognito() const override;
   void MaybeStartDrag(
       Tab* tab,
@@ -250,7 +247,7 @@
       const ui::ListSelectionModel& original_selection) override;
   void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override;
   bool EndDrag(EndDragReason reason) override;
-  Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override;
+  Tab* GetTabAt(const gfx::Point& point) override;
   const Tab* GetSubsequentTab(const Tab* tab) override;
   void OnMouseEventInTab(views::View* source,
                          const ui::MouseEvent& event) override;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout.cc b/chrome/browser/ui/views/tabs/tab_strip_layout.cc
index f83e204a..bd0486f 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_layout.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_layout.cc
@@ -27,10 +27,9 @@
 
   // Calculate the desired tab width by dividing the available space into equal
   // portions, bounded by the standard width.
-  const int total_overlap = tab_size_info.tab_overlap * (num_normal_tabs - 1);
-  int desired_tab_width =
-      std::min((normal_width + total_overlap) / num_normal_tabs,
-               tab_size_info.standard_size.width());
+  normal_width += tab_size_info.tab_overlap * (num_normal_tabs - 1);
+  int desired_tab_width = std::min(normal_width / num_normal_tabs,
+                                   tab_size_info.standard_size.width());
 
   *active_width = std::max(desired_tab_width, tab_size_info.min_active_width);
 
@@ -38,10 +37,8 @@
   // we need to recalculate it having accounted for the active tab, since that
   // may further shrink inactive tabs.
   if ((*active_width > desired_tab_width) && is_active_tab_normal &&
-      (num_normal_tabs > 1)) {
-    desired_tab_width =
-        (normal_width + total_overlap - *active_width) / (num_normal_tabs - 1);
-  }
+      (num_normal_tabs > 1))
+    desired_tab_width = (normal_width - *active_width) / (num_normal_tabs - 1);
 
   *inactive_width =
       std::max(desired_tab_width, tab_size_info.min_inactive_width);
diff --git a/chrome/browser/ui/views/tabs/tab_strip_layout.h b/chrome/browser/ui/views/tabs/tab_strip_layout.h
index c9e82f5..228970a 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_layout.h
+++ b/chrome/browser/ui/views/tabs/tab_strip_layout.h
@@ -28,7 +28,7 @@
   // The overlap between adjacent tabs. When positioning tabs the x-coordinate
   // of a tab is calculated as the x-coordinate of the previous tab plus the
   // previous tab's width minus the |tab_overlap|, e.g.
-  // next_tab_x = previous_tab.max_x() - tab_overlap.
+  // next_tab_x = previous_tab.bounds().right() - tab_overlap.
   int tab_overlap;
 
   // Additional offset between the last pinned tab and the first normal tab.
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc
index af0e43a1..1236bd4 100644
--- a/chrome/browser/ui/views/tabs/tab_unittest.cc
+++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -59,6 +59,7 @@
   bool IsTabPinned(const Tab* tab) const override { return false; }
   bool IsFirstVisibleTab(const Tab* tab) const override { return false; }
   bool IsLastVisibleTab(const Tab* tab) const override { return false; }
+  bool SingleTabMode() const override { return false; }
   bool IsIncognito() const override { return false; }
   void MaybeStartDrag(
       Tab* tab,
@@ -67,9 +68,7 @@
   void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override {
   }
   bool EndDrag(EndDragReason reason) override { return false; }
-  Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override {
-    return nullptr;
-  }
+  Tab* GetTabAt(const gfx::Point& point) override { return nullptr; }
   const Tab* GetSubsequentTab(const Tab* tab) override { return nullptr; }
   void OnMouseEventInTab(views::View* source,
                          const ui::MouseEvent& event) override {}
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 5a68d24..721518a 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/profiles/profile_shortcut_manager.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "chrome/browser/profiles/profiles_state.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -32,7 +31,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/signin/core/browser/profile_management_switches.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index 4352ef8..1912aa4 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/unified_consent_helper.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/webui/signin/sync_confirmation_handler.h"
@@ -18,10 +18,10 @@
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/signin/core/browser/avatar_icon_util.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
+#include "services/identity/public/cpp/identity_manager.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
@@ -92,8 +92,8 @@
 
     constexpr int kAccountPictureSize = 68;
     std::string custom_picture_url = profiles::GetPlaceholderAvatarIconUrl();
-    GURL account_picture_url(SigninManagerFactory::GetForProfile(profile)
-                                 ->GetAuthenticatedAccountInfo()
+    GURL account_picture_url(IdentityManagerFactory::GetForProfile(profile)
+                                 ->GetPrimaryAccountInfo()
                                  .picture_url);
     if (account_picture_url.is_valid()) {
       custom_picture_url = signin::GetAvatarImageURLWithOptions(
diff --git a/chrome/browser/vr/elements/transient_element.cc b/chrome/browser/vr/elements/transient_element.cc
index 3a27a96..7765701d 100644
--- a/chrome/browser/vr/elements/transient_element.cc
+++ b/chrome/browser/vr/elements/transient_element.cc
@@ -69,62 +69,4 @@
   return false;
 }
 
-ShowUntilSignalTransientElement::ShowUntilSignalTransientElement(
-    const base::TimeDelta& min_duration,
-    const base::TimeDelta& timeout,
-    OnMinDurationCallback min_duration_callback,
-    OnHideCallback hide_callback)
-    : super(timeout),
-      min_duration_(min_duration),
-      min_duration_callback_(min_duration_callback),
-      hide_callback_(hide_callback) {
-  SetVisibleImmediately(false);
-}
-
-ShowUntilSignalTransientElement::~ShowUntilSignalTransientElement() {}
-
-bool ShowUntilSignalTransientElement::OnBeginFrame(
-    const gfx::Transform& head_pose) {
-  // Do nothing if we're not going to be visible.
-  if (GetTargetOpacity() != opacity_when_visible())
-    return false;
-
-  // SetVisible may have been called during initialization which means that the
-  // last frame time would be zero.
-  if (set_visible_time_.is_null() && opacity() > 0.0f)
-    set_visible_time_ = last_frame_time();
-
-  bool set_invisible = false;
-
-  base::TimeDelta duration = last_frame_time() - set_visible_time_;
-  if (!set_visible_time_.is_null() && !min_duration_callback_called_ &&
-      duration >= min_duration_) {
-    min_duration_callback_.Run();
-    min_duration_callback_called_ = true;
-  }
-
-  if (!set_visible_time_.is_null() && duration > timeout_) {
-    hide_callback_.Run(TransientElementHideReason::kTimeout);
-    set_invisible = true;
-  } else if (!set_visible_time_.is_null() && duration >= min_duration_ &&
-             signaled_) {
-    hide_callback_.Run(TransientElementHideReason::kSignal);
-    set_invisible = true;
-  }
-  if (set_invisible) {
-    super::SetVisible(false);
-    return true;
-  }
-  return false;
-}
-
-void ShowUntilSignalTransientElement::Signal(bool value) {
-  signaled_ = value;
-}
-
-void ShowUntilSignalTransientElement::Reset() {
-  min_duration_callback_called_ = false;
-  super::Reset();
-}
-
 }  // namespace vr
diff --git a/chrome/browser/vr/elements/transient_element.h b/chrome/browser/vr/elements/transient_element.h
index 837d9640..b63de3f 100644
--- a/chrome/browser/vr/elements/transient_element.h
+++ b/chrome/browser/vr/elements/transient_element.h
@@ -60,42 +60,6 @@
   kSignal,
 };
 
-// An element that waits for a signal or timeout to hide itself once its been
-// made visible. The element will stay visible for at least the set
-// minimum duration regardless of when ::Signal is called. The set callback
-// is triggered when the element hides itself.
-class VR_EXPORT ShowUntilSignalTransientElement : public TransientElement {
- public:
-  typedef typename base::RepeatingCallback<void()> OnMinDurationCallback;
-  typedef typename base::RepeatingCallback<void(TransientElementHideReason)>
-      OnHideCallback;
-
-  ShowUntilSignalTransientElement(const base::TimeDelta& min_duration,
-                                  const base::TimeDelta& timeout,
-                                  OnMinDurationCallback min_duration_callback,
-                                  OnHideCallback hide_callback);
-  ~ShowUntilSignalTransientElement() override;
-
-  // This must be called before the set timeout to hide the element.
-  void Signal(bool value);
-
- protected:
-  void Reset() override;
-
- private:
-  bool OnBeginFrame(const gfx::Transform& head_pose) override;
-
-  typedef TransientElement super;
-
-  base::TimeDelta min_duration_;
-  OnMinDurationCallback min_duration_callback_;
-  OnHideCallback hide_callback_;
-  bool signaled_ = false;
-  bool min_duration_callback_called_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(ShowUntilSignalTransientElement);
-};
-
 }  // namespace vr
 
 #endif  // CHROME_BROWSER_VR_ELEMENTS_TRANSIENT_ELEMENT_H_
diff --git a/chrome/browser/vr/elements/transient_element_unittest.cc b/chrome/browser/vr/elements/transient_element_unittest.cc
index e28af2d..4b861c6 100644
--- a/chrome/browser/vr/elements/transient_element_unittest.cc
+++ b/chrome/browser/vr/elements/transient_element_unittest.cc
@@ -148,119 +148,4 @@
   EXPECT_FALSE(parent->IsVisible());
 }
 
-class ShowUntilSignalElementTest : public testing::Test {
- public:
-  ShowUntilSignalElementTest() {}
-
-  void SetUp() override {
-    ResetCallbackTriggered();
-    element_ = std::make_unique<ShowUntilSignalTransientElement>(
-        base::TimeDelta::FromSeconds(2), base::TimeDelta::FromSeconds(5),
-        base::BindRepeating(&ShowUntilSignalElementTest::OnMinDuration,
-                            base::Unretained(this)),
-        base::BindRepeating(&ShowUntilSignalElementTest::OnTimeout,
-                            base::Unretained(this)));
-  }
-
-  ShowUntilSignalTransientElement& element() { return *element_; }
-  TransientElementHideReason hide_reason() { return hide_reason_; }
-  bool min_duration_callback_triggered() {
-    return min_duration_callback_triggered_;
-  }
-  bool hide_callback_triggered() { return hide_callback_triggered_; }
-
-  void OnMinDuration() { min_duration_callback_triggered_ = true; }
-
-  void OnTimeout(TransientElementHideReason reason) {
-    hide_callback_triggered_ = true;
-    hide_reason_ = reason;
-  }
-
-  void ResetCallbackTriggered() {
-    min_duration_callback_triggered_ = false;
-    hide_callback_triggered_ = false;
-  }
-
-  void VerifyElementHidesAfterSignal() {
-    EXPECT_FALSE(element().IsVisible());
-
-    // Make element visible.
-    element().SetVisible(true);
-    EXPECT_FALSE(DoBeginFrame(&element(), 10));
-    EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-
-    // Signal, element should still be visible since time < min duration.
-    element().Signal(true);
-    EXPECT_FALSE(DoBeginFrame(&element(), 200));
-    EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-
-    // Element hides and callback triggered.
-    EXPECT_TRUE(DoBeginFrame(&element(), 2010));
-    EXPECT_EQ(0.0f, element().opacity());
-    EXPECT_TRUE(min_duration_callback_triggered());
-    EXPECT_TRUE(hide_callback_triggered());
-    ResetCallbackTriggered();
-    EXPECT_EQ(TransientElementHideReason::kSignal, hide_reason());
-  }
-
- private:
-  bool min_duration_callback_triggered_ = false;
-  bool hide_callback_triggered_ = false;
-  TransientElementHideReason hide_reason_;
-  std::unique_ptr<ShowUntilSignalTransientElement> element_;
-};
-
-// Test that the element disappears when signalled.
-TEST_F(ShowUntilSignalElementTest, ElementHidesAfterSignal) {
-  // We run this twice to verify that an element can be shown again after being
-  // hidden.
-  VerifyElementHidesAfterSignal();
-  VerifyElementHidesAfterSignal();
-}
-
-// Test that the transient element times out.
-TEST_F(ShowUntilSignalElementTest, TimedOut) {
-  EXPECT_FALSE(element().IsVisible());
-
-  // Make element visible.
-  element().SetVisible(true);
-  EXPECT_FALSE(DoBeginFrame(&element(), 10));
-  EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-
-  // Element should be visible since we haven't signalled.
-  EXPECT_FALSE(DoBeginFrame(&element(), 2010));
-  EXPECT_TRUE(min_duration_callback_triggered());
-  EXPECT_FALSE(hide_callback_triggered());
-  ResetCallbackTriggered();
-  EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-
-  // Element hides and callback triggered.
-  EXPECT_TRUE(DoBeginFrame(&element(), 6010));
-  EXPECT_EQ(0.0f, element().opacity());
-  EXPECT_FALSE(min_duration_callback_triggered());
-  EXPECT_TRUE(hide_callback_triggered());
-  EXPECT_EQ(TransientElementHideReason::kTimeout, hide_reason());
-}
-
-// Test that refreshing the visibility resets the transience timeout if the
-// element is currently visible.
-TEST_F(ShowUntilSignalElementTest, RefreshVisibility) {
-  // Enable, and ensure that the element is visible.
-  element().SetVisible(true);
-  EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-  EXPECT_FALSE(DoBeginFrame(&element(), 0));
-  EXPECT_FALSE(DoBeginFrame(&element(), 1000));
-  element().Signal(true);
-
-  // Refresh visibility, and ensure that the element still transiently
-  // disappears, but at a later time.
-  element().RefreshVisible();
-  EXPECT_FALSE(DoBeginFrame(&element(), 1000));
-  EXPECT_FALSE(DoBeginFrame(&element(), 2500));
-  EXPECT_EQ(element().opacity_when_visible(), element().opacity());
-  EXPECT_TRUE(DoBeginFrame(&element(), 3000));
-  EXPECT_EQ(0.0f, element().opacity());
-  EXPECT_EQ(TransientElementHideReason::kSignal, hide_reason());
-}
-
 }  // namespace vr
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc
index b0dcfc1..914c313 100644
--- a/chrome/browser/vr/elements/ui_element_name.cc
+++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -108,13 +108,9 @@
     "kExitWarningText",
     "kExitWarningBackground",
     "kExitPrompt",
-    "kWebVrUrlToastTransientParent",
-    "kWebVrUrlToast",
     "kWebVrExclusiveScreenToast",
     "kPlatformToastTransientParent",
     "kPlatformToast",
-    "kSplashScreenTransientParent",
-    "kSplashScreenText",
     "kSolidBackground",
     "kWebVrFloor",
     "kWebVrHostedUi",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h
index ac39b7d..489e3eee 100644
--- a/chrome/browser/vr/elements/ui_element_name.h
+++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -109,13 +109,9 @@
   kExitWarningText,
   kExitWarningBackground,
   kExitPrompt,
-  kWebVrUrlToastTransientParent,
-  kWebVrUrlToast,
   kWebVrExclusiveScreenToast,
   kPlatformToastTransientParent,
   kPlatformToast,
-  kSplashScreenTransientParent,
-  kSplashScreenText,
   kSolidBackground,
   kWebVrFloor,
   kWebVrHostedUi,
diff --git a/chrome/browser/vr/model/model.cc b/chrome/browser/vr/model/model.cc
index 0660a19..e57cde34 100644
--- a/chrome/browser/vr/model/model.cc
+++ b/chrome/browser/vr/model/model.cc
@@ -13,7 +13,6 @@
     case kModeBrowsing:
     case kModeFullscreen:
     case kModeWebVr:
-    case kModeWebVrAutopresented:
     case kModeVoiceSearch:
     case kModeEditingOmnibox:
     case kModeTabsView:
@@ -114,12 +113,7 @@
 }
 
 bool Model::web_vr_enabled() const {
-  return get_last_opaque_mode() == kModeWebVr ||
-         get_last_opaque_mode() == kModeWebVrAutopresented;
-}
-
-bool Model::web_vr_autopresentation_enabled() const {
-  return get_last_opaque_mode() == kModeWebVrAutopresented;
+  return get_last_opaque_mode() == kModeWebVr;
 }
 
 bool Model::reposition_window_enabled() const {
diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h
index e9147270..953b76d 100644
--- a/chrome/browser/vr/model/model.h
+++ b/chrome/browser/vr/model/model.h
@@ -81,7 +81,6 @@
   bool editing_enabled() const;
   bool fullscreen_enabled() const;
   bool web_vr_enabled() const;
-  bool web_vr_autopresentation_enabled() const;
   bool reposition_window_enabled() const;
   bool reposition_window_permitted() const;
 
diff --git a/chrome/browser/vr/model/ui_mode.h b/chrome/browser/vr/model/ui_mode.h
index e60ba9d..b9604ef 100644
--- a/chrome/browser/vr/model/ui_mode.h
+++ b/chrome/browser/vr/model/ui_mode.h
@@ -12,7 +12,6 @@
   kModeBrowsing,
   kModeFullscreen,
   kModeWebVr,
-  kModeWebVrAutopresented,
   kModeVoiceSearch,
   kModeEditingOmnibox,
   kModeTabsView,
diff --git a/chrome/browser/vr/model/web_vr_model.h b/chrome/browser/vr/model/web_vr_model.h
index 4b189ae6..77176b1 100644
--- a/chrome/browser/vr/model/web_vr_model.h
+++ b/chrome/browser/vr/model/web_vr_model.h
@@ -11,10 +11,6 @@
 enum WebVrState {
   // We are not awaiting a WebVR frame.
   kWebVrNoTimeoutPending = 0,
-  // We are waiting for the minimum splash screen duration to be over. We're in
-  // this state only during WebVR auto-presentation. During this phase, sending
-  // VSync to the WebVR page is paused.
-  kWebVrAwaitingMinSplashScreenDuration,
   kWebVrAwaitingFirstFrame,
   // We are awaiting a WebVR frame, and we will soon exceed the amount of time
   // that we're willing to wait. In this state, it could be appropriate to show
@@ -36,9 +32,6 @@
   bool presenting_web_vr() const {
     return state == kWebVrPresenting && !showing_hosted_ui;
   }
-  bool awaiting_min_splash_screen_duration() const {
-    return state == kWebVrAwaitingMinSplashScreenDuration;
-  }
 };
 
 }  // namespace vr
diff --git a/chrome/browser/vr/test/ui_test.cc b/chrome/browser/vr/test/ui_test.cc
index a46beca..82821971 100644
--- a/chrome/browser/vr/test/ui_test.cc
+++ b/chrome/browser/vr/test/ui_test.cc
@@ -103,13 +103,6 @@
   CreateScene(state);
 }
 
-void UiTest::CreateSceneForAutoPresentation() {
-  UiInitialState state;
-  state.in_web_vr = true;
-  state.web_vr_autopresentation_expected = true;
-  CreateScene(state);
-}
-
 void UiTest::SetIncognito(bool incognito) {
   model_->incognito = incognito;
 }
diff --git a/chrome/browser/vr/test/ui_test.h b/chrome/browser/vr/test/ui_test.h
index 1e348eb6..09fb60b9 100644
--- a/chrome/browser/vr/test/ui_test.h
+++ b/chrome/browser/vr/test/ui_test.h
@@ -48,7 +48,6 @@
 
   void CreateScene(const UiInitialState& state);
   void CreateScene(InCct in_cct, InWebVr in_web_vr);
-  void CreateSceneForAutoPresentation();
 
  protected:
   void CreateSceneInternal(
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc
index 917d6a0d..5d95f3b0 100644
--- a/chrome/browser/vr/testapp/vr_test_context.cc
+++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -501,8 +501,6 @@
       ui_->SetWebVrMode(true);
       break;
     }
-    case kWebVrAwaitingMinSplashScreenDuration:
-      break;
     case kWebVrAwaitingFirstFrame:
       ui_->OnWebVrTimeoutImminent();
       break;
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc
index a1c89b9..d64a54e 100644
--- a/chrome/browser/vr/ui.cc
+++ b/chrome/browser/vr/ui.cc
@@ -85,20 +85,11 @@
 void Ui::SetWebVrMode(bool enabled) {
   if (enabled) {
     model_->web_vr.has_received_permissions = false;
-    if (!model_->web_vr_autopresentation_enabled()) {
-      // When auto-presenting, we transition into this state when the minimum
-      // splash-screen duration has passed.
-      model_->web_vr.state = kWebVrAwaitingFirstFrame;
-    }
-    // We have this check here so that we don't set the mode to kModeWebVr when
-    // it should be kModeWebVrAutopresented. The latter is set when the UI is
-    // initialized.
-    if (!model_->web_vr_enabled())
-      model_->push_mode(kModeWebVr);
+    model_->web_vr.state = kWebVrAwaitingFirstFrame;
+    model_->push_mode(kModeWebVr);
   } else {
     model_->web_vr.state = kWebVrNoTimeoutPending;
-    if (model_->web_vr_enabled())
-      model_->pop_mode();
+    model_->pop_mode();
   }
 }
 
@@ -279,9 +270,7 @@
 }
 
 bool Ui::CanSendWebVrVSync() {
-  return model_->web_vr_enabled() &&
-         !model_->web_vr.awaiting_min_splash_screen_duration() &&
-         !model_->web_vr.showing_hosted_ui;
+  return model_->web_vr_enabled() && !model_->web_vr.showing_hosted_ui;
 }
 
 void Ui::SetAlertDialogEnabled(bool enabled,
@@ -360,9 +349,8 @@
 }
 
 void Ui::OnAppButtonClicked() {
-  // App button clicks should be a no-op when auto-presenting WebVR or if
-  // browsing mode is disabled.
-  if (model_->web_vr_autopresentation_enabled() || model_->browsing_disabled)
+  // App button clicks should be a no-op when browsing mode is disabled.
+  if (model_->browsing_disabled)
     return;
 
   if (model_->reposition_window_enabled()) {
@@ -525,12 +513,7 @@
   if (ui_initial_state.in_web_vr) {
     auto mode = kModeWebVr;
     model_->web_vr.has_received_permissions = false;
-    if (ui_initial_state.web_vr_autopresentation_expected) {
-      mode = kModeWebVrAutopresented;
-      model_->web_vr.state = kWebVrAwaitingMinSplashScreenDuration;
-    } else {
-      model_->web_vr.state = kWebVrAwaitingFirstFrame;
-    }
+    model_->web_vr.state = kWebVrAwaitingFirstFrame;
     model_->push_mode(mode);
   }
 
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h
index 95fe821..ef95ef1 100644
--- a/chrome/browser/vr/ui.h
+++ b/chrome/browser/vr/ui.h
@@ -120,11 +120,6 @@
   void RemoveTab(int id, bool incognito) override;
   void RemoveAllTabs() override;
 
-  // TODO(ymalik): We expose this to stop sending VSync to the WebVR page until
-  // the splash screen has been visible for its minimum duration. The visibility
-  // logic currently lives in the UI, and it'd be much cleaner if the UI didn't
-  // have to worry about this, and if it were told to hide the splash screen
-  // like other WebVR phases (e.g. OnWebVrFrameAvailable below).
   bool CanSendWebVrVSync();
 
   void SetAlertDialogEnabled(bool enabled,
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc
index b58dc958..cad0d528 100644
--- a/chrome/browser/vr/ui_scene_creator.cc
+++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1509,7 +1509,6 @@
 }
 
 void UiSceneCreator::CreateWebVrSubtree() {
-  CreateSplashScreenForDirectWebVrLaunch();
   CreateWebVrOverlayElements();
   CreateWebVrTimeoutScreen();
 
@@ -1557,72 +1556,16 @@
   scene_->AddUiElement(kWebVrRoot, std::move(bg));
 }
 
-void UiSceneCreator::CreateSplashScreenForDirectWebVrLaunch() {
-  // Create transient parent.
-  // TODO(crbug.com/762074): We should timeout after some time and show an
-  // error if the user is stuck on the splash screen.
-  auto transient_parent = std::make_unique<ShowUntilSignalTransientElement>(
-      base::TimeDelta::FromSeconds(kSplashScreenMinDurationSeconds),
-      base::TimeDelta::Max(),
-      base::BindRepeating(
-          [](Model* model) {
-            DCHECK(model->web_vr.awaiting_min_splash_screen_duration());
-            // TODO(ymalik): The assumption here is that the WebVR VSync will be
-            // paused until the min splash screen duration passes. This state
-            // change should be driven by the scheduler in the future and the UI
-            // should act on it.
-            model->web_vr.state = kWebVrAwaitingFirstFrame;
-          },
-          base::Unretained(model_)),
-      base::BindRepeating(
-          [](Model* model, UiBrowserInterface* browser,
-             TransientElementHideReason reason) {
-            if (reason == TransientElementHideReason::kTimeout) {
-              browser->ExitPresent();
-            }
-          },
-          base::Unretained(model_), base::Unretained(browser_)));
-  transient_parent->SetName(kSplashScreenTransientParent);
-  transient_parent->SetTransitionedProperties({OPACITY});
-  VR_BIND_VISIBILITY(transient_parent,
-                     model->web_vr_autopresentation_enabled());
-  transient_parent->AddBinding(VR_BIND_FUNC(
-      bool, Model, model_,
-      model->web_vr_autopresentation_enabled() &&
-          model->web_vr.state > kWebVrAwaitingFirstFrame,
-      ShowUntilSignalTransientElement, transient_parent.get(), Signal));
-  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(transient_parent));
-
-  // Add "Running in Chrome" text.
-  auto text_scaler =
-      std::make_unique<ScaledDepthAdjuster>(kSplashScreenTextDistance);
-  auto text = std::make_unique<Text>(kSplashScreenTextFontHeightDMM);
-  VR_BIND_COLOR(model_, text.get(), &ColorScheme::splash_screen_text_color,
-                &Text::SetColor);
-  text->SetText(l10n_util::GetStringUTF16(IDS_VR_RUNNING_IN_CHROME_MESSAGE));
-  text->SetName(kSplashScreenText);
-  text->SetDrawPhase(kPhaseForeground);
-  text->SetFieldWidth(kSplashScreenTextWidthDMM);
-  text->SetTranslate(0, kSplashScreenTextVerticalOffsetDMM, 0);
-  text_scaler->AddChild(std::move(text));
-  scene_->AddUiElement(kSplashScreenTransientParent, std::move(text_scaler));
-}
-
 void UiSceneCreator::CreateWebVrTimeoutScreen() {
   auto scaler = std::make_unique<ScaledDepthAdjuster>(kTimeoutScreenDisatance);
   scaler->SetName(kWebVrTimeoutRoot);
   scaler->AddBinding(std::make_unique<Binding<bool>>(
       VR_BIND_LAMBDA(
-          [](Model* model, UiElement* splash_screen) {
-            // The timeout UI should only be visible when the splash screen is
-            // not visible.
+          [](Model* model) {
             return (model->web_vr.state == kWebVrTimeoutImminent ||
-                    model->web_vr.state == kWebVrTimedOut) &&
-                   splash_screen->GetTargetOpacity() == 0.f;
+                    model->web_vr.state == kWebVrTimedOut);
           },
-          base::Unretained(model_),
-          base::Unretained(
-              scene_->GetUiElementByName(kSplashScreenTransientParent))),
+          base::Unretained(model_)),
       VR_BIND_LAMBDA(
           [](UiElement* e, const bool& value) { e->SetVisible(value); },
           base::Unretained(scaler.get()))));
@@ -2941,26 +2884,6 @@
 }
 
 void UiSceneCreator::CreateWebVrOverlayElements() {
-  // Create url toast shown when WebVR is auto-presented.
-  auto parent = CreateTransientParent(kWebVrUrlToastTransientParent,
-                                      kToastTimeoutSeconds, true);
-  parent->AddBinding(std::make_unique<Binding<bool>>(
-      VR_BIND_LAMBDA(
-          [](Model* model, UiElement* splash_screen) {
-            // The WebVR indicators should only be visible when the splash
-            // screen is not visible.
-            return model->web_vr_autopresentation_enabled() &&
-                   model->web_vr.presenting_web_vr() &&
-                   splash_screen->GetTargetOpacity() == 0.f;
-          },
-          base::Unretained(model_),
-          base::Unretained(
-              scene_->GetUiElementByName(kSplashScreenTransientParent))),
-      VR_BIND_LAMBDA(
-          [](UiElement* e, const bool& value) { e->SetVisible(value); },
-          base::Unretained(parent.get()))));
-  scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(parent));
-
   // Create transient WebVR elements.
   auto indicators = Create<LinearLayout>(kWebVrIndicatorLayout, kPhaseNone,
                                          LinearLayout::kDown);
@@ -2979,39 +2902,23 @@
                                    false};
   indicators->AddChild(CreateWebVrIndicator(model_, browser_, app_button_spec));
 
-  IndicatorSpec url_indicator_spec = {kNone,
-                                      kWebVrUrlToast,
-                                      toolbar::kHttpsInvalidIcon,
-                                      0,
-                                      0,
-                                      0,
-                                      nullptr,
-                                      nullptr,
-                                      nullptr,
-                                      true};
-  indicators->AddChild(
-      CreateWebVrIndicator(model_, browser_, url_indicator_spec));
-
   auto specs = GetIndicatorSpecs();
   for (const auto& spec : specs) {
     indicators->AddChild(CreateWebVrIndicator(model_, browser_, spec));
   }
 
-  parent = CreateTransientParent(kWebVrIndicatorTransience,
-                                 kToastTimeoutSeconds, true);
+  auto parent = CreateTransientParent(kWebVrIndicatorTransience,
+                                      kToastTimeoutSeconds, true);
   parent->AddBinding(std::make_unique<Binding<std::tuple<bool, bool, bool>>>(
       VR_BIND_LAMBDA(
-          [](Model* model, UiElement* splash_screen) {
+          [](Model* model) {
             return std::tuple<bool, bool, bool>(
                 model->web_vr_enabled() && model->web_vr.presenting_web_vr() &&
-                    model->web_vr.has_received_permissions &&
-                    splash_screen->GetTargetOpacity() == 0.f,
+                    model->web_vr.has_received_permissions,
                 model->controller.app_button_long_pressed,
                 model->web_vr.showing_hosted_ui);
           },
-          base::Unretained(model_),
-          base::Unretained(
-              scene_->GetUiElementByName(kSplashScreenTransientParent))),
+          base::Unretained(model_)),
       VR_BIND_LAMBDA(
           [](TransientElement* e, Model* model, UiScene* scene,
              const base::Optional<std::tuple<bool, bool, bool>>& last_value,
@@ -3045,11 +2952,7 @@
             e->RefreshVisible();
             SetVisibleInLayout(
                 scene->GetUiElementByName(kWebVrExclusiveScreenToast),
-                !model->web_vr_autopresentation_enabled() &&
-                    !model->browsing_disabled && !in_long_press);
-            SetVisibleInLayout(scene->GetUiElementByName(kWebVrUrlToast),
-                               model->web_vr_autopresentation_enabled() &&
-                                   model->toolbar_state.should_display_url);
+                !model->browsing_disabled && !in_long_press);
 
             auto specs = GetIndicatorSpecs();
             for (const auto& spec : specs) {
diff --git a/chrome/browser/vr/ui_scene_creator.h b/chrome/browser/vr/ui_scene_creator.h
index ce2b8f4..9bee8ca0 100644
--- a/chrome/browser/vr/ui_scene_creator.h
+++ b/chrome/browser/vr/ui_scene_creator.h
@@ -54,7 +54,6 @@
   void CreateExitWarning();
   void CreateWebVrSubtree();
   void CreateWebVrOverlayElements();
-  void CreateSplashScreenForDirectWebVrLaunch();
   void CreateWebVrTimeoutScreen();
   void CreateController();
   void CreateKeyboard();
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc
index d3ee3c7..2d760f2 100644
--- a/chrome/browser/vr/ui_unittest.cc
+++ b/chrome/browser/vr/ui_unittest.cc
@@ -388,54 +388,6 @@
   EXPECT_TRUE(IsVisible(kContentQuad));
 }
 
-TEST_F(UiTest, WebVrAutopresented) {
-  CreateSceneForAutoPresentation();
-
-  // Initially, we should only show the splash screen.
-  VerifyOnlyElementsVisible("Initial", {kSplashScreenText, kWebVrBackground});
-
-  // Enter WebVR with autopresentation.
-  ui_->SetWebVrMode(true);
-  ui_->SetCapturingState(CapturingStateModel());
-
-  // The splash screen should go away.
-  RunForSeconds(kSplashScreenMinDurationSeconds + kSmallDelaySeconds);
-  ui_->OnWebVrFrameAvailable();
-  RunForMs(200);
-  EXPECT_TRUE(IsVisible(kWebVrUrlToast));
-
-  // Make sure the transient URL bar times out.
-  RunForSeconds(kToastTimeoutSeconds + kSmallDelaySeconds + 1);
-  EXPECT_FALSE(IsVisible(kWebVrUrlToast));
-}
-
-TEST_F(UiTest, WebVrSplashScreenHiddenWhenTimeoutImminent) {
-  CreateSceneForAutoPresentation();
-
-  // Initially, we should only show the splash screen.
-  VerifyOnlyElementsVisible("Initial", {kSplashScreenText, kWebVrBackground});
-
-  ui_->SetWebVrMode(true);
-  EXPECT_FALSE(
-      RunForSeconds(kSplashScreenMinDurationSeconds + kSmallDelaySeconds * 2));
-
-  ui_->OnWebVrTimeoutImminent();
-  EXPECT_TRUE(RunForMs(10));
-
-  VerifyOnlyElementsVisible(
-      "Timeout imminent",
-      {kWebVrTimeoutSpinner, kWebVrBackground, kWebVrFloor});
-}
-
-TEST_F(UiTest, AppButtonClickForAutopresentation) {
-  CreateSceneForAutoPresentation();
-
-  // Clicking app button should be a no-op.
-  EXPECT_CALL(*browser_, ExitPresent()).Times(0);
-  EXPECT_CALL(*browser_, ExitFullscreen()).Times(0);
-  ui_->OnAppButtonClicked();
-}
-
 TEST_F(UiTest, HostedUiInWebVr) {
   CreateScene(kNotInCct, kInWebVr);
   VerifyVisibility({kWebVrHostedUi, kWebVrFloor}, false);
@@ -1082,50 +1034,6 @@
   ui_->OnAppButtonClicked();
 }
 
-// Tests that transient elements will show, even if there is a long delay
-// between when they are asked to appear and when we issue the first frame with
-// them visible.
-TEST_F(UiTest, TransientToastsWithDelayedFirstFrame) {
-  CreateSceneForAutoPresentation();
-
-  // Initially, we should only show the splash screen.
-  EXPECT_TRUE(IsVisible(kSplashScreenText));
-  EXPECT_TRUE(IsVisible(kWebVrBackground));
-  EXPECT_FALSE(IsVisible(kWebVrUrlToast));
-
-  // Enter WebVR with autopresentation.
-  ui_->SetWebVrMode(true);
-  ui_->SetCapturingState(CapturingStateModel());
-  OnDelayedFrame(MsToDelta(1000 * kSplashScreenMinDurationSeconds));
-  EXPECT_TRUE(IsVisible(kSplashScreenText));
-  EXPECT_TRUE(IsVisible(kWebVrBackground));
-  EXPECT_FALSE(IsVisible(kWebVrUrlToast));
-
-  OnDelayedFrame(MsToDelta(2000));
-  ui_->OnWebVrTimeoutImminent();
-  OnDelayedFrame(MsToDelta(3000));
-  ui_->OnWebVrTimedOut();
-
-  // A while later, receive only one frame (possibly a splash screen). This will
-  // trigger indicators to start fading in, but they won't actually be visible
-  // on the first frame.  The transient element should know that it's not
-  // visible, and not start its timeout.
-  OnDelayedFrame(MsToDelta(5000));
-  ui_->OnWebVrFrameAvailable();
-  EXPECT_FALSE(IsVisible(kSplashScreenText));
-  EXPECT_FALSE(IsVisible(kWebVrBackground));
-  EXPECT_TRUE(IsVisible(kWebVrUrlToast));
-
-  // If we advance far beyond the timeout for our first frame and our logic was
-  // naive, we would start to hide the transient element.  But, because the
-  // transient element was never actually visible, it should still be showing.
-  OnDelayedFrame(MsToDelta(40000));
-  EXPECT_TRUE(IsVisible(kWebVrUrlToast));
-
-  // Now that it's been seen, it should transiently fade.
-  OnDelayedFrame(MsToDelta(10000));
-  EXPECT_FALSE(IsVisible(kWebVrUrlToast));
-}
 
 TEST_F(UiTest, DefaultBackgroundWhenNoAssetAvailable) {
   UiInitialState state;
diff --git a/chrome/service/OWNERS b/chrome/service/OWNERS
index 3a21c291..3b8d2d0 100644
--- a/chrome/service/OWNERS
+++ b/chrome/service/OWNERS
@@ -1,5 +1,3 @@
-gene@chromium.org
-scottbyer@chromium.org
-vitalybuka@chromium.org
+file://cloud_print/OWNERS
 
 # COMPONENT: Services>CloudPrint
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9d724a1..b4b4568 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -5406,6 +5406,7 @@
       "../browser/sync/test/integration/single_client_sessions_sync_test.cc",
       "../browser/sync/test/integration/single_client_themes_sync_test.cc",
       "../browser/sync/test/integration/single_client_typed_urls_sync_test.cc",
+      "../browser/sync/test/integration/single_client_user_consents_sync_test.cc",
       "../browser/sync/test/integration/single_client_user_events_sync_test.cc",
       "../browser/sync/test/integration/single_client_wallet_sync_test.cc",
       "../browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc",
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 2768b19..13e1e62f 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -17,8 +17,6 @@
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/printing/print_job_manager.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h"
-#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_paths.h"
@@ -54,6 +52,8 @@
 #endif
 
 #if !defined(OS_ANDROID)
+#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "components/keep_alive_registry/keep_alive_registry.h"
 #endif
 
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 0fa8be5..e07bf803 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -463,6 +463,10 @@
     "//components/prefs",
     "//media:test_support",
   ]
+
+  data = [
+    "//media/test/data/",
+  ]
 }
 
 cast_source_set("unittests") {
diff --git a/chromecast/device/bluetooth/le/mock_gatt_client_manager.h b/chromecast/device/bluetooth/le/mock_gatt_client_manager.h
index f900ef3..f8d97571 100644
--- a/chromecast/device/bluetooth/le/mock_gatt_client_manager.h
+++ b/chromecast/device/bluetooth/le/mock_gatt_client_manager.h
@@ -5,7 +5,7 @@
 #ifndef CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_
 #define CHROMECAST_DEVICE_BLUETOOTH_LE_MOCK_GATT_CLIENT_MANAGER_H_
 
-#include "base/containers/flat_set.h"
+#include "base/observer_list.h"
 #include "chromecast/device/bluetooth/le/gatt_client_manager.h"
 #include "chromecast/device/bluetooth/le/mock_remote_device.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -18,14 +18,8 @@
   MockGattClientManager();
   ~MockGattClientManager();
 
-  void AddObserver(Observer* o) override {
-    DCHECK(o && !observers_.count(o));
-    observers_.insert(o);
-  }
-  void RemoveObserver(Observer* o) override {
-    DCHECK(o && observers_.count(o));
-    observers_.erase(o);
-  }
+  void AddObserver(Observer* o) override { observers_.AddObserver(o); }
+  void RemoveObserver(Observer* o) override { observers_.RemoveObserver(o); }
 
   MOCK_METHOD1(
       GetDevice,
@@ -43,7 +37,7 @@
   MOCK_METHOD1(NotifyConnect, void(const bluetooth_v2_shlib::Addr& addr));
   MOCK_METHOD0(task_runner, scoped_refptr<base::SingleThreadTaskRunner>());
 
-  base::flat_set<Observer*> observers_;
+  base::ObserverList<Observer> observers_;
 };
 
 }  // namespace bluetooth
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h
index 0108f6b8..def50bad 100644
--- a/components/autofill/content/renderer/form_autofill_util.h
+++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -293,6 +293,10 @@
 blink::WebFormElement FindFormByUniqueRendererId(blink::WebDocument doc,
                                                  uint32_t form_renderer_id);
 
+// Note: The vector-based API of the following two functions is a tax for limiting
+// the frequency and duration of retrieving a lot of DOM elements. Alternative
+// solutions have been discussed on https://crrev.com/c/1108201.
+
 // Returns form control elements by unique renderer id. The result has the same
 // number elements as |form_control_renderer_ids| and i-th element of the result
 // corresponds to the i-th element of |form_control_renderer_ids|.
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 52845f3f..1095a03 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -96,23 +96,6 @@
 // The time limit, in ms, between a fill and when a refill can happen.
 const int kLimitBeforeRefillMs = 1000;
 
-// Precondition: |form_structure| and |form| should correspond to the same
-// logical form.  Returns true if any field in the given |section| within |form|
-// is auto-filled.
-bool SectionHasAutofilledField(const FormStructure& form_structure,
-                               const FormData& form,
-                               const std::string& section) {
-  DCHECK_EQ(form_structure.field_count(), form.fields.size());
-  for (size_t i = 0; i < form_structure.field_count(); ++i) {
-    if (form_structure.field(i)->section == section &&
-        form.fields[i].is_autofilled) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
 // Returns the credit card field |value| trimmed from whitespace and with stop
 // characters removed.
 base::string16 SanitizeCreditCardFieldValue(const base::string16& value) {
@@ -562,8 +545,7 @@
       // suggestions available.
       // TODO(mathp): Differentiate between number of suggestions available
       // (current metric) and number shown to the user.
-      if (!has_logged_address_suggestions_count_ &&
-          !context.section_has_autofilled_field) {
+      if (!has_logged_address_suggestions_count_) {
         AutofillMetrics::LogAddressSuggestionsCount(suggestions.size());
         has_logged_address_suggestions_count_ = true;
       }
@@ -2079,27 +2061,6 @@
     warning_suggestion.frontend_id =
         POPUP_ITEM_ID_INSECURE_CONTEXT_PAYMENT_DISABLED_MESSAGE;
     suggestions->assign(1, warning_suggestion);
-  } else {
-    context->section_has_autofilled_field = SectionHasAutofilledField(
-        *context->form_structure, form, context->focused_field->section);
-    if (context->section_has_autofilled_field) {
-      // If the relevant section has auto-filled  fields and the renderer is
-      // querying for suggestions, then for some fields, the user is editing
-      // the value of a field. In this case, mimic autocomplete: don't
-      // display labels or icons, as that information is redundant.
-      // Moreover, filter out duplicate suggestions.
-      std::set<base::string16> seen_values;
-      for (auto iter = suggestions->begin(); iter != suggestions->end();) {
-        if (!seen_values.insert(iter->value).second) {
-          // If we've seen this suggestion value before, remove it.
-          iter = suggestions->erase(iter);
-        } else {
-          iter->label.clear();
-          iter->icon.clear();
-          ++iter;
-        }
-      }
-    }
   }
 }
 
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 16b016b..943ba12 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -329,7 +329,6 @@
     bool is_filling_credit_card = false;
     // Flag to indicate whether all suggestions come from Google Payments.
     bool is_all_server_suggestions = false;
-    bool section_has_autofilled_field = false;
     SuppressReason suppress_reason = SuppressReason::kNotSuppressed;
   };
 
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 617d3c2c..c4d0fe8 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -997,9 +997,10 @@
 
   // Test that we sent the right values to the external delegate. No labels,
   // with duplicate values "Grimes" merged.
-  CheckSuggestions(kDefaultPageID,
-                   Suggestion("Googler", "" /* no label */, "", 1),
-                   Suggestion("Grimes", "" /* no label */, "", 2));
+  CheckSuggestions(
+      kDefaultPageID, Suggestion("Googler", "1600 Amphitheater pkwy", "", 1),
+      Suggestion("Grimes", "1234 Smith Blvd., Carl Grimes", "", 2),
+      Suggestion("Grimes", "1234 Smith Blvd., Robin Grimes", "", 3));
 }
 
 // Tests that we return address profile suggestions values when the section
@@ -1021,7 +1022,7 @@
 
   // Test that we sent the right values to the external delegate. No labels.
   CheckSuggestions(kDefaultPageID,
-                   Suggestion("Elvis", "" /* no label */, "", 1));
+                   Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", 1));
 }
 
 // Test that we return no suggestions when the form has no relevant fields.
@@ -1547,7 +1548,7 @@
       AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
 }
 
-// Test that we return autocomplete-like suggestions when trying to autofill
+// Test that we return normal autofill suggestions when trying to autofill
 // already filled forms.
 TEST_F(AutofillManagerTest, GetFieldSuggestionsWhenFormIsAutofilled) {
   // Set up our form data.
@@ -1562,8 +1563,9 @@
   GetAutofillSuggestions(form, field);
 
   // Test that we sent the right values to the external delegate.
-  CheckSuggestions(kDefaultPageID, Suggestion("Charles", "", "", 1),
-                   Suggestion("Elvis", "", "", 2));
+  CheckSuggestions(kDefaultPageID,
+                   Suggestion("Charles", "123 Apple St.", "", 1),
+                   Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", 2));
 }
 
 // Test that nothing breaks when there are autocomplete suggestions but no
@@ -1614,7 +1616,8 @@
   GetAutofillSuggestions(form, field);
 
   // Test that we sent the right values to the external delegate.
-  CheckSuggestions(kDefaultPageID, Suggestion("Elvis", "", "", 1));
+  CheckSuggestions(kDefaultPageID,
+                   Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", 1));
 }
 
 TEST_F(AutofillManagerTest, GetProfileSuggestions_FancyPhone) {
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 069f520..c35de1e 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -2716,12 +2716,12 @@
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
-    // Simulate activating the autofill popup for the email field after typing.
+    // Simulate activating the autofill popup for the email field after a fill.
     form.fields[0].is_autofilled = true;
     base::HistogramTester histogram_tester;
     autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-    histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 0);
+    histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 1);
   }
 }
 
diff --git a/components/autofill/core/browser/test_sync_service.cc b/components/autofill/core/browser/test_sync_service.cc
index 8fc0ada..8199fed4 100644
--- a/components/autofill/core/browser/test_sync_service.cc
+++ b/components/autofill/core/browser/test_sync_service.cc
@@ -34,6 +34,10 @@
   return is_engine_initialized_;
 }
 
+bool TestSyncService::IsFirstSetupComplete() const {
+  return true;
+}
+
 bool TestSyncService::IsUsingSecondaryPassphrase() const {
   return is_using_secondary_passphrase_;
 }
diff --git a/components/autofill/core/browser/test_sync_service.h b/components/autofill/core/browser/test_sync_service.h
index df67fb2..39044613 100644
--- a/components/autofill/core/browser/test_sync_service.h
+++ b/components/autofill/core/browser/test_sync_service.h
@@ -20,6 +20,7 @@
   syncer::ModelTypeSet GetPreferredDataTypes() const override;
   syncer::ModelTypeSet GetActiveDataTypes() const override;
   bool IsEngineInitialized() const override;
+  bool IsFirstSetupComplete() const override;
   bool IsUsingSecondaryPassphrase() const override;
   bool IsSyncActive() const override;
   bool ConfigurationDone() const override;
diff --git a/components/navigation_metrics/OWNERS b/components/navigation_metrics/OWNERS
index a815f481..db827c8 100644
--- a/components/navigation_metrics/OWNERS
+++ b/components/navigation_metrics/OWNERS
@@ -1,4 +1,4 @@
-cbentzel@chromium.org
+cthomp@chromium.org
 davidben@chromium.org
 estark@chromium.org
 
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc
index 1f74366..11a2730 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -402,20 +402,20 @@
     std::vector<gaia::ListedAccount>* accounts,
     std::vector<gaia::ListedAccount>* signed_out_accounts,
     const std::string& source) {
-  if (!list_accounts_stale_) {
-    if (accounts)
-      accounts->assign(listed_accounts_.begin(), listed_accounts_.end());
+  if (accounts)
+    accounts->assign(listed_accounts_.begin(), listed_accounts_.end());
 
-    if (signed_out_accounts) {
-      signed_out_accounts->assign(signed_out_accounts_.begin(),
-                                  signed_out_accounts_.end());
-    }
-
-    return true;
+  if (signed_out_accounts) {
+    signed_out_accounts->assign(signed_out_accounts_.begin(),
+                                signed_out_accounts_.end());
   }
 
-  TriggerListAccounts(source);
-  return false;
+  if (list_accounts_stale_) {
+    TriggerListAccounts(source);
+    return false;
+  }
+
+  return true;
 }
 
 void GaiaCookieManagerService::TriggerListAccounts(const std::string& source) {
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h
index 31a08a6..a7d75f1 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.h
+++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -180,11 +180,11 @@
                                    const std::string& access_token,
                                    const std::string& source);
 
-  // Returns if the listed accounts are up to date or not (ignore the out
-  // parameter if return is false). The parameter will be assigned the current
-  // cached accounts. If the accounts are not up to date, a ListAccounts fetch
-  // is sent GAIA and Observer::OnGaiaAccountsInCookieUpdated will be called.
-  // If either of |accounts| or |signed_out_accounts| is null, the corresponding
+  // Returns if the listed accounts are up to date or not. The out parameter
+  // will be assigned the current cached accounts (whether they are not up to
+  // date or not). If the accounts are not up to date, a ListAccounts fetch is
+  // sent GAIA and Observer::OnGaiaAccountsInCookieUpdated will be called.  If
+  // either of |accounts| or |signed_out_accounts| is null, the corresponding
   // accounts returned from /ListAccounts are ignored.
   bool ListAccounts(std::vector<gaia::ListedAccount>* accounts,
                     std::vector<gaia::ListedAccount>* signed_out_accounts,
diff --git a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
index 3f9195cf..1c47d2f20 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
@@ -716,14 +716,13 @@
 
   // OnCookieChange should invalidate the cached data.
 
-  // Clear the list before calling |ListAccounts()| as GaiaCookieManagerService
-  // simply leaves the input unaffected in the case where the accounts are
-  // stale.
+  // Clear the list before calling |ListAccounts()| to make sure that
+  // GaiaCookieManagerService repopulates it with the stale cached information.
   list_accounts.clear();
 
   ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts,
                                    GaiaConstants::kChromeSource));
-  ASSERT_TRUE(list_accounts.empty());
+  ASSERT_TRUE(AreAccountListsEqual(nonempty_list_accounts, list_accounts));
   ASSERT_TRUE(signed_out_accounts.empty());
   SimulateListAccountsSuccess(&helper, "[\"f\",[]]");
 }
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
index e3f1b6c7..1b50578 100644
--- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
+++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc
@@ -134,12 +134,15 @@
   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
                "SubresourceFilterSafeBrowsingActivationThrottle::NotifyResult");
   DCHECK(!check_results_.empty());
-  const std::vector<SubresourceFilterSafeBrowsingClient::CheckResult>
-      last_result_array = {check_results_.back()};
-  const bool consider_redirects = base::FeatureList::IsEnabled(
-      kSafeBrowsingSubresourceFilterConsiderRedirects);
-  const auto& check_results_to_consider =
-      consider_redirects ? check_results_ : last_result_array;
+
+  // Determine which results to consider for safebrowsing/abusive.
+  std::vector<SubresourceFilterSafeBrowsingClient::CheckResult>
+      check_results_to_consider = {check_results_.back()};
+  if (check_results_.size() >= 2 &&
+      base::FeatureList::IsEnabled(
+          kSafeBrowsingSubresourceFilterConsiderRedirects)) {
+    check_results_to_consider = {check_results_[0], check_results_.back()};
+  }
 
   // Find the ConfigResult for each safe browsing check.
   std::vector<ConfigResult> matched_configurations;
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
index 342cab7..7c71e86 100644
--- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
+++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -911,27 +911,34 @@
       "SubresourceFilter.PageLoad.Activation.RedirectPosition";
 
   // Set up the urls for enforcement.
-  GURL enforce_url("https://example.enforce");
-  GURL warn_url("https://example.warning");
   GURL normal_url("https://example.regular");
-  safe_browsing::SubresourceFilterType type =
-      safe_browsing::SubresourceFilterType::ABUSIVE;
-  safe_browsing::ThreatMetadata metadata;
-  metadata.subresource_filter_match[type] =
-      safe_browsing::SubresourceFilterLevel::WARN;
-  ConfigureForMatch(enforce_url,
-                    safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER);
-  ConfigureForMatch(warn_url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
-                    metadata);
+  GURL bad_url("https://example.bad");
+  GURL worse_url("https://example.worse");
+
+  // Set up the configurations, make phishing worse than subresource_filter.
+  Configuration config_p1(ActivationLevel::ENABLED,
+                          ActivationScope::ACTIVATION_LIST,
+                          ActivationList::SUBRESOURCE_FILTER);
+  config_p1.activation_conditions.priority = 1;
+  Configuration config_p2(ActivationLevel::ENABLED,
+                          ActivationScope::ACTIVATION_LIST,
+                          ActivationList::PHISHING_INTERSTITIAL);
+  config_p2.activation_conditions.priority = 2;
+  scoped_configuration()->ResetConfiguration({config_p1, config_p2});
+
+  // Configure the URLs to match on different lists, phishing is worse.
+  ConfigureForMatch(bad_url, safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER);
+  ConfigureForMatch(worse_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING);
 
   // Check cases where there are multiple redirection.
   const RedirectSamplesAndResults kTestCases[] = {
-      {{enforce_url, normal_url, normal_url}, true, ActivationPosition::kFirst},
-      {{warn_url, normal_url, enforce_url}, true, ActivationPosition::kLast},
-      {{enforce_url, normal_url, warn_url}, true, ActivationPosition::kFirst},
-      {{normal_url, enforce_url, warn_url}, true, ActivationPosition::kMiddle},
+      {{worse_url, normal_url, normal_url}, true, ActivationPosition::kFirst},
+      {{bad_url, normal_url, worse_url}, true, ActivationPosition::kLast},
+      {{worse_url, normal_url, bad_url}, true, ActivationPosition::kFirst},
+      {{normal_url, worse_url, bad_url}, true, ActivationPosition::kLast},
       {{normal_url, normal_url}, false, ActivationPosition::kMaxValue},
-      {{enforce_url}, true, ActivationPosition::kOnly},
+      {{normal_url, bad_url, normal_url}, false, ActivationPosition::kMaxValue},
+      {{worse_url}, true, ActivationPosition::kOnly},
   };
   for (const auto& test_case : kTestCases) {
     const base::HistogramTester histograms;
diff --git a/components/subresource_filter/core/common/document_subresource_filter.cc b/components/subresource_filter/core/common/document_subresource_filter.cc
index 07bd2ae..9b0bf70 100644
--- a/components/subresource_filter/core/common/document_subresource_filter.cc
+++ b/components/subresource_filter/core/common/document_subresource_filter.cc
@@ -34,7 +34,8 @@
 LoadPolicy DocumentSubresourceFilter::GetLoadPolicy(
     const GURL& subresource_url,
     url_pattern_index::proto::ElementType subresource_type) {
-  TRACE_EVENT1("loader", "DocumentSubresourceFilter::GetLoadPolicy", "url",
+  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("loading"),
+               "DocumentSubresourceFilter::GetLoadPolicy", "url",
                subresource_url.spec());
 
   ++statistics_.num_loads_total;
diff --git a/components/suggestions/suggestions_service_impl_unittest.cc b/components/suggestions/suggestions_service_impl_unittest.cc
index 442f3fc..f897ff6c 100644
--- a/components/suggestions/suggestions_service_impl_unittest.cc
+++ b/components/suggestions/suggestions_service_impl_unittest.cc
@@ -86,6 +86,8 @@
   MockSyncService() {}
   ~MockSyncService() override {}
   MOCK_CONST_METHOD0(GetDisableReasons, int());
+  MOCK_CONST_METHOD0(IsEngineInitialized, bool());
+  MOCK_CONST_METHOD0(IsFirstSetupComplete, bool());
   MOCK_CONST_METHOD0(IsSyncActive, bool());
   MOCK_CONST_METHOD0(ConfigurationDone, bool());
   MOCK_CONST_METHOD0(IsLocalSyncEnabled, bool());
@@ -156,6 +158,12 @@
     EXPECT_CALL(*sync_service(), GetDisableReasons())
         .Times(AnyNumber())
         .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
+    EXPECT_CALL(*sync_service(), IsEngineInitialized())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
+    EXPECT_CALL(*sync_service(), IsFirstSetupComplete())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(true));
     EXPECT_CALL(*sync_service(), IsSyncActive())
         .Times(AnyNumber())
         .WillRepeatedly(Return(true));
@@ -344,6 +352,8 @@
 // This should *not* result in an automatic fetch.
 TEST_F(SuggestionsServiceTest, DoesNotFetchOnStartup) {
   // The sync service starts out inactive.
+  EXPECT_CALL(*sync_service(), IsEngineInitialized())
+      .WillRepeatedly(Return(false));
   EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
   static_cast<SyncServiceObserver*>(suggestions_service())
       ->OnStateChanged(sync_service());
@@ -352,6 +362,8 @@
   ASSERT_FALSE(suggestions_service()->HasPendingRequestForTesting());
 
   // Sync getting enabled should not result in a fetch.
+  EXPECT_CALL(*sync_service(), IsEngineInitialized())
+      .WillRepeatedly(Return(true));
   EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(true));
   static_cast<SyncServiceObserver*>(suggestions_service())
       ->OnStateChanged(sync_service());
@@ -385,6 +397,8 @@
 }
 
 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncNotInitializedEnabled) {
+  EXPECT_CALL(*sync_service(), IsEngineInitialized())
+      .WillRepeatedly(Return(false));
   EXPECT_CALL(*sync_service(), IsSyncActive()).WillRepeatedly(Return(false));
   static_cast<SyncServiceObserver*>(suggestions_service())
       ->OnStateChanged(sync_service());
diff --git a/components/sync/driver/resources/types.html b/components/sync/driver/resources/types.html
index 1a39be6f..609ecc5 100644
--- a/components/sync/driver/resources/types.html
+++ b/components/sync/driver/resources/types.html
@@ -4,9 +4,12 @@
       <table id="type-counters-table">
         <thead>
           <tr>
-            <th class='type'>Type</th>
-            <th>Total Entries</th>
-
+            <th class='type' rowspan="2">Type</th>
+            <th rowspan="2">Total Entries</th>
+            <th colspan="8">Updates</th>
+            <th colspan="7">Commits</th>
+          </tr>
+          <tr>
             <th>Updates Received</th>
             <th>Reflected Updates Received</th>
             <th>Tombstone Updates Received</th>
@@ -18,7 +21,10 @@
             <th>Server Overwrite Conflicts</th>
             <th>Local Overwrite Conflicts</th>
 
-            <th>Commit Attempts</th>
+            <th>Creation Commit Attempts</th>
+            <th>Deletion Commit Attempts</th>
+            <th>Update Commit Attempts</th>
+            <th>All Commit Attempts</th>
             <th>Commit Successes</th>
             <th>Commit Conflicts</th>
             <th>Commit Errors</th>
@@ -40,6 +46,9 @@
             <td jscontent="counters.numServerOverwrites || 0">0</td>
             <td jscontent="counters.numLocalOverwrites || 0">0</td>
 
+            <td jscontent="counters.numCreationCommitsAttempted || 0">0</td>
+            <td jscontent="counters.numDeletionCommitsAttempted || 0">0</td>
+            <td jscontent="counters.numUpdateCommitsAttempted || 0">0</td>
             <td jscontent="counters.numCommitsAttempted || 0">0</td>
             <td jscontent="counters.numCommitsSuccess || 0">0</td>
             <td jscontent="counters.numCommitsConflict || 0">0</td>
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc
index 471bdff..94a91cf8 100644
--- a/components/sync/driver/sync_service_utils.cc
+++ b/components/sync/driver/sync_service_utils.cc
@@ -16,12 +16,11 @@
   // Note: Before configuration is done, GetPreferredDataTypes returns
   // "everything" (i.e. the default setting). If a data type is missing there,
   // it must be because the user explicitly disabled it.
-  if (!sync_service || !sync_service->CanSyncStart() ||
-      sync_service->IsLocalSyncEnabled() ||
-      !sync_service->GetPreferredDataTypes().Has(type) ||
-      sync_service->GetAuthError().IsPersistentError()) {
+  if (!sync_service || sync_service->IsLocalSyncEnabled() ||
+      !sync_service->GetPreferredDataTypes().Has(type)) {
     return UploadState::NOT_ACTIVE;
   }
+
   // If the given ModelType is encrypted with a custom passphrase, we also
   // consider uploading inactive, since Google can't read the data.
   // Note that encryption is tricky: Some data types (e.g. PASSWORDS) are always
@@ -32,22 +31,46 @@
       sync_service->IsUsingSecondaryPassphrase()) {
     return UploadState::NOT_ACTIVE;
   }
-  // TODO(crbug.com/831579): We currently need to wait for GetLastCycleSnapshot
-  // to return an initialized snapshot because we don't actually know if the
-  // token is valid until sync has tried it. This is bad because sync can take
-  // arbitrarily long to try the token (especially if the user doesn't have
-  // history sync enabled). Instead, if the identity code would persist
-  // persistent auth errors, we could read those from startup.
-  if (!sync_service->IsSyncActive() || !sync_service->ConfigurationDone() ||
-      !sync_service->GetLastCycleSnapshot().is_initialized()) {
-    return UploadState::INITIALIZING;
+
+  switch (sync_service->GetState()) {
+    case SyncService::State::DISABLED:
+      return UploadState::NOT_ACTIVE;
+
+    case SyncService::State::AUTH_ERROR:
+      // For transient errors, give the benefit of the doubt and say we're
+      // INITIALIZING.
+      if (sync_service->GetAuthError().IsTransientError()) {
+        return UploadState::INITIALIZING;
+      }
+      return UploadState::NOT_ACTIVE;
+
+    case SyncService::State::WAITING_FOR_START_REQUEST:
+    case SyncService::State::START_DEFERRED:
+    case SyncService::State::INITIALIZING:
+    case SyncService::State::WAITING_FOR_CONSENT:
+    case SyncService::State::CONFIGURING:
+      return UploadState::INITIALIZING;
+
+    case SyncService::State::ACTIVE:
+      // If sync is active, but the data type in question still isn't, then
+      // something must have gone wrong with that data type.
+      if (!sync_service->GetActiveDataTypes().Has(type)) {
+        return UploadState::NOT_ACTIVE;
+      }
+      // TODO(crbug.com/831579): We currently need to wait for
+      // GetLastCycleSnapshot to return an initialized snapshot because we don't
+      // actually know if the token is valid until sync has tried it. This is
+      // bad because sync can take arbitrarily long to try the token (especially
+      // if the user doesn't have history sync enabled). Instead, if the
+      // identity code would persist persistent auth errors, we could read those
+      // from startup.
+      if (!sync_service->GetLastCycleSnapshot().is_initialized()) {
+        return UploadState::INITIALIZING;
+      }
+      return UploadState::ACTIVE;
   }
-  // If configuration is done and sync is active, but the data type in question
-  // still isn't, then something must have gone wrong with that data type.
-  if (!sync_service->GetActiveDataTypes().Has(type)) {
-    return UploadState::NOT_ACTIVE;
-  }
-  return UploadState::ACTIVE;
+  NOTREACHED();
+  return UploadState::NOT_ACTIVE;
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_service_utils.h b/components/sync/driver/sync_service_utils.h
index d97fcfa..65f29ec 100644
--- a/components/sync/driver/sync_service_utils.h
+++ b/components/sync/driver/sync_service_utils.h
@@ -17,8 +17,9 @@
 // A Java counterpart will be generated for this enum.
 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.sync
 enum class UploadState {
-  // Syncing is enabled in principle, but the sync service is still
-  // initializing, so e.g. we don't know about any auth errors yet.
+  // Syncing is enabled in principle, but the sync service is not actually
+  // active yet. Either it's still initializing (in which case we e.g. don't
+  // know about any auth errors yet), or it's in a transient auth error state.
   INITIALIZING,
   // We are not syncing to Google, and the caller should assume that we do not
   // have consent to do so. This can have a number of reasons, e.g.: sync as a
diff --git a/components/sync/driver/sync_service_utils_unittest.cc b/components/sync/driver/sync_service_utils_unittest.cc
index e26224d..8ad67f58 100644
--- a/components/sync/driver/sync_service_utils_unittest.cc
+++ b/components/sync/driver/sync_service_utils_unittest.cc
@@ -36,8 +36,10 @@
 
   // SyncService implementation.
   int GetDisableReasons() const override { return disable_reasons_; }
+  bool IsEngineInitialized() const override { return sync_active_; }
   bool IsSyncActive() const override { return sync_active_; }
   bool IsLocalSyncEnabled() const override { return local_sync_enabled_; }
+  bool IsFirstSetupComplete() const override { return true; }
   ModelTypeSet GetPreferredDataTypes() const override {
     return preferred_data_types_;
   }
@@ -215,13 +217,13 @@
   ASSERT_EQ(UploadState::ACTIVE,
             GetUploadToGoogleState(&service, syncer::BOOKMARKS));
 
-  // On a transient error, uploading remains active.
+  // On a transient error, uploading goes back to INITIALIZING.
   GoogleServiceAuthError transient_error(
       GoogleServiceAuthError::CONNECTION_FAILED);
   ASSERT_TRUE(transient_error.IsTransientError());
   service.set_auth_error(transient_error);
 
-  EXPECT_EQ(UploadState::ACTIVE,
+  EXPECT_EQ(UploadState::INITIALIZING,
             GetUploadToGoogleState(&service, syncer::BOOKMARKS));
 
   // On a persistent error, uploading is not considered active anymore (even
diff --git a/components/sync/engine/cycle/commit_counters.cc b/components/sync/engine/cycle/commit_counters.cc
index d2a79f10..8ca4eab 100644
--- a/components/sync/engine/cycle/commit_counters.cc
+++ b/components/sync/engine/cycle/commit_counters.cc
@@ -9,7 +9,9 @@
 namespace syncer {
 
 CommitCounters::CommitCounters()
-    : num_commits_attempted(0),
+    : num_creation_commits_attempted(0),
+      num_deletion_commits_attempted(0),
+      num_update_commits_attempted(0),
       num_commits_success(0),
       num_commits_conflict(0),
       num_commits_error(0) {}
@@ -18,7 +20,14 @@
 
 std::unique_ptr<base::DictionaryValue> CommitCounters::ToValue() const {
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  value->SetInteger("numCommitsAttempted", num_commits_attempted);
+  value->SetInteger("numCreationCommitsAttempted",
+                    num_creation_commits_attempted);
+  value->SetInteger("numDeletionCommitsAttempted",
+                    num_deletion_commits_attempted);
+  value->SetInteger("numUpdateCommitsAttempted", num_update_commits_attempted);
+  value->SetInteger("numCommitsAttempted", num_creation_commits_attempted +
+                                               num_deletion_commits_attempted +
+                                               num_update_commits_attempted);
   value->SetInteger("numCommitsSuccess", num_commits_success);
   value->SetInteger("numCommitsConflict", num_commits_conflict);
   value->SetInteger("numCommitsError", num_commits_error);
diff --git a/components/sync/engine/cycle/commit_counters.h b/components/sync/engine/cycle/commit_counters.h
index 7b9fc010..f7cb353 100644
--- a/components/sync/engine/cycle/commit_counters.h
+++ b/components/sync/engine/cycle/commit_counters.h
@@ -20,7 +20,12 @@
   std::unique_ptr<base::DictionaryValue> ToValue() const;
   std::string ToString() const;
 
-  int num_commits_attempted;
+  // Counters updated before sending a commit message to the server.
+  int num_creation_commits_attempted;
+  int num_deletion_commits_attempted;
+  int num_update_commits_attempted;
+
+  // Counters updated based on the response from the server.
   int num_commits_success;
   int num_commits_conflict;
   int num_commits_error;
diff --git a/components/sync/engine_impl/directory_commit_contribution.cc b/components/sync/engine_impl/directory_commit_contribution.cc
index efce62a8d..b1ce01c 100644
--- a/components/sync/engine_impl/directory_commit_contribution.cc
+++ b/components/sync/engine_impl/directory_commit_contribution.cc
@@ -67,7 +67,16 @@
     commit_message->add_client_contexts()->Swap(&context_);
 
   CommitCounters* counters = debug_info_emitter_->GetMutableCommitCounters();
-  counters->num_commits_attempted += entities_.size();
+  for (const sync_pb::SyncEntity& entity : entities_) {
+    // Update the relevant counter based on the type of |entity|.
+    if (entity.deleted()) {
+      counters->num_deletion_commits_attempted++;
+    } else if (entity.version() <= 0) {
+      counters->num_creation_commits_attempted++;
+    } else {
+      counters->num_update_commits_attempted++;
+    }
+  }
 }
 
 SyncerError DirectoryCommitContribution::ProcessCommitResponse(
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc
index 7a2ac8f..7164b7ae 100644
--- a/components/sync/engine_impl/model_type_worker_unittest.cc
+++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -103,9 +103,14 @@
 }
 
 void VerifyCommitCount(const DataTypeDebugInfoEmitter* emitter,
-                       int expected_count) {
-  EXPECT_EQ(expected_count, emitter->GetCommitCounters().num_commits_attempted);
-  EXPECT_EQ(expected_count, emitter->GetCommitCounters().num_commits_success);
+                       int expected_creation_count,
+                       int expected_deletion_count) {
+  EXPECT_EQ(expected_creation_count,
+            emitter->GetCommitCounters().num_creation_commits_attempted);
+  EXPECT_EQ(expected_deletion_count,
+            emitter->GetCommitCounters().num_deletion_commits_attempted);
+  EXPECT_EQ(expected_creation_count + expected_deletion_count,
+            emitter->GetCommitCounters().num_commits_success);
 }
 
 }  // namespace
@@ -510,7 +515,8 @@
   EXPECT_EQ(nullptr, worker()->GetContribution(INT_MAX));
   EXPECT_EQ(0U, server()->GetNumCommitMessages());
   EXPECT_EQ(0U, processor()->GetNumCommitResponses());
-  VerifyCommitCount(emitter(), 0);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/0,
+                    /*expected_deletion_count=*/0);
 
   worker()->NudgeForCommit();
   EXPECT_EQ(1, nudge_handler()->GetNumCommitNudges());
@@ -535,7 +541,8 @@
   EXPECT_FALSE(entity.deleted());
   EXPECT_EQ(kValue1, entity.specifics().preference().value());
 
-  VerifyCommitCount(emitter(), 1);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/1,
+                    /*expected_deletion_count=*/0);
 
   // Exhaustively verify the commit response returned to the model thread.
   ASSERT_EQ(1U, processor()->GetNumCommitResponses());
@@ -559,11 +566,13 @@
 
   // We can't delete an entity that was never committed.
   // Step 1 is to create and commit a new entity.
-  VerifyCommitCount(emitter(), 0);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/0,
+                    /*expected_deletion_count=*/0);
   processor()->SetCommitRequest(GenerateCommitRequest(kTag1, kValue1));
   DoSuccessfulCommit();
 
-  VerifyCommitCount(emitter(), 1);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/1,
+                    /*expected_deletion_count=*/0);
 
   ASSERT_TRUE(processor()->HasCommitResponse(kHash1));
   const CommitResponseData& initial_commit_response =
@@ -574,7 +583,8 @@
   processor()->SetCommitRequest(GenerateDeleteRequest(kTag1));
   DoSuccessfulCommit();
 
-  VerifyCommitCount(emitter(), 2);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/1,
+                    /*expected_deletion_count=*/1);
 
   // Verify the SyncEntity sent in the commit message.
   ASSERT_EQ(2U, server()->GetNumCommitMessages());
@@ -1141,7 +1151,8 @@
   EXPECT_TRUE(entity.specifics().has_user_event());
   EXPECT_EQ(id, entity.specifics().user_event().event_time_usec());
 
-  VerifyCommitCount(emitter(), 1);
+  VerifyCommitCount(emitter(), /*expected_creation_count=*/1,
+                    /*expected_deletion_count=*/0);
 
   ASSERT_EQ(1U, processor()->GetNumCommitResponses());
   EXPECT_EQ(1U, processor()->GetNthCommitResponse(0).size());
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
index f7485ad8..eb61e14 100644
--- a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
+++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
@@ -44,6 +44,7 @@
 
   commit_message->mutable_entries()->Reserve(commit_message->entries_size() +
                                              commit_requests_.size());
+  CommitCounters* counters = debug_info_emitter_->GetMutableCommitCounters();
 
   for (const auto& commit_request : commit_requests_) {
     sync_pb::SyncEntity* sync_entity = commit_message->add_entries();
@@ -57,13 +58,19 @@
       PopulateCommitProto(commit_request, sync_entity);
       AdjustCommitProto(sync_entity);
     }
+
+    // Update the relevant counter based on the type of the commit request.
+    if (commit_request.entity->is_deleted()) {
+      counters->num_deletion_commits_attempted++;
+    } else if (commit_request.base_version <= 0) {
+      counters->num_creation_commits_attempted++;
+    } else {
+      counters->num_update_commits_attempted++;
+    }
   }
 
   if (!context_.context().empty())
     commit_message->add_client_contexts()->CopyFrom(context_);
-
-  CommitCounters* counters = debug_info_emitter_->GetMutableCommitCounters();
-  counters->num_commits_attempted += commit_requests_.size();
 }
 
 SyncerError NonBlockingTypeCommitContribution::ProcessCommitResponse(
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc
index 4740b74f..0623e1b 100644
--- a/components/sync/engine_impl/syncer_unittest.cc
+++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -1198,9 +1198,9 @@
   EXPECT_EQ(1, GetUpdateCounters(BOOKMARKS).num_local_overwrites);
 
   // We successfully commited item(s).
-  EXPECT_EQ(2, GetCommitCounters(BOOKMARKS).num_commits_attempted);
+  EXPECT_EQ(2, GetCommitCounters(BOOKMARKS).num_update_commits_attempted);
   EXPECT_EQ(2, GetCommitCounters(BOOKMARKS).num_commits_success);
-  EXPECT_EQ(1, GetCommitCounters(PREFERENCES).num_commits_attempted);
+  EXPECT_EQ(1, GetCommitCounters(PREFERENCES).num_update_commits_attempted);
   EXPECT_EQ(1, GetCommitCounters(PREFERENCES).num_commits_success);
 
   EXPECT_TRUE(SyncShareNudge());
diff --git a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
index 49a6f8f..ca32d5e 100644
--- a/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
+++ b/components/unified_consent/url_keyed_data_collection_consent_helper_unittest.cc
@@ -35,6 +35,8 @@
     return syncer::ModelTypeSet(syncer::ModelType::HISTORY_DELETE_DIRECTIVES,
                                 syncer::ModelType::USER_EVENTS);
   }
+  bool IsFirstSetupComplete() const override { return true; }
+  bool IsEngineInitialized() const override { return true; }
   bool IsSyncActive() const override { return true; }
   bool ConfigurationDone() const override { return true; }
 
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index 50933bb..a0ca5b1 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -2591,7 +2591,7 @@
 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
                 BackgroundFilterRendererTypes);
 
-TYPED_TEST(RendererPixelTestWithBackgroundFilter, DISABLED_InvertFilter) {
+TYPED_TEST(RendererPixelTestWithBackgroundFilter, InvertFilter) {
   this->background_filters_.Append(
       cc::FilterOperation::CreateInvertFilter(1.f));
 
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index eb3e154..68e62b1 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -979,26 +979,54 @@
   return table_info->col_count;
 }
 
+std::vector<int32_t> BrowserAccessibility::GetColHeaderNodeIds() const {
+  ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+  if (!table_info)
+    return {};
+
+  std::vector<std::vector<int32_t>> headers = table_info->col_headers;
+  std::vector<int32_t> all_ids;
+  for (const auto& col_ids : headers) {
+    all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+  }
+
+  return all_ids;
+}
+
 std::vector<int32_t> BrowserAccessibility::GetColHeaderNodeIds(
     int32_t col_index) const {
   ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
   if (!table_info)
-    return std::vector<int32_t>();
+    return {};
 
   if (col_index < 0 || col_index >= table_info->col_count)
-    return std::vector<int32_t>();
+    return {};
 
   return table_info->col_headers[col_index];
 }
 
+std::vector<int32_t> BrowserAccessibility::GetRowHeaderNodeIds() const {
+  ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+  if (!table_info)
+    return {};
+
+  std::vector<std::vector<int32_t>> headers = table_info->row_headers;
+  std::vector<int32_t> all_ids;
+  for (const auto& col_ids : headers) {
+    all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+  }
+
+  return all_ids;
+}
+
 std::vector<int32_t> BrowserAccessibility::GetRowHeaderNodeIds(
     int32_t row_index) const {
   ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
   if (!table_info)
-    return std::vector<int32_t>();
+    return {};
 
   if (row_index < 0 || row_index >= table_info->row_count)
-    return std::vector<int32_t>();
+    return {};
 
   return table_info->row_headers[row_index];
 }
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index 5b36dc1..9ce3fc97 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -343,7 +343,9 @@
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   int GetTableRowCount() const override;
   int GetTableColCount() const override;
+  std::vector<int32_t> GetColHeaderNodeIds() const override;
   std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override;
+  std::vector<int32_t> GetRowHeaderNodeIds() const override;
   std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override;
   int32_t GetCellId(int32_t row_index, int32_t col_index) const override;
   int32_t CellIdToIndex(int32_t cell_id) const override;
diff --git a/content/browser/background_fetch/background_fetch.proto b/content/browser/background_fetch/background_fetch.proto
index 91f2a167..c87087703 100644
--- a/content/browser/background_fetch/background_fetch.proto
+++ b/content/browser/background_fetch/background_fetch.proto
@@ -76,6 +76,10 @@
 
   // Number of fetches initiated by the developer.
   optional int32 num_fetches = 5;
+
+  // Raw bytes needed to deserialize into a PNG icon. Only used if the icon
+  // has a max resolution of 256x256. This means this is at most ~256KB.
+  optional bytes icon = 6;
 }
 
 // A background fetch request that is still in a pending state.
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc
index 2155925..833cce06 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -131,7 +131,7 @@
   auto registration_callback =
       base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
   AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
-      this, registration_id, requests, options,
+      this, registration_id, requests, options, icon,
       std::move(registration_callback)));
 }
 
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index 84bceab..cab30b6 100644
--- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -29,6 +29,9 @@
 #include "content/public/browser/storage_partition.h"
 #include "storage/browser/blob/blob_data_handle.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/image/image.h"
 
 namespace content {
 namespace {
@@ -143,6 +146,23 @@
   return requests;
 }
 
+// TODO(crbug.com/855789): Remove this helper function when icon deserialization
+// is added.
+void CheckSerializedIcon(const std::string& bytes, const SkBitmap& test_icon) {
+  SkBitmap icon =
+      gfx::Image::CreateFrom1xPNGBytes(
+          reinterpret_cast<const unsigned char*>(bytes.c_str()), bytes.size())
+          .AsBitmap();
+
+  EXPECT_FALSE(icon.isNull());
+  EXPECT_EQ(icon.width(), test_icon.width());
+  EXPECT_EQ(icon.height(), test_icon.height());
+  for (int i = 0; i < icon.width(); i++) {
+    for (int j = 0; j < icon.height(); j++)
+      EXPECT_EQ(icon.getColor(i, j), SK_ColorGREEN);
+  }
+}
+
 }  // namespace
 
 class BackgroundFetchDataManagerTest
@@ -190,12 +210,13 @@
       const BackgroundFetchRegistrationId& registration_id,
       const std::vector<ServiceWorkerFetchRequest>& requests,
       const BackgroundFetchOptions& options,
+      const SkBitmap& icon,
       blink::mojom::BackgroundFetchError* out_error) {
     DCHECK(out_error);
 
     base::RunLoop run_loop;
     background_fetch_data_manager_->CreateRegistration(
-        registration_id, requests, options, SkBitmap(),
+        registration_id, requests, options, icon,
         base::BindOnce(&DidCreateRegistration, run_loop.QuitClosure(),
                        out_error));
     run_loop.Run();
@@ -592,7 +613,7 @@
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
 
   // Creating the initial registration should succeed.
-  CreateRegistration(registration_id1, requests, options, &error);
+  CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Different |unique_id|, since this is a new Background Fetch registration,
@@ -603,7 +624,7 @@
 
   // Attempting to create a second registration with the same |developer_id| and
   // |service_worker_registration_id| should yield an error.
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
 
   // Deactivating the second registration that failed to be created should fail.
@@ -617,7 +638,7 @@
   // And now registering the second registration should work fine, since there
   // is no longer an *active* registration with the same |developer_id|, even
   // though the initial registration has not yet been deleted.
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 }
 
@@ -637,7 +658,7 @@
   // Create a single registration.
   BackgroundFetchRegistrationId registration_id1(
       sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
-  CreateRegistration(registration_id1, requests, options, &error);
+  CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that the developer ID can be found.
@@ -655,7 +676,7 @@
   // Create another registration.
   BackgroundFetchRegistrationId registration_id2(
       sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that both developer IDs can be found.
@@ -684,7 +705,7 @@
   blink::mojom::BackgroundFetchError error;
 
   // Create a single registration.
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that the registration can be retrieved.
@@ -722,8 +743,12 @@
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
 
+  SkBitmap icon;
+  icon.allocN32Pixels(42, 42);
+  icon.eraseColor(SK_ColorGREEN);
+
   // Create a single registration.
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, icon, &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that the metadata can be retrieved.
@@ -733,6 +758,7 @@
   EXPECT_EQ(metadata->origin(), origin().Serialize());
   EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
   EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
+  ASSERT_NO_FATAL_FAILURE(CheckSerializedIcon(metadata->icon(), icon));
 
   // Verify that retrieving using the wrong developer id doesn't work.
   metadata = GetMetadata(sw_id, origin(), kAlternativeDeveloperId, &error);
@@ -750,6 +776,35 @@
   EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
 }
 
+TEST_F(BackgroundFetchDataManagerTest, LargeIconNotPersisted) {
+  int64_t sw_id = RegisterServiceWorker();
+  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+  BackgroundFetchRegistrationId registration_id(
+      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+
+  std::vector<ServiceWorkerFetchRequest> requests(2u);
+  BackgroundFetchOptions options;
+  blink::mojom::BackgroundFetchError error;
+
+  SkBitmap icon;
+  icon.allocN32Pixels(512, 512);
+  icon.eraseColor(SK_ColorGREEN);
+
+  // Create a single registration.
+  CreateRegistration(registration_id, requests, options, icon, &error);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+  // Verify that the metadata can be retrieved.
+  auto metadata = GetMetadata(sw_id, origin(), kExampleDeveloperId, &error);
+  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  ASSERT_TRUE(metadata);
+  EXPECT_EQ(metadata->origin(), origin().Serialize());
+  EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
+  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
+  EXPECT_TRUE(metadata->icon().empty());
+}
+
 TEST_F(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
   int64_t sw_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -768,7 +823,7 @@
   EXPECT_TRUE(title.empty());
 
   // Create a single registration.
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that the title can be retrieved.
@@ -805,7 +860,7 @@
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
 
-  CreateRegistration(registration_id1, requests, options, &error);
+  CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   RestartDataManagerFromPersistentStorage();
@@ -818,7 +873,7 @@
   // Attempting to create a second registration with the same |developer_id| and
   // |service_worker_registration_id| should yield an error, even after
   // restarting.
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
 
   // Verify that the registration can be retrieved before deletion.
@@ -850,7 +905,7 @@
   // restarting, since there is no longer an *active* registration with the same
   // |developer_id|, even though the initial registration has not yet been
   // deleted.
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   RestartDataManagerFromPersistentStorage();
@@ -882,7 +937,7 @@
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
 
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
   EXPECT_EQ(
       GetRequestStats(sw_id),
@@ -945,7 +1000,7 @@
 
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   auto registration =
@@ -994,7 +1049,7 @@
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
 
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   scoped_refptr<BackgroundFetchRequestInfo> request_info;
@@ -1038,7 +1093,7 @@
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
 
-  CreateRegistration(registration_id, {request}, options, &error);
+  CreateRegistration(registration_id, {request}, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   scoped_refptr<BackgroundFetchRequestInfo> request_info;
@@ -1070,7 +1125,7 @@
   BackgroundFetchRegistrationId registration_id(
       sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
 
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
   EXPECT_EQ(
       GetRequestStats(sw_id),
@@ -1120,7 +1175,7 @@
 
   BackgroundFetchOptions options;
   blink::mojom::BackgroundFetchError error;
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   bool succeeded = false;
@@ -1184,7 +1239,7 @@
   blink::mojom::BackgroundFetchError error;
 
   CreateRegistration(registration_id, {ServiceWorkerFetchRequest()}, options,
-                     &error);
+                     SkBitmap(), &error);
 
   size_t size = 0u;
   GetNumRequestsTask(registration_id, background_fetch::RequestType::kAny,
@@ -1255,7 +1310,7 @@
   EXPECT_EQ(0u,
             GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
   // Create a registration.
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // We expect as many pending entries as there are requests.
@@ -1315,7 +1370,7 @@
   BackgroundFetchRegistrationId registration_id(
       sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
 
-  CreateRegistration(registration_id, requests, options, &error);
+  CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
   {
     std::vector<BackgroundFetchInitializationData> data =
@@ -1351,7 +1406,7 @@
   // Create another registration.
   BackgroundFetchRegistrationId registration_id2(
       sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
-  CreateRegistration(registration_id2, requests, options, &error);
+  CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
   {
     std::vector<BackgroundFetchInitializationData> data =
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc
index 6999f19..6e2a9c6 100644
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "content/browser/background_fetch/background_fetch_context.h"
 #include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
 #include "content/browser/background_fetch/background_fetch_job_controller.h"
@@ -1101,20 +1102,10 @@
   // Simulate browser restart by re-creating |context_| and |service_|.
   SetUp();
 
-  // Give initialization tasks a chance to finish.
-  base::RunLoop().RunUntilIdle();
-
-  // At this point the Fetch ran up until the MarkRequestCompleteTask, since it
-  // is waiting for the Cache Storage to respond which runs on another thread.
-  // Check that the job is re-loaded into the job map.
-  ASSERT_EQ(GetJobIDs().size(), 1u);
-  EXPECT_EQ(*GetJobIDs().begin(), kExampleUniqueId);
-
+  // Queue up a GetRegistration DatabaseTask to run right after the
+  // initialization, but before the fetch is resumed.
   BackgroundFetchRegistration registration;
   blink::mojom::BackgroundFetchError error;
-
-  // NOTE: This GetRegistration works because it runs between the
-  // MarkRequestCompleteTask and the GetSettledFetchesTask.
   GetRegistration(service_worker_registration_id, kExampleDeveloperId, &error,
                   &registration);
   ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1123,6 +1114,7 @@
   // Allow the fetch to completely finish.
   thread_bundle_.RunUntilIdle();
 
+  // At this point the fetch ran to completion.
   EXPECT_TRUE(GetJobIDs().empty());
   GetRegistration(service_worker_registration_id, kExampleDeveloperId, &error,
                   &registration);
diff --git a/content/browser/background_fetch/storage/create_metadata_task.cc b/content/browser/background_fetch/storage/create_metadata_task.cc
index 399a7ee..33d5cf9 100644
--- a/content/browser/background_fetch/storage/create_metadata_task.cc
+++ b/content/browser/background_fetch/storage/create_metadata_task.cc
@@ -6,26 +6,49 @@
 
 #include <utility>
 
+#include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
 #include "content/browser/background_fetch/storage/database_helpers.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "ui/gfx/image/image.h"
 
 namespace content {
 
 namespace background_fetch {
 
+namespace {
+
+std::string ConvertAndSerializeIcon(const SkBitmap& icon) {
+  // Serialize the icon and copy the bytes over.
+  std::string serialized_icon;
+  auto icon_bytes = gfx::Image::CreateFrom1xBitmap(icon).As1xPNGBytes();
+  serialized_icon.assign(icon_bytes->front_as<char>(),
+                         icon_bytes->front_as<char>() + icon_bytes->size());
+  return serialized_icon;
+}
+
+}  // namespace
+
+// The max icon resolution, this is used as a threshold to decide
+// whether the icon should be persisted.
+constexpr int kMaxIconResolution = 256 * 256;
+
 CreateMetadataTask::CreateMetadataTask(
     DatabaseTaskHost* host,
     const BackgroundFetchRegistrationId& registration_id,
     const std::vector<ServiceWorkerFetchRequest>& requests,
     const BackgroundFetchOptions& options,
+    const SkBitmap& icon,
     CreateMetadataCallback callback)
     : DatabaseTask(host),
       registration_id_(registration_id),
       requests_(requests),
       options_(options),
+      icon_(icon),
       callback_(std::move(callback)),
       weak_factory_(this) {}
 
@@ -43,7 +66,7 @@
                                         blink::ServiceWorkerStatusCode status) {
   switch (ToDatabaseStatus(status)) {
     case DatabaseStatus::kNotFound:
-      StoreMetadata();
+      InitializeMetadataProto();
       return;
     case DatabaseStatus::kOk:
       // Can't create a registration since there is already an active
@@ -64,15 +87,16 @@
 }
 
 void CreateMetadataTask::InitializeMetadataProto() {
-  metadata_proto_ = std::make_unique<proto::BackgroundFetchMetadata>();
+  auto metadata_proto = std::make_unique<proto::BackgroundFetchMetadata>();
+
   // Set BackgroundFetchRegistration fields.
-  auto* registration_proto = metadata_proto_->mutable_registration();
+  auto* registration_proto = metadata_proto->mutable_registration();
   registration_proto->set_unique_id(registration_id_.unique_id());
   registration_proto->set_developer_id(registration_id_.developer_id());
   registration_proto->set_download_total(options_.download_total);
 
   // Set Options fields.
-  auto* options_proto = metadata_proto_->mutable_options();
+  auto* options_proto = metadata_proto->mutable_options();
   options_proto->set_title(options_.title);
   options_proto->set_download_total(options_.download_total);
   for (const auto& icon : options_.icons) {
@@ -103,20 +127,45 @@
   }
 
   // Set other metadata fields.
-  metadata_proto_->set_origin(registration_id_.origin().Serialize());
-  metadata_proto_->set_creation_microseconds_since_unix_epoch(
+  metadata_proto->set_origin(registration_id_.origin().Serialize());
+  metadata_proto->set_creation_microseconds_since_unix_epoch(
       (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds());
-  metadata_proto_->set_num_fetches(requests_.size());
+  metadata_proto->set_num_fetches(requests_.size());
+
+  // Check if |icon_| should be persisted.
+  if (icon_.height() * icon_.width() > kMaxIconResolution) {
+    StoreMetadata(std::move(metadata_proto));
+    return;
+  }
+
+  // Do the initialization on a seperate thread to avoid blocking on
+  // expensive operations (image conversions), then post back to IO thread
+  // and continue normally.
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
+       base::TaskPriority::BACKGROUND},
+      base::BindOnce(&ConvertAndSerializeIcon, icon_),
+      base::BindOnce(&CreateMetadataTask::StoreIcon, weak_factory_.GetWeakPtr(),
+                     std::move(metadata_proto)));
 }
 
-void CreateMetadataTask::StoreMetadata() {
+void CreateMetadataTask::StoreIcon(
+    std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto,
+    std::string serialized_icon) {
+  DCHECK(metadata_proto);
+  metadata_proto->set_icon(std::move(serialized_icon));
+  StoreMetadata(std::move(metadata_proto));
+}
+
+void CreateMetadataTask::StoreMetadata(
+    std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto) {
   std::vector<std::pair<std::string, std::string>> entries;
   entries.reserve(requests_.size() * 2 + 1);
 
-  InitializeMetadataProto();
   std::string serialized_metadata_proto;
 
-  if (!metadata_proto_->SerializeToString(&serialized_metadata_proto)) {
+  if (!metadata_proto->SerializeToString(&serialized_metadata_proto)) {
     // TODO(crbug.com/780025): Log failures to UMA.
     std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
                              nullptr /* metadata */);
@@ -144,13 +193,14 @@
   service_worker_context()->StoreRegistrationUserData(
       registration_id_.service_worker_registration_id(),
       registration_id_.origin().GetURL(), entries,
-      base::BindRepeating(&CreateMetadataTask::DidStoreMetadata,
-                          weak_factory_.GetWeakPtr()));
+      base::BindOnce(&CreateMetadataTask::DidStoreMetadata,
+                     weak_factory_.GetWeakPtr(), std::move(metadata_proto)));
 }
 
 void CreateMetadataTask::DidStoreMetadata(
+    std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto,
     blink::ServiceWorkerStatusCode status) {
-  DCHECK(metadata_proto_);
+  DCHECK(metadata_proto);
 
   switch (ToDatabaseStatus(status)) {
     case DatabaseStatus::kOk:
@@ -165,7 +215,7 @@
   }
 
   std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
-                           std::move(metadata_proto_));
+                           std::move(metadata_proto));
   Finished();  // Destroys |this|.
 }
 }  // namespace background_fetch
diff --git a/content/browser/background_fetch/storage/create_metadata_task.h b/content/browser/background_fetch/storage/create_metadata_task.h
index d877c65..e0f4e19 100644
--- a/content/browser/background_fetch/storage/create_metadata_task.h
+++ b/content/browser/background_fetch/storage/create_metadata_task.h
@@ -13,6 +13,7 @@
 #include "content/browser/background_fetch/storage/database_task.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 #include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 
 namespace content {
 
@@ -29,6 +30,7 @@
                      const BackgroundFetchRegistrationId& registration_id,
                      const std::vector<ServiceWorkerFetchRequest>& requests,
                      const BackgroundFetchOptions& options,
+                     const SkBitmap& icon,
                      CreateMetadataCallback callback);
 
   ~CreateMetadataTask() override;
@@ -39,19 +41,24 @@
   void DidGetUniqueId(const std::vector<std::string>& data,
                       blink::ServiceWorkerStatusCode status);
 
-  void StoreMetadata();
+  void StoreIcon(std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto,
+                 std::string serialized_icon);
 
-  void DidStoreMetadata(blink::ServiceWorkerStatusCode status);
+  void StoreMetadata(
+      std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto);
+
+  void DidStoreMetadata(
+      std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto,
+      blink::ServiceWorkerStatusCode status);
 
   void InitializeMetadataProto();
 
   BackgroundFetchRegistrationId registration_id_;
   std::vector<ServiceWorkerFetchRequest> requests_;
   BackgroundFetchOptions options_;
+  SkBitmap icon_;
   CreateMetadataCallback callback_;
 
-  std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto_;
-
   base::WeakPtrFactory<CreateMetadataTask> weak_factory_;  // Keep as last.
 
   DISALLOW_COPY_AND_ASSIGN(CreateMetadataTask);
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 95f4936..50658a2 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -204,8 +204,7 @@
 #endif
 
 #if defined(OS_FUCHSIA)
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
+#include <lib/zx/job.h>
 
 #include "base/fuchsia/default_job.h"
 #include "base/fuchsia/fuchsia_logging.h"
@@ -395,10 +394,10 @@
 // Create and register the job which will contain all child processes
 // of the browser process as well as their descendents.
 void InitDefaultJob() {
-  base::ScopedZxHandle handle;
-  zx_status_t result = zx_job_create(zx_job_default(), 0, handle.receive());
+  zx::job job;
+  zx_status_t result = zx::job::create(*zx::job::default_job(), 0, &job);
   ZX_CHECK(ZX_OK == result, result) << "zx_job_create";
-  base::SetDefaultJob(std::move(handle));
+  base::SetDefaultJob(std::move(job));
 }
 #endif  // defined(OS_FUCHSIA)
 
diff --git a/content/browser/browser_side_navigation_browsertest.cc b/content/browser/browser_side_navigation_browsertest.cc
index 3054b8ca..46fb1fa 100644
--- a/content/browser/browser_side_navigation_browsertest.cc
+++ b/content/browser/browser_side_navigation_browsertest.cc
@@ -52,13 +52,33 @@
 // below (BrowserSideNavigationBrowserTest), it will automatically start the
 // default server.
 // TODO(clamy): Rename those NavigationBrowserTests.
-class BrowserSideNavigationBaseBrowserTest : public ContentBrowserTest {
+class BrowserSideNavigationBaseBrowserTest
+    : public ContentBrowserTest,
+      public ::testing::WithParamInterface<bool> {
  protected:
   void SetUpOnMainThread() override {
+    ToogleNavigationImmediateResponse();
     host_resolver()->AddRule("*", "127.0.0.1");
   }
+
+ private:
+  void ToogleNavigationImmediateResponse() {
+    if (GetParam()) {
+      feature_list.InitAndDisableFeature(
+          features::kNavigationImmediateResponseBody);
+    } else {
+      feature_list.InitAndEnableFeature(
+          features::kNavigationImmediateResponseBody);
+    }
+  }
+
+  base::test::ScopedFeatureList feature_list;
 };
 
+INSTANTIATE_TEST_CASE_P(/* no prefix */,
+                        BrowserSideNavigationBaseBrowserTest,
+                        ::testing::Bool());
+
 class BrowserSideNavigationBrowserTest
     : public BrowserSideNavigationBaseBrowserTest {
  protected:
@@ -68,9 +88,13 @@
   }
 };
 
+INSTANTIATE_TEST_CASE_P(/* no prefix */,
+                        BrowserSideNavigationBrowserTest,
+                        ::testing::Bool());
+
 // Ensure that browser initiated basic navigations work with browser side
 // navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        BrowserInitiatedNavigations) {
   // Perform a navigation with no live renderer.
   {
@@ -114,7 +138,7 @@
 
 // Ensure that renderer initiated same-site navigations work with browser side
 // navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        RendererInitiatedSameSiteNavigation) {
   // Perform a navigation with no live renderer.
   {
@@ -150,7 +174,7 @@
 
 // Ensure that renderer initiated cross-site navigations work with browser side
 // navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        RendererInitiatedCrossSiteNavigation) {
   // Perform a navigation with no live renderer.
   {
@@ -204,7 +228,7 @@
 }
 
 // Ensure that browser side navigation handles navigation failures.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, FailedNavigation) {
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest, FailedNavigation) {
   // Perform a navigation with no live renderer.
   {
     TestNavigationObserver observer(shell()->web_contents());
@@ -231,7 +255,7 @@
 
 // Ensure that browser side navigation can load browser initiated navigations
 // to view-source URLs.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        ViewSourceNavigation_BrowserInitiated) {
   TestNavigationObserver observer(shell()->web_contents());
   GURL url(embedded_test_server()->GetURL("/title1.html"));
@@ -244,7 +268,7 @@
 
 // Ensure that browser side navigation blocks content initiated navigations to
 // view-source URLs.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        ViewSourceNavigation_RendererInitiated) {
   TestNavigationObserver observer(shell()->web_contents());
   GURL kUrl(embedded_test_server()->GetURL("/simple_links.html"));
@@ -275,7 +299,7 @@
 
 // Ensure that closing a page by running its beforeunload handler doesn't hang
 // if there's an ongoing navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        UnloadDuringNavigation) {
   content::WindowedNotificationObserver close_observer(
       content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
@@ -289,7 +313,7 @@
 }
 
 // Ensure that the referrer of a navigation is properly sanitized.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, SanitizeReferrer) {
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest, SanitizeReferrer) {
   const GURL kInsecureUrl(embedded_test_server()->GetURL("/title1.html"));
   const Referrer kSecureReferrer(
       GURL("https://secure-url.com"),
@@ -321,7 +345,7 @@
 
 // Test to verify that an exploited renderer process trying to upload a file
 // it hasn't been explicitly granted permissions to is correctly terminated.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        PostUploadIllegalFilePath) {
   GURL form_url(
       embedded_test_server()->GetURL("/form_that_posts_to_echoall.html"));
@@ -384,7 +408,7 @@
 // based on Blink's state instead of the history state in the browser process,
 // which ends up loading the originally blocked URL. With PlzNavigate, the
 // reload uses the NavigationEntry state to create a navigation and commit it.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        VerifyBlockedErrorPageURL_Reload) {
   NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
       shell()->web_contents()->GetController());
@@ -430,13 +454,17 @@
   }
 };
 
+INSTANTIATE_TEST_CASE_P(/* no prefix */,
+                        BrowserSideNavigationBrowserDisableWebSecurityTest,
+                        ::testing::Bool());
+
 // Test to verify that an exploited renderer process trying to specify a
 // non-empty URL for base_url_for_data_url on navigation is correctly
 // terminated.
 // TODO(nasko): This test case belongs better in
 // security_exploit_browsertest.cc, so move it there once PlzNavigate is on
 // by default.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserDisableWebSecurityTest,
                        ValidateBaseUrlForDataUrl) {
   GURL start_url(embedded_test_server()->GetURL("/title1.html"));
   EXPECT_TRUE(NavigateToURL(shell(), start_url));
@@ -519,7 +547,7 @@
   EXPECT_TRUE(result.empty());
 }
 
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, BackFollowedByReload) {
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest, BackFollowedByReload) {
   // First, make two history entries.
   GURL url1(embedded_test_server()->GetURL("/title1.html"));
   GURL url2(embedded_test_server()->GetURL("/title2.html"));
@@ -539,7 +567,7 @@
 
 // Test that a navigation response can be entirely fetched, even after the
 // NavigationURLLoader has been deleted.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBaseBrowserTest,
                        FetchResponseAfterNavigationURLLoaderDeleted) {
   net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                       "/main_document");
@@ -591,7 +619,7 @@
 // renderer process. This test ensures that when the the URLLoader is deleted
 // (in the browser process), the URLLoaderClient (in the renderer process) stops
 // properly.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBaseBrowserTest,
                        CancelRequestAfterReadyToCommit) {
   // This test cancels the request using the ResourceDispatchHost. With the
   // NetworkService, it is not used so the request is not canceled.
@@ -646,7 +674,7 @@
 
 // Data URLs can have a reference fragment like any other URLs. This test makes
 // sure it is taken into account.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        DataURLWithReferenceFragment) {
   GURL url("data:text/html,body#foo");
   EXPECT_TRUE(NavigateToURL(shell(), url));
@@ -671,7 +699,7 @@
 // 1) Start on a document with history.length == 1.
 // 2) Create an iframe and call history.pushState at the same time.
 // 3) history.back() must work.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBrowserTest,
                        IframeAndPushStateSimultaneously) {
   GURL main_url = embedded_test_server()->GetURL("/simple_page.html");
   GURL iframe_url = embedded_test_server()->GetURL("/hello.html");
@@ -718,7 +746,7 @@
 
 // Regression test for https://crbug.com/260144
 // Back/Forward navigation in an iframe must not stop ongoing XHR.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBaseBrowserTest,
                        IframeNavigationsDoNotStopXHR) {
   // A response for the XHR request. It will be delayed until the end of all the
   // navigations.
@@ -807,7 +835,7 @@
 }
 
 // Regression test for https://crbug.com/856396.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_P(BrowserSideNavigationBaseBrowserTest,
                        ReplacingDocumentLoaderFiresLoadEvent) {
   net::test_server::ControllableHttpResponse main_document_response(
       embedded_test_server(), "/main_document");
@@ -893,7 +921,7 @@
 // 3) The request for the new navigation starts and it turns out it is a
 //    download. The navigation is dropped.
 // 4) There are no more possibilities for DidStopLoading() to be sent.
-IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
+IN_PROC_BROWSER_TEST_P(NavigationDownloadBrowserTest,
                        StopLoadingAfterDroppedNavigation) {
   net::test_server::ControllableHttpResponse main_response(
       embedded_test_server(), "/main");
@@ -927,4 +955,8 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 }
 
+INSTANTIATE_TEST_CASE_P(/* no prefix */,
+                        NavigationDownloadBrowserTest,
+                        ::testing::Bool());
+
 }  // namespace content
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 8f12714..df0ec2a 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -56,6 +56,7 @@
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
 #include "content/public/common/web_preferences.h"
+#include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -919,6 +920,7 @@
 void NavigationRequest::OnResponseStarted(
     const scoped_refptr<network::ResourceResponse>& response,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
@@ -1027,6 +1029,7 @@
   // Store the response and the URLLoaderClient endpoints until checks have been
   // processed.
   response_ = response;
+  response_body_ = std::move(response_body);
   url_loader_client_endpoints_ = std::move(url_loader_client_endpoints);
   ssl_info_ = response->head.ssl_info.has_value() ? *response->head.ssl_info
                                                   : net::SSLInfo();
@@ -1639,8 +1642,9 @@
     associated_site_instance_id_.reset();
   }
   render_frame_host->CommitNavigation(
-      response_.get(), std::move(url_loader_client_endpoints_), common_params_,
-      request_params_, is_view_source_, std::move(subresource_loader_params_),
+      response_.get(), std::move(url_loader_client_endpoints_),
+      std::move(response_body_), common_params_, request_params_,
+      is_view_source_, std::move(subresource_loader_params_),
       std::move(subresource_overrides_), devtools_navigation_token_);
 
   // Give SpareRenderProcessHostManager a heads-up about the most recently used
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 6e38171..4ba9fcd 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -22,6 +22,7 @@
 #include "content/common/navigation_subresource_loader_params.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/common/previews_state.h"
+#include "mojo/public/cpp/system/data_pipe.h"
 
 namespace network {
 class ResourceRequestBody;
@@ -233,6 +234,7 @@
   void OnResponseStarted(
       const scoped_refptr<network::ResourceResponse>& response,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
@@ -411,6 +413,7 @@
   // checks are performed by the NavigationHandle. Once the checks have been
   // completed, these objects will be used to continue the navigation.
   scoped_refptr<network::ResourceResponse> response_;
+  mojo::ScopedDataPipeConsumerHandle response_body_;
   network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints_;
   net::SSLInfo ssl_info_;
   bool is_download_;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index ab634ef2..e7af1d2 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -3472,8 +3472,9 @@
       std::vector<ContentSecurityPolicy>() /* initiator_csp */,
       CSPSource() /* initiator_self_source */);
   CommitNavigation(nullptr, network::mojom::URLLoaderClientEndpointsPtr(),
-                   common_params, RequestNavigationParams(), false,
-                   base::nullopt, base::nullopt /* subresource_overrides */,
+                   mojo::ScopedDataPipeConsumerHandle(), common_params,
+                   RequestNavigationParams(), false, base::nullopt,
+                   base::nullopt /* subresource_overrides */,
                    base::UnguessableToken::Create() /* not traced */);
 }
 
@@ -3632,6 +3633,7 @@
 void RenderFrameHostImpl::CommitNavigation(
     network::ResourceResponse* response,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     bool is_view_source,
@@ -3803,15 +3805,15 @@
         navigation_request_->GetCommitNavigationClient()) {
       navigation_request_->GetCommitNavigationClient()->CommitNavigation(
           head, common_params, request_params,
-          std::move(url_loader_client_endpoints), CloneSubresourceFactories(),
-          std::move(subresource_overrides), std::move(controller),
-          devtools_navigation_token);
+          std::move(url_loader_client_endpoints), std::move(response_body),
+          CloneSubresourceFactories(), std::move(subresource_overrides),
+          std::move(controller), devtools_navigation_token);
     } else {
       GetNavigationControl()->CommitNavigation(
           head, common_params, request_params,
-          std::move(url_loader_client_endpoints), CloneSubresourceFactories(),
-          std::move(subresource_overrides), std::move(controller),
-          devtools_navigation_token,
+          std::move(url_loader_client_endpoints), std::move(response_body),
+          CloneSubresourceFactories(), std::move(subresource_overrides),
+          std::move(controller), devtools_navigation_token,
           navigation_request_
               ? base::BindOnce(
                     &RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 9585ba0..9b71328 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -572,6 +572,7 @@
   void CommitNavigation(
       network::ResourceResponse* response,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       bool is_view_source,
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index 4910201..e162611 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -17,6 +17,7 @@
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/loader/resource_request_info_impl.h"
 #include "content/public/browser/global_request_id.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "net/base/mime_sniffer.h"
@@ -191,7 +192,13 @@
     response->head.ssl_info = request()->ssl_info();
   }
 
-  url_loader_client_->OnReceiveResponse(response->head);
+  if (IsNavigationImmediateResponseBodyEnabled()) {
+    MaybeCreateResponseBodyDataPipe();
+    url_loader_client_->OnReceiveResponse(response->head);
+    MaybeSendStartLoadingResponseBody();
+  } else {
+    url_loader_client_->OnReceiveResponse(response->head);
+  }
 
   net::IOBufferWithSize* metadata = GetResponseMetadata(request());
   if (metadata) {
@@ -242,31 +249,10 @@
     return;
   }
 
-  bool first_call = false;
+  MaybeCreateResponseBodyDataPipe();
   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();
+    controller->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);
+    return;
   }
 
   bool defer = false;
@@ -288,7 +274,8 @@
   // 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) {
+  if (!has_started_one_read_ &&
+      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);
@@ -301,6 +288,8 @@
 
   *buf = buffer_;
   *buf_size = buffer_->size();
+
+  has_started_one_read_ = true;
   controller->Resume();
 }
 
@@ -329,12 +318,8 @@
     }
   }
 
-  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();
-  }
+  // Send the data pipe on the first OnReadCompleted call.
+  MaybeSendStartLoadingResponseBody();
 
   if (is_using_io_buffer_not_from_writer_) {
     // Couldn't allocate a large enough buffer on the data pipe in OnWillRead.
@@ -654,4 +639,40 @@
     upload_progress_tracker_->OnAckReceived();
 }
 
+void MojoAsyncResourceHandler::MaybeCreateResponseBodyDataPipe() {
+  if (has_created_response_body_data_pipe_)
+    return;
+  has_created_response_body_data_pipe_ = 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)
+    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::BindRepeating(&MojoAsyncResourceHandler::OnWritable,
+                          base::Unretained(this)));
+  handle_watcher_.ArmOrNotify();
+}
+
+void MojoAsyncResourceHandler::MaybeSendStartLoadingResponseBody() {
+  if (response_body_consumer_handle_.is_valid()) {
+    url_loader_client_->OnStartLoadingResponseBody(
+        std::move(response_body_consumer_handle_));
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/loader/mojo_async_resource_handler.h b/content/browser/loader/mojo_async_resource_handler.h
index ad870657..4d94a489 100644
--- a/content/browser/loader/mojo_async_resource_handler.h
+++ b/content/browser/loader/mojo_async_resource_handler.h
@@ -135,11 +135,17 @@
   void OnUploadProgressACK();
   static void InitializeResourceBufferConstants();
 
+  void MaybeCreateResponseBodyDataPipe();
+  void MaybeSendStartLoadingResponseBody();
+
+  bool has_created_response_body_data_pipe_ = false;
+
   ResourceDispatcherHostImpl* rdh_;
   mojo::Binding<network::mojom::URLLoader> binding_;
 
   uint32_t url_loader_options_;
 
+  bool has_started_one_read_ = false;
   bool has_checked_for_sufficient_resources_ = false;
   bool sent_received_response_message_ = false;
   bool is_using_io_buffer_not_from_writer_ = false;
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc
index b20ac0d..a6134e66 100644
--- a/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -1280,8 +1280,6 @@
 
   ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
 
-  ASSERT_FALSE(url_loader_client_.response_body().is_valid());
-
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnReadCompleted("A"));
   url_loader_client_.RunUntilResponseBodyArrived();
@@ -1333,7 +1331,6 @@
   ASSERT_EQ(MockResourceLoader::Status::IDLE,
             mock_loader_->OnReadCompleted("B"));
 
-  ASSERT_FALSE(url_loader_client_.response_body().is_valid());
   url_loader_client_.RunUntilResponseBodyArrived();
   ASSERT_TRUE(url_loader_client_.response_body().is_valid());
 
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h
index c7d2382..b3abb2a 100644
--- a/content/browser/loader/navigation_url_loader_delegate.h
+++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -48,6 +48,7 @@
   virtual void OnResponseStarted(
       const scoped_refptr<network::ResourceResponse>& response,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 0cd03e5..b62b588b 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -54,6 +54,7 @@
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/url_constants.h"
@@ -912,6 +913,15 @@
  private:
   // network::mojom::URLLoaderClient implementation:
   void OnReceiveResponse(const network::ResourceResponseHead& head) override {
+    // When NavigationImmediateResponseBody is enabled, wait for
+    // DidStartLoadingResponseBody() before sending anything to the renderer
+    // process.
+    if (IsNavigationImmediateResponseBodyEnabled() &&
+        !IsLoaderInterceptionEnabled() && !response_body_.is_valid()) {
+      head_ = head;
+      return;
+    }
+
     received_response_ = true;
 
     // If the default loader (network) was used to handle the URL load request
@@ -1066,11 +1076,11 @@
     // response. https://crbug.com/416050
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
-        base::BindOnce(&NavigationURLLoaderImpl::OnReceiveResponse, owner_,
-                       response->DeepCopy(),
-                       std::move(url_loader_client_endpoints),
-                       std::move(cloned_navigation_data), global_request_id_,
-                       is_download, is_stream));
+        base::BindOnce(
+            &NavigationURLLoaderImpl::OnReceiveResponse, owner_,
+            response->DeepCopy(), std::move(url_loader_client_endpoints),
+            std::move(response_body_), std::move(cloned_navigation_data),
+            global_request_id_, is_download, is_stream));
   }
 
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -1108,10 +1118,19 @@
   void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override {}
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
 
-  void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle) override {
-    // Not reached. At this point, the loader and client endpoints must have
-    // been unbound and forwarded to the renderer.
-    CHECK(false);
+  void OnStartLoadingResponseBody(
+      mojo::ScopedDataPipeConsumerHandle response_body) override {
+    // When NavigationImmediateResponseBody is disabled, this is not reached.
+    // At this point, the loader and client endpoints must have been unbound and
+    // forwarded to the renderer.
+    CHECK(IsNavigationImmediateResponseBodyEnabled());
+
+    // When NavigationImmediateResponseBody is enabled, the NavigationURLLoader
+    // waits for OnStartLoadingResponseBody() instead of OnReceiveResponse()
+    // before delegating the load to an URLLoaderClientImpl in the renderer
+    // process.
+    response_body_ = std::move(response_body);
+    OnReceiveResponse(head_);
   }
 
   void OnComplete(const network::URLLoaderCompletionStatus& status) override {
@@ -1281,6 +1300,9 @@
   // protocol handlers.
   std::set<std::string> known_schemes_;
 
+  network::ResourceResponseHead head_;
+  mojo::ScopedDataPipeConsumerHandle response_body_;
+
   mutable base::WeakPtrFactory<URLLoaderRequestController> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
@@ -1444,6 +1466,7 @@
 void NavigationURLLoaderImpl::OnReceiveResponse(
     scoped_refptr<network::ResourceResponse> response,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& global_request_id,
     bool is_download,
@@ -1456,7 +1479,7 @@
 
   delegate_->OnResponseStarted(
       std::move(response), std::move(url_loader_client_endpoints),
-      std::move(navigation_data), global_request_id,
+      std::move(response_body), std::move(navigation_data), global_request_id,
       allow_download_ && is_download, is_stream,
       request_controller_->TakeSubresourceLoaderParams());
 }
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index ac5e384a..270bf46 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -53,6 +53,7 @@
   void OnReceiveResponse(
       scoped_refptr<network::ResourceResponse> response,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& global_request_id,
       bool is_download,
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 89b7a09..3fbf387 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -85,6 +85,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/origin_util.h"
 #include "content/public/common/resource_type.h"
+#include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/auth.h"
 #include "net/base/load_flags.h"
 #include "net/base/mime_util.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index bc6050f..c9885623 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3017,7 +3017,9 @@
 }
 
 bool RenderProcessHostImpl::Send(IPC::Message* msg) {
-  TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
+  TRACE_EVENT2("renderer_host", "RenderProcessHostImpl::Send", "class",
+               IPC_MESSAGE_ID_CLASS(msg->type()), "line",
+               IPC_MESSAGE_ID_LINE(msg->type()));
 
   std::unique_ptr<IPC::Message> message(msg);
 
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index a7a74a8..a9bfd41 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -994,6 +994,14 @@
   scroll_end_observer.Wait();
 }
 
+#if defined(OS_LINUX)
+// The test is flaky on Linux:  https://crbug.com/833380.
+#define MAYBE_BubbledScrollEventsTransformedCorrectly \
+  DISABLED_BubbledScrollEventsTransformedCorrectly
+#else
+#define MAYBE_BubbledScrollEventsTransformedCorrectly \
+  BubbledScrollEventsTransformedCorrectly
+#endif
 // When a scroll event is bubbled, ensure that the bubbled event's coordinates
 // are correctly updated to the ancestor's coordinate space. In particular,
 // ensure that the transformation considers CSS scaling of the child where
@@ -1001,7 +1009,7 @@
 // coordinates in the ancestor's coordinate space.
 // See https://crbug.com/817392
 IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
-                       BubbledScrollEventsTransformedCorrectly) {
+                       MAYBE_BubbledScrollEventsTransformedCorrectly) {
   GURL main_url(embedded_test_server()->GetURL(
       "/frame_tree/page_with_positioned_scaled_frame.html"));
   ASSERT_TRUE(NavigateToURL(shell(), main_url));
@@ -1215,8 +1223,16 @@
   RunTest(ScrollBubbling);
 }
 
+#if defined(OS_LINUX)
+// Flaky: https://crbug.com/833380
+#define MAYBE_EmulatedTouchPinchGoesToMainFrame \
+  DISABLED_EmulatedTouchPinchGoesToMainFrame
+#else
+#define MAYBE_EmulatedTouchPinchGoesToMainFrame \
+  EmulatedTouchPinchGoesToMainFrame
+#endif
 IN_PROC_BROWSER_TEST_P(SitePerProcessEmulatedTouchBrowserTest,
-                       EmulatedTouchPinchGoesToMainFrame) {
+                       MAYBE_EmulatedTouchPinchGoesToMainFrame) {
   RunTest(PinchGoesToMainFrame);
 }
 
@@ -1767,7 +1783,7 @@
   EXPECT_EQ(result.target_location.value(), parent_location);
 }
 
-#if defined(THREAD_SANITIZER)
+#if defined(THREAD_SANITIZER) || defined(OS_LINUX)
 // Flaky: https://crbug.com/833380
 #define MAYBE_SurfaceHitTestPointerEventsNone \
   DISABLED_SurfaceHitTestPointerEventsNone
@@ -3675,9 +3691,10 @@
   EXPECT_NEAR(point.y(), params.y, 2);
 }
 
-#if defined(OS_ANDROID) || defined(OS_WIN)
+#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_LINUX)
 // High DPI tests don't work properly on Android, which has fixed scale factor.
 // Windows is disabled because of https://crbug.com/545547.
+// The test is flaky on Linux:  https://crbug.com/833380.
 #define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
 #elif defined(THREAD_SANITIZER)
 // TSAN is flaky on both standard and High DPI: https://crbug.com/833380
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 4da80f3..22b9313 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -198,9 +198,6 @@
   gfx::NativeView native_view = GetNativeViewForFocus();
   NSWindow* window = [native_view window];
   [window makeFirstResponder:native_view];
-  if (![window isVisible])
-    return;
-  [window makeKeyAndOrderFront:nil];
 }
 
 void WebContentsViewMac::SetInitialFocus() {
diff --git a/content/child/child_process_sandbox_support_impl_linux.cc b/content/child/child_process_sandbox_support_impl_linux.cc
index 9cbcca5..9dd008c8 100644
--- a/content/child/child_process_sandbox_support_impl_linux.cc
+++ b/content/child/child_process_sandbox_support_impl_linux.cc
@@ -79,7 +79,7 @@
       font_render_style.is_null()) {
     LOG(ERROR) << "GetRenderStyleForStrike did not receive a response for "
                   "family and size: "
-               << family << ", " << size;
+               << (family ? family : "<empty>") << ", " << size;
     return;
   }
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 33881e49..ed497549 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -316,11 +316,11 @@
   if (base::FeatureList::IsEnabled(features::kCSSFragmentIdentifiers))
     WebRuntimeFeatures::EnableCSSFragmentIdentifiers(true);
 
-  if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
-    WebRuntimeFeatures::EnableGenericSensor(true);
-    if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
-      WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
-  }
+  if (!base::FeatureList::IsEnabled(features::kGenericSensor))
+    WebRuntimeFeatures::EnableGenericSensor(false);
+
+  if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
+    WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
 
   if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS))
     WebRuntimeFeatures::EnableOutOfBlinkCORS(true);
diff --git a/content/child/webthemeengine_impl_android.cc b/content/child/webthemeengine_impl_android.cc
index 9ef5ab7..74efb5d 100644
--- a/content/child/webthemeengine_impl_android.cc
+++ b/content/child/webthemeengine_impl_android.cc
@@ -189,8 +189,8 @@
   // currently fade out so the fadeOutDuration and Delay  Now that this has
   // been added into Blink for other platforms we should plumb that through for
   // Android as well.
-  style->fade_out_delay_seconds = 0;
-  style->fade_out_duration_seconds = 0;
+  style->fade_out_delay = base::TimeDelta();
+  style->fade_out_duration = base::TimeDelta();
   if (getMajorVersion() >= kVersionLollipop) {
     style->thumb_thickness = 4;
     style->scrollbar_margin = 0;
diff --git a/content/child/webthemeengine_impl_default.cc b/content/child/webthemeengine_impl_default.cc
index 9be5b5a..ecda4fe 100644
--- a/content/child/webthemeengine_impl_default.cc
+++ b/content/child/webthemeengine_impl_default.cc
@@ -243,9 +243,8 @@
 }
 
 void WebThemeEngineImpl::GetOverlayScrollbarStyle(ScrollbarStyle* style) {
-  style->fade_out_delay_seconds = ui::kOverlayScrollbarFadeDelay.InSecondsF();
-  style->fade_out_duration_seconds =
-      ui::kOverlayScrollbarFadeDuration.InSecondsF();
+  style->fade_out_delay = ui::kOverlayScrollbarFadeDelay;
+  style->fade_out_duration = ui::kOverlayScrollbarFadeDuration;
   // The other fields in this struct are used only on Android to draw solid
   // color scrollbars. On other platforms the scrollbars are painted in
   // NativeTheme so these fields are unused.
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 4a14664a..21e773401 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -65,6 +65,9 @@
   // Note: |url_loader_client_endpoints| will be empty iff the navigation URL
   // wasn't handled by the network stack (i.e. about:blank, ...)
   //
+  // Note: |response_body| is only used when NavigationImmediateResponseBody is
+  // enabled. It contains the datapipe used to read the response body.
+  //
   // When the Network Service is enabled, |subresource_loader_factories| may
   // also be provided by the browser as a a means for the renderer to load
   // subresources where applicable.
@@ -88,6 +91,7 @@
       CommonNavigationParams common_params,
       RequestNavigationParams request_params,
       network.mojom.URLLoaderClientEndpoints? url_loader_client_endpoints,
+      handle<data_pipe_consumer>? response_body,
       URLLoaderFactoryBundle? subresource_loader_factories,
       array<TransferrableURLLoader>? subresource_overrides,
       ControllerServiceWorkerInfo? controller_service_worker_info,
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom
index 0e7b677..8f2afe0 100644
--- a/content/common/navigation_client.mojom
+++ b/content/common/navigation_client.mojom
@@ -53,6 +53,7 @@
       CommonNavigationParams common_params,
       RequestNavigationParams request_params,
       network.mojom.URLLoaderClientEndpoints? url_loader_client_endpoints,
+      handle<data_pipe_consumer>? response_body,
       URLLoaderFactoryBundle? subresource_loader_factories,
       array<TransferrableURLLoader>? subresource_overrides,
       ControllerServiceWorkerInfo? controller_service_worker_info,
diff --git a/content/public/common/browser_side_navigation_policy.cc b/content/public/common/browser_side_navigation_policy.cc
index 726289e..ccc210bd 100644
--- a/content/public/common/browser_side_navigation_policy.cc
+++ b/content/public/common/browser_side_navigation_policy.cc
@@ -19,4 +19,9 @@
   return base::FeatureList::IsEnabled(features::kPerNavigationMojoInterface);
 }
 
+bool IsNavigationImmediateResponseBodyEnabled() {
+  return base::FeatureList::IsEnabled(
+      features::kNavigationImmediateResponseBody);
+}
+
 }  // namespace content
diff --git a/content/public/common/browser_side_navigation_policy.h b/content/public/common/browser_side_navigation_policy.h
index d5887a1..8c352a0 100644
--- a/content/public/common/browser_side_navigation_policy.h
+++ b/content/public/common/browser_side_navigation_policy.h
@@ -14,6 +14,7 @@
 
 CONTENT_EXPORT bool IsBrowserSideNavigationEnabled();
 CONTENT_EXPORT bool IsPerNavigationMojoInterfaceEnabled();
+CONTENT_EXPORT bool IsNavigationImmediateResponseBodyEnabled();
 
 }  // namespace content
 
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 6b5e05d..dd700ee 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -245,6 +245,11 @@
 #endif
 };
 
+// Transmit the response body datapipe to the renderer process in
+// CommitNavigation() so that it can start reading earlier.
+const base::Feature kNavigationImmediateResponseBody{
+    "NavigationImmediateResponseBody", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // If the network service is enabled, runs it in process.
 const base::Feature kNetworkServiceInProcess{"NetworkServiceInProcess",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 1293be7..cb2e3e9 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -62,6 +62,7 @@
 CONTENT_EXPORT extern const base::Feature kModuleScriptsImportMetaUrl;
 CONTENT_EXPORT extern const base::Feature kMojoSessionStorage;
 CONTENT_EXPORT extern const base::Feature kMojoVideoCapture;
+CONTENT_EXPORT extern const base::Feature kNavigationImmediateResponseBody;
 CONTENT_EXPORT extern const base::Feature kNetworkServiceInProcess;
 CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
 CONTENT_EXPORT extern const base::Feature kOffMainThreadWebSocket;
diff --git a/content/renderer/loader/navigation_response_override_parameters.h b/content/renderer/loader/navigation_response_override_parameters.h
index e9a9b7b..70b6a420 100644
--- a/content/renderer/loader/navigation_response_override_parameters.h
+++ b/content/renderer/loader/navigation_response_override_parameters.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "content/common/content_export.h"
+#include "mojo/public/cpp/system/data_pipe.h"
 #include "net/url_request/redirect_info.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
@@ -22,6 +23,7 @@
   ~NavigationResponseOverrideParameters();
 
   network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
+  mojo::ScopedDataPipeConsumerHandle response_body;
   network::ResourceResponseHead response;
   std::vector<GURL> redirects;
   std::vector<network::ResourceResponseHead> redirect_responses;
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc
index 3d5bd290..5a3dcb2 100644
--- a/content/renderer/loader/resource_dispatcher.cc
+++ b/content/renderer/loader/resource_dispatcher.cc
@@ -788,6 +788,15 @@
   if (!GetPendingRequestInfo(request_id))
     return;
 
+  if (response_override->response_body.is_valid()) {
+    client_ptr->OnStartLoadingResponseBody(
+        std::move(response_override->response_body));
+
+    // Abort if the request is cancelled.
+    if (!GetPendingRequestInfo(request_id))
+      return;
+  }
+
   DCHECK(response_override->url_loader_client_endpoints);
   client_ptr->Bind(std::move(response_override->url_loader_client_endpoints));
 }
diff --git a/content/renderer/loader/web_url_loader_impl.h b/content/renderer/loader/web_url_loader_impl.h
index 9cfb970..df7487d 100644
--- a/content/renderer/loader/web_url_loader_impl.h
+++ b/content/renderer/loader/web_url_loader_impl.h
@@ -9,7 +9,6 @@
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "content/common/frame.mojom.h"
-#include "mojo/public/cpp/system/data_pipe.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "third_party/blink/public/platform/web_url_loader.h"
diff --git a/content/renderer/media/webrtc/webrtc_audio_renderer.cc b/content/renderer/media/webrtc/webrtc_audio_renderer.cc
index 3c7efbd..0825131 100644
--- a/content/renderer/media/webrtc/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc/webrtc_audio_renderer.cc
@@ -93,8 +93,7 @@
 
   void Play() override {
     DCHECK(thread_checker_.CalledOnValidThread());
-    DCHECK(started_);
-    if (playing_state_.playing())
+    if (!started_ || playing_state_.playing())
       return;
     playing_state_.set_playing(true);
     on_play_state_changed_.Run(media_stream_, &playing_state_);
@@ -102,8 +101,7 @@
 
   void Pause() override {
     DCHECK(thread_checker_.CalledOnValidThread());
-    DCHECK(started_);
-    if (!playing_state_.playing())
+    if (!started_ || !playing_state_.playing())
       return;
     playing_state_.set_playing(false);
     on_play_state_changed_.Run(media_stream_, &playing_state_);
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index a52cbf74..1f58e972 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -18,6 +18,7 @@
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
     base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
         subresource_overrides,
@@ -30,8 +31,8 @@
   ResetDisconnectionHandler();
   render_frame_->CommitNavigation(
       head, common_params, request_params,
-      std::move(url_loader_client_endpoints), std::move(subresource_loaders),
-      std::move(subresource_overrides),
+      std::move(url_loader_client_endpoints), std::move(response_body),
+      std::move(subresource_loaders), std::move(subresource_overrides),
       std::move(controller_service_worker_info), devtools_navigation_token,
       mojom::FrameNavigationControl::CommitNavigationCallback());
 }
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h
index 6905161e..5b36beb 100644
--- a/content/renderer/navigation_client.h
+++ b/content/renderer/navigation_client.h
@@ -23,6 +23,7 @@
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
       base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
           subresource_overrides,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index f2b919e5..4f6bff1 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2601,6 +2601,12 @@
   }
 
   std::unique_ptr<DocumentState> document_state;
+  // If we sent a successful navigation to commit but for whatever reason the
+  // commit was interrupted we might end up with empty
+  // |pending_navigation_params_| here. For example, if
+  // there's no byte in the response and the network connection gets closed. In
+  // that case, the provisional load does not commit and we get a
+  // DidFailProvisionalLoad.
   if (pending_navigation_params_)
     document_state =
         BuildDocumentStateFromPending(pending_navigation_params_.get());
@@ -3039,6 +3045,7 @@
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
     base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
         subresource_overrides,
@@ -3133,7 +3140,7 @@
     } else {
       WebURLRequest request = CreateURLRequestForCommit(
           common_params, request_params, std::move(url_loader_client_endpoints),
-          head);
+          std::move(response_body), head);
       frame_->CommitNavigation(request, load_type, item_for_history_navigation,
                                is_client_redirect, devtools_navigation_token,
                                std::move(document_state));
@@ -6512,6 +6519,7 @@
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     const network::ResourceResponseHead& head) {
   // This will override the url requested by the WebURLLoader, as well as
   // provide it with the response to the request.
@@ -6519,6 +6527,7 @@
       new NavigationResponseOverrideParameters());
   response_override->url_loader_client_endpoints =
       std::move(url_loader_client_endpoints);
+  response_override->response_body = std::move(response_body);
   response_override->response = head;
   response_override->redirects = request_params.redirects;
   response_override->redirect_responses = request_params.redirect_response;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 1b10136..6ab340e 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -525,6 +525,7 @@
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
       base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
           subresource_overrides,
@@ -1093,6 +1094,7 @@
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       const network::ResourceResponseHead& head);
 
   // Returns a ChildURLLoaderFactoryBundle which can be used to request
diff --git a/content/renderer/web_database_observer_impl.cc b/content/renderer/web_database_observer_impl.cc
index 76426679..31a64d4 100644
--- a/content/renderer/web_database_observer_impl.cc
+++ b/content/renderer/web_database_observer_impl.cc
@@ -9,8 +9,6 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string16.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/storage_util.h"
-#include "storage/common/database/database_identifier.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/sqlite/sqlite3.h"
@@ -62,7 +60,6 @@
 WebDatabaseObserverImpl::WebDatabaseObserverImpl(
     scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host)
     : web_database_host_(std::move(web_database_host)),
-      open_connections_(new storage::DatabaseConnectionsWrapper),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
   DCHECK(main_thread_task_runner_);
 }
@@ -74,8 +71,6 @@
     const WebString& database_name,
     const WebString& database_display_name,
     unsigned long estimated_size) {
-  open_connections_->AddOpenConnection(storage::GetIdentifierFromOrigin(origin),
-                                       database_name.Utf16());
   GetWebDatabaseHost().Opened(origin, database_name.Utf16(),
                               database_display_name.Utf16(), estimated_size);
 }
@@ -89,8 +84,6 @@
                                              const WebString& database_name) {
   DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence());
   GetWebDatabaseHost().Closed(origin, database_name.Utf16());
-  open_connections_->RemoveOpenConnection(
-      storage::GetIdentifierFromOrigin(origin), database_name.Utf16());
 }
 
 void WebDatabaseObserverImpl::ReportOpenDatabaseResult(
@@ -165,12 +158,6 @@
   HandleSqliteError(origin, database_name, sqlite_error);
 }
 
-bool WebDatabaseObserverImpl::WaitForAllDatabasesToClose(
-    base::TimeDelta timeout) {
-  DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
-  return open_connections_->WaitForAllDatabasesToClose(timeout);
-}
-
 void WebDatabaseObserverImpl::HandleSqliteError(const WebSecurityOrigin& origin,
                                                 const WebString& database_name,
                                                 int error) {
diff --git a/content/renderer/web_database_observer_impl.h b/content/renderer/web_database_observer_impl.h
index 629f126..74544bc 100644
--- a/content/renderer/web_database_observer_impl.h
+++ b/content/renderer/web_database_observer_impl.h
@@ -7,7 +7,6 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "storage/common/database/database_connections.h"
 #include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
 #include "third_party/blink/public/platform/web_database_observer.h"
 
@@ -62,8 +61,6 @@
                                   const blink::WebString& database_name,
                                   int sqlite_error) override;
 
-  bool WaitForAllDatabasesToClose(base::TimeDelta timeout);
-
  private:
   void HandleSqliteError(const blink::WebSecurityOrigin& origin,
                          const blink::WebString& database_name,
@@ -73,7 +70,6 @@
   blink::mojom::WebDatabaseHost& GetWebDatabaseHost();
 
   scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
-  scoped_refptr<storage::DatabaseConnectionsWrapper> open_connections_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(WebDatabaseObserverImpl);
diff --git a/content/test/data/accessibility/html/input-datetime-local-expected-win.txt b/content/test/data/accessibility/html/input-datetime-local-expected-win.txt
index 0080564c..1fe75bd 100644
--- a/content/test/data/accessibility/html/input-datetime-local-expected-win.txt
+++ b/content/test/data/accessibility/html/input-datetime-local-expected-win.txt
@@ -3,21 +3,21 @@
 ++++IA2_ROLE_DATE_EDITOR FOCUSABLE ia2_hypertext='<obj0><obj1>'
 ++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
 ++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>/<obj2>/<obj4> <obj6>:<obj8> <obj10>'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='mm' description='Month'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Month' FOCUSABLE ia2_hypertext='mm'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='mm' ia2_hypertext='mm'
 ++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='dd' description='Day'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Day' FOCUSABLE ia2_hypertext='dd'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='dd' ia2_hypertext='dd'
 ++++++++++ROLE_SYSTEM_STATICTEXT name='/' ia2_hypertext='/'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='yyyy' description='Year'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Year' FOCUSABLE ia2_hypertext='yyyy'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='yyyy' ia2_hypertext='yyyy'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=' ' ia2_hypertext=' '
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='--' description='Hours'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Hours' FOCUSABLE ia2_hypertext='--'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='--' ia2_hypertext='--'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=':' ia2_hypertext=':'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='--' description='Minutes'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Minutes' FOCUSABLE ia2_hypertext='--'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='--' ia2_hypertext='--'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=' ' ia2_hypertext=' '
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='--' description='AM/PM'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='AM/PM' FOCUSABLE ia2_hypertext='--'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='--' ia2_hypertext='--'
-++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP haspopup:menu ia2_hypertext='Show date picker'
+++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP haspopup:menu ia2_hypertext='Show date picker'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-month-expected-blink.txt b/content/test/data/accessibility/html/input-month-expected-blink.txt
index a3f327e..f4b39fcf 100644
--- a/content/test/data/accessibility/html/input-month-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-month-expected-blink.txt
@@ -3,12 +3,12 @@
 ++++dateTime
 ++++++genericContainer
 ++++++++genericContainer
-++++++++++spinButton description='Month' descriptionFrom=attribute valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++spinButton name='Month' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=12.00
 ++++++++++++staticText name='---------'
 ++++++++++++++inlineTextBox name='---------'
 ++++++++++staticText name=' '
 ++++++++++++inlineTextBox name=' '
-++++++++++spinButton description='Year' descriptionFrom=attribute valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++spinButton name='Year' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
 ++++++++++++staticText name='----'
 ++++++++++++++inlineTextBox name='----'
-++++++popUpButton name='Show date picker' haspopup=menu
+++++++popUpButton name='Show date picker' haspopup=menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-month-expected-mac.txt b/content/test/data/accessibility/html/input-month-expected-mac.txt
index 0260659..343bdf1 100644
--- a/content/test/data/accessibility/html/input-month-expected-mac.txt
+++ b/content/test/data/accessibility/html/input-month-expected-mac.txt
@@ -3,9 +3,9 @@
 ++++AXDateField AXRoleDescription='date field'
 ++++++AXGroup AXRoleDescription='group'
 ++++++++AXGroup AXRoleDescription='group'
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXHelp='Month'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXDescription='Month'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='---------'
 ++++++++++AXStaticText AXRoleDescription='text' AXValue=' '
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXHelp='Year'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXDescription='Year'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='----'
-++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
+++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-expected-blink.txt b/content/test/data/accessibility/html/input-time-expected-blink.txt
index 6bd3d78d..efa5d25 100644
--- a/content/test/data/accessibility/html/input-time-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-time-expected-blink.txt
@@ -3,16 +3,16 @@
 ++++inputTime
 ++++++genericContainer
 ++++++++genericContainer
-++++++++++spinButton description='Hours' descriptionFrom=attribute valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
+++++++++++spinButton name='Hours' valueForRange=12.00 minValueForRange=1.00 maxValueForRange=12.00
 ++++++++++++staticText name='12'
 ++++++++++++++inlineTextBox name='12'
 ++++++++++staticText name=':'
 ++++++++++++inlineTextBox name=':'
-++++++++++spinButton description='Minutes' descriptionFrom=attribute valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
+++++++++++spinButton name='Minutes' valueForRange=0.00 minValueForRange=0.00 maxValueForRange=59.00
 ++++++++++++staticText name='00'
 ++++++++++++++inlineTextBox name='00'
 ++++++++++staticText name=' '
 ++++++++++++inlineTextBox name=' '
-++++++++++spinButton description='AM/PM' descriptionFrom=attribute valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
+++++++++++spinButton name='AM/PM' valueForRange=1.00 minValueForRange=1.00 maxValueForRange=2.00
 ++++++++++++staticText name='AM'
-++++++++++++++inlineTextBox name='AM'
+++++++++++++++inlineTextBox name='AM'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-expected-mac.txt b/content/test/data/accessibility/html/input-time-expected-mac.txt
index c1329f4..acf774d8 100644
--- a/content/test/data/accessibility/html/input-time-expected-mac.txt
+++ b/content/test/data/accessibility/html/input-time-expected-mac.txt
@@ -3,11 +3,11 @@
 ++++AXTimeField AXRoleDescription='time field' AXValue='00:00:00'
 ++++++AXGroup AXRoleDescription='group'
 ++++++++AXGroup AXRoleDescription='group'
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='12' AXHelp='Hours'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='12' AXDescription='Hours'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='12'
 ++++++++++AXStaticText AXRoleDescription='text' AXValue=':'
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXHelp='Minutes'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXDescription='Minutes'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='00'
 ++++++++++AXStaticText AXRoleDescription='text' AXValue=' '
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='1' AXHelp='AM/PM'
-++++++++++++AXStaticText AXRoleDescription='text' AXValue='AM'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='1' AXDescription='AM/PM'
+++++++++++++AXStaticText AXRoleDescription='text' AXValue='AM'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-time-expected-win.txt b/content/test/data/accessibility/html/input-time-expected-win.txt
index e554a1c..aa061c3 100644
--- a/content/test/data/accessibility/html/input-time-expected-win.txt
+++ b/content/test/data/accessibility/html/input-time-expected-win.txt
@@ -3,11 +3,11 @@
 ++++ROLE_SYSTEM_GROUPING FOCUSABLE ia2_hypertext='<obj0>'
 ++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
 ++++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>:<obj2> <obj4>'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE xml-roles:spinbutton ia2_hypertext='12' description='Hours'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Hours' FOCUSABLE xml-roles:spinbutton ia2_hypertext='12'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='12' ia2_hypertext='12'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=':' ia2_hypertext=':'
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE xml-roles:spinbutton ia2_hypertext='00' description='Minutes'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Minutes' FOCUSABLE xml-roles:spinbutton ia2_hypertext='00'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='00' ia2_hypertext='00'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=' ' ia2_hypertext=' '
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE xml-roles:spinbutton ia2_hypertext='AM' description='AM/PM'
-++++++++++++ROLE_SYSTEM_STATICTEXT name='AM' ia2_hypertext='AM'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='AM/PM' FOCUSABLE xml-roles:spinbutton ia2_hypertext='AM'
+++++++++++++ROLE_SYSTEM_STATICTEXT name='AM' ia2_hypertext='AM'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-week-expected-blink.txt b/content/test/data/accessibility/html/input-week-expected-blink.txt
index 389a3d84..751ef207 100644
--- a/content/test/data/accessibility/html/input-week-expected-blink.txt
+++ b/content/test/data/accessibility/html/input-week-expected-blink.txt
@@ -5,12 +5,12 @@
 ++++++++genericContainer
 ++++++++++staticText name='Week '
 ++++++++++++inlineTextBox name='Week '
-++++++++++spinButton description='Week' descriptionFrom=attribute valueForRange=0.00 minValueForRange=1.00 maxValueForRange=53.00
+++++++++++spinButton name='Week' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=53.00
 ++++++++++++staticText name='--'
 ++++++++++++++inlineTextBox name='--'
 ++++++++++staticText name=', '
 ++++++++++++inlineTextBox name=', '
-++++++++++spinButton description='Year' descriptionFrom=attribute valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
+++++++++++spinButton name='Year' valueForRange=0.00 minValueForRange=1.00 maxValueForRange=275760.00
 ++++++++++++staticText name='----'
 ++++++++++++++inlineTextBox name='----'
-++++++popUpButton name='Show date picker' haspopup=menu
+++++++popUpButton name='Show date picker' haspopup=menu
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-week-expected-mac.txt b/content/test/data/accessibility/html/input-week-expected-mac.txt
index ca49a7c..ca8e7db 100644
--- a/content/test/data/accessibility/html/input-week-expected-mac.txt
+++ b/content/test/data/accessibility/html/input-week-expected-mac.txt
@@ -4,9 +4,9 @@
 ++++++AXGroup AXRoleDescription='group'
 ++++++++AXGroup AXRoleDescription='group'
 ++++++++++AXStaticText AXRoleDescription='text' AXValue='Week '
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXHelp='Week'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXDescription='Week'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='--'
 ++++++++++AXStaticText AXRoleDescription='text' AXValue=', '
-++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXHelp='Year'
+++++++++++AXIncrementor AXRoleDescription='stepper' AXValue='0' AXDescription='Year'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='----'
-++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
+++++++AXPopUpButton AXRoleDescription='pop up button' AXDescription='Show date picker'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/input-week-expected-win.txt b/content/test/data/accessibility/html/input-week-expected-win.txt
index 8ef167b..6a6fe64 100644
--- a/content/test/data/accessibility/html/input-week-expected-win.txt
+++ b/content/test/data/accessibility/html/input-week-expected-win.txt
@@ -4,9 +4,9 @@
 ++++++IA2_ROLE_SECTION ia2_hypertext='<obj0>'
 ++++++++IA2_ROLE_SECTION ia2_hypertext='Week <obj1>, <obj3>'
 ++++++++++ROLE_SYSTEM_STATICTEXT name='Week ' ia2_hypertext='Week '
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='--' description='Week'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Week' FOCUSABLE ia2_hypertext='--'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='--' ia2_hypertext='--'
 ++++++++++ROLE_SYSTEM_STATICTEXT name=', ' ia2_hypertext=', '
-++++++++++ROLE_SYSTEM_SPINBUTTON FOCUSABLE ia2_hypertext='----' description='Year'
+++++++++++ROLE_SYSTEM_SPINBUTTON name='Year' FOCUSABLE ia2_hypertext='----'
 ++++++++++++ROLE_SYSTEM_STATICTEXT name='----' ia2_hypertext='----'
-++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP haspopup:menu ia2_hypertext='Show date picker'
+++++++ROLE_SYSTEM_BUTTONMENU name='Show date picker' FOCUSABLE HASPOPUP haspopup:menu ia2_hypertext='Show date picker'
\ No newline at end of file
diff --git a/content/test/mock_navigation_client_impl.cc b/content/test/mock_navigation_client_impl.cc
index a59e055e..053af7f 100644
--- a/content/test/mock_navigation_client_impl.cc
+++ b/content/test/mock_navigation_client_impl.cc
@@ -20,6 +20,7 @@
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
     base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
         subresource_overrides,
diff --git a/content/test/mock_navigation_client_impl.h b/content/test/mock_navigation_client_impl.h
index a82b269..926a6176 100644
--- a/content/test/mock_navigation_client_impl.h
+++ b/content/test/mock_navigation_client_impl.h
@@ -22,6 +22,7 @@
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
       base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
           subresource_overrides,
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc
index 793bf525..2e9072f 100644
--- a/content/test/test_navigation_url_loader.cc
+++ b/content/test/test_navigation_url_loader.cc
@@ -90,6 +90,7 @@
           url_loader_ptr.PassInterface(), std::move(url_loader_client_request));
 
   delegate_->OnResponseStarted(response, std::move(url_loader_client_endpoints),
+                               mojo::ScopedDataPipeConsumerHandle(),
                                std::move(navigation_data), global_id, false,
                                false, base::nullopt);
 }
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc
index 2429660..0545a3de 100644
--- a/content/test/test_navigation_url_loader_delegate.cc
+++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -44,6 +44,7 @@
 
 void TestNavigationURLLoaderDelegate::ReleaseURLLoaderClientEndpoints() {
   url_loader_client_endpoints_ = nullptr;
+  response_body_.reset();
 }
 
 void TestNavigationURLLoaderDelegate::OnRequestRedirected(
@@ -58,6 +59,7 @@
 void TestNavigationURLLoaderDelegate::OnResponseStarted(
     const scoped_refptr<network::ResourceResponse>& response,
     network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+    mojo::ScopedDataPipeConsumerHandle response_body,
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
@@ -65,6 +67,7 @@
     base::Optional<SubresourceLoaderParams> subresource_loader_params) {
   response_ = response;
   url_loader_client_endpoints_ = std::move(url_loader_client_endpoints);
+  response_body_ = std::move(response_body);
   if (response->head.ssl_info.has_value())
     ssl_info_ = *response->head.ssl_info;
   is_download_ = is_download;
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h
index e7ecf4f..8db8590 100644
--- a/content/test/test_navigation_url_loader_delegate.h
+++ b/content/test/test_navigation_url_loader_delegate.h
@@ -63,6 +63,7 @@
   void OnResponseStarted(
       const scoped_refptr<network::ResourceResponse>& response,
       network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+      mojo::ScopedDataPipeConsumerHandle response_body,
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
@@ -78,6 +79,7 @@
   scoped_refptr<network::ResourceResponse> redirect_response_;
   network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints_;
   scoped_refptr<network::ResourceResponse> response_;
+  mojo::ScopedDataPipeConsumerHandle response_body_;
   int net_error_;
   net::SSLInfo ssl_info_;
   int on_request_handled_counter_;
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index c970e525..ed2f631c 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -154,6 +154,7 @@
   CommitNavigation(
       network::ResourceResponseHead(), common_params, request_params,
       network::mojom::URLLoaderClientEndpointsPtr(),
+      mojo::ScopedDataPipeConsumerHandle(),
       std::make_unique<URLLoaderFactoryBundleInfo>(), base::nullopt,
       mojom::ControllerServiceWorkerInfoPtr(), base::UnguessableToken::Create(),
       CommitNavigationCallback());
diff --git a/docs/speed/benchmark/harnesses/power_perf.md b/docs/speed/benchmark/harnesses/power_perf.md
index c7c4a172..7f04802 100644
--- a/docs/speed/benchmark/harnesses/power_perf.md
+++ b/docs/speed/benchmark/harnesses/power_perf.md
@@ -4,80 +4,39 @@
 
 ## Overview
 
-The Telemetry power benchmarks use BattOr, a small external power monitor, to collect power measurements while Chrome performs various tasks (a.k.a. user stories).
+The Telemetry power benchmarks measure power indirectly by measuring the CPU time used by Chrome while it performs various tasks (a.k.a. user stories).
 
-There are currently seven benchmarks that collect power data, grouped together by the type of task during which the power data is collected:
+## List of power metrics
+
+### `cpu_time_percentage_avg`
+This metric measures the average number of cores that Chrome used over the duration of the trace.
+
+This metric is enabled by adding `'cpuTimeMetric'` to the list of TBM2 metrics in the benchmark's Python class:
+
+```python
+options.SetTimelineBasedMetrics(['cpuTimeMetric', 'memoryMetric'])
+```
+
+Additionally, the `toplevel` trace category must be enabled for this metric to function correctly because it ensures that a trace span is active whenever Chrome is doing work:
+
+```python
+category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(filter_string='toplevel')
+```
+
+## List of power benchmarks
+
+The primary power benchmarks are:
 
 - **`system_health.common_desktop`**: A desktop-only benchmark in which each page focuses on a single, common way in which users use Chrome (e.g. browsing Facebook photos, shopping on Amazon, searching Google)
 - **`system_health.common_mobile`**: A mobile-only benchmark that parallels `system_health.common_desktop`
-- **`battor.trivial_pages`**: A Mac-only benchmark in which each page focuses on a single, extremely simple behavior (e.g. a blinking cursor, a CSS blur animation)
-- **`battor.steady_state`**: A Mac-only benchmark in which each page focuses on a website that Chrome has exhibited pathological idle behavior in the past
-- **`media.tough_video_cases_tbmv2`**: A desktop-only benchmark in which each page tests a particular media-related scenario (e.g. playing a 1080p, H264 video with sound)
-- **`media.android.tough_video_cases_tbmv2`**: A mobile-only benchmark that parallels `media.tough_video_cases_tbmv2`
-- **`power.idle_platform`**: A benchmark that sits idle without starting Chrome for various lengths of time. Used as a debugging benchmark to monitor machine background noise.
+- **`power.desktop`**: A desktop-only benchmark made up of two types of pages:
+  - Pages focusing on a single, extremely simple behavior (e.g. a blinking cursor, a CSS blur animation)
+  - Pages on which Chrome has exhibited pathological idle behavior in the past
+- **`power.typical_10_mobile`**: A mobile-only benchmark which visits ten popular sites and uses Android-specific APIs to measure approximately how much power is consumed. This benchmark is necessary to provide data to the Android System Health Council to assess whether Chrome Android is fit for release
+- **`media.desktop`**: A desktop-only benchmark in which each page tests a particular media-related scenario (e.g. playing a 1080p, H264 video with sound)
+- **`media.mobile`**: A mobile-only benchmark that parallels `media.desktop`
 
-Note that these benchmarks are in the process of being consolidated and that there will likely be fewer, larger power benchmarks in the near future.
-
-The legacy power benchmarks consist of:
-
-- **`power.typical_10_mobile`**, which visits ten popular sites and uses Android-specific APIs to measure approximately how much power was consumed. This can't be deleted because it's still used by the Android System Health Council to assess whether Chrome Android is fit for release on hardware configurations for which BattOrs are not yet available.
-
-## Running the tests remotely
-
-If you're just trying to gauge whether your change has caused a power regression, you can do so by [running a benchmark remotely via a perf try job](https://chromium.googlesource.com/chromium/src/+/master/docs/speed/perf_trybots.md).
-
-When you do this, be sure to use a configuration that's equipped with BattOrs:
-
-- `android_nexus5X`
-- `android-webview-arm64-aosp`
-- `mac-retina`
-- `mac-10-11`
-- `winx64-high-dpi`
-
-If you're unsure of which benchmark to choose, `system_health.common_[desktop/mobile]` is a safe, broad choice.
-
-## Running the tests locally
-
-For more in-depth analysis and shorter cycle times, it can be helpful to run the tests locally. Because the power benchmarks rely on having a BattOr, you'll need to get one before you can do so. If you're a Googler, you can ask around (many Chrome offices already have a BattOr in them) or request one at [go/battor-request-form](http://go/battor-request-form). If you're external to Google, you can contact the BattOr's manufacturer at <sales@mellowlabs.com>.
-
-Once you have a BattOr, follow the instructions in the [BattOr laptop setup guide](https://docs.google.com/document/d/1UsHc990NRO2MEm5A3b9oRk9o7j7KZ1qftOrJyV1Tr2c/edit) to hook it up to your laptop. If you're using a phone with a BattOr, you'll need to run one USB to micro-USB cable from the host computer triggering the Telemetry tests to the BattOr and another from the host computer to the phone.
-
-Once you've done this, you can start the Telemetry benchmark with:
-
-```
-./tools/perf/run_benchmark <benchmark_name> --browser=<browser>
-```
-
-where `benchmark_name` is one of the above benchmark names.
-
-## Understanding power metrics
-
-To understand our power metrics, it's important to understand the distinction between power and energy. *Energy* is what makes computers run and is measured in Joules, whereas *power* is the rate at which that energy is used and is measured in Joules per second.
-
-Some of our power metrics measure energy, whereas others measure power. Specifically:
-
-- We measure *energy* when the user cares about whether the task is completed (e.g. "energy required to load a page", "energy required to responsd to a mouse click").
-- We measure *power* when the user cares about the power required to continue performing an action (e.g. "power while scrolling", "power while playing a video animation").
-
-The full list of our metrics is as follows:
-
-### Energy metrics
-- **`load:energy_sum`**: Total energy used in between page navigations and first meaningful paint on all navigations in the story.
-- **`scroll_response:energy_sum`**: Total energy used to respond to all scroll requests in the story.
-- **`tap_response:energy_sum`**: Total energy used to respond to all taps in the story.
-- **`keyboard_response:energy_sum`**: Total energy used to respond to all key entries in the story.
-
-### Power metrics
-- **`story:power_avg`**: Average power over the entire story.
-- **`css_animation:power_avg`**: Average power over all CSS animations in the story.
-- **`scroll_animation:power_avg`**: Average power over all scroll animations in the story.
-- **`touch_animation:power_avg`**: Average power over all touch animations (e.g. finger drags) in the story.
-- **`video_animation:power_avg`**: Average power over all videos played in the story.
-- **`webgl_animation:power_avg`**: Average power over all WebGL animations in the story.
-- **`idle:power_avg`**: Average power over all idle periods in the story.
-
-### Other metrics
-- **`cpu_time_percentage_avg`**: Average CPU load over the entire story.
+[This spreadsheet](https://docs.google.com/spreadsheets/d/1xaAo0_SU3iDfGdqDJZX_jRV0QtkufwHUKH3kQKF3YQs/edit#gid=0) lists the owner for each benchmark.
 
 ## Adding new power test cases
-We're not currently accepting new power stories until we've consolidated the existing ones.
+To add a new test case to a power benchmark, contact the owner of the benchmark above that sounds like the best fit.
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index f293adb..26d6afa 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -482,12 +482,14 @@
     sources += [
       "api/cec_private/cec_private_apitest.cc",
       "api/media_perception_private/media_perception_private_apitest.cc",
+      "api/system_power_source/system_power_source_apitest.cc",
       "api/virtual_keyboard/virtual_keyboard_apitest.cc",
     ]
 
     deps += [
       "//chromeos",
       "//chromeos:media_perception_proto",
+      "//chromeos:power_manager_proto",
     ]
   }
 }
diff --git a/extensions/browser/api/system_power_source/system_power_source_apitest.cc b/extensions/browser/api/system_power_source/system_power_source_apitest.cc
new file mode 100644
index 0000000..5f99c76
--- /dev/null
+++ b/extensions/browser/api/system_power_source/system_power_source_apitest.cc
@@ -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.
+
+#include <memory>
+#include <utility>
+
+#include "base/macros.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/fake_power_manager_client.h"
+#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
+#include "extensions/common/features/feature_session_type.h"
+#include "extensions/shell/test/shell_apitest.h"
+#include "extensions/test/result_catcher.h"
+
+namespace extensions {
+
+namespace {
+
+class SystemPowerSourceApiTest : public ShellApiTest {
+ public:
+  SystemPowerSourceApiTest()
+      : session_type_(
+            ScopedCurrentFeatureSessionType(FeatureSessionType::KIOSK)) {
+    auto power_manager_client =
+        std::make_unique<chromeos::FakePowerManagerClient>();
+
+    // These values must match the assertions in
+    // extensions/test/data/api_test/system_power_source/api/background.js.
+    power_manager::PowerSupplyProperties_PowerSource power_source;
+    power_source.set_id("AC");
+    power_source.set_type(
+        power_manager::PowerSupplyProperties_PowerSource_Type_MAINS);
+    power_source.set_max_power(0);
+
+    power_manager::PowerSupplyProperties props;
+    props.set_external_power_source_id("AC");
+    *props.add_available_external_power_source() = power_source;
+
+    power_manager_client->UpdatePowerProperties(props);
+
+    chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
+        std::move(power_manager_client));
+  }
+
+  ~SystemPowerSourceApiTest() override = default;
+
+ private:
+  std::unique_ptr<base::AutoReset<FeatureSessionType>> session_type_;
+  DISALLOW_COPY_AND_ASSIGN(SystemPowerSourceApiTest);
+};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(SystemPowerSourceApiTest, TestAllApiFunctions) {
+  EXPECT_TRUE(RunAppTest("api_test/system_power_source/api"));
+}
+
+}  // namespace extensions
diff --git a/extensions/test/data/api_test/system_power_source/api/background.js b/extensions/test/data/api_test/system_power_source/api/background.js
new file mode 100644
index 0000000..21efc07
--- /dev/null
+++ b/extensions/test/data/api_test/system_power_source/api/background.js
@@ -0,0 +1,19 @@
+// 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.
+
+chrome.test.runTests([
+  function getPowerSourceInfo() {
+    chrome.system.powerSource.getPowerSourceInfo(
+        chrome.test.callbackPass(info => {
+          chrome.test.assertEq([{active: true, type: 'mains'}], info);
+        }));
+  },
+
+  function onPowerChanged() {
+    chrome.test.listenOnce(chrome.system.powerSource.onPowerChanged, info => {
+      chrome.test.assertEq([{active: true, type: 'mains'}], info);
+    });
+    chrome.system.powerSource.requestStatusUpdate();
+  },
+]);
diff --git a/extensions/test/data/api_test/system_power_source/api/manifest.json b/extensions/test/data/api_test/system_power_source/api/manifest.json
new file mode 100644
index 0000000..b6c4177
--- /dev/null
+++ b/extensions/test/data/api_test/system_power_source/api/manifest.json
@@ -0,0 +1,15 @@
+{
+  "name": "chrome.system.powerSource",
+  "manifest_version": 2,
+  "version": "0.1",
+  "description": "end-to-end browser tests for chrome.system.powerSource API",
+  "app": {
+    "background": {
+      "scripts": ["background.js"]
+    }
+  },
+  "permissions": [
+    "system.powerSource"
+  ],
+  "kiosk_enabled": true
+}
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index eec1b00..4f8cd005 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -2455,6 +2455,7 @@
     builders { mixins: "linux-try" name: "linux-blink-gen-property-trees" }
     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-gcc-rel" }
     builders { mixins: "linux-try" name: "linux-jumbo-rel" }
     builders { mixins: "linux-try" name: "linux-ozone-rel" }
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 62033d6576..6549770 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -38,6 +38,7 @@
 #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h"
 #include "ios/chrome/browser/ui/background_generator.h"
 #import "ios/chrome/browser/ui/browser_view_controller.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/main/browser_view_information.h"
@@ -364,7 +365,7 @@
       BOOL incognito =
           bvc == [[_browserLauncher browserViewInformation] otrBVC];
       [bvc.dispatcher
-          openNewTab:[OpenNewTabCommand commandWithIncognito:incognito]];
+          openURL:[OpenNewTabCommand commandWithIncognito:incognito]];
     }
   } else {
     [[[_browserLauncher browserViewInformation] currentBVC]
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index 362d31e..6ced742 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -32,7 +32,9 @@
 #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h"
 #import "ios/chrome/browser/tabs/tab_model.h"
 #import "ios/chrome/browser/ui/browser_view_controller.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/main/browser_view_information.h"
 #import "ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
@@ -687,8 +689,8 @@
   id mainTabModel = [OCMockObject mockForClass:[TabModel class]];
   [[mainTabModel expect] resetSessionMetrics];
 
-  id dispatcher = [OCMockObject mockForProtocol:@protocol(BrowserCommands)];
-  [[dispatcher expect] openNewTab:[OCMArg any]];
+  id dispatcher = [OCMockObject mockForProtocol:@protocol(ApplicationCommands)];
+  [((id<ApplicationCommands>)[dispatcher expect]) openURL:[OCMArg any]];
 
   id currentBVC = [OCMockObject mockForClass:[BrowserViewController class]];
   stubBrowserState(currentBVC);
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index f050030b..9851611 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -78,6 +78,7 @@
 #include "ios/chrome/browser/download/download_directory_util.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/feature_engagement/tracker_factory.h"
+#include "ios/chrome/browser/feature_engagement/tracker_util.h"
 #include "ios/chrome/browser/file_metadata_util.h"
 #import "ios/chrome/browser/first_run/first_run.h"
 #include "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h"
@@ -111,7 +112,6 @@
 #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h"
 #import "ios/chrome/browser/ui/browser_view_controller.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/download/legacy_download_manager_controller.h"
 #import "ios/chrome/browser/ui/external_file_remover_factory.h"
@@ -466,7 +466,11 @@
 // Sets up self.currentBVC for testing by closing existing tabs.
 - (void)setUpCurrentBVCForTesting;
 // Opens an url from a link in the settings UI.
-- (void)openUrlFromSettings:(OpenUrlCommand*)command;
+- (void)openUrlFromSettings:(OpenNewTabCommand*)command;
+// Switches to show either regular or incognito tabs, and then opens
+// a new oen of those tabs. |newTabCommand|'s |incognito| property inidcates
+// the type of tab to open.
+- (void)switchModesAndOpenNewTab:(OpenNewTabCommand*)command;
 // Switch all global states for the given mode (normal or incognito).
 - (void)switchGlobalStateToMode:(ApplicationMode)mode;
 // Updates the local storage, cookie store, and sets the global state.
@@ -1321,7 +1325,7 @@
     OpenNewTabCommand* command = [OpenNewTabCommand
         commandWithIncognito:(self.currentBVC == self.otrBVC)];
     command.userInitiated = NO;
-    [self.currentBVC.dispatcher openNewTab:command];
+    [self.currentBVC.dispatcher openURL:command];
   }
 
   if (firstRun) {
@@ -1435,26 +1439,6 @@
   [self dismissModalDialogsWithCompletion:nil dismissOmnibox:YES];
 }
 
-- (void)switchModesAndOpenNewTab:(OpenNewTabCommand*)command {
-  BrowserViewController* bvc = command.incognito ? self.otrBVC : self.mainBVC;
-  DCHECK(bvc);
-  [bvc expectNewForegroundTab];
-  self.currentBVC = bvc;
-  [self.currentBVC.dispatcher openNewTab:command];
-}
-
-- (void)startVoiceSearch {
-  if (!_isProcessingTabSwitcherCommand) {
-    [self startVoiceSearchInCurrentBVC];
-    _isProcessingVoiceSearchCommand = YES;
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
-                                 kExpectedTransitionDurationInNanoSeconds),
-                   dispatch_get_main_queue(), ^{
-                     _isProcessingVoiceSearchCommand = NO;
-                   });
-  }
-}
-
 - (void)showHistory {
   if (IsUIRefreshPhase1Enabled()) {
     // New History UIReboot coordinator.
@@ -1475,7 +1459,7 @@
   }
 }
 
-- (void)closeSettingsUIAndOpenURL:(OpenUrlCommand*)command {
+- (void)closeSettingsUIAndOpenURL:(OpenNewTabCommand*)command {
   [self openUrlFromSettings:command];
 }
 
@@ -1541,22 +1525,48 @@
   });
 }
 
-- (void)openURL:(OpenUrlCommand*)command {
-  if ([command fromChrome]) {
-    [self dismissModalsAndOpenSelectedTabInMode:ApplicationMode::NORMAL
-                                        withURL:[command url]
-                                 dismissOmnibox:YES
-                                     transition:ui::PAGE_TRANSITION_TYPED
-                                     completion:nil];
-  } else {
-    [self dismissModalDialogsWithCompletion:^{
-      self.currentBVC = [command inIncognito] ? self.otrBVC : self.mainBVC;
-      [self.currentBVC webPageOrderedOpen:[command url]
-                                 referrer:[command referrer]
-                             inBackground:[command inBackground]
-                                 appendTo:[command appendTo]];
+- (void)openURL:(OpenNewTabCommand*)command {
+  if (command.URL.is_valid()) {
+    if ([command fromChrome]) {
+      [self dismissModalsAndOpenSelectedTabInMode:ApplicationMode::NORMAL
+                                          withURL:[command URL]
+                                   dismissOmnibox:YES
+                                       transition:ui::PAGE_TRANSITION_TYPED
+                                       completion:nil];
+    } else {
+      [self dismissModalDialogsWithCompletion:^{
+        self.currentBVC = [command inIncognito] ? self.otrBVC : self.mainBVC;
+        [self.currentBVC webPageOrderedOpen:[command URL]
+                                   referrer:[command referrer]
+                               inBackground:[command inBackground]
+                                   appendTo:[command appendTo]];
+      }
+                               dismissOmnibox:YES];
     }
-                             dismissOmnibox:YES];
+
+  } else {
+    if (self.currentBrowserState->IsOffTheRecord() != command.inIncognito) {
+      // Must take a snapshot of the tab before we switch the incognito mode
+      // because the currentTab will change after the switch.
+      Tab* currentTab = self.currentTabModel.currentTab;
+      if (currentTab) {
+        SnapshotTabHelper::FromWebState(currentTab.webState)
+            ->UpdateSnapshot(/*with_overlays=*/true,
+                             /*visible_frame_only=*/true);
+      }
+      // Not for this browser state, send it on its way.
+      [self switchModesAndOpenNewTab:command];
+      return;
+    }
+
+    // Either send or don't send the "New Tab Opened" or "Incognito Tab Opened"
+    // events to the feature_engagement::Tracker based on
+    // |command.userInitiated| and |command.incognito|.
+    feature_engagement::NotifyNewTabEventForCommand(self.currentBrowserState,
+                                                    command);
+
+    [self.currentBVC openNewTabFromOriginPoint:command.originPoint
+                                  focusOmnibox:command.shouldFocusOmnibox];
   }
 }
 
@@ -1691,11 +1701,11 @@
 
 #pragma mark - ApplicationCommands helpers
 
-- (void)openUrlFromSettings:(OpenUrlCommand*)command {
+- (void)openUrlFromSettings:(OpenNewTabCommand*)command {
   DCHECK([command fromChrome]);
   ProceduralBlock completion = ^{
     [self dismissModalsAndOpenSelectedTabInMode:ApplicationMode::NORMAL
-                                        withURL:[command url]
+                                        withURL:[command URL]
                                  dismissOmnibox:YES
                                      transition:ui::PAGE_TRANSITION_TYPED
                                      completion:nil];
@@ -1841,6 +1851,26 @@
 
 #pragma mark - Mode Switching
 
+- (void)switchModesAndOpenNewTab:(OpenNewTabCommand*)command {
+  BrowserViewController* bvc = command.inIncognito ? self.otrBVC : self.mainBVC;
+  DCHECK(bvc);
+  [bvc expectNewForegroundTab];
+  self.currentBVC = bvc;
+  [self openURL:command];
+}
+
+- (void)startVoiceSearch {
+  if (!_isProcessingTabSwitcherCommand) {
+    [self startVoiceSearchInCurrentBVC];
+    _isProcessingVoiceSearchCommand = YES;
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
+                                 kExpectedTransitionDurationInNanoSeconds),
+                   dispatch_get_main_queue(), ^{
+                     _isProcessingVoiceSearchCommand = NO;
+                   });
+  }
+}
+
 - (void)switchGlobalStateToMode:(ApplicationMode)mode {
   const BOOL incognito = (mode == ApplicationMode::INCOGNITO);
   // Write the state to disk of what is "active".
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index d12e17f..a188578 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -699,7 +699,7 @@
       <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_TITLE" desc="Title for the view in the Settings for enabling/disabling Sync and all the Google services. [Length: 15em] [iOS only]">
+      <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE" desc="Title for the view in the Settings for enabling/disabling Sync and all the Google services. [Length: 26em] [iOS only]">
         Sync and Google Services
       </message>
       <message name="IDS_IOS_HISTORY_OTHER_FORMS_OF_HISTORY" desc="The notification at the top of the history page indicating that deleting Chrome browsing history will not delete other forms of history stored at Google My Activity.">
diff --git a/ios/chrome/browser/feature_engagement/tracker_util.mm b/ios/chrome/browser/feature_engagement/tracker_util.mm
index 3d93a0c..74415c1 100644
--- a/ios/chrome/browser/feature_engagement/tracker_util.mm
+++ b/ios/chrome/browser/feature_engagement/tracker_util.mm
@@ -27,7 +27,7 @@
 void NotifyNewTabEventForCommand(ios::ChromeBrowserState* browserState,
                                  OpenNewTabCommand* command) {
   if (command.isUserInitiated) {
-    NotifyNewTabEvent(browserState, command.incognito);
+    NotifyNewTabEvent(browserState, command.inIncognito);
   }
 }
 
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_infobar_delegate.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_infobar_delegate.mm
index ce8c8e1..44fa56f 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_infobar_delegate.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_infobar_delegate.mm
@@ -11,7 +11,7 @@
 #include "components/password_manager/core/browser/password_manager_constants.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
 #include "ios/web/public/referrer.h"
@@ -46,7 +46,7 @@
 
 bool IOSChromePasswordManagerInfoBarDelegate::LinkClicked(
     WindowOpenDisposition disposition) {
-  OpenUrlCommand* command = [[OpenUrlCommand alloc]
+  OpenNewTabCommand* command = [[OpenNewTabCommand alloc]
        initWithURL:GURL(password_manager::kPasswordManagerHelpCenterSmartLock)
           referrer:web::Referrer()
        inIncognito:NO
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 430ce81..7c9a8ad 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -64,7 +64,6 @@
 #include "ios/chrome/browser/translate/chrome_ios_translate_client.h"
 #import "ios/chrome/browser/u2f/u2f_controller.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/open_in_controller.h"
 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h"
diff --git a/ios/chrome/browser/ui/browser_view_controller.h b/ios/chrome/browser/ui/browser_view_controller.h
index 4d31316..1904432 100644
--- a/ios/chrome/browser/ui/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view_controller.h
@@ -110,6 +110,9 @@
 // deallocated soon.
 - (void)browserStateDestroyed;
 
+- (void)openNewTabFromOriginPoint:(CGPoint)originPoint
+                     focusOmnibox:(BOOL)focusOmnibox;
+
 // Add a new tab with the given url, appends it to the end of the model,
 // and makes it the selected tab. The selected tab is returned.
 - (Tab*)addSelectedTabWithURL:(const GURL&)url
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 4a4de2f..b0659b8 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -132,7 +132,6 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
 #import "ios/chrome/browser/ui/commands/popup_menu_commands.h"
 #import "ios/chrome/browser/ui/commands/reading_list_add_command.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
@@ -834,8 +833,8 @@
 // Tap Handling
 // ------------
 // Record the last tap point based on the |originPoint| (if any) passed in
-// |command|.
-- (void)setLastTapPoint:(OpenNewTabCommand*)command;
+// command.
+- (void)setLastTapPointFromCommand:(CGPoint)originPoint;
 // Returns the last stored |_lastTapPoint| if it's been set within the past
 // second.
 - (CGPoint)lastTapPoint;
@@ -1409,6 +1408,54 @@
   _dispatcher = nil;
 }
 
+- (void)openNewTabFromOriginPoint:(CGPoint)originPoint
+                     focusOmnibox:(BOOL)focusOmnibox {
+  NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
+  BOOL offTheRecord = self.isOffTheRecord;
+  ProceduralBlock oldForegroundTabWasAddedCompletionBlock =
+      self.foregroundTabWasAddedCompletionBlock;
+  __weak BrowserViewController* weakSelf = self;
+  self.foregroundTabWasAddedCompletionBlock = ^{
+    if (oldForegroundTabWasAddedCompletionBlock) {
+      oldForegroundTabWasAddedCompletionBlock();
+    }
+    double duration = [NSDate timeIntervalSinceReferenceDate] - startTime;
+    base::TimeDelta timeDelta = base::TimeDelta::FromSecondsD(duration);
+    if (offTheRecord) {
+      UMA_HISTOGRAM_TIMES("Toolbar.Menu.NewIncognitoTabPresentationDuration",
+                          timeDelta);
+    } else {
+      UMA_HISTOGRAM_TIMES("Toolbar.Menu.NewTabPresentationDuration", timeDelta);
+    }
+    if (focusOmnibox) {
+      [weakSelf.dispatcher focusOmnibox];
+    }
+  };
+
+  [self setLastTapPointFromCommand:originPoint];
+  // When the tab switcher presentation experiment is enabled, the new tab can
+  // be opened before BVC has been made visible onscreen.  Test for this case by
+  // checking if the parent container VC is currently in the process of being
+  // presented.
+  DCHECK(self.visible || self.dismissingModal ||
+         (TabSwitcherPresentsBVCEnabled() &&
+          self.parentViewController.isBeingPresented));
+
+  // In most cases, we want to take a snapshot of the current tab before opening
+  // a new tab. However, if the current tab is not fully visible (did not finish
+  // |-viewDidAppear:|, then we must not take an empty snapshot, replacing an
+  // existing snapshot for the tab. This can happen when a new regular tab is
+  // opened from an incognito tab. A different BVC is displayed, which may not
+  // have enough time to finish appearing before a snapshot is requested.
+  Tab* currentTab = [_model currentTab];
+  if (currentTab && self.viewVisible) {
+    SnapshotTabHelper::FromWebState(currentTab.webState)
+        ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true);
+  }
+  [self addSelectedTabWithURL:GURL(kChromeUINewTabURL)
+                   transition:ui::PAGE_TRANSITION_TYPED];
+}
+
 - (Tab*)addSelectedTabWithURL:(const GURL&)url
                    transition:(ui::PageTransition)transition {
   return [self addSelectedTabWithURL:url
@@ -2793,12 +2840,12 @@
 
 #pragma mark - Private Methods: Tap handling
 
-- (void)setLastTapPoint:(OpenNewTabCommand*)command {
-  if (CGPointEqualToPoint(command.originPoint, CGPointZero)) {
+- (void)setLastTapPointFromCommand:(CGPoint)originPoint {
+  if (CGPointEqualToPoint(originPoint, CGPointZero)) {
     _lastTapPoint = CGPointZero;
   } else {
     _lastTapPoint =
-        [self.view.window convertPoint:command.originPoint toView:self.view];
+        [self.view.window convertPoint:originPoint toView:self.view];
   }
   _lastTapTime = CACurrentMediaTime();
 }
@@ -3721,8 +3768,7 @@
   switch (action) {
     case OverscrollAction::NEW_TAB:
       [self.dispatcher
-          openNewTab:[OpenNewTabCommand
-                         commandWithIncognito:self.isOffTheRecord]];
+          openURL:[OpenNewTabCommand commandWithIncognito:self.isOffTheRecord]];
       break;
     case OverscrollAction::CLOSE_TAB:
       [self.dispatcher closeCurrentTab];
@@ -4221,7 +4267,7 @@
   if (entry->type != sessions::TabRestoreService::TAB)
     return;
 
-  [self.dispatcher openNewTab:[OpenNewTabCommand command]];
+  [self.dispatcher openURL:[OpenNewTabCommand command]];
   [self restoreTabWithSessionID:entry->id];
 }
 
@@ -4404,7 +4450,7 @@
   // ends up appended to the end of the model, not just next to what is
   // currently selected in the other mode. This is done with the |append|
   // parameter.
-  OpenUrlCommand* command = [[OpenUrlCommand alloc]
+  OpenNewTabCommand* command = [[OpenNewTabCommand alloc]
        initWithURL:url
           referrer:web::Referrer()  // Strip referrer when switching modes.
        inIncognito:inIncognito
@@ -4626,68 +4672,7 @@
 }
 
 - (void)openNewTab:(OpenNewTabCommand*)command {
-  if (self.isOffTheRecord != command.incognito) {
-    // Must take a snapshot of the tab before we switch the incognito mode
-    // because the currentTab will change after the switch.
-    Tab* currentTab = [_model currentTab];
-    if (currentTab) {
-      SnapshotTabHelper::FromWebState(currentTab.webState)
-          ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true);
-    }
-    // Not for this browser state, send it on its way.
-    [self.dispatcher switchModesAndOpenNewTab:command];
-    return;
-  }
-
-  // Either send or don't send the "New Tab Opened" or "Incognito Tab Opened"
-  // events to the feature_engagement::Tracker based on |command.userInitiated|
-  // and |command.incognito|.
-  feature_engagement::NotifyNewTabEventForCommand(_browserState, command);
-
-  NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
-  BOOL offTheRecord = self.isOffTheRecord;
-  ProceduralBlock oldForegroundTabWasAddedCompletionBlock =
-      self.foregroundTabWasAddedCompletionBlock;
-  __weak BrowserViewController* weakSelf = self;
-  self.foregroundTabWasAddedCompletionBlock = ^{
-    if (oldForegroundTabWasAddedCompletionBlock) {
-      oldForegroundTabWasAddedCompletionBlock();
-    }
-    double duration = [NSDate timeIntervalSinceReferenceDate] - startTime;
-    base::TimeDelta timeDelta = base::TimeDelta::FromSecondsD(duration);
-    if (offTheRecord) {
-      UMA_HISTOGRAM_TIMES("Toolbar.Menu.NewIncognitoTabPresentationDuration",
-                          timeDelta);
-    } else {
-      UMA_HISTOGRAM_TIMES("Toolbar.Menu.NewTabPresentationDuration", timeDelta);
-    }
-    if (command.shouldFocusOmnibox) {
-      [weakSelf.dispatcher focusOmnibox];
-    }
-  };
-
-  [self setLastTapPoint:command];
-  // When the tab switcher presentation experiment is enabled, the new tab can
-  // be opened before BVC has been made visible onscreen.  Test for this case by
-  // checking if the parent container VC is currently in the process of being
-  // presented.
-  DCHECK(self.visible || self.dismissingModal ||
-         (TabSwitcherPresentsBVCEnabled() &&
-          self.parentViewController.isBeingPresented));
-
-  // In most cases, we want to take a snapshot of the current tab before opening
-  // a new tab. However, if the current tab is not fully visible (did not finish
-  // |-viewDidAppear:|, then we must not take an empty snapshot, replacing an
-  // existing snapshot for the tab. This can happen when a new regular tab is
-  // opened from an incognito tab. A different BVC is displayed, which may not
-  // have enough time to finish appearing before a snapshot is requested.
-  Tab* currentTab = [_model currentTab];
-  if (currentTab && self.viewVisible) {
-    SnapshotTabHelper::FromWebState(currentTab.webState)
-        ->UpdateSnapshot(/*with_overlays=*/true, /*visible_frame_only=*/true);
-  }
-  [self addSelectedTabWithURL:GURL(kChromeUINewTabURL)
-                   transition:ui::PAGE_TRANSITION_TYPED];
+  [self.dispatcher openURL:command];
 }
 
 - (void)printTab {
@@ -5780,7 +5765,7 @@
   [self.tabModel.currentTab goBack];
 
   if (url.is_valid()) {
-    OpenUrlCommand* command = [[OpenUrlCommand alloc]
+    OpenNewTabCommand* command = [[OpenNewTabCommand alloc]
          initWithURL:url
             referrer:web::Referrer()  // Strip referrer when switching modes.
          inIncognito:YES
@@ -5788,7 +5773,7 @@
             appendTo:kLastTab];
     [self.dispatcher openURL:command];
   } else {
-    [self.dispatcher openNewTab:[OpenNewTabCommand command]];
+    [self.dispatcher openURL:[OpenNewTabCommand command]];
   }
 }
 
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn
index 706d3616..4095484f 100644
--- a/ios/chrome/browser/ui/commands/BUILD.gn
+++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -17,8 +17,6 @@
     "omnibox_suggestion_commands.h",
     "open_new_tab_command.h",
     "open_new_tab_command.mm",
-    "open_url_command.h",
-    "open_url_command.mm",
     "page_info_commands.h",
     "popup_menu_commands.h",
     "qr_scanner_commands.h",
diff --git a/ios/chrome/browser/ui/commands/application_commands.h b/ios/chrome/browser/ui/commands/application_commands.h
index b4bb66c..1a175376c 100644
--- a/ios/chrome/browser/ui/commands/application_commands.h
+++ b/ios/chrome/browser/ui/commands/application_commands.h
@@ -10,7 +10,6 @@
 #import "ios/chrome/browser/ui/commands/browsing_data_commands.h"
 
 @class OpenNewTabCommand;
-@class OpenUrlCommand;
 @class ShowSigninCommand;
 @class StartVoiceSearchCommand;
 @class UIViewController;
@@ -58,11 +57,6 @@
 // Shows the Settings UI, presenting from |baseViewController|.
 - (void)showSettingsFromViewController:(UIViewController*)baseViewController;
 
-// Switches to show either regular or incognito tabs, and then opens
-// a new oen of those tabs. |newTabCommand|'s |incognito| property inidcates
-// the type of tab to open.
-- (void)switchModesAndOpenNewTab:(OpenNewTabCommand*)newTabCommand;
-
 // Starts a voice search on the current BVC.
 - (void)startVoiceSearch;
 
@@ -70,7 +64,7 @@
 - (void)showHistory;
 
 // Closes the History UI and opens a URL.
-- (void)closeSettingsUIAndOpenURL:(OpenUrlCommand*)command;
+- (void)closeSettingsUIAndOpenURL:(OpenNewTabCommand*)command;
 
 // Closes the History UI.
 - (void)closeSettingsUI;
@@ -91,8 +85,9 @@
 - (void)showReportAnIssueFromViewController:
     (UIViewController*)baseViewController;
 
-// Opens the |command| URL.
-- (void)openURL:(OpenUrlCommand*)command;
+// TODO(crbug.com/861729): Rename this to openURLInNewTab.
+// Opens the |command| URL in a new tab.
+- (void)openURL:(OpenNewTabCommand*)command;
 
 // TODO(crbug.com/779791) : Do not pass baseViewController through dispatcher.
 // Shows the signin UI, presenting from |baseViewController|.
diff --git a/ios/chrome/browser/ui/commands/browser_commands.h b/ios/chrome/browser/ui/commands/browser_commands.h
index 5f47d93..944ec99 100644
--- a/ios/chrome/browser/ui/commands/browser_commands.h
+++ b/ios/chrome/browser/ui/commands/browser_commands.h
@@ -49,7 +49,10 @@
 // Bookmarks the current page.
 - (void)bookmarkPage;
 
+// TODO(crbug.com/800266): Remove this command when the StackView and
+// TabSwitcher are removed.
 // Opens a new tab as specified by |newTabCommand|.
+// DEPRECATED: Don't add uses for this command.
 - (void)openNewTab:(OpenNewTabCommand*)newTabCommand;
 
 // Prints the currently active tab.
diff --git a/ios/chrome/browser/ui/commands/open_new_tab_command.h b/ios/chrome/browser/ui/commands/open_new_tab_command.h
index b56bd61..5ccfc55 100644
--- a/ios/chrome/browser/ui/commands/open_new_tab_command.h
+++ b/ios/chrome/browser/ui/commands/open_new_tab_command.h
@@ -7,19 +7,35 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/url_loader.h"
+
 // Command sent to open a new tab, optionally including a point (in UIWindow
 // coordinates).
 @interface OpenNewTabCommand : NSObject
 
-- (instancetype)initWithIncognito:(BOOL)incognito
-                      originPoint:(CGPoint)originPoint
-    NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithURL:(const GURL&)URL
+                   referrer:(const web::Referrer&)referrer
+                inIncognito:(BOOL)inIncognito
+               inBackground:(BOOL)inBackground
+                   appendTo:(OpenPosition)append;
+
+// Initializes a command intended to open a new page.
+- (instancetype)initInIncognito:(BOOL)inIncognito
+                   inBackground:(BOOL)inBackground NS_DESIGNATED_INITIALIZER;
 
 // Mark inherited initializer as unavailable to prevent calling it by mistake.
 - (instancetype)init NS_UNAVAILABLE;
 
 // Convenience initializers
 
+// Initializes a command intended to open a URL from browser chrome (e.g.,
+// settings). This will always open in a new foreground tab in non-incognito
+// mode.
++ (instancetype)commandWithURLFromChrome:(const GURL&)URL;
+
++ (instancetype)commandWithIncognito:(BOOL)incognito
+                         originPoint:(CGPoint)origin;
+
 // Creates an OpenTabCommand with |incognito| and an |originPoint| of
 // CGPointZero.
 + (instancetype)commandWithIncognito:(BOOL)incognito;
@@ -32,18 +48,43 @@
 // CGPointZero.
 + (instancetype)incognitoTabCommand;
 
-@property(nonatomic, readonly) BOOL incognito;
-
-@property(nonatomic, readonly) CGPoint originPoint;
+#pragma mark - ReadWrite properties
 
 // Whether the new tab command was initiated by the user (e.g. by tapping the
 // new tab button in the tools menu) or not (e.g. opening a new tab via a
-// Javascript action). Defaults to |YES|.
+// Javascript action). Defaults to |YES|. Only used when the |URL| isn't valid.
 @property(nonatomic, assign, getter=isUserInitiated) BOOL userInitiated;
 
 // Whether the new tab command should also trigger the omnibox to be focused.
+// Only used when the |URL| isn't valid.
 @property(nonatomic, assign) BOOL shouldFocusOmnibox;
 
+// Origin point of the action triggering this command.
+@property(nonatomic, assign) CGPoint originPoint;
+
+#pragma mark - ReadOnly properties
+
+// Whether this URL command requests opening in incognito or not.
+@property(nonatomic, readonly, assign) BOOL inIncognito;
+
+// Whether this URL command requests opening in background or not.
+@property(nonatomic, readonly, assign) BOOL inBackground;
+
+// ---- Properties only used when |URL| is valid.
+
+// URL to open.
+@property(nonatomic, readonly, assign) const GURL& URL;
+
+// Referrer for the URL.
+@property(nonatomic, readonly, assign) const web::Referrer& referrer;
+
+// Whether or not this URL command comes from a chrome context (e.g., settings),
+// as opposed to a web page context.
+@property(nonatomic, readonly, assign) BOOL fromChrome;
+
+// Location where the new tab should be opened.
+@property(nonatomic, readonly, assign) OpenPosition appendTo;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_COMMANDS_OPEN_NEW_TAB_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/open_new_tab_command.mm b/ios/chrome/browser/ui/commands/open_new_tab_command.mm
index a70f748..e6611c5 100644
--- a/ios/chrome/browser/ui/commands/open_new_tab_command.mm
+++ b/ios/chrome/browser/ui/commands/open_new_tab_command.mm
@@ -4,29 +4,72 @@
 
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 
+#include "base/logging.h"
+#include "ios/web/public/referrer.h"
+#include "url/gurl.h"
+
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-@implementation OpenNewTabCommand
+@implementation OpenNewTabCommand {
+  GURL _URL;
+  web::Referrer _referrer;
+}
 
-@synthesize incognito = _incognito;
+@synthesize inIncognito = _inIncognito;
+@synthesize inBackground = _inBackground;
 @synthesize originPoint = _originPoint;
+@synthesize fromChrome = _fromChrome;
+@synthesize appendTo = _appendTo;
 @synthesize userInitiated = _userInitiated;
 @synthesize shouldFocusOmnibox = _shouldFocusOmnibox;
 
-- (instancetype)initWithIncognito:(BOOL)incognito
-                      originPoint:(CGPoint)originPoint {
+- (instancetype)initInIncognito:(BOOL)inIncognito
+                   inBackground:(BOOL)inBackground {
   if ((self = [super init])) {
-    _incognito = incognito;
-    _originPoint = originPoint;
+    _inIncognito = inIncognito;
+    _inBackground = inBackground;
     _userInitiated = YES;
   }
   return self;
 }
 
+- (instancetype)initWithURL:(const GURL&)URL
+                   referrer:(const web::Referrer&)referrer
+                inIncognito:(BOOL)inIncognito
+               inBackground:(BOOL)inBackground
+                   appendTo:(OpenPosition)append {
+  if ((self = [self initInIncognito:inIncognito inBackground:inBackground])) {
+    _URL = URL;
+    _referrer = referrer;
+    _appendTo = append;
+  }
+  return self;
+}
+
+- (instancetype)initFromChrome:(const GURL&)URL {
+  self = [self initWithURL:URL
+                  referrer:web::Referrer()
+               inIncognito:NO
+              inBackground:NO
+                  appendTo:kLastTab];
+  if (self) {
+    _fromChrome = YES;
+  }
+  return self;
+}
+
++ (instancetype)commandWithIncognito:(BOOL)incognito
+                         originPoint:(CGPoint)origin {
+  OpenNewTabCommand* command =
+      [[self alloc] initInIncognito:incognito inBackground:NO];
+  command.originPoint = origin;
+  return command;
+}
+
 + (instancetype)commandWithIncognito:(BOOL)incognito {
-  return [[self alloc] initWithIncognito:incognito originPoint:CGPointZero];
+  return [[self alloc] initInIncognito:incognito inBackground:NO];
 }
 
 + (instancetype)command {
@@ -37,4 +80,16 @@
   return [self commandWithIncognito:YES];
 }
 
++ (instancetype)commandWithURLFromChrome:(const GURL&)URL {
+  return [[self alloc] initFromChrome:URL];
+}
+
+- (const GURL&)URL {
+  return _URL;
+}
+
+- (const web::Referrer&)referrer {
+  return _referrer;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/commands/open_url_command.h b/ios/chrome/browser/ui/commands/open_url_command.h
deleted file mode 100644
index 74b149d..0000000
--- a/ios/chrome/browser/ui/commands/open_url_command.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_OPEN_URL_COMMAND_H_
-#define IOS_CHROME_BROWSER_UI_COMMANDS_OPEN_URL_COMMAND_H_
-
-#import <UIKit/UIKit.h>
-
-#import "ios/chrome/browser/ui/url_loader.h"
-
-namespace web {
-struct Referrer;
-}
-
-class GURL;
-
-// A command to open a new tab.
-@interface OpenUrlCommand : NSObject
-
-// Mark inherited initializer as unavailable to prevent calling it by mistake.
-- (instancetype)init NS_UNAVAILABLE;
-
-// Initializes a command intended to open a URL as a link from a page.
-- (instancetype)initWithURL:(const GURL&)url
-                   referrer:(const web::Referrer&)referrer
-                inIncognito:(BOOL)inIncognito
-               inBackground:(BOOL)inBackground
-                   appendTo:(OpenPosition)append NS_DESIGNATED_INITIALIZER;
-
-// Initializes a command intended to open a URL from browser chrome (e.g.,
-// settings). This will always open in a new foreground tab in non-incognito
-// mode.
-- (instancetype)initWithURLFromChrome:(const GURL&)url;
-
-// URL to open.
-@property(nonatomic, readonly) const GURL& url;
-
-// Referrer for the URL.
-@property(nonatomic, readonly) const web::Referrer& referrer;
-
-// Whether this URL command requests opening in incognito or not.
-@property(nonatomic, readonly) BOOL inIncognito;
-
-// Whether this URL command requests opening in background or not.
-@property(nonatomic, readonly) BOOL inBackground;
-
-// Whether or not this URL command comes from a chrome context (e.g., settings),
-// as opposed to a web page context.
-@property(nonatomic, readonly) BOOL fromChrome;
-
-// Location where the new tab should be opened.
-@property(nonatomic, readonly) OpenPosition appendTo;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_COMMANDS_OPEN_URL_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/open_url_command.mm b/ios/chrome/browser/ui/commands/open_url_command.mm
deleted file mode 100644
index aff4db64..0000000
--- a/ios/chrome/browser/ui/commands/open_url_command.mm
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
-
-#include "base/logging.h"
-#include "ios/web/public/referrer.h"
-#include "url/gurl.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-@implementation OpenUrlCommand {
-  GURL _url;
-  web::Referrer _referrer;
-}
-
-@synthesize inIncognito = _inIncognito;
-@synthesize inBackground = _inBackground;
-@synthesize fromChrome = _fromChrome;
-@synthesize appendTo = _appendTo;
-
-- (instancetype)initWithURL:(const GURL&)url
-                   referrer:(const web::Referrer&)referrer
-                inIncognito:(BOOL)inIncognito
-               inBackground:(BOOL)inBackground
-                   appendTo:(OpenPosition)appendTo {
-  if ((self = [super init])) {
-    _url = url;
-    _referrer = referrer;
-    _inIncognito = inIncognito;
-    _inBackground = inBackground;
-    _appendTo = appendTo;
-  }
-  return self;
-}
-
-- (instancetype)initWithURLFromChrome:(const GURL&)url {
-  if ((self = [self initWithURL:url
-                       referrer:web::Referrer()
-                    inIncognito:NO
-                   inBackground:NO
-                       appendTo:kLastTab])) {
-    _fromChrome = YES;
-  }
-  return self;
-}
-
-- (const GURL&)url {
-  return _url;
-}
-
-- (const web::Referrer&)referrer {
-  return _referrer;
-}
-
-@end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
index 91f4de5..42d6dee 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -18,6 +18,7 @@
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h"
@@ -230,7 +231,7 @@
                    didTriggerAction:(OverscrollAction)action {
   switch (action) {
     case OverscrollAction::NEW_TAB: {
-      [_dispatcher openNewTab:[OpenNewTabCommand command]];
+      [_dispatcher openURL:[OpenNewTabCommand command]];
     } break;
     case OverscrollAction::CLOSE_TAB: {
       [_dispatcher closeCurrentTab];
diff --git a/ios/chrome/browser/ui/key_commands_provider.mm b/ios/chrome/browser/ui/key_commands_provider.mm
index 44170e6..743321b2 100644
--- a/ios/chrome/browser/ui/key_commands_provider.mm
+++ b/ios/chrome/browser/ui/key_commands_provider.mm
@@ -67,14 +67,14 @@
   void (^newTab)() = ^{
     OpenNewTabCommand* newTabCommand = [OpenNewTabCommand command];
     newTabCommand.shouldFocusOmnibox = YES;
-    [weakDispatcher openNewTab:newTabCommand];
+    [weakDispatcher openURL:newTabCommand];
   };
 
   void (^newIncognitoTab)() = ^{
     OpenNewTabCommand* newIncognitoTabCommand =
         [OpenNewTabCommand incognitoTabCommand];
     newIncognitoTabCommand.shouldFocusOmnibox = YES;
-    [weakDispatcher openNewTab:newIncognitoTabCommand];
+    [weakDispatcher openURL:newIncognitoTabCommand];
   };
 
   const int browseLeftDescriptionID = useRTLLayout
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_perftest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_perftest.mm
index ffd3429..ffd6ca1 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_perftest.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_perftest.mm
@@ -8,6 +8,7 @@
 #include "ios/chrome/browser/test/perf_test_with_bvc_ios.h"
 #import "ios/chrome/browser/ui/browser_view_controller.h"
 #import "ios/chrome/browser/ui/browser_view_controller_dependency_factory.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 
@@ -39,7 +40,7 @@
   }
   base::TimeDelta TimedNewTab() {
     base::Time startTime = base::Time::NowFromSystemTime();
-    [[bvc_ dispatcher] openNewTab:[OpenNewTabCommand command]];
+    [[bvc_ dispatcher] openURL:[OpenNewTabCommand command]];
     return base::Time::NowFromSystemTime() - startTime;
   }
   void SettleUI() {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_table_view_controller.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_table_view_controller.mm
index 2a2edff..8055193 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_table_view_controller.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_table_view_controller.mm
@@ -202,15 +202,13 @@
       break;
     case PopupMenuActionOpenNewTab:
       base::RecordAction(UserMetricsAction("MobileMenuNewTab"));
-      [self.dispatcher
-          openNewTab:[[OpenNewTabCommand alloc] initWithIncognito:NO
-                                                      originPoint:origin]];
+      [self.dispatcher openURL:[OpenNewTabCommand commandWithIncognito:NO
+                                                           originPoint:origin]];
       break;
     case PopupMenuActionOpenNewIncognitoTab:
       base::RecordAction(UserMetricsAction("MobileMenuNewIncognitoTab"));
-      [self.dispatcher
-          openNewTab:[[OpenNewTabCommand alloc] initWithIncognito:YES
-                                                      originPoint:origin]];
+      [self.dispatcher openURL:[OpenNewTabCommand commandWithIncognito:YES
+                                                           originPoint:origin]];
       break;
     case PopupMenuActionReadLater:
       base::RecordAction(UserMetricsAction("MobileMenuReadLater"));
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
index 58ff8dd..2f9444f 100644
--- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
+++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -12,7 +12,7 @@
 #include "ios/chrome/browser/chrome_url_constants.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/url_loader.h"
@@ -308,8 +308,8 @@
   _footerLabelLinkController = [[LabelLinkController alloc]
       initWithLabel:label
              action:^(const GURL& URL) {
-               OpenUrlCommand* command =
-                   [[OpenUrlCommand alloc] initWithURLFromChrome:URL];
+               OpenNewTabCommand* command =
+                   [OpenNewTabCommand commandWithURLFromChrome:URL];
                [weakSelf.dispatcher openURL:command];
              }];
 
diff --git a/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm b/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
index 7ee6888..069fc8f 100644
--- a/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/accounts_collection_view_controller.mm
@@ -33,7 +33,7 @@
 #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/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
@@ -652,8 +652,8 @@
 - (void)openURL:(NSURL*)url
               view:(UIView*)view
     viewController:(UIViewController*)viewController {
-  OpenUrlCommand* command =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:net::GURLWithNSURL(url)];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:net::GURLWithNSURL(url)];
   [self.dispatcher closeSettingsUIAndOpenURL:command];
 }
 
diff --git a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
index 3124d698..ba6fe4b 100644
--- a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
@@ -22,7 +22,7 @@
 #import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -93,8 +93,8 @@
   if (_creditCard.record_type() == autofill::CreditCard::FULL_SERVER_CARD ||
       _creditCard.record_type() == autofill::CreditCard::MASKED_SERVER_CARD) {
     GURL paymentsURL = autofill::payments::GetManageInstrumentsUrl(0);
-    OpenUrlCommand* command =
-        [[OpenUrlCommand alloc] initWithURLFromChrome:paymentsURL];
+    OpenNewTabCommand* command =
+        [OpenNewTabCommand commandWithURLFromChrome:paymentsURL];
     [self.dispatcher closeSettingsUIAndOpenURL:command];
 
     // Don't call [super editButtonPressed] because edit mode is not actually
diff --git a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm
index 70185a5..6d0ce88 100644
--- a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm
@@ -16,7 +16,7 @@
 #import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #include "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
@@ -124,8 +124,8 @@
   if (_autofillProfile.record_type() ==
       autofill::AutofillProfile::SERVER_PROFILE) {
     GURL paymentsURL = autofill::payments::GetManageAddressesUrl(0);
-    OpenUrlCommand* command =
-        [[OpenUrlCommand alloc] initWithURLFromChrome:paymentsURL];
+    OpenNewTabCommand* command =
+        [OpenNewTabCommand commandWithURLFromChrome:paymentsURL];
     [self.dispatcher closeSettingsUIAndOpenURL:command];
 
     // Don't call [super editButtonPressed] because edit mode is not actually
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn
index bffb5da4..addfb48 100644
--- a/ios/chrome/browser/ui/settings/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -20,8 +20,8 @@
     "copied_to_chrome_item.mm",
     "encryption_item.h",
     "encryption_item.mm",
-    "import_data_multiline_detail_cell.h",
-    "import_data_multiline_detail_cell.mm",
+    "import_data_multiline_detail_item.h",
+    "import_data_multiline_detail_item.mm",
     "passphrase_error_item.h",
     "passphrase_error_item.mm",
     "password_details_item.h",
@@ -69,7 +69,7 @@
     "clear_browsing_data_item_unittest.mm",
     "copied_to_chrome_item_unittest.mm",
     "encryption_item_unittest.mm",
-    "import_data_multiline_detail_cell_unittest.mm",
+    "import_data_multiline_detail_item_unittest.mm",
     "passphrase_error_item_unittest.mm",
     "password_details_item_unittest.mm",
     "sync_switch_item_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.h b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
similarity index 64%
rename from ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.h
rename to ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
index 1616691..7548b152 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.h
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h
@@ -2,13 +2,29 @@
 // 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_CELLS_IMPORT_DATA_MULTILINE_DETAIL_CELL_H_
-#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_IMPORT_DATA_MULTILINE_DETAIL_CELL_H_
+#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_IMPORT_DATA_MULTILINE_DETAIL_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_IMPORT_DATA_MULTILINE_DETAIL_ITEM_H_
 
 #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"
 
+// ImportDataMultilineDetailItem is a model class that uses
+// ImportDataMultilineDetailCell.
+@interface ImportDataMultilineDetailItem : CollectionViewItem
+
+// The accessory type to display on the trailing edge of the cell.
+@property(nonatomic) MDCCollectionViewCellAccessoryType accessoryType;
+
+// The main text string.
+@property(nonatomic, copy) NSString* text;
+
+// The detail text string.
+@property(nonatomic, copy) NSString* detailText;
+
+@end
+
 // ImportDataMultilineDetailCell implements an MDCCollectionViewCell
 // 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
@@ -22,4 +38,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_IMPORT_DATA_MULTILINE_DETAIL_CELL_H_
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_IMPORT_DATA_MULTILINE_DETAIL_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.mm b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
similarity index 85%
rename from ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.mm
rename to ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
index 5c97d5e..30823e2 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell.mm
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.mm
@@ -2,8 +2,9 @@
 // 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/cells/import_data_multiline_detail_cell.h"
+#import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 
+#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.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"
 
@@ -19,6 +20,31 @@
 const CGFloat kVerticalPadding = 16;
 }  // namespace
 
+@implementation ImportDataMultilineDetailItem
+
+@synthesize accessoryType = _accessoryType;
+@synthesize text = _text;
+@synthesize detailText = _detailText;
+
+- (instancetype)initWithType:(NSInteger)type {
+  self = [super initWithType:type];
+  if (self) {
+    self.cellClass = [ImportDataMultilineDetailCell class];
+  }
+  return self;
+}
+
+#pragma mark CollectionViewItem
+
+- (void)configureCell:(ImportDataMultilineDetailCell*)cell {
+  [super configureCell:cell];
+  [cell cr_setAccessoryType:self.accessoryType];
+  cell.textLabel.text = self.text;
+  cell.detailTextLabel.text = self.detailText;
+}
+
+@end
+
 @implementation ImportDataMultilineDetailCell
 
 @synthesize textLabel = _textLabel;
diff --git a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell_unittest.mm b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
similarity index 79%
rename from ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell_unittest.mm
rename to ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
index b2945a9..68aab66 100644
--- a/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_cell_unittest.mm
+++ b/ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item_unittest.mm
@@ -2,9 +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/settings/cells/import_data_multiline_detail_cell.h"
+#import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 
-#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -20,12 +19,13 @@
 // Tests that the text and detail text are honoured after a call to
 // |configureCell:|.
 TEST_F(ImportDataMultilineDetailItemTest, ConfigureCell) {
-  SettingsDetailItem* item = [[SettingsDetailItem alloc] initWithType:0];
-  item.cellClass = [ImportDataMultilineDetailCell class];
+  ImportDataMultilineDetailItem* item =
+      [[ImportDataMultilineDetailItem alloc] initWithType:0];
   NSString* text = @"Test Text";
-  NSString* detailText = @"Test Detail Text that can span multiple lines. For "
-                         @"example, this line probably fits on three or four "
-                         @"lines.";
+  NSString* detailText =
+      @"Test Detail Text that can span multiple lines. For "
+      @"example, this line probably fits on three or four "
+      @"lines.";
 
   item.text = text;
   item.detailText = detailText;
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm
index e490f8d..de45249 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm
@@ -25,7 +25,7 @@
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browsing_data_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h"
 #import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_item.h"
@@ -308,8 +308,8 @@
 }
 
 - (void)openMyActivityLink {
-  OpenUrlCommand* openMyActivityCommand =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:GURL(kGoogleMyAccountURL)];
+  OpenNewTabCommand* openMyActivityCommand =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL(kGoogleMyAccountURL)];
   [self.dispatcher closeSettingsUIAndOpenURL:openMyActivityCommand];
 }
 
diff --git a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm b/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm
index e112233..1c3c311 100644
--- a/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/import_data_collection_view_controller.mm
@@ -11,8 +11,7 @@
 #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_cell.h"
-#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h"
+#import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.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"
@@ -50,8 +49,8 @@
   NSString* _toEmail;
   BOOL _isSignedIn;
   ShouldClearData _shouldClearData;
-  SettingsDetailItem* _importDataItem;
-  SettingsDetailItem* _keepDataSeparateItem;
+  ImportDataMultilineDetailItem* _importDataItem;
+  ImportDataMultilineDetailItem* _keepDataSeparateItem;
 }
 
 #pragma mark Initialization
@@ -126,10 +125,9 @@
   return item;
 }
 
-- (SettingsDetailItem*)importDataItem {
-  SettingsDetailItem* item =
-      [[SettingsDetailItem alloc] initWithType:ItemTypeOptionImportData];
-  item.cellClass = [ImportDataMultilineDetailCell class];
+- (ImportDataMultilineDetailItem*)importDataItem {
+  ImportDataMultilineDetailItem* item = [[ImportDataMultilineDetailItem alloc]
+      initWithType:ItemTypeOptionImportData];
   item.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_TITLE);
   item.detailText =
       l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_IMPORT_SUBTITLE,
@@ -140,10 +138,9 @@
   return item;
 }
 
-- (SettingsDetailItem*)keepDataSeparateItem {
-  SettingsDetailItem* item =
-      [[SettingsDetailItem alloc] initWithType:ItemTypeOptionKeepDataSeparate];
-  item.cellClass = [ImportDataMultilineDetailCell class];
+- (ImportDataMultilineDetailItem*)keepDataSeparateItem {
+  ImportDataMultilineDetailItem* item = [[ImportDataMultilineDetailItem alloc]
+      initWithType:ItemTypeOptionKeepDataSeparate];
   item.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_IMPORT_DATA_KEEP_TITLE);
   if (_isSignedIn) {
     item.detailText = l10n_util::GetNSStringF(
diff --git a/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm
index 89b5902..4583446 100644
--- a/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/import_data_collection_view_controller_unittest.mm
@@ -9,7 +9,7 @@
 #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/settings_detail_item.h"
+#import "ios/chrome/browser/ui/settings/cells/import_data_multiline_detail_item.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
@@ -127,12 +127,12 @@
   NSIndexPath* importIndexPath = [NSIndexPath indexPathForItem:0 inSection:1];
   NSIndexPath* keepSeparateIndexPath =
       [NSIndexPath indexPathForItem:1 inSection:1];
-  SettingsDetailItem* importItem =
-      base::mac::ObjCCastStrict<SettingsDetailItem>(
+  ImportDataMultilineDetailItem* importItem =
+      base::mac::ObjCCastStrict<ImportDataMultilineDetailItem>(
           [import_data_controller.collectionViewModel
               itemAtIndexPath:importIndexPath]);
-  SettingsDetailItem* keepSeparateItem =
-      base::mac::ObjCCastStrict<SettingsDetailItem>(
+  ImportDataMultilineDetailItem* keepSeparateItem =
+      base::mac::ObjCCastStrict<ImportDataMultilineDetailItem>(
           [import_data_controller.collectionViewModel
               itemAtIndexPath:keepSeparateIndexPath]);
 
diff --git a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm b/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm
index 26414b8..c8f7535 100644
--- a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm
@@ -15,7 +15,6 @@
 #import "components/prefs/ios/pref_observer_bridge.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/application_context.h"
 #import "ios/chrome/browser/autofill/autofill_controller.h"
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.h b/ios/chrome/browser/ui/settings/settings_navigation_controller.h
index 8bbd7c7..d153a84 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.h
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.h
@@ -11,7 +11,6 @@
 
 @protocol BrowserCommands;
 @protocol ImportDataControllerDelegate;
-@class OpenUrlCommand;
 @protocol UserFeedbackDataSource;
 
 namespace ios {
diff --git a/ios/chrome/browser/ui/settings/settings_root_collection_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_collection_view_controller.mm
index 4e767a8..d2a5427 100644
--- a/ios/chrome/browser/ui/settings/settings_root_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_root_collection_view_controller.mm
@@ -10,7 +10,7 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/settings/bar_button_activity_indicator.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
 #import "ios/chrome/browser/ui/settings/settings_utils.h"
@@ -130,7 +130,7 @@
 - (void)cell:(CollectionViewFooterCell*)cell didTapLinkURL:(GURL)URL {
   // Subclass must have a valid dispatcher assigned.
   DCHECK(self.dispatcher);
-  OpenUrlCommand* command = [[OpenUrlCommand alloc] initWithURLFromChrome:URL];
+  OpenNewTabCommand* command = [OpenNewTabCommand commandWithURLFromChrome:URL];
   [self.dispatcher closeSettingsUIAndOpenURL:command];
 }
 
diff --git a/ios/chrome/browser/ui/settings/settings_utils.mm b/ios/chrome/browser/ui/settings/settings_utils.mm
index d0a8184..ddbc84e1 100644
--- a/ios/chrome/browser/ui/settings/settings_utils.mm
+++ b/ios/chrome/browser/ui/settings/settings_utils.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/ui/settings/settings_utils.h"
 
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -19,8 +19,8 @@
     UIResponder* strongResponder = weakResponder;
     if (!strongResponder)
       return;
-    OpenUrlCommand* command =
-        [[OpenUrlCommand alloc] initWithURLFromChrome:url];
+    OpenNewTabCommand* command =
+        [OpenNewTabCommand commandWithURLFromChrome:url];
     [weakDispatcher closeSettingsUIAndOpenURL:command];
   };
   return [blockToOpenURL copy];
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 e57fa85..01aa8ad 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
@@ -33,7 +33,7 @@
 #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/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h"
@@ -499,8 +499,8 @@
       GURL learnMoreUrl = google_util::AppendGoogleLocaleParam(
           GURL(kSyncGoogleDashboardURL),
           GetApplicationContext()->GetApplicationLocale());
-      OpenUrlCommand* command =
-          [[OpenUrlCommand alloc] initWithURLFromChrome:learnMoreUrl];
+      OpenNewTabCommand* command =
+          [OpenNewTabCommand commandWithURLFromChrome:learnMoreUrl];
       [self.dispatcher closeSettingsUIAndOpenURL:command];
       break;
     }
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
index b2967cb..76f0485 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -14,7 +14,7 @@
 #import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -337,8 +337,8 @@
   [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()];
 
   // Open new tab to cancel sign-in.
-  OpenUrlCommand* command =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:GURL("about:blank")];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL("about:blank")];
   [chrome_test_util::DispatcherForActiveViewController() openURL:command];
 
   // Re-open the sign-in screen. If it wasn't correctly dismissed previously,
@@ -378,8 +378,8 @@
   [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
 
   // Open new tab to cancel sign-in.
-  OpenUrlCommand* command =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:GURL("about:blank")];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL("about:blank")];
   [chrome_test_util::DispatcherForActiveViewController() openURL:command];
 
   // Re-open the sign-in screen. If it wasn't correctly dismissed previously,
@@ -440,8 +440,8 @@
   [ChromeEarlGreyUI signInToIdentityByEmail:identity1.userEmail];
 
   // Open new tab to cancel sign-in.
-  OpenUrlCommand* command =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:GURL("about:blank")];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL("about:blank")];
   [chrome_test_util::DispatcherForActiveViewController() openURL:command];
 
   // Re-open the sign-in screen. If it wasn't correctly dismissed previously,
@@ -482,8 +482,8 @@
       assertWithMatcher:grey_sufficientlyVisible()];
 
   // Open new tab to cancel sign-in.
-  OpenUrlCommand* command =
-      [[OpenUrlCommand alloc] initWithURLFromChrome:GURL("about:blank")];
+  OpenNewTabCommand* command =
+      [OpenNewTabCommand commandWithURLFromChrome:GURL("about:blank")];
   [chrome_test_util::DispatcherForActiveViewController() openURL:command];
 
   // Re-open the sign-in screen. If it wasn't correctly dismissed previously,
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
index 2431916..4367135a 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
@@ -2864,7 +2864,7 @@
 
 - (void)openNewTab:(OpenNewTabCommand*)command {
   // Ensure that the right mode is showing.
-  if ([self isCurrentSetIncognito] != command.incognito)
+  if ([self isCurrentSetIncognito] != command.inIncognito)
     [self setActiveCardSet:[self inactiveCardSet]];
 
   // Either send or don't send the "New Tab Opened" or "Incognito Tab Opened" to
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_toolbar_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_toolbar_controller.mm
index 1301a30..342ba0e 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_toolbar_controller.mm
@@ -98,8 +98,8 @@
       [_openNewTabButton.superview convertPoint:_openNewTabButton.center
                                          toView:_openNewTabButton.window];
   OpenNewTabCommand* command =
-      [[OpenNewTabCommand alloc] initWithIncognito:_openNewTabButton.isIncognito
-                                       originPoint:center];
+      [OpenNewTabCommand commandWithIncognito:_openNewTabButton.isIncognito
+                                  originPoint:center];
   [_dispatcher openNewTab:command];
 }
 
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
index d6e025b..b988445b 100644
--- a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -340,7 +340,7 @@
 - (void)openNewTab:(OpenNewTabCommand*)command {
   DCHECK(self.regularTabModel && self.incognitoTabModel);
   TabModel* activeTabModel =
-      command.incognito ? self.incognitoTabModel : self.regularTabModel;
+      command.inIncognito ? self.incognitoTabModel : self.regularTabModel;
   // TODO(crbug.com/804587) : It is better to use the mediator to insert a
   // webState and show the active tab.
   DCHECK(self.tabSwitcher);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
index 7e307fc..2764388 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
@@ -444,13 +444,13 @@
 
 - (void)openNewTab:(OpenNewTabCommand*)command {
   // Ensure that the right mode is showing.
-  NSInteger panelIndex = command.incognito ? kLocalTabsOffTheRecordPanelIndex
-                                           : kLocalTabsOnTheRecordPanelIndex;
+  NSInteger panelIndex = command.inIncognito ? kLocalTabsOffTheRecordPanelIndex
+                                             : kLocalTabsOnTheRecordPanelIndex;
   [_tabSwitcherView selectPanelAtIndex:panelIndex];
 
   const TabSwitcherSessionType panelSessionType =
-      (command.incognito) ? TabSwitcherSessionType::OFF_THE_RECORD_SESSION
-                          : TabSwitcherSessionType::REGULAR_SESSION;
+      (command.inIncognito) ? TabSwitcherSessionType::OFF_THE_RECORD_SESSION
+                            : TabSwitcherSessionType::REGULAR_SESSION;
 
   TabModel* model = [self tabModelForSessionType:panelSessionType];
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
index da505f9..7be45cb 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
@@ -458,7 +458,7 @@
   UIView* view = base::mac::ObjCCast<UIView>(sender);
   CGPoint center = [view.superview convertPoint:view.center toView:view.window];
   OpenNewTabCommand* command =
-      [[OpenNewTabCommand alloc] initWithIncognito:NO originPoint:center];
+      [OpenNewTabCommand commandWithIncognito:NO originPoint:center];
   [self.dispatcher openNewTab:command];
 }
 
@@ -466,7 +466,7 @@
   UIView* view = base::mac::ObjCCast<UIView>(sender);
   CGPoint center = [view.superview convertPoint:view.center toView:view.window];
   OpenNewTabCommand* command =
-      [[OpenNewTabCommand alloc] initWithIncognito:YES originPoint:center];
+      [OpenNewTabCommand commandWithIncognito:YES originPoint:center];
   [self.dispatcher openNewTab:command];
 }
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index 7a0ed249..d024f7e5 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -30,7 +30,6 @@
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
 #include "ios/chrome/browser/ui/fullscreen/fullscreen_controller_factory.h"
 #include "ios/chrome/browser/ui/fullscreen/scoped_fullscreen_disabler.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
@@ -674,8 +673,7 @@
   CGPoint center = [_buttonNewTab.superview convertPoint:_buttonNewTab.center
                                                   toView:_buttonNewTab.window];
   OpenNewTabCommand* command =
-      [[OpenNewTabCommand alloc] initWithIncognito:_isIncognito
-                                       originPoint:center];
+      [OpenNewTabCommand commandWithIncognito:_isIncognito originPoint:center];
   [self.dispatcher openNewTab:command];
 }
 
@@ -1675,11 +1673,12 @@
 
 - (void)URLWasDropped:(GURL const&)url {
   // Called when a URL is dropped on the new tab button.
-  OpenUrlCommand* command = [[OpenUrlCommand alloc] initWithURL:url
-                                                       referrer:web::Referrer()
-                                                    inIncognito:_isIncognito
-                                                   inBackground:NO
-                                                       appendTo:kLastTab];
+  OpenNewTabCommand* command =
+      [[OpenNewTabCommand alloc] initWithURL:url
+                                    referrer:web::Referrer()
+                                 inIncognito:_isIncognito
+                                inBackground:NO
+                                    appendTo:kLastTab];
   [self.dispatcher openURL:command];
 }
 
diff --git a/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm
index 810dfd3..2ad64de6 100644
--- a/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm
+++ b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm
@@ -30,8 +30,8 @@
   UIView* view = self.tableViewCell;
   CGPoint center = [view.superview convertPoint:view.center toView:view.window];
   OpenNewTabCommand* command =
-      [[OpenNewTabCommand alloc] initWithIncognito:self.isIncognito
-                                       originPoint:center];
+      [OpenNewTabCommand commandWithIncognito:self.isIncognito
+                                  originPoint:center];
   [dispatcher openNewTab:command];
 }
 
diff --git a/ios/chrome/browser/upgrade/upgrade_center.mm b/ios/chrome/browser/upgrade/upgrade_center.mm
index 31f5c856..04ca9795 100644
--- a/ios/chrome/browser/upgrade/upgrade_center.mm
+++ b/ios/chrome/browser/upgrade/upgrade_center.mm
@@ -17,7 +17,7 @@
 #include "components/infobars/core/infobar_manager.h"
 #include "components/version_info/version_info.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
-#import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/url_scheme_util.h"
@@ -356,8 +356,8 @@
 
     if (web::UrlHasWebScheme(URL)) {
       // This URL can be opened in the application, just open in a new tab.
-      OpenUrlCommand* command =
-          [[OpenUrlCommand alloc] initWithURLFromChrome:URL];
+      OpenNewTabCommand* command =
+          [OpenNewTabCommand commandWithURLFromChrome:URL];
       [self.dispatcher openURL:command];
     } else {
       // This URL scheme is not understood, ask the system to open it.
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 129df29..4cf1398 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -415,15 +415,6 @@
 }
 
 void WebMediaPlayerImpl::OnSurfaceIdUpdated(viz::SurfaceId surface_id) {
-  pip_surface_id_ = surface_id;
-
-  // If there was a request to enter Picture-in-Picture while the pipeline was
-  // suspended, this call should trigger Picture-in-Picture.
-  if (enter_pip_callback_) {
-    EnterPictureInPicture(std::move(*enter_pip_callback_));
-    enter_pip_callback_.reset();
-  }
-
   // TODO(726619): Handle the behavior when Picture-in-Picture mode is
   // disabled.
   // The viz::SurfaceId may be updated when the video begins playback or when
@@ -810,29 +801,20 @@
 
 void WebMediaPlayerImpl::EnterPictureInPicture(
     blink::WebMediaPlayer::PipWindowOpenedCallback callback) {
-  // When the pipeline is not stable, there will be no valid surface. In this
-  // case, resuming the pipeline will auto-trigger Picture-in-Picture.
-  if (!pip_surface_id_.is_valid()) {
-    DCHECK(!pipeline_controller_.IsStable());
-    enter_pip_callback_ = std::move(callback);
+  DCHECK(bridge_);
 
-    // This will trigger the pipeline to resume now that the player is pending
-    // to enter in Picture-in-Picture.
-    UpdatePlayState();
-    return;
-  }
+  const viz::SurfaceId& surface_id = bridge_->GetSurfaceId();
+  DCHECK(surface_id.is_valid());
 
   // Notifies the browser process that the player should now be in
   // Picture-in-Picture mode.
-  delegate_->DidPictureInPictureModeStart(delegate_id_, pip_surface_id_,
+  delegate_->DidPictureInPictureModeStart(delegate_id_, surface_id,
                                           pipeline_metadata_.natural_size,
                                           std::move(callback));
 }
 
 void WebMediaPlayerImpl::ExitPictureInPicture(
     blink::WebMediaPlayer::PipWindowClosedCallback callback) {
-  DCHECK(pip_surface_id_.is_valid());
-
   // Notifies the browser process that Picture-in-Picture has ended. It will
   // clear out the states and close the window.
   delegate_->DidPictureInPictureModeEnd(delegate_id_, std::move(callback));
@@ -843,7 +825,6 @@
 
 void WebMediaPlayerImpl::RegisterPictureInPictureWindowResizeCallback(
     blink::WebMediaPlayer::PipWindowResizedCallback callback) {
-  DCHECK(pip_surface_id_.is_valid());
   DCHECK(client_->DisplayType() ==
              WebMediaPlayer::DisplayType::kPictureInPicture &&
          !client_->IsInAutoPIP());
@@ -2122,18 +2103,14 @@
 }
 
 void WebMediaPlayerImpl::OnPictureInPictureModeEnded() {
-  // This should never be called if |pip_surface_id_| is invalid. This is either
-  // called from the Picture-in-Picture window side by a user gesture to end
-  // Picture-in-Picture mode, or in ExitPictureInPicture(), which already checks
-  // for validity.
-  DCHECK(pip_surface_id_.is_valid());
-
-  // It is possible for |pip_surface_id_| to be valid when |client_| is not in
-  // Picture-in-Picture mode. In this case, do nothing.
-  if (client_ && client_->DisplayType() ==
-                     WebMediaPlayer::DisplayType::kPictureInPicture) {
-    client_->PictureInPictureStopped();
+  // It is possible for this method to be called when the player is no longer in
+  // Picture-in-Picture mode.
+  if (!client_ || client_->DisplayType() !=
+                      WebMediaPlayer::DisplayType::kPictureInPicture) {
+    return;
   }
+
+  client_->PictureInPictureStopped();
 }
 
 void WebMediaPlayerImpl::OnPictureInPictureControlClicked() {
@@ -2723,11 +2700,6 @@
   result.is_suspended = is_remote || must_suspend || idle_suspended ||
                         background_suspended || can_stay_suspended;
 
-  // When Picture-in-Picture has been triggered, the pipeline needs to be
-  // resumed.
-  if (enter_pip_callback_ && !must_suspend && !is_remote)
-    result.is_suspended = false;
-
   DVLOG(3) << __func__ << ": is_remote=" << is_remote
            << ", must_suspend=" << must_suspend
            << ", idle_suspended=" << idle_suspended
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index 1174ed93..49931cb 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -925,17 +925,6 @@
   // True if a frame has ever been rendered.
   bool has_first_frame_ = false;
 
-  // Keeps track of the SurfaceId for Picture-in-Picture. This is used to
-  // route the video to be shown in the Picture-in-Picture window.
-  viz::SurfaceId pip_surface_id_;
-
-  // Sets when entering Picture-in-Picture was delayed because no
-  // |pip_surface_id_| was available. This happens when the
-  // PreloadMetadataSuspend optimization is enabled and the player wouldn't
-  // create the surface until playback.
-  base::Optional<blink::WebMediaPlayer::PipWindowOpenedCallback>
-      enter_pip_callback_;
-
   DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
 };
 
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
index 97cc6d07..a478cfa 100644
--- a/media/blink/webmediaplayer_impl_unittest.cc
+++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -297,6 +297,7 @@
   MOCK_METHOD0(ClearSurfaceId, void());
   MOCK_METHOD1(SetContentsOpaque, void(bool));
   MOCK_METHOD0(CreateSurfaceLayer, void());
+  MOCK_CONST_METHOD0(GetSurfaceId, const viz::SurfaceId&());
 };
 
 class MockVideoFrameCompositor : public VideoFrameCompositor {
@@ -1390,6 +1391,18 @@
 TEST_F(WebMediaPlayerImplTest, PictureInPictureTriggerCallback) {
   InitializeWebMediaPlayerImpl();
 
+  EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+  EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId())
+      .WillOnce(ReturnRef(frame_sink_id_));
+  EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId())
+      .WillOnce(ReturnRef(surface_id_));
+  EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
+  EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
+
+  PipelineMetadata metadata;
+  metadata.has_video = true;
+  OnMetadata(metadata);
+
   EXPECT_CALL(client_, DisplayType())
       .WillRepeatedly(
           Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture));
diff --git a/net/BUILD.gn b/net/BUILD.gn
index e322435..bf1b809 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -69,6 +69,7 @@
     "ENABLE_REPORTING=$enable_reporting",
     "ENABLE_WEBSOCKETS=$enable_websockets",
     "INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST=$include_transport_security_state_preload_list",
+    "USE_KERBEROS=$use_kerberos",
   ]
 }
 
@@ -78,11 +79,8 @@
     "NET_IMPLEMENTATION",
   ]
 
-  if (use_kerberos) {
-    defines += [ "USE_KERBEROS" ]
-    if (is_android) {
-      include_dirs = [ "/usr/include/kerberosV" ]
-    }
+  if (use_kerberos && is_android) {
+    include_dirs = [ "/usr/include/kerberosV" ]
   }
 
   if (enable_built_in_dns) {
@@ -5365,10 +5363,6 @@
     }
   }
 
-  if (use_kerberos) {
-    defines += [ "USE_KERBEROS" ]
-  }
-
   # These are excluded on Android, because the actual Kerberos support, which
   # these test, is in a separate app on Android.
   if (use_kerberos && ((is_posix && !is_android) || is_fuchsia)) {
diff --git a/net/http/http_auth_handler_factory.cc b/net/http/http_auth_handler_factory.cc
index 9f66e60..db13d5af3 100644
--- a/net/http/http_auth_handler_factory.cc
+++ b/net/http/http_auth_handler_factory.cc
@@ -16,9 +16,10 @@
 #include "net/http/http_auth_handler_ntlm.h"
 #include "net/http/http_auth_preferences.h"
 #include "net/http/http_auth_scheme.h"
+#include "net/net_buildflags.h"
 #include "net/ssl/ssl_info.h"
 
-#if defined(USE_KERBEROS)
+#if BUILDFLAG(USE_KERBEROS)
 #include "net/http/http_auth_handler_negotiate.h"
 #endif
 
@@ -53,7 +54,7 @@
 namespace {
 
 const char* const kDefaultAuthSchemes[] = {kBasicAuthScheme, kDigestAuthScheme,
-#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
+#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
                                            kNegotiateAuthScheme,
 #endif
                                            kNtlmAuthScheme};
@@ -157,7 +158,7 @@
     registry_factory->RegisterSchemeFactory(kNtlmAuthScheme, ntlm_factory);
   }
 
-#if defined(USE_KERBEROS)
+#if BUILDFLAG(USE_KERBEROS)
   if (base::ContainsKey(auth_schemes_set, kNegotiateAuthScheme)) {
     DCHECK(host_resolver);
     HttpAuthHandlerNegotiate::Factory* negotiate_factory =
@@ -175,7 +176,7 @@
     registry_factory->RegisterSchemeFactory(kNegotiateAuthScheme,
                                             negotiate_factory);
   }
-#endif  // defined(USE_KERBEROS)
+#endif  // BUILDFLAG(USE_KERBEROS)
 
   if (prefs) {
     registry_factory->set_http_auth_preferences(prefs);
diff --git a/net/http/http_auth_handler_factory_unittest.cc b/net/http/http_auth_handler_factory_unittest.cc
index 277a776..f371018 100644
--- a/net/http/http_auth_handler_factory_unittest.cc
+++ b/net/http/http_auth_handler_factory_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "build/build_config.h"
 #include "net/base/net_errors.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_auth_handler.h"
@@ -13,6 +14,7 @@
 #include "net/http/mock_allow_http_auth_preferences.h"
 #include "net/http/url_security_manager.h"
 #include "net/log/net_log_with_source.h"
+#include "net/net_buildflags.h"
 #include "net/ssl/ssl_info.h"
 #include "net/test/gtest_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -172,7 +174,7 @@
         "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, server_origin,
         NetLogWithSource(), &handler);
 // Note the default factory doesn't support Kerberos on Android
-#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
+#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
     EXPECT_THAT(rv, IsOk());
     ASSERT_FALSE(handler.get() == NULL);
     EXPECT_EQ(HttpAuth::AUTH_SCHEME_NEGOTIATE, handler->auth_scheme());
@@ -183,7 +185,7 @@
 #else
     EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME));
     EXPECT_TRUE(handler.get() == NULL);
-#endif  // defined(USE_KERBEROS) && !defined(OS_ANDROID)
+#endif  // BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
   }
 }
 
diff --git a/net/http/http_auth_unittest.cc b/net/http/http_auth_unittest.cc
index 04d415b9..58f9f04 100644
--- a/net/http/http_auth_unittest.cc
+++ b/net/http/http_auth_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_util.h"
+#include "build/build_config.h"
 #include "net/base/net_errors.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_auth_challenge_tokenizer.h"
@@ -22,6 +23,7 @@
 #include "net/http/http_util.h"
 #include "net/http/mock_allow_http_auth_preferences.h"
 #include "net/log/net_log_with_source.h"
+#include "net/net_buildflags.h"
 #include "net/ssl/ssl_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -73,54 +75,51 @@
     const char* challenge_realm;
   } tests[] = {
       {
-       // Basic is the only challenge type, pick it.
-       "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
-       "www-authenticate: Basic realm=\"BasicRealm\"\n",
+          // Basic is the only challenge type, pick it.
+          "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
+          "www-authenticate: Basic realm=\"BasicRealm\"\n",
 
-       HttpAuth::AUTH_SCHEME_BASIC,
-       "BasicRealm",
+          HttpAuth::AUTH_SCHEME_BASIC, "BasicRealm",
       },
       {
-       // Fake is the only challenge type, but it is unsupported.
-       "Y: Digest realm=\"FooBar\", nonce=\"aaaaaaaaaa\"\n"
-       "www-authenticate: Fake realm=\"FooBar\"\n",
+          // Fake is the only challenge type, but it is unsupported.
+          "Y: Digest realm=\"FooBar\", nonce=\"aaaaaaaaaa\"\n"
+          "www-authenticate: Fake realm=\"FooBar\"\n",
 
-       HttpAuth::AUTH_SCHEME_MAX,
-       "",
+          HttpAuth::AUTH_SCHEME_MAX, "",
       },
       {
-       // Pick Digest over Basic.
-       "www-authenticate: Basic realm=\"FooBar\"\n"
-       "www-authenticate: Fake realm=\"FooBar\"\n"
-       "www-authenticate: nonce=\"aaaaaaaaaa\"\n"
-       "www-authenticate: Digest realm=\"DigestRealm\", nonce=\"aaaaaaaaaa\"\n",
+          // Pick Digest over Basic.
+          "www-authenticate: Basic realm=\"FooBar\"\n"
+          "www-authenticate: Fake realm=\"FooBar\"\n"
+          "www-authenticate: nonce=\"aaaaaaaaaa\"\n"
+          "www-authenticate: Digest realm=\"DigestRealm\", "
+          "nonce=\"aaaaaaaaaa\"\n",
 
-       HttpAuth::AUTH_SCHEME_DIGEST,
-       "DigestRealm",
+          HttpAuth::AUTH_SCHEME_DIGEST, "DigestRealm",
       },
       {
-       // Handle an empty header correctly.
-       "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
-       "www-authenticate:\n",
+          // Handle an empty header correctly.
+          "Y: Digest realm=\"X\", nonce=\"aaaaaaaaaa\"\n"
+          "www-authenticate:\n",
 
-       HttpAuth::AUTH_SCHEME_MAX,
-       "",
+          HttpAuth::AUTH_SCHEME_MAX, "",
       },
       {
-       "WWW-Authenticate: Negotiate\n"
-       "WWW-Authenticate: NTLM\n",
+          "WWW-Authenticate: Negotiate\n"
+          "WWW-Authenticate: NTLM\n",
 
-#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
-       // Choose Negotiate over NTLM on all platforms.
-       // TODO(ahendrickson): This may be flaky on Linux and OSX as it
-       // relies on being able to load one of the known .so files
-       // for gssapi.
-       HttpAuth::AUTH_SCHEME_NEGOTIATE,
+#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
+          // Choose Negotiate over NTLM on all platforms.
+          // TODO(ahendrickson): This may be flaky on Linux and OSX as it
+          // relies on being able to load one of the known .so files
+          // for gssapi.
+          HttpAuth::AUTH_SCHEME_NEGOTIATE,
 #else
-       // On systems that don't use Kerberos fall back to NTLM.
-       HttpAuth::AUTH_SCHEME_NTLM,
-#endif  // defined(USE_KERBEROS)
-       "",
+          // On systems that don't use Kerberos fall back to NTLM.
+          HttpAuth::AUTH_SCHEME_NTLM,
+#endif  // BUILDFLAG(USE_KERBEROS)
+          "",
       }};
   GURL origin("http://www.example.com");
   std::set<HttpAuth::Scheme> disabled_schemes;
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc
index e0eed6b..8ffa62b 100644
--- a/services/network/network_service_unittest.cc
+++ b/services/network/network_service_unittest.cc
@@ -15,8 +15,8 @@
 #include "net/dns/dns_config_service.h"
 #include "net/dns/host_resolver.h"
 #include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_auth_handler_negotiate.h"
 #include "net/http/http_auth_scheme.h"
+#include "net/net_buildflags.h"
 #include "net/proxy_resolution/proxy_config.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
@@ -33,6 +33,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(USE_KERBEROS)
+#include "net/http/http_auth_handler_negotiate.h"
+#endif
+
 namespace network {
 
 namespace {
@@ -107,9 +111,7 @@
 }
 
 // Platforms where Negotiate can be used.
-#if defined(OS_WIN) || \
-    (defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS))
-
+#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
 // Returns the negotiate factory, if one exists, to query its configuration.
 net::HttpAuthHandlerNegotiate::Factory* GetNegotiateFactory(
     NetworkContext* network_context) {
@@ -120,8 +122,7 @@
           ->GetSchemeFactory(net::kNegotiateAuthScheme));
 }
 
-#endif  //  defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_ANDROID) &&
-        //  !defined(OS_IOS))
+#endif  // BUILDFLAG(USE_KERBEROS)
 
 TEST_F(NetworkServiceTest, AuthDefaultParams) {
   mojom::NetworkContextPtr network_context_ptr;
@@ -139,17 +140,16 @@
   EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kDigestAuthScheme));
   EXPECT_TRUE(auth_handler_factory->GetSchemeFactory(net::kNtlmAuthScheme));
 
-#if defined(OS_CHROMEOS)
+#if BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
   ASSERT_TRUE(GetNegotiateFactory(&network_context));
+#if defined(OS_CHROMEOS)
   EXPECT_TRUE(GetNegotiateFactory(&network_context)
                   ->allow_gssapi_library_load_for_testing());
-#elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_IOS)
-  ASSERT_TRUE(GetNegotiateFactory(&network_context));
+#elif defined(OS_POSIX)
   EXPECT_EQ("",
             GetNegotiateFactory(&network_context)->GetLibraryNameForTesting());
-#elif defined(OS_WIN)
-  EXPECT_TRUE(GetNegotiateFactory(&network_context));
 #endif
+#endif  // BUILDFLAG(USE_KERBEROS) && !defined(OS_ANDROID)
 
   EXPECT_FALSE(auth_handler_factory->http_auth_preferences()
                    ->NegotiateDisableCnameLookup());
diff --git a/services/service_manager/public/tools/manifest/manifest_collator.py b/services/service_manager/public/tools/manifest/manifest_collator.py
index 42cef490..f631fccb 100755
--- a/services/service_manager/public/tools/manifest/manifest_collator.py
+++ b/services/service_manager/public/tools/manifest/manifest_collator.py
@@ -13,6 +13,11 @@
 import urlparse
 
 
+sys.path.append(os.path.join(
+    os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir,
+    os.pardir, "build", "android", "gyp"))
+from util import build_utils
+
 # Keys which are completely overridden by manifest overlays
 _MANIFEST_OVERLAY_OVERRIDE_KEYS = [
   "display_name",
@@ -123,8 +128,8 @@
   for overlay_path in args.overlays:
     MergeManifestOverlay(parent, ParseJSONFile(overlay_path))
 
-  with open(args.output, "w") as output_file:
-    json.dump(parent, output_file, indent=2 if args.pretty else -1)
+  with build_utils.AtomicOutput(args.output) as f:
+    json.dump(parent, f, indent=2 if args.pretty else -1)
 
   # NOTE: We do the sanity check and possible failure *after* outputting the
   # aggregate manifest so it's easier to inspect erroneous output.
diff --git a/storage/common/database/database_connections.cc b/storage/common/database/database_connections.cc
index 996c8c3..ace4dc4 100644
--- a/storage/common/database/database_connections.cc
+++ b/storage/common/database/database_connections.cc
@@ -4,13 +4,7 @@
 
 #include "storage/common/database/database_connections.h"
 
-#include <stdint.h>
-
-#include "base/auto_reset.h"
-#include "base/bind.h"
 #include "base/logging.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread_task_runner_handle.h"
 
 namespace storage {
 
@@ -119,48 +113,4 @@
   return true;
 }
 
-DatabaseConnectionsWrapper::DatabaseConnectionsWrapper() = default;
-
-DatabaseConnectionsWrapper::~DatabaseConnectionsWrapper() = default;
-
-bool DatabaseConnectionsWrapper::HasOpenConnections() {
-  base::AutoLock auto_lock(open_connections_lock_);
-  return !open_connections_.IsEmpty();
-}
-
-void DatabaseConnectionsWrapper::AddOpenConnection(
-    const std::string& origin_identifier,
-    const base::string16& database_name) {
-  base::AutoLock auto_lock(open_connections_lock_);
-  open_connections_.AddConnection(origin_identifier, database_name);
-}
-
-void DatabaseConnectionsWrapper::RemoveOpenConnection(
-    const std::string& origin_identifier,
-    const base::string16& database_name) {
-  base::AutoLock auto_lock(open_connections_lock_);
-  open_connections_.RemoveConnection(origin_identifier, database_name);
-  if (waiting_to_close_event_ && open_connections_.IsEmpty())
-    waiting_to_close_event_->Signal();
-}
-
-bool DatabaseConnectionsWrapper::WaitForAllDatabasesToClose(
-    base::TimeDelta timeout) {
-  base::WaitableEvent waitable_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  {
-    base::AutoLock auto_lock(open_connections_lock_);
-    if (open_connections_.IsEmpty())
-      return true;
-    waiting_to_close_event_ = &waitable_event;
-  }
-  waitable_event.TimedWait(timeout);
-  {
-    base::AutoLock auto_lock(open_connections_lock_);
-    waiting_to_close_event_ = nullptr;
-    return open_connections_.IsEmpty();
-  }
-}
-
 }  // namespace storage
diff --git a/storage/common/database/database_connections.h b/storage/common/database/database_connections.h
index e0ad75b..ff46934 100644
--- a/storage/common/database/database_connections.h
+++ b/storage/common/database/database_connections.h
@@ -11,16 +11,9 @@
 #include <string>
 #include <vector>
 
-#include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
 #include "storage/common/storage_common_export.h"
 
-namespace base {
-class WaitableEvent;
-}
-
 namespace storage {
 
 class STORAGE_COMMON_EXPORT DatabaseConnections {
@@ -67,32 +60,6 @@
                                int num_connections);
 };
 
-// A wrapper class that provides thread-safety and the
-// ability to wait until all connections have closed.
-// Intended for use in renderer processes.
-class STORAGE_COMMON_EXPORT DatabaseConnectionsWrapper
-    : public base::RefCountedThreadSafe<DatabaseConnectionsWrapper> {
- public:
-  DatabaseConnectionsWrapper();
-
-  bool HasOpenConnections();
-  void AddOpenConnection(const std::string& origin_identifier,
-                         const base::string16& database_name);
-  void RemoveOpenConnection(const std::string& origin_identifier,
-                            const base::string16& database_name);
-
-  // Returns true if all databases are closed.
-  bool WaitForAllDatabasesToClose(base::TimeDelta timeout);
-
- private:
-  ~DatabaseConnectionsWrapper();
-  friend class base::RefCountedThreadSafe<DatabaseConnectionsWrapper>;
-
-  base::Lock open_connections_lock_;
-  DatabaseConnections open_connections_;
-  base::WaitableEvent* waiting_to_close_event_ = nullptr;
-};
-
 }  // namespace storage
 
 #endif  // STORAGE_COMMON_DATABASE_DATABASE_CONNECTIONS_H_
diff --git a/storage/common/database/database_connections_unittest.cc b/storage/common/database/database_connections_unittest.cc
index 42b0398..ee595f9 100644
--- a/storage/common/database/database_connections_unittest.cc
+++ b/storage/common/database/database_connections_unittest.cc
@@ -4,31 +4,13 @@
 
 #include <stdint.h>
 
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "storage/common/database/database_connections.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::ASCIIToUTF16;
-using storage::DatabaseConnections;
-using storage::DatabaseConnectionsWrapper;
 
-namespace content {
-
-namespace {
-
-void RemoveConnectionTask(
-    const std::string& origin_id, const base::string16& database_name,
-    scoped_refptr<DatabaseConnectionsWrapper> obj,
-    bool* did_task_execute) {
-  *did_task_execute = true;
-  obj->RemoveOpenConnection(origin_id, database_name);
-}
-
-}  // anonymous namespace
+namespace storage {
 
 TEST(DatabaseConnectionsTest, DatabaseConnectionsTest) {
   const std::string kOriginId("origin_id");
@@ -92,38 +74,4 @@
   EXPECT_TRUE(connections.RemoveConnection(kOriginId, kName));
 }
 
-TEST(DatabaseConnectionsTest, DatabaseConnectionsWrapperTest) {
-  const std::string kOriginId("origin_id");
-  const base::string16 kName(ASCIIToUTF16("database_name"));
-
-  base::MessageLoop message_loop;
-  scoped_refptr<DatabaseConnectionsWrapper> obj(new DatabaseConnectionsWrapper);
-  EXPECT_FALSE(obj->HasOpenConnections());
-  obj->AddOpenConnection(kOriginId, kName);
-  EXPECT_TRUE(obj->HasOpenConnections());
-  obj->AddOpenConnection(kOriginId, kName);
-  EXPECT_TRUE(obj->HasOpenConnections());
-  obj->RemoveOpenConnection(kOriginId, kName);
-  EXPECT_TRUE(obj->HasOpenConnections());
-  obj->RemoveOpenConnection(kOriginId, kName);
-  EXPECT_FALSE(obj->HasOpenConnections());
-  EXPECT_TRUE(obj->WaitForAllDatabasesToClose(base::TimeDelta()));
-
-  // Test WaitForAllDatabasesToClose with the last connection
-  // being removed on another thread.
-  obj->AddOpenConnection(kOriginId, kName);
-  EXPECT_FALSE(obj->WaitForAllDatabasesToClose(base::TimeDelta()));
-  base::Thread thread("WrapperTestThread");
-  thread.Start();
-  bool did_task_execute = false;
-  thread.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&RemoveConnectionTask, kOriginId, kName, obj,
-                                &did_task_execute));
-  // Use a long timeout value to avoid timeouts on test bots.
-  EXPECT_TRUE(obj->WaitForAllDatabasesToClose(
-      base::TimeDelta::FromSeconds(15)));
-  EXPECT_TRUE(did_task_execute);
-  EXPECT_FALSE(obj->HasOpenConnections());
-}
-
-}  // namespace content
+}  // namespace storage
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index c99e142..f3b6d1b 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -2914,6 +2914,15 @@
         "test": "base_unittests"
       },
       {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "content_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
@@ -2941,6 +2950,12 @@
         "test": "ipc_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "media_unittests"
+      },
+      {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter"
         ],
@@ -2962,6 +2977,12 @@
         "test": "skia_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
+        "test": "sql_unittests"
+      },
+      {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter"
         ],
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 368533e..63285af 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -93,7 +93,7 @@
           "--test-launcher-jobs=1"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": false
+          "can_use_on_swarming_builders": true
         },
         "test": "cast_shell_browsertests"
       },
@@ -356,7 +356,7 @@
           "--test-launcher-jobs=1"
         ],
         "swarming": {
-          "can_use_on_swarming_builders": false
+          "can_use_on_swarming_builders": true
         },
         "test": "cast_shell_browsertests"
       },
@@ -597,6 +597,31 @@
       },
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ipc_tests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
+        "test": "ipc_tests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
+        "test": "media_unittests"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.mojo_unittests.filter"
         ],
         "swarming": {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index a65a8d5..c08a866 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -327,9 +327,6 @@
           '--no-sandbox',
           '--test-launcher-jobs=1',
         ],
-        'swarming': {
-          'can_use_on_swarming_builders': False,
-        },
       },
       'Cast Linux': {
         'args': [
@@ -338,9 +335,6 @@
           '--no-sandbox',
           '--test-launcher-jobs=1',
         ],
-        'swarming': {
-          'can_use_on_swarming_builders': False,
-        },
       },
     },
   },
@@ -922,10 +916,6 @@
     },
   },
   'content_unittests': {
-    'remove_from': [
-      # chromium.fyi
-      'fuchsia-fyi-arm64-rel',
-    ],
     'modifications': {
       # TODO(dpranke) - on chromium.swarm, remove this exception.
       'Android N5X Swarm': {
@@ -1301,10 +1291,6 @@
     },
   },
   'ipc_tests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-    ],
     'modifications': {
       # chromium.android
       'KitKat Tablet Tester': {
@@ -1391,14 +1377,6 @@
       },
     },
   },
-  'media_unittests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-      # chromium.fyi
-      'fuchsia-fyi-arm64-rel',
-    ],
-  },
   'mojo_test_apk': {
     'modifications': {
       # chromium.clang
@@ -1434,10 +1412,10 @@
   'net_unittests': {
     'remove_from': [
       # chromium.fyi
-      'fuchsia-fyi-arm64-rel',
-      'fuchsia-fyi-x64-dbg',
+      'fuchsia-fyi-arm64-rel',  # https://crbug.com/847915
+      'fuchsia-fyi-x64-dbg',  # https://crbug.com/844416 (and 847915)
       # chromium.linux
-      'Fuchsia x64',
+      'Fuchsia x64',  # https://crbug.com/847915
     ],
     'modifications': {
       # chromium.clang
@@ -1782,10 +1760,6 @@
     },
   },
   'sql_unittests': {
-    'remove_from': [
-      # chromium.fyi
-      'fuchsia-fyi-arm64-rel',
-    ],
     'modifications': {
       'KitKat Tablet Tester': {
         'swarming': {
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 1384d6b..e50fa76d 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -346,8 +346,6 @@
 crbug.com/591099 fast/block/line-layout/floats-do-not-fit-on-line.html [ Failure ]
 crbug.com/591099 fast/block/over-constrained-auto-margin.html [ Failure ]
 crbug.com/591099 fast/block/positioning/positioned-child-inside-relative-positioned-anonymous-block.html [ Failure ]
-crbug.com/591099 fast/block/positioning/rtl-static-positioning.html [ Failure ]
-crbug.com/591099 fast/block/positioning/table-cell-static-position.html [ Failure ]
 crbug.com/591099 fast/borders/bidi-002.html [ Failure ]
 crbug.com/859497 fast/borders/bidi-009a.html [ Failure ]
 crbug.com/591099 fast/borders/bidi-012.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 1e22593..5221a67 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3760,11 +3760,6 @@
 
 # ====== End of display: contents tests ======
 
-# Temporarily disabled tests that will pass once deprecated console methods are removed, see crrev.com/c/1082112
-crbug.com/706804 external/wpt/console/console-tests-historical.any.html [ Skip ]
-crbug.com/706804 external/wpt/console/console-tests-historical.any.worker.html [ Skip ]
-crbug.com/706804 fast/workers/chromium/worker-console-log.html [ Skip ]
-
 crbug.com/676229 [ Win Linux Mac ] plugins/mouse-click-plugin-clears-selection.html [ Failure Pass ]
 crbug.com/736333 [ Win7 Linux ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ]
 crbug.com/742670 [ Mac ] plugins/iframe-plugin-bgcolor.html [ Failure Pass ]
@@ -4597,7 +4592,7 @@
 crbug.com/851090 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-click-hyperlink.html [ Pass Failure ]
 
 # Sheriff 2018-06-11
-crbug.com/850202 [ Linux ] http/tests/devtools/network/network-filters.js [ Pass Failure ]
+crbug.com/850202 [ Linux ] http/tests/devtools/network/network-filters.js [ Pass Failure Timeout ]
 crbug.com/851746 fast/canvas/color-space/canvas-colorManaged-convertToBlob-roundtrip.html [ Pass Timeout Failure ]
 crbug.com/851746 virtual/gpu/fast/canvas/color-space/canvas-colorManaged-convertToBlob-roundtrip.html [ Pass Timeout Failure ]
 
@@ -4675,3 +4670,14 @@
 crbug.com/861544 [ Win ] fast/text/selection/khmer-selection.html [ Failure Pass ]
 
 crbug.com/861682 [ Win ] external/wpt/css/mediaqueries/device-aspect-ratio-003.html [ Failure Pass ]
+
+# Sheriff 2018-07-09
+# MSAN
+crbug.com/856601 [ Linux ] external/wpt/FileAPI/idlharness.worker.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/bluetooth/idl/idlharness.tentative.window.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/css/cssom-view/interfaces.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/mediacapture-streams/MediaDevices-IDL-enumerateDevices.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/page-visibility/idlharness.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/touch-events/idlharness.window.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] external/wpt/web-animations/interfaces/Animation/idlharness.html [ Timeout Pass ]
+crbug.com/856601 [ Linux ] http/tests/event-timing/event-timing-retrievability.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 7bb8069..16b6b292 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -341231,7 +341231,7 @@
    "testharness"
   ],
   "css/cssom/interfaces-expected.txt": [
-   "5aa57f38cb9eb09b1e5f4d896f12e30420ed45c8",
+   "8013e3aad136dc05a1f33317b4e29df05dcd6f8b",
    "support"
   ],
   "css/cssom/interfaces.html": [
@@ -388283,7 +388283,7 @@
    "testharness"
   ],
   "referrer-policy/generic/referrer-policy-test-case.js": [
-   "62d77f2911b075bfa2de6138faffd8f5997ac7d5",
+   "ae4b5d29fa31dcfe9ab7ac1250ef57af9cc39812",
    "support"
   ],
   "referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/dedicated-worker-helper.js b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/dedicated-worker-helper.js
index c1ed208..8441ab0d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/dedicated-worker-helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/dedicated-worker-helper.js
@@ -1,2 +1,5 @@
 var url = new URL("../support/ping.js", document.baseURI).toString();
-assert_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
+if (document.getElementById("foo").hasAttribute("blocked-worker"))
+  assert_worker_is_blocked(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
+else
+  assert_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/service-worker-helper.js b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/service-worker-helper.js
index 4e8f8b5..b5f65c9 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/service-worker-helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/service-worker-helper.js
@@ -1,2 +1,5 @@
 var url = new URL("../support/ping.js", document.baseURI).toString();
-assert_service_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
+if (document.getElementById("foo").hasAttribute("blocked-worker"))
+  assert_service_worker_is_blocked(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
+else
+  assert_service_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/shared-worker-helper.js b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/shared-worker-helper.js
index d0637ec..2a38738 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/shared-worker-helper.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/shared-worker-helper.js
@@ -1,2 +1,5 @@
 var url = new URL("../support/ping.js", document.baseURI).toString();
-assert_shared_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
+if (document.getElementById("foo").hasAttribute("blocked-worker"))
+  assert_shared_worker_is_blocked(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
+else
+  assert_shared_worker_is_loaded(url, document.getElementById("foo").getAttribute("data-desc-fallback"));
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/dedicated-worker-src-child-fallback-blocked.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/dedicated-worker-src-child-fallback-blocked.sub.html
new file mode 100644
index 0000000..f9f68fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/dedicated-worker-src-child-fallback-blocked.sub.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Web platform test for dedicated worker allowed by worker-src self</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../support/testharness-helper.js"></script>
+
+<meta http-equiv="Content-Security-Policy" content="child-src 'none'; script-src 'self'; default-src 'none'; ">
+<script src="../support/dedicated-worker-helper.js" blocked-worker id="foo" data-desc-fallback="Same-origin dedicated worker allowed by worker-src 'self'."></script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/service-worker-src-child-fallback-blocked.https.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/service-worker-src-child-fallback-blocked.https.sub.html
new file mode 100644
index 0000000..979abd5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/service-worker-src-child-fallback-blocked.https.sub.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Web platform test for service worker allowed by child-src self</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../support/testharness-helper.js"></script>
+
+<meta http-equiv="Content-Security-Policy" content="child-src 'none'; script-src 'self'; default-src 'none'; ">
+<script src="../support/service-worker-helper.js" blocked-worker id="foo" data-desc-fallback="Same-origin service worker allowed by child-src 'self'."></script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/shared-worker-src-child-fallback-blocked.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/shared-worker-src-child-fallback-blocked.sub.html
new file mode 100644
index 0000000..00dbdb4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/worker-src/shared-worker-src-child-fallback-blocked.sub.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Web platform test for shared worker allowed by child-src self</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../support/testharness-helper.js"></script>
+
+<meta http-equiv="Content-Security-Policy" content="child-src 'none'; script-src 'self'; default-src 'none'; ">
+<script src="../support/shared-worker-helper.js" blocked-worker id="foo" data-desc-fallback="Same-origin shared worker allowed by child-src 'self'."></script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html
index ddca2e4..e6e9f434 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html
@@ -17,6 +17,12 @@
     --length-percentage-1: 17em;
     --length-percentage-2: 18%;
     --length-percentage-3: calc(19em - 2%);
+    --csv-1: 10px, 3em;
+    --csv-2: 4em ,9px;
+    --csv-3: 8em;
+    --csv-4: 3% , 10vmax  , 22px;
+    --csv-5: calc(50% + 1em), 4px;
+    --csv-6: calc(13% + 37px);
     --list-1: 10px 3em;
     --list-2: 4em 9px;
     --list-3: 3% 10vmax 22px;
@@ -45,6 +51,12 @@
     CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
     CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
     CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-1', syntax: '<length>#', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-2', syntax: '<length>#', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-3', syntax: '<length>#', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-4', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-5', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
+    CSS.registerProperty({name: '--csv-6', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
     CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px', inherits: false});
     CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px', inherits: false});
     CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px', inherits: false});
@@ -72,6 +84,18 @@
     }, "<length-percentage> values are computed correctly for " + id);
 
     test(function() {
+        assert_equals(computedStyle.getPropertyValue('--csv-1'), '10px, 30px');
+        assert_equals(computedStyle.getPropertyValue('--csv-2'), '40px, 9px');
+        assert_equals(computedStyle.getPropertyValue('--csv-3'), '80px');
+    }, "<length># values are computed correctly for " + id);
+
+    test(function() {
+        assert_equals(computedStyle.getPropertyValue('--csv-4'), '3%, 80px, 22px');
+        assert_equals(computedStyle.getPropertyValue('--csv-5'), 'calc(10px + 50%), 4px');
+        assert_equals(computedStyle.getPropertyValue('--csv-6'), 'calc(37px + 13%)');
+    }, "<length-percentage># values are computed correctly for " + id);
+
+    test(function() {
         assert_equals(computedStyle.getPropertyValue('--list-1'), '10px 30px');
         assert_equals(computedStyle.getPropertyValue('--list-2'), '40px 9px');
     }, "<length>+ values are computed correctly for " + id);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js
index 7c8cba4..14ccd4e 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js
@@ -72,7 +72,6 @@
 
     _invokeSubresource: function(callback, test) {
       var invoker = subresourceInvoker[t._scenario.subresource];
-
       // Depending on the delivery method, extend the subresource element with
       // these attributes.
       var elementAttributesForDeliveryMethod = {
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
similarity index 99%
rename from third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
rename to third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
index 758196f..c4653d903 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 578 tests; 400 PASS, 178 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 578 tests; 401 PASS, 177 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
@@ -317,8 +317,8 @@
 PASS grid-template-rows: "5px" onto "1px"
 PASS grid-template-rows: "1px" onto "5px"
 PASS hyphens (type: discrete) has testAccumulation function
-FAIL hyphens: "auto" onto "manual" assert_equals: The value should be auto at 0ms expected "auto" but got "manual"
-PASS hyphens: "manual" onto "auto"
+PASS hyphens: "none" onto "manual"
+PASS hyphens: "manual" onto "none"
 PASS image-orientation (type: discrete) has testAccumulation function
 FAIL image-orientation: "90deg" onto "0deg" assert_equals: The value should be 90deg at 0ms expected "90deg" but got "0deg"
 PASS image-orientation: "0deg" onto "90deg"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
similarity index 99%
rename from third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
rename to third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
index b6327c10..19b5374 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -317,8 +317,8 @@
 PASS grid-template-rows: "5px" onto "1px"
 PASS grid-template-rows: "1px" onto "5px"
 PASS hyphens (type: discrete) has testAddition function
-PASS hyphens: "auto" onto "manual"
-PASS hyphens: "manual" onto "auto"
+PASS hyphens: "none" onto "manual"
+PASS hyphens: "manual" onto "none"
 PASS image-orientation (type: discrete) has testAddition function
 FAIL image-orientation: "90deg" onto "0deg" assert_equals: The value should be 90deg at 0ms expected "90deg" but got "0deg"
 PASS image-orientation: "0deg" onto "90deg"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
similarity index 99%
rename from third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
rename to third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
index 3379b81..83d4f27 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -394,9 +394,9 @@
 PASS grid-template-rows uses discrete animation when animating between "1px" and "5px" with effect easing
 PASS grid-template-rows uses discrete animation when animating between "1px" and "5px" with keyframe easing
 PASS hyphens (type: discrete) has testInterpolation function
-PASS hyphens uses discrete animation when animating between "manual" and "auto" with linear easing
-PASS hyphens uses discrete animation when animating between "manual" and "auto" with effect easing
-PASS hyphens uses discrete animation when animating between "manual" and "auto" with keyframe easing
+PASS hyphens uses discrete animation when animating between "manual" and "none" with linear easing
+PASS hyphens uses discrete animation when animating between "manual" and "none" with effect easing
+PASS hyphens uses discrete animation when animating between "manual" and "none" with keyframe easing
 PASS image-orientation (type: discrete) has testInterpolation function
 FAIL image-orientation uses discrete animation when animating between "0deg" and "90deg" with linear easing assert_equals: The value should be 90deg at 500ms expected "90deg" but got "0deg"
 FAIL image-orientation uses discrete animation when animating between "0deg" and "90deg" with effect easing assert_equals: The value should be 90deg at 960ms expected "90deg" but got "0deg"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
index 8871343..7e53e07f9 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
@@ -705,7 +705,7 @@
   'hyphens': {
     // https://drafts.csswg.org/css-text-3/#propdef-hyphens
     types: [
-      { type: 'discrete', options: [ [ 'manual', 'auto' ] ] }
+      { type: 'discrete', options: [ [ 'manual', 'none' ] ] }
     ]
   },
   'image-orientation': {
diff --git a/third_party/WebKit/LayoutTests/fast/forms/calendar-picker/date-picker-ax-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/calendar-picker/date-picker-ax-expected.txt
index 4bdfcfa..1d7b8710 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/calendar-picker/date-picker-ax-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/calendar-picker/date-picker-ax-expected.txt
@@ -3,8 +3,8 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focused: 
-Focused: 
+Focused: Month
+Focused: Month
 PASS Received ActiveDescendantChanged
 PASS Received ActiveDescendantChanged
 Focused: Show next month
diff --git a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes-expected.txt
deleted file mode 100644
index 00c6356..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This test checks aria-help attribute of fields in multiple fields date input UI.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Initial empty state
-PASS focusedElementDescription() is "Month, AXValueDescription: mm, intValue:0, range:1-12"
-PASS focusedElementDescription() is "Day, AXValueDescription: dd, intValue:0, range:1-31"
-PASS focusedElementDescription() is "Year, AXValueDescription: yyyy, intValue:0, range:1-275760"
-Non-empty value
-PASS focusedElementDescription() is "Month, AXValueDescription: 10, intValue:10, range:1-12"
-PASS focusedElementDescription() is "Day, AXValueDescription: 09, intValue:9, range:1-31"
-PASS focusedElementDescription() is "Year, AXValueDescription: 2012, intValue:2012, range:1-275760"
-Empty value
-PASS focusedElementDescription() is "Year, AXValueDescription: yyyy, intValue:0, range:1-275760"
-PASS focusedElementDescription() is "Day, AXValueDescription: dd, intValue:0, range:1-31"
-PASS focusedElementDescription() is "Month, AXValueDescription: mm, intValue:0, range:1-12"
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes.html b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes.html
index db2e85ba..d8a514d7e 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-aria-attributes.html
@@ -1,50 +1,55 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <script src="../resources/multiple-fields-ax-aria-attributes.js"></script>
 </head>
 <body>
-<input id="test" type="date">
+<input id="test" type="date" aria-label="TestLabel" title="TestTitle">
 <script>
-description('This test checks aria-help attribute of fields in multiple fields date input UI.');
-
 var testInput = document.getElementById('test');
 
-if (!window.accessibilityController || !window.eventSender)
-    debug('Please run inside DRT or WTR.');
-else {
+test(function(t) {
     testInput.focus();
-    debug('Initial empty state');
-    checkFocusedElementAXAttributes('Month, AXValueDescription: mm, intValue:0, range:1-12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, mm, "", TestTitle, intValue:0, range:1-12');
     eventSender.keyDown('\t');
-    checkFocusedElementAXAttributes('Day, AXValueDescription: dd, intValue:0, range:1-31');
+    assert_equals(focusedElementDescription(),
+                  'Day TestLabel, dd, "", TestTitle, intValue:0, range:1-31');
     eventSender.keyDown('\t');
-    checkFocusedElementAXAttributes('Year, AXValueDescription: yyyy, intValue:0, range:1-275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, yyyy, "", TestTitle, intValue:0, range:1-275760');
+    eventSender.keyDown('\t', ['shiftKey']);
+    eventSender.keyDown('\t', ['shiftKey']);
+}, 'Initial empty state');
 
-    eventSender.keyDown('\t', ['shiftKey']);
-    eventSender.keyDown('\t', ['shiftKey']);
-    debug('Non-empty value');
+test(function(t) {
+    testInput.focus();
     testInput.value = "2012-10-09";
-    checkFocusedElementAXAttributes('Month, AXValueDescription: 10, intValue:10, range:1-12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, mm, "10", TestTitle, intValue:10, range:1-12');
     eventSender.keyDown('\t');
-    checkFocusedElementAXAttributes('Day, AXValueDescription: 09, intValue:9, range:1-31');
+    assert_equals(focusedElementDescription(),
+                  'Day TestLabel, dd, "09", TestTitle, intValue:9, range:1-31');
     eventSender.keyDown('\t');
-    checkFocusedElementAXAttributes('Year, AXValueDescription: 2012, intValue:2012, range:1-275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, yyyy, "2012", TestTitle, intValue:2012, range:1-275760');
+}, 'Non-empty value');
 
-    debug('Empty value');
+test(function(t) {
     eventSender.keyDown('Backspace');
-    checkFocusedElementAXAttributes('Year, AXValueDescription: yyyy, intValue:0, range:1-275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, yyyy, "", TestTitle, intValue:0, range:1-275760');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    checkFocusedElementAXAttributes('Day, AXValueDescription: dd, intValue:0, range:1-31');
+    assert_equals(focusedElementDescription(),
+                  'Day TestLabel, dd, "", TestTitle, intValue:0, range:1-31');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    checkFocusedElementAXAttributes('Month, AXValueDescription: mm, intValue:0, range:1-12');
-
-    debug('');
-    testInput.parentNode.removeChild(testInput);
-}
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, mm, "", TestTitle, intValue:0, range:1-12');
+}, 'Empty value');
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt
index 011158e..c3d7643a 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification-expected.txt
@@ -3,13 +3,13 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focus Month=AXValueDescription: 10
-Focus Day=AXValueDescription: 09
-Focus Year=AXValueDescription: 2012
-ValueChanged Day=AXValueDescription: 04
-ValueChanged Day=AXValueDescription: 04
-ValueChanged Year=AXValueDescription: 2013
-ValueChanged Year=AXValueDescription: 2013
+Focus Month=10
+Focus Day=09
+Focus Year=2012
+ValueChanged Day=04
+ValueChanged Day=04
+ValueChanged Year=2013
+ValueChanged Year=2013
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
index a525b60..34498cf 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-ax-value-changed-notification.html
@@ -15,7 +15,7 @@
 else {
     accessibilityController.addNotificationListener(function (element, notification) {
         if (notification == 'Focus' || notification == 'ValueChanged') {
-            debug(notification + ' ' + element.description + '=' + element.valueDescription);
+            debug(notification + ' ' + element.name.trim() + '=' + element.valueDescription.substr(20));
         }
     });
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes-expected.txt
deleted file mode 100644
index 266309e..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes-expected.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-This test checks aria-help attribute of fields in multiple fields datetime-local input UI.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Non-empty value
-PASS focusedFieldValueDescription() is "Month, AXValueDescription: 10, 1, 12"
-PASS focusedFieldValueDescription() is "Day, AXValueDescription: 09, 1, 31"
-PASS focusedFieldValueDescription() is "Year, AXValueDescription: 2012, 1, 275760"
-PASS focusedFieldValueDescription() is "Hours, AXValueDescription: 12, 1, 12"
-PASS focusedFieldValueDescription() is "Minutes, AXValueDescription: 34, 0, 59"
-PASS focusedFieldValueDescription() is "Seconds, AXValueDescription: 56, 0, 59"
-PASS focusedFieldValueDescription() is "Milliseconds, AXValueDescription: 789, 0, 999"
-PASS focusedFieldValueDescription() is "AM/PM, AXValueDescription: PM, 1, 2"
-Empty value
-PASS focusedFieldValueDescription() is "AM/PM, AXValueDescription: --, 1, 2"
-PASS focusedFieldValueDescription() is "Milliseconds, AXValueDescription: ---, 0, 999"
-PASS focusedFieldValueDescription() is "Seconds, AXValueDescription: --, 0, 59"
-PASS focusedFieldValueDescription() is "Minutes, AXValueDescription: --, 0, 59"
-PASS focusedFieldValueDescription() is "Hours, AXValueDescription: --, 1, 12"
-PASS focusedFieldValueDescription() is "Year, AXValueDescription: yyyy, 1, 275760"
-PASS focusedFieldValueDescription() is "Day, AXValueDescription: dd, 1, 31"
-PASS focusedFieldValueDescription() is "Month, AXValueDescription: mm, 1, 12"
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes.html b/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes.html
index be4df70..4a2a0c0 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-aria-attributes.html
@@ -1,70 +1,76 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/multiple-fields-ax-aria-attributes.js"></script>
 </head>
 <body>
-<input id="test" type="datetime-local" step="0.001" value="2012-10-09T12:34:56.789">
+<input id="test" type="datetime-local" step="0.001" value="2012-10-09T12:34:56.789" aria-label="TestLabel" title="TestTitle">
 <script>
-description('This test checks aria-help attribute of fields in multiple fields datetime-local input UI.');
-
-function focusedFieldValueDescription()
-{
-    var element = accessibilityController.focusedElement;
-    return element.description + ', ' +  element.valueDescription + ', ' + element.minValue + ', ' + element.maxValue;
-}
-
 var testInput = document.getElementById('test');
 
-if (!window.accessibilityController || !window.eventSender)
-    debug('Please run inside DRT or WTR.');
-else {
-    debug('Non-empty value');
+test(function(t) {
     testInput.focus();
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Month, AXValueDescription: 10, 1, 12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, mm, "10", TestTitle, intValue:10, range:1-12');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Day, AXValueDescription: 09, 1, 31');
+    assert_equals(focusedElementDescription(),
+                  'Day TestLabel, dd, "09", TestTitle, intValue:9, range:1-31');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Year, AXValueDescription: 2012, 1, 275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, yyyy, "2012", TestTitle, intValue:2012, range:1-275760');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Hours, AXValueDescription: 12, 1, 12');
+    assert_equals(focusedElementDescription(),
+                  'Hours TestLabel, --, "12", TestTitle, intValue:12, range:1-12');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Minutes, AXValueDescription: 34, 0, 59');
+    assert_equals(focusedElementDescription(),
+                  'Minutes TestLabel, --, "34", TestTitle, intValue:34, range:0-59');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Seconds, AXValueDescription: 56, 0, 59');
+    assert_equals(focusedElementDescription(),
+                  'Seconds TestLabel, --, "56", TestTitle, intValue:56, range:0-59');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Milliseconds, AXValueDescription: 789, 0, 999');
+    assert_equals(focusedElementDescription(),
+                  'Milliseconds TestLabel, ---, "789", TestTitle, intValue:789, range:0-999');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'AM/PM, AXValueDescription: PM, 1, 2');
+    assert_equals(focusedElementDescription(),
+                  'AM/PM TestLabel, --, "PM", TestTitle, intValue:2, range:1-2');
+}, 'Non-empty value');
 
-    debug('Empty value');
+test(function(t) {
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'AM/PM, AXValueDescription: --, 1, 2');
+    assert_equals(focusedElementDescription(),
+                  'AM/PM TestLabel, --, "", TestTitle, intValue:0, range:1-2');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Milliseconds, AXValueDescription: ---, 0, 999');
+    assert_equals(focusedElementDescription(),
+                  'Milliseconds TestLabel, ---, "", TestTitle, intValue:0, range:0-999');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Seconds, AXValueDescription: --, 0, 59');
+    assert_equals(focusedElementDescription(),
+                  'Seconds TestLabel, --, "", TestTitle, intValue:0, range:0-59');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Minutes, AXValueDescription: --, 0, 59');
+    assert_equals(focusedElementDescription(),
+                  'Minutes TestLabel, --, "", TestTitle, intValue:0, range:0-59');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Hours, AXValueDescription: --, 1, 12');
+    assert_equals(focusedElementDescription(),
+                  'Hours TestLabel, --, "", TestTitle, intValue:0, range:1-12');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Year, AXValueDescription: yyyy, 1, 275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, yyyy, "", TestTitle, intValue:0, range:1-275760');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Day, AXValueDescription: dd, 1, 31');
+    assert_equals(focusedElementDescription(),
+                  'Day TestLabel, dd, "", TestTitle, intValue:0, range:1-31');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Month, AXValueDescription: mm, 1, 12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, mm, "", TestTitle, intValue:0, range:1-12');
+}, 'Empty value');
 
-    debug('');
-    testInput.parentNode.removeChild(testInput);
-}
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification-expected.txt
index 6424c54..de5c52d 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-ax-value-changed-notification-expected.txt
@@ -3,19 +3,19 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focus Month=AXValueDescription: 10
-Focus Day=AXValueDescription: 09
-Focus Year=AXValueDescription: 2012
-Focus Hours=AXValueDescription: 12
-Focus Minutes=AXValueDescription: 34
-ValueChanged Day=AXValueDescription: 04
-ValueChanged Day=AXValueDescription: 04
-ValueChanged Year=AXValueDescription: 2013
-ValueChanged Year=AXValueDescription: 2013
-ValueChanged Hours=AXValueDescription: 02
-ValueChanged Hours=AXValueDescription: 02
-ValueChanged Minutes=AXValueDescription: 33
-ValueChanged Minutes=AXValueDescription: 33
+Focus =AXValueDescription: 10
+Focus =AXValueDescription: 09
+Focus =AXValueDescription: 2012
+Focus =AXValueDescription: 12
+Focus =AXValueDescription: 34
+ValueChanged =AXValueDescription: 04
+ValueChanged =AXValueDescription: 04
+ValueChanged =AXValueDescription: 2013
+ValueChanged =AXValueDescription: 2013
+ValueChanged =AXValueDescription: 02
+ValueChanged =AXValueDescription: 02
+ValueChanged =AXValueDescription: 33
+ValueChanged =AXValueDescription: 33
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes-expected.txt
deleted file mode 100644
index bd1f008..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-This test checks aria-help attribute of fields in multiple fields week input UI.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Non-empty value
-PASS focusedElementDescription() is "Month, AXValueDescription: October, intValue:10, range:1-12"
-PASS focusedElementDescription() is "Year, AXValueDescription: 2012, intValue:2012, range:1-275760"
-Empty value
-PASS focusedElementDescription() is "Year, AXValueDescription: ----, intValue:0, range:1-275760"
-PASS focusedElementDescription() is "Month, AXValueDescription: ---------, intValue:0, range:1-12"
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes.html b/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes.html
index d99b199..15ddb94 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-aria-attributes.html
@@ -1,35 +1,34 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <script src="../resources/multiple-fields-ax-aria-attributes.js"></script>
 </head>
 <body>
-<input id="test" type="month" value="2012-10">
+<input id="test" type="month" value="2012-10" aria-label="TestLabel" title="TestTitle">
 <script>
-description('This test checks aria-help attribute of fields in multiple fields week input UI.');
 
-var testInput = document.getElementById('test');
-
-if (!window.accessibilityController || !window.eventSender)
-    debug('Please run inside DRT or WTR.');
-else {
-    debug('Non-empty value');
+test(function(t) {
+    var testInput = document.getElementById('test');
     testInput.focus();
-    checkFocusedElementAXAttributes('Month, AXValueDescription: October, intValue:10, range:1-12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, ---------, "October", TestTitle, intValue:10, range:1-12');
     eventSender.keyDown('\t');
-    checkFocusedElementAXAttributes('Year, AXValueDescription: 2012, intValue:2012, range:1-275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, ----, "2012", TestTitle, intValue:2012, range:1-275760');
+}, 'Non-empty value');
 
-    debug('Empty value');
+test(function(t) {
     eventSender.keyDown('Backspace');
-    checkFocusedElementAXAttributes('Year, AXValueDescription: ----, intValue:0, range:1-275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, ----, "", TestTitle, intValue:0, range:1-275760');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    checkFocusedElementAXAttributes('Month, AXValueDescription: ---------, intValue:0, range:1-12');
+    assert_equals(focusedElementDescription(),
+                  'Month TestLabel, ---------, "", TestTitle, intValue:0, range:1-12');
+}, 'Empty value');
 
-    debug('');
-    testInput.remove();
-}
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification-expected.txt
index 346aee5..fb9f4c3 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/month-multiple-fields/month-multiple-fields-ax-value-changed-notification-expected.txt
@@ -3,12 +3,12 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focus Month=AXValueDescription: October
-Focus Year=AXValueDescription: 2012
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
+Focus =AXValueDescription: October
+Focus =AXValueDescription: 2012
+ValueChanged =AXValueDescription: 0005
+ValueChanged =AXValueDescription: 0005
+ValueChanged =AXValueDescription: 0005
+ValueChanged =AXValueDescription: 0005
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/resources/multiple-fields-ax-aria-attributes.js b/third_party/WebKit/LayoutTests/fast/forms/resources/multiple-fields-ax-aria-attributes.js
index f8e2a91d..9e33275 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/resources/multiple-fields-ax-aria-attributes.js
+++ b/third_party/WebKit/LayoutTests/fast/forms/resources/multiple-fields-ax-aria-attributes.js
@@ -1,9 +1,9 @@
 function focusedElementDescription()
 {
-    var element = accessibilityController.focusedElement;
-    return element.description + ', ' +  element.valueDescription + ', intValue:' + element.intValue + ', range:'+ element.minValue + '-' + element.maxValue;
-}
-
-function checkFocusedElementAXAttributes(expected) {
-    shouldBeEqualToString('focusedElementDescription()', expected);
+  var element = accessibilityController.focusedElement;
+  var name = element.name;
+  var value = '"' + element.valueDescription.substr(20) + '"';
+  var description = element.description;
+  var placeholder = element.placeholder;
+  return name + ', ' + placeholder + ', ' + value + ', ' + description + ', intValue:' + element.intValue + ', range:' + element.minValue + '-' + element.maxValue;
 }
diff --git a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt
index 9127add..45e21a4 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/suggested-value-expected.txt
@@ -29,7 +29,8 @@
 |         pseudo="-webkit-datetime-edit-fields-wrapper"
 |         shadow:pseudoId="-webkit-datetime-edit-fields-wrapper"
 |         <span>
-|           aria-help="Month"
+|           aria-label="Month"
+|           aria-placeholder="---------"
 |           aria-valuemax="12"
 |           aria-valuemin="1"
 |           aria-valuenow="1"
@@ -43,7 +44,8 @@
 |           shadow:pseudoId="-webkit-datetime-edit-text"
 |           " "
 |         <span>
-|           aria-help="Year"
+|           aria-label="Year"
+|           aria-placeholder="----"
 |           aria-valuemax="275760"
 |           aria-valuemin="1"
 |           aria-valuenow="2014"
diff --git a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes-expected.txt
deleted file mode 100644
index d2608d6..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes-expected.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-This test checks aria-help attribute of fields in multiple fields time input UI.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Non-empty value
-PASS focusedElementDescription() is "Hours, AXValueDescription: 12, intValue:12, range:1-12"
-PASS focusedElementDescription() is "Minutes, AXValueDescription: 34, intValue:34, range:0-59"
-PASS focusedElementDescription() is "Seconds, AXValueDescription: 56, intValue:56, range:0-59"
-PASS focusedElementDescription() is "Milliseconds, AXValueDescription: 789, intValue:789, range:0-999"
-PASS focusedElementDescription() is "AM/PM, AXValueDescription: PM, intValue:2, range:1-2"
-Empty value
-PASS focusedElementDescription() is "AM/PM, AXValueDescription: --, intValue:0, range:1-2"
-PASS focusedElementDescription() is "Milliseconds, AXValueDescription: ---, intValue:0, range:0-999"
-PASS focusedElementDescription() is "Seconds, AXValueDescription: --, intValue:0, range:0-59"
-PASS focusedElementDescription() is "Minutes, AXValueDescription: --, intValue:0, range:0-59"
-PASS focusedElementDescription() is "Hours, AXValueDescription: --, intValue:0, range:1-12"
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes.html b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes.html
index 73d58025..e9e90c85 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-aria-attributes.html
@@ -1,22 +1,13 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
 <script src="../resources/multiple-fields-ax-aria-attributes.js"></script>
 </head>
 <body>
-<input id=test type="time" step="0.001" value="12:34:56.789">
+<input id=test type="time" step="0.001" value="12:34:56.789" aria-label="TestLabel" title="TestTitle">
 <script>
-description('This test checks aria-help attribute of fields in multiple fields time input UI.');
-
-function enableAccessibility()
-{
-    if (!window.accessibilityController) {
-        debug("Please run inside DumpRenderTree.");
-        return;
-    }
-}
-
 function keyDown(key, modifiers)
 {
     if (!window.eventSender)
@@ -26,39 +17,46 @@
 
 var testInput = document.getElementById("test");
 
-enableAccessibility();
-testInput.focus();
+test(function(t) {
+    testInput.focus();
+    assert_equals(focusedElementDescription(),
+                  'Hours TestLabel, --, "12", TestTitle, intValue:12, range:1-12');
+    keyDown('\t');
+    assert_equals(focusedElementDescription(),
+                  'Minutes TestLabel, --, "34", TestTitle, intValue:34, range:0-59');
+    keyDown('\t');
+    assert_equals(focusedElementDescription(),
+                  'Seconds TestLabel, --, "56", TestTitle, intValue:56, range:0-59');
+    keyDown('\t');
+    assert_equals(focusedElementDescription(),
+                  'Milliseconds TestLabel, ---, "789", TestTitle, intValue:789, range:0-999');
+    keyDown('\t');
+    assert_equals(focusedElementDescription(),
+                  'AM/PM TestLabel, --, "PM", TestTitle, intValue:2, range:1-2');
+}, 'Non-empty value');
 
-debug('Non-empty value');
-testInput.focus();
-checkFocusedElementAXAttributes('Hours, AXValueDescription: 12, intValue:12, range:1-12');
-keyDown('\t');
-checkFocusedElementAXAttributes('Minutes, AXValueDescription: 34, intValue:34, range:0-59');
-keyDown('\t');
-checkFocusedElementAXAttributes('Seconds, AXValueDescription: 56, intValue:56, range:0-59');
-keyDown('\t');
-checkFocusedElementAXAttributes('Milliseconds, AXValueDescription: 789, intValue:789, range:0-999');
-keyDown('\t');
-checkFocusedElementAXAttributes('AM/PM, AXValueDescription: PM, intValue:2, range:1-2');
+test(function(t) {
+    keyDown('Backspace');
+    assert_equals(focusedElementDescription(),
+                  'AM/PM TestLabel, --, "", TestTitle, intValue:0, range:1-2');
+    keyDown('\t', ['shiftKey']);
+    keyDown('Backspace');
+    assert_equals(focusedElementDescription(),
+                  'Milliseconds TestLabel, ---, "", TestTitle, intValue:0, range:0-999');
+    keyDown('\t', ['shiftKey']);
+    keyDown('Backspace');
+    assert_equals(focusedElementDescription(),
+                  'Seconds TestLabel, --, "", TestTitle, intValue:0, range:0-59');
+    keyDown('\t', ['shiftKey']);
+    keyDown('Backspace');
+    assert_equals(focusedElementDescription(),
+                  'Minutes TestLabel, --, "", TestTitle, intValue:0, range:0-59');
+    keyDown('\t', ['shiftKey']);
+    keyDown('Backspace');
+    assert_equals(focusedElementDescription(),
+                  'Hours TestLabel, --, "", TestTitle, intValue:0, range:1-12');
+}, 'Empty value');
 
-debug('Empty value');
-keyDown('Backspace');
-checkFocusedElementAXAttributes('AM/PM, AXValueDescription: --, intValue:0, range:1-2');
-keyDown('\t', ['shiftKey']);
-keyDown('Backspace');
-checkFocusedElementAXAttributes('Milliseconds, AXValueDescription: ---, intValue:0, range:0-999');
-keyDown('\t', ['shiftKey']);
-keyDown('Backspace');
-checkFocusedElementAXAttributes('Seconds, AXValueDescription: --, intValue:0, range:0-59');
-keyDown('\t', ['shiftKey']);
-keyDown('Backspace');
-checkFocusedElementAXAttributes('Minutes, AXValueDescription: --, intValue:0, range:0-59');
-keyDown('\t', ['shiftKey']);
-keyDown('Backspace');
-checkFocusedElementAXAttributes('Hours, AXValueDescription: --, intValue:0, range:1-12');
-
-debug('');
-testInput.parentNode.removeChild(testInput);
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification-expected.txt
index 2c8451abc..05189492 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification-expected.txt
@@ -3,12 +3,12 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focus Hours=AXValueDescription: 12
-Focus Minutes=AXValueDescription: 34
-ValueChanged Minutes=AXValueDescription: 05
-ValueChanged Minutes=AXValueDescription: 05
-ValueChanged Minutes=AXValueDescription: 05
-ValueChanged Minutes=AXValueDescription: 05
+Focus Hours=12
+Focus Minutes=34
+ValueChanged Minutes=05
+ValueChanged Minutes=05
+ValueChanged Minutes=05
+ValueChanged Minutes=05
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
index 4b04f96..bbf579f 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-ax-value-changed-notification.html
@@ -17,7 +17,7 @@
 
     accessibilityController.addNotificationListener(function (element, notification) {
         if (notification == 'Focus' || notification == 'ValueChanged') {
-            debug(notification + ' ' + element.description + '=' + element.valueDescription);
+            debug(notification + ' ' + element.name.trim() + '=' + element.valueDescription.substr(20));
         }
     });
 }
diff --git a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes-expected.txt
deleted file mode 100644
index 5bf7356..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-This test checks aria-help attribute of fields in multiple fields week input UI.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Non-empty value
-PASS focusedFieldValueDescription() is "Week, AXValueDescription: 10, 1, 53"
-PASS focusedFieldValueDescription() is "Year, AXValueDescription: 2012, 1, 275760"
-Empty value
-PASS focusedFieldValueDescription() is "Year, AXValueDescription: ----, 1, 275760"
-PASS focusedFieldValueDescription() is "Week, AXValueDescription: --, 1, 53"
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes.html b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes.html
index e03b888..0ae2201 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-aria-attributes.html
@@ -1,40 +1,34 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/multiple-fields-ax-aria-attributes.js"></script>
 </head>
 <body>
-<input id="test" type="week" value="2012-W10">
+<input id="test" type="week" value="2012-W10" aria-label="TestLabel" title="TestTitle">
 <script>
-description('This test checks aria-help attribute of fields in multiple fields week input UI.');
-
-function focusedFieldValueDescription()
-{
-    var element = accessibilityController.focusedElement;
-    return element.description + ', ' +  element.valueDescription + ', ' + element.minValue + ', ' + element.maxValue;
-}
-
 var testInput = document.getElementById('test');
 
-if (!window.accessibilityController || !window.eventSender)
-    debug('Please run inside DRT or WTR.');
-else {
-    debug('Non-empty value');
+test(function(t) {
     testInput.focus();
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Week, AXValueDescription: 10, 1, 53');
+    assert_equals(focusedElementDescription(),
+                  'Week TestLabel, --, "10", TestTitle, intValue:10, range:1-53');
     eventSender.keyDown('\t');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Year, AXValueDescription: 2012, 1, 275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, ----, "2012", TestTitle, intValue:2012, range:1-275760');
+}, 'Non-empty value');
 
-    debug('Empty value');
+test(function(t) {
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Year, AXValueDescription: ----, 1, 275760');
+    assert_equals(focusedElementDescription(),
+                  'Year TestLabel, ----, "", TestTitle, intValue:0, range:1-275760');
     eventSender.keyDown('\t', ['shiftKey']);
     eventSender.keyDown('Backspace');
-    shouldBeEqualToString('focusedFieldValueDescription()', 'Week, AXValueDescription: --, 1, 53');
+    assert_equals(focusedElementDescription(),
+                  'Week TestLabel, --, "", TestTitle, intValue:0, range:1-53');
+}, 'Empty value');
 
-    debug('');
-    testInput.remove();
-}
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification-expected.txt
index 6df1b1b..01454ff 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification-expected.txt
@@ -3,12 +3,12 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Focus Week=AXValueDescription: 10
-Focus Year=AXValueDescription: 2012
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
-ValueChanged Year=AXValueDescription: 0005
+Focus Week=10
+Focus Year=2012
+ValueChanged Year=0005
+ValueChanged Year=0005
+ValueChanged Year=0005
+ValueChanged Year=0005
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
index 20b083e..ee0df823 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/week-multiple-fields/week-multiple-fields-ax-value-changed-notification.html
@@ -15,7 +15,7 @@
 else {
     accessibilityController.addNotificationListener(function (element, notification) {
         if (notification == 'Focus' || notification == 'ValueChanged') {
-            debug(notification + ' ' + element.description + '=' + element.valueDescription);
+            debug(notification + ' ' + element.name.trim() + '=' + element.valueDescription.substr(20));
         }
     });
 
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
deleted file mode 100644
index 920160da..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ /dev/null
@@ -1,582 +0,0 @@
-This is a testharness.js-based test.
-Found 578 tests; 401 PASS, 177 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup
-PASS align-content (type: discrete) has testAccumulation function
-PASS align-content: "flex-end" onto "flex-start"
-PASS align-content: "flex-start" onto "flex-end"
-PASS align-items (type: discrete) has testAccumulation function
-PASS align-items: "flex-end" onto "flex-start"
-PASS align-items: "flex-start" onto "flex-end"
-PASS align-self (type: discrete) has testAccumulation function
-PASS align-self: "flex-end" onto "flex-start"
-PASS align-self: "flex-start" onto "flex-end"
-PASS backface-visibility (type: discrete) has testAccumulation function
-PASS backface-visibility: "hidden" onto "visible"
-PASS backface-visibility: "visible" onto "hidden"
-PASS background-attachment (type: discrete) has testAccumulation function
-PASS background-attachment: "local" onto "fixed"
-PASS background-attachment: "fixed" onto "local"
-PASS background-color (type: color) has testAccumulation function
-FAIL background-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL background-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL background-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL background-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL background-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL background-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS background-blend-mode (type: discrete) has testAccumulation function
-PASS background-blend-mode: "screen" onto "multiply"
-PASS background-blend-mode: "multiply" onto "screen"
-PASS background-clip (type: discrete) has testAccumulation function
-PASS background-clip: "content-box" onto "padding-box"
-PASS background-clip: "padding-box" onto "content-box"
-PASS background-image (type: discrete) has testAccumulation function
-PASS background-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS background-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS background-origin (type: discrete) has testAccumulation function
-PASS background-origin: "content-box" onto "padding-box"
-PASS background-origin: "padding-box" onto "content-box"
-PASS background-repeat (type: discrete) has testAccumulation function
-PASS background-repeat: "round" onto "space"
-PASS background-repeat: "space" onto "round"
-PASS border-bottom-color (type: color) has testAccumulation function
-FAIL border-bottom-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-bottom-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-bottom-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-bottom-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-bottom-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-bottom-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS border-bottom-style (type: discrete) has testAccumulation function
-PASS border-bottom-style: "solid" onto "dotted"
-PASS border-bottom-style: "dotted" onto "solid"
-PASS border-bottom-width (type: length) has testAccumulation function
-FAIL border-bottom-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL border-bottom-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS border-collapse (type: discrete) has testAccumulation function
-PASS border-collapse: "separate" onto "collapse"
-PASS border-collapse: "collapse" onto "separate"
-PASS border-image-outset (type: discrete) has testAccumulation function
-PASS border-image-outset: "5 6 7 8" onto "1 2 3 4"
-PASS border-image-outset: "1 2 3 4" onto "5 6 7 8"
-PASS border-image-repeat (type: discrete) has testAccumulation function
-FAIL border-image-repeat: "repeat repeat" onto "stretch stretch" assert_equals: The value should be repeat repeat at 0ms expected "repeat repeat" but got "repeat"
-FAIL border-image-repeat: "stretch stretch" onto "repeat repeat" assert_equals: The value should be stretch stretch at 0ms expected "stretch stretch" but got "stretch"
-PASS border-image-slice (type: discrete) has testAccumulation function
-PASS border-image-slice: "5 6 7 8" onto "1 2 3 4"
-PASS border-image-slice: "1 2 3 4" onto "5 6 7 8"
-PASS border-image-source (type: discrete) has testAccumulation function
-PASS border-image-source: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS border-image-source: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS border-image-width (type: discrete) has testAccumulation function
-PASS border-image-width: "5 6 7 8" onto "1 2 3 4"
-PASS border-image-width: "1 2 3 4" onto "5 6 7 8"
-PASS border-left-color (type: color) has testAccumulation function
-FAIL border-left-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-left-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-left-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-left-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-left-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-left-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS border-left-style (type: discrete) has testAccumulation function
-PASS border-left-style: "solid" onto "dotted"
-PASS border-left-style: "dotted" onto "solid"
-PASS border-left-width (type: length) has testAccumulation function
-FAIL border-left-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL border-left-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS border-right-color (type: color) has testAccumulation function
-FAIL border-right-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-right-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-right-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-right-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-right-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-right-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS border-right-style (type: discrete) has testAccumulation function
-PASS border-right-style: "solid" onto "dotted"
-PASS border-right-style: "dotted" onto "solid"
-PASS border-right-width (type: length) has testAccumulation function
-FAIL border-right-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL border-right-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS border-spacing (type: lengthPair) has testAccumulation function
-FAIL border-spacing: length pair assert_equals: The value should be 20px 20px at 0ms expected "20px 20px" but got "10px 10px"
-FAIL border-spacing: length pair of rem assert_equals: The value should be 20px 20px at 0ms expected "20px 20px" but got "10px 10px"
-PASS border-top-color (type: color) has testAccumulation function
-FAIL border-top-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-top-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-top-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL border-top-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-top-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL border-top-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS border-top-style (type: discrete) has testAccumulation function
-PASS border-top-style: "solid" onto "dotted"
-PASS border-top-style: "dotted" onto "solid"
-PASS border-top-width (type: length) has testAccumulation function
-FAIL border-top-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL border-top-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS box-shadow (type: boxShadowList) has testAccumulation function
-FAIL box-shadow: shadow assert_equals: The value should be rgb(240, 240, 240) 20px 20px 20px 20px at 0ms expected "rgb(240, 240, 240) 20px 20px 20px 20px" but got "rgb(120, 120, 120) 10px 10px 10px 10px"
-PASS box-sizing (type: discrete) has testAccumulation function
-PASS box-sizing: "border-box" onto "content-box"
-PASS box-sizing: "content-box" onto "border-box"
-PASS caption-side (type: discrete) has testAccumulation function
-PASS caption-side: "bottom" onto "top"
-PASS caption-side: "top" onto "bottom"
-PASS caret-color (type: color) has testAccumulation function
-FAIL caret-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL caret-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL caret-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL caret-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL caret-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL caret-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS clear (type: discrete) has testAccumulation function
-PASS clear: "right" onto "left"
-PASS clear: "left" onto "right"
-PASS clip (type: rect) has testAccumulation function
-FAIL clip: rect assert_equals: The value should be rect(110px, 110px, 110px, 110px) at 0ms expected "rect(110px, 110px, 110px, 110px)" but got "rect(10px, 10px, 10px, 10px)"
-PASS clip (type: discrete) has testAccumulation function
-PASS clip: "auto" onto "rect(10px, 10px, 10px, 10px)"
-PASS clip: "rect(10px, 10px, 10px, 10px)" onto "auto"
-PASS clip: "rect(10px, 10px, 10px, auto)" onto "rect(10px, 10px, 10px, 10px)"
-PASS clip: "rect(10px, 10px, 10px, 10px)" onto "rect(10px, 10px, 10px, auto)"
-PASS clip-rule (type: discrete) has testAccumulation function
-PASS clip-rule: "nonzero" onto "evenodd"
-PASS clip-rule: "evenodd" onto "nonzero"
-PASS color (type: color) has testAccumulation function
-FAIL color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS color-interpolation (type: discrete) has testAccumulation function
-PASS color-interpolation: "auto" onto "linearRGB"
-FAIL color-interpolation: "linearRGB" onto "auto" assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-PASS color-interpolation-filters (type: discrete) has testAccumulation function
-FAIL color-interpolation-filters: "linearRGB" onto "sRGB" assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-FAIL color-interpolation-filters: "sRGB" onto "linearRGB" assert_equals: The value should be srgb at 0ms expected "srgb" but got "sRGB"
-PASS column-count (type: positiveInteger) has testAccumulation function
-FAIL column-count: positive integer assert_equals: The value should be 3 at 0ms expected "3" but got "2"
-PASS column-count (type: discrete) has testAccumulation function
-PASS column-count: "10" onto "auto"
-PASS column-count: "auto" onto "10"
-PASS column-gap (type: length) has testAccumulation function
-FAIL column-gap: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL column-gap: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS column-gap (type: discrete) has testAccumulation function
-PASS column-gap: "200px" onto "normal"
-PASS column-gap: "normal" onto "200px"
-PASS column-rule-color (type: color) has testAccumulation function
-FAIL column-rule-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL column-rule-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL column-rule-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL column-rule-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL column-rule-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL column-rule-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS column-fill (type: discrete) has testAccumulation function
-PASS column-fill: "balance" onto "auto"
-PASS column-fill: "auto" onto "balance"
-PASS column-rule-style (type: discrete) has testAccumulation function
-PASS column-rule-style: "dotted" onto "none"
-PASS column-rule-style: "none" onto "dotted"
-PASS column-rule-width (type: length) has testAccumulation function
-FAIL column-rule-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL column-rule-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS column-width (type: length) has testAccumulation function
-FAIL column-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL column-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS column-width (type: discrete) has testAccumulation function
-PASS column-width: "1px" onto "auto"
-PASS column-width: "auto" onto "1px"
-PASS contain (type: discrete) has testAccumulation function
-PASS contain: "none" onto "strict"
-PASS contain: "strict" onto "none"
-PASS content (type: discrete) has testAccumulation function
-PASS content: ""b"" onto ""a""
-PASS content: ""a"" onto ""b""
-PASS counter-increment (type: discrete) has testAccumulation function
-PASS counter-increment: "ident-2 2" onto "ident-1 1"
-PASS counter-increment: "ident-1 1" onto "ident-2 2"
-PASS counter-reset (type: discrete) has testAccumulation function
-PASS counter-reset: "ident-2 2" onto "ident-1 1"
-PASS counter-reset: "ident-1 1" onto "ident-2 2"
-PASS cursor (type: discrete) has testAccumulation function
-PASS cursor: "wait" onto "pointer"
-PASS cursor: "pointer" onto "wait"
-PASS dominant-baseline (type: discrete) has testAccumulation function
-PASS dominant-baseline: "alphabetic" onto "ideographic"
-PASS dominant-baseline: "ideographic" onto "alphabetic"
-PASS empty-cells (type: discrete) has testAccumulation function
-PASS empty-cells: "hide" onto "show"
-PASS empty-cells: "show" onto "hide"
-PASS fill-opacity (type: opacity) has testAccumulation function
-FAIL fill-opacity: [0, 1] number assert_equals: The value should be 0.6 at 0ms expected "0.6" but got "0.3"
-FAIL fill-opacity: [0, 1] number (clamped) assert_equals: The value should be 1 at 0ms expected "1" but got "0.3"
-PASS fill-rule (type: discrete) has testAccumulation function
-PASS fill-rule: "nonzero" onto "evenodd"
-PASS fill-rule: "evenodd" onto "nonzero"
-PASS filter (type: filterList) has testAccumulation function
-FAIL filter: same ordered filter functions assert_equals: The value should be blur(30px) brightness(0) at 0ms expected "blur(30px) brightness(0)" but got "blur(20px) brightness(0.1)"
-PASS filter: mismatched ordered filter functions
-PASS flex-basis (type: lengthPercentageOrCalc) has testAccumulation function
-PASS flex-basis: length
-PASS flex-basis: length of rem
-PASS flex-basis: percentage
-FAIL flex-basis: units "%" onto "px" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10%"
-FAIL flex-basis: units "px" onto "%" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10px"
-FAIL flex-basis: units "rem" onto "%" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "20px"
-FAIL flex-basis: units "%" onto "rem" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "10%"
-FAIL flex-basis: units "rem" onto "em" assert_equals: The value should be 40px at 0ms expected "40px" but got "20px"
-FAIL flex-basis: units "em" onto "rem" assert_equals: The value should be 40px at 0ms expected "40px" but got "20px"
-FAIL flex-basis: units "calc" onto "px" assert_equals: The value should be calc(30px + 20%) at 0ms expected "calc(30px + 20%)" but got "calc(20px + 20%)"
-FAIL flex-basis: calc assert_equals: The value should be calc(30px + 30%) at 0ms expected "calc(30px + 30%)" but got "calc(20px + 20%)"
-PASS flex-basis (type: discrete) has testAccumulation function
-PASS flex-basis: "10px" onto "auto"
-PASS flex-basis: "auto" onto "10px"
-PASS flex-direction (type: discrete) has testAccumulation function
-PASS flex-direction: "row-reverse" onto "row"
-PASS flex-direction: "row" onto "row-reverse"
-PASS flex-grow (type: positiveNumber) has testAccumulation function
-FAIL flex-grow: positive number assert_equals: The value should be 2.2 at 0ms expected "2.2" but got "1.1"
-PASS flex-shrink (type: positiveNumber) has testAccumulation function
-FAIL flex-shrink: positive number assert_equals: The value should be 2.2 at 0ms expected "2.2" but got "1.1"
-PASS flex-wrap (type: discrete) has testAccumulation function
-PASS flex-wrap: "wrap" onto "nowrap"
-PASS flex-wrap: "nowrap" onto "wrap"
-PASS flood-color (type: color) has testAccumulation function
-FAIL flood-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL flood-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL flood-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL flood-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL flood-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL flood-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS flood-opacity (type: opacity) has testAccumulation function
-FAIL flood-opacity: [0, 1] number assert_equals: The value should be 0.6 at 0ms expected "0.6" but got "0.3"
-FAIL flood-opacity: [0, 1] number (clamped) assert_equals: The value should be 1 at 0ms expected "1" but got "0.3"
-PASS font-stretch (type: percentage) has testAccumulation function
-FAIL font-stretch: percentage assert_equals: The value should be 130% at 0ms expected "130%" but got "70%"
-PASS font-style (type: discrete) has testAccumulation function
-FAIL font-style: "oblique" onto "italic" assert_equals: The value should be oblique at 0ms expected "oblique" but got "italic"
-PASS font-style: "italic" onto "oblique"
-PASS float (type: discrete) has testAccumulation function
-PASS float: "right" onto "left"
-PASS float: "left" onto "right"
-PASS font-family (type: discrete) has testAccumulation function
-PASS font-family: "verdana" onto "helvetica"
-PASS font-family: "helvetica" onto "verdana"
-PASS font-feature-settings (type: discrete) has testAccumulation function
-PASS font-feature-settings: "normal" onto ""liga" 5"
-PASS font-feature-settings: ""liga" 5" onto "normal"
-PASS font-kerning (type: discrete) has testAccumulation function
-PASS font-kerning: "normal" onto "auto"
-PASS font-kerning: "auto" onto "normal"
-PASS font-variant-caps (type: discrete) has testAccumulation function
-PASS font-variant-caps: "unicase" onto "small-caps"
-PASS font-variant-caps: "small-caps" onto "unicase"
-PASS font-variant-east-asian (type: discrete) has testAccumulation function
-PASS font-variant-east-asian: "proportional-width" onto "full-width"
-PASS font-variant-east-asian: "full-width" onto "proportional-width"
-PASS font-variant-ligatures (type: discrete) has testAccumulation function
-PASS font-variant-ligatures: "no-common-ligatures" onto "common-ligatures"
-PASS font-variant-ligatures: "common-ligatures" onto "no-common-ligatures"
-PASS font-variant-numeric (type: discrete) has testAccumulation function
-PASS font-variant-numeric: "oldstyle-nums" onto "lining-nums"
-PASS font-variant-numeric: "lining-nums" onto "oldstyle-nums"
-PASS font-variation-settings (type: fontVariationSettings) has testAccumulation function
-FAIL font-variation-settings with composite type accumulate assert_equals: The value should be "wght" 2.2 at 250ms expected "\"wght\" 2.2" but got "\"wght\" 1.2"
-PASS font-variation-settings (type: discrete) has testAccumulation function
-PASS font-variation-settings: ""wdth" 5" onto ""wght" 1.1, "wdth" 1"
-PASS font-variation-settings: ""wght" 1.1, "wdth" 1" onto ""wdth" 5"
-PASS font-variation-settings: "normal" onto ""wdth" 5"
-PASS font-variation-settings: ""wdth" 5" onto "normal"
-PASS grid-auto-columns (type: discrete) has testAccumulation function
-PASS grid-auto-columns: "5px" onto "1px"
-PASS grid-auto-columns: "1px" onto "5px"
-PASS grid-auto-flow (type: discrete) has testAccumulation function
-PASS grid-auto-flow: "column" onto "row"
-PASS grid-auto-flow: "row" onto "column"
-PASS grid-auto-rows (type: discrete) has testAccumulation function
-PASS grid-auto-rows: "5px" onto "1px"
-PASS grid-auto-rows: "1px" onto "5px"
-PASS grid-column-end (type: discrete) has testAccumulation function
-PASS grid-column-end: "5" onto "1"
-PASS grid-column-end: "1" onto "5"
-PASS grid-column-start (type: discrete) has testAccumulation function
-PASS grid-column-start: "5" onto "1"
-PASS grid-column-start: "1" onto "5"
-PASS grid-row-end (type: discrete) has testAccumulation function
-PASS grid-row-end: "5" onto "1"
-PASS grid-row-end: "1" onto "5"
-PASS grid-row-start (type: discrete) has testAccumulation function
-PASS grid-row-start: "5" onto "1"
-PASS grid-row-start: "1" onto "5"
-PASS grid-template-areas (type: discrete) has testAccumulation function
-PASS grid-template-areas: "none" onto "". . a b" ". .a b""
-FAIL grid-template-areas: "". . a b" ". .a b"" onto "none" assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
-PASS grid-template-columns (type: discrete) has testAccumulation function
-PASS grid-template-columns: "5px" onto "1px"
-PASS grid-template-columns: "1px" onto "5px"
-PASS grid-template-rows (type: discrete) has testAccumulation function
-PASS grid-template-rows: "5px" onto "1px"
-PASS grid-template-rows: "1px" onto "5px"
-PASS hyphens (type: discrete) has testAccumulation function
-PASS hyphens: "auto" onto "manual"
-PASS hyphens: "manual" onto "auto"
-PASS image-orientation (type: discrete) has testAccumulation function
-FAIL image-orientation: "90deg" onto "0deg" assert_equals: The value should be 90deg at 0ms expected "90deg" but got "0deg"
-PASS image-orientation: "0deg" onto "90deg"
-PASS isolation (type: discrete) has testAccumulation function
-PASS isolation: "isolate" onto "auto"
-PASS isolation: "auto" onto "isolate"
-PASS justify-content (type: discrete) has testAccumulation function
-PASS justify-content: "end" onto "start"
-PASS justify-content: "start" onto "end"
-PASS justify-items (type: discrete) has testAccumulation function
-PASS justify-items: "end" onto "start"
-PASS justify-items: "start" onto "end"
-PASS justify-self (type: discrete) has testAccumulation function
-PASS justify-self: "end" onto "start"
-PASS justify-self: "start" onto "end"
-PASS letter-spacing (type: length) has testAccumulation function
-FAIL letter-spacing: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL letter-spacing: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS lighting-color (type: color) has testAccumulation function
-FAIL lighting-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL lighting-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL lighting-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL lighting-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL lighting-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL lighting-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS list-style-image (type: discrete) has testAccumulation function
-PASS list-style-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS list-style-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS list-style-position (type: discrete) has testAccumulation function
-PASS list-style-position: "outside" onto "inside"
-PASS list-style-position: "inside" onto "outside"
-PASS list-style-type (type: discrete) has testAccumulation function
-PASS list-style-type: "square" onto "circle"
-PASS list-style-type: "circle" onto "square"
-PASS marker-end (type: discrete) has testAccumulation function
-PASS marker-end: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-end: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS marker-mid (type: discrete) has testAccumulation function
-PASS marker-mid: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-mid: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS marker-start (type: discrete) has testAccumulation function
-PASS marker-start: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-start: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS mask (type: discrete) has testAccumulation function
-PASS mask: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS mask: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS mask-type (type: discrete) has testAccumulation function
-PASS mask-type: "luminance" onto "alpha"
-PASS mask-type: "alpha" onto "luminance"
-PASS mix-blend-mode (type: discrete) has testAccumulation function
-PASS mix-blend-mode: "screen" onto "multiply"
-PASS mix-blend-mode: "multiply" onto "screen"
-PASS object-fit (type: discrete) has testAccumulation function
-PASS object-fit: "contain" onto "fill"
-PASS object-fit: "fill" onto "contain"
-PASS order (type: integer) has testAccumulation function
-FAIL order: integer assert_equals: The value should be -3 at 0ms expected "-3" but got "-2"
-PASS outline-color (type: color) has testAccumulation function
-FAIL outline-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL outline-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL outline-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL outline-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL outline-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL outline-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS outline-offset (type: length) has testAccumulation function
-FAIL outline-offset: length assert_equals: The value should be 20px at 0ms expected "20px" but got "0px"
-FAIL outline-offset: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "0px"
-PASS outline-style (type: discrete) has testAccumulation function
-PASS outline-style: "dotted" onto "none"
-PASS outline-style: "none" onto "dotted"
-PASS outline-width (type: length) has testAccumulation function
-FAIL outline-width: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL outline-width: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS overflow-wrap (type: discrete) has testAccumulation function
-PASS overflow-wrap: "break-word" onto "normal"
-PASS overflow-wrap: "normal" onto "break-word"
-PASS overflow-x (type: discrete) has testAccumulation function
-PASS overflow-x: "hidden" onto "visible"
-PASS overflow-x: "visible" onto "hidden"
-PASS overflow-y (type: discrete) has testAccumulation function
-PASS overflow-y: "hidden" onto "visible"
-PASS overflow-y: "visible" onto "hidden"
-PASS page-break-after (type: discrete) has testAccumulation function
-PASS page-break-after: "auto" onto "always"
-PASS page-break-after: "always" onto "auto"
-PASS page-break-before (type: discrete) has testAccumulation function
-PASS page-break-before: "auto" onto "always"
-PASS page-break-before: "always" onto "auto"
-PASS page-break-inside (type: discrete) has testAccumulation function
-PASS page-break-inside: "avoid" onto "auto"
-PASS page-break-inside: "auto" onto "avoid"
-PASS paint-order (type: discrete) has testAccumulation function
-FAIL paint-order: "stroke" onto "fill" assert_equals: The value should be stroke at 0ms expected "stroke" but got "stroke fill markers"
-FAIL paint-order: "fill" onto "stroke" assert_equals: The value should be fill at 0ms expected "fill" but got "fill stroke markers"
-PASS perspective (type: length) has testAccumulation function
-FAIL perspective: length assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-FAIL perspective: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "10px"
-PASS perspective-origin (type: position) has testAccumulation function
-PASS perspective-origin: length pair
-PASS perspective-origin: length pair of rem
-FAIL perspective-origin: position of percentage assert_equals: The value should be 1019.19px 0px at 0ms expected "1019.19px 0px" but got "548.797px 0px"
-PASS pointer-events (type: discrete) has testAccumulation function
-PASS pointer-events: "none" onto "fill"
-PASS pointer-events: "fill" onto "none"
-PASS position (type: discrete) has testAccumulation function
-PASS position: "fixed" onto "absolute"
-PASS position: "absolute" onto "fixed"
-PASS quotes (type: discrete) has testAccumulation function
-PASS quotes: ""‘" "’" "“" "”"" onto ""“" "”" "‘" "’""
-PASS quotes: ""“" "”" "‘" "’"" onto ""‘" "’" "“" "”""
-PASS resize (type: discrete) has testAccumulation function
-PASS resize: "horizontal" onto "both"
-PASS resize: "both" onto "horizontal"
-PASS scroll-behavior (type: discrete) has testAccumulation function
-PASS scroll-behavior: "smooth" onto "auto"
-PASS scroll-behavior: "auto" onto "smooth"
-PASS shape-outside (type: discrete) has testAccumulation function
-PASS shape-outside: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS shape-outside: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS shape-rendering (type: discrete) has testAccumulation function
-FAIL shape-rendering: "crispEdges" onto "optimizeSpeed" assert_equals: The value should be crispedges at 0ms expected "crispedges" but got "crispEdges"
-FAIL shape-rendering: "optimizeSpeed" onto "crispEdges" assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS stop-color (type: color) has testAccumulation function
-FAIL stop-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL stop-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL stop-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL stop-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL stop-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL stop-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS stop-opacity (type: opacity) has testAccumulation function
-FAIL stop-opacity: [0, 1] number assert_equals: The value should be 0.6 at 0ms expected "0.6" but got "0.3"
-FAIL stop-opacity: [0, 1] number (clamped) assert_equals: The value should be 1 at 0ms expected "1" but got "0.3"
-PASS stroke-dasharray (type: dasharray) has testAccumulation function
-FAIL stroke-dasharray: dasharray assert_equals: The value should be 1, 2, 3, 4, 5 at 0ms expected "1, 2, 3, 4, 5" but got "1px, 2px, 3px, 4px, 5px"
-PASS stroke-dasharray (type: discrete) has testAccumulation function
-FAIL stroke-dasharray: "10, 20" onto "none" assert_equals: The value should be 10, 20 at 0ms expected "10, 20" but got "10px, 20px"
-PASS stroke-dasharray: "none" onto "10, 20"
-PASS stroke-linecap (type: discrete) has testAccumulation function
-PASS stroke-linecap: "square" onto "round"
-PASS stroke-linecap: "round" onto "square"
-PASS stroke-linejoin (type: discrete) has testAccumulation function
-PASS stroke-linejoin: "miter" onto "round"
-PASS stroke-linejoin: "round" onto "miter"
-PASS stroke-miterlimit (type: positiveNumber) has testAccumulation function
-FAIL stroke-miterlimit: positive number assert_equals: The value should be 2.2 at 0ms expected "2.2" but got "1.1"
-PASS stroke-opacity (type: opacity) has testAccumulation function
-FAIL stroke-opacity: [0, 1] number assert_equals: The value should be 0.6 at 0ms expected "0.6" but got "0.3"
-FAIL stroke-opacity: [0, 1] number (clamped) assert_equals: The value should be 1 at 0ms expected "1" but got "0.3"
-PASS table-layout (type: discrete) has testAccumulation function
-PASS table-layout: "fixed" onto "auto"
-PASS table-layout: "auto" onto "fixed"
-PASS text-align (type: discrete) has testAccumulation function
-PASS text-align: "end" onto "start"
-PASS text-align: "start" onto "end"
-PASS text-align-last (type: discrete) has testAccumulation function
-PASS text-align-last: "end" onto "start"
-PASS text-align-last: "start" onto "end"
-PASS text-anchor (type: discrete) has testAccumulation function
-PASS text-anchor: "end" onto "middle"
-PASS text-anchor: "middle" onto "end"
-PASS text-combine-upright (type: discrete) has testAccumulation function
-PASS text-combine-upright: "none" onto "all"
-PASS text-combine-upright: "all" onto "none"
-PASS text-decoration-color (type: color) has testAccumulation function
-FAIL text-decoration-color supports animating as color of rgb() with overflowed  from and to values assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL text-decoration-color supports animating as color of #RGB assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL text-decoration-color supports animating as color of hsl() assert_equals: The value should be rgb(255, 128, 128) at 0ms expected "rgb(255, 128, 128)" but got "rgb(255, 0, 0)"
-FAIL text-decoration-color supports animating as color of #RGBa assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL text-decoration-color supports animating as color of rgba() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-FAIL text-decoration-color supports animating as color of hsla() assert_equals: The value should be rgb(230, 128, 128) at 0ms expected "rgb(230, 128, 128)" but got "rgba(255, 0, 0, 0.4)"
-PASS text-decoration-line (type: discrete) has testAccumulation function
-PASS text-decoration-line: "overline" onto "underline"
-PASS text-decoration-line: "underline" onto "overline"
-PASS text-decoration-style (type: discrete) has testAccumulation function
-PASS text-decoration-style: "dotted" onto "solid"
-PASS text-decoration-style: "solid" onto "dotted"
-PASS text-orientation (type: discrete) has testAccumulation function
-PASS text-orientation: "sideways" onto "upright"
-PASS text-orientation: "upright" onto "sideways"
-PASS text-overflow (type: discrete) has testAccumulation function
-PASS text-overflow: "ellipsis" onto "clip"
-PASS text-overflow: "clip" onto "ellipsis"
-PASS text-rendering (type: discrete) has testAccumulation function
-FAIL text-rendering: "optimizeLegibility" onto "optimizeSpeed" assert_equals: The value should be optimizelegibility at 0ms expected "optimizelegibility" but got "optimizeLegibility"
-FAIL text-rendering: "optimizeSpeed" onto "optimizeLegibility" assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS text-shadow (type: textShadowList) has testAccumulation function
-FAIL text-shadow: shadow assert_equals: The value should be rgb(240, 240, 240) 20px 20px 20px at 0ms expected "rgb(240, 240, 240) 20px 20px 20px" but got "rgb(120, 120, 120) 10px 10px 10px"
-PASS text-transform (type: discrete) has testAccumulation function
-PASS text-transform: "uppercase" onto "capitalize"
-PASS text-transform: "capitalize" onto "uppercase"
-PASS touch-action (type: discrete) has testAccumulation function
-PASS touch-action: "none" onto "auto"
-PASS touch-action: "auto" onto "none"
-PASS transform (type: transformList) has testAccumulation function
-FAIL transform: translate assert_approx_equals: expected matrix(1,0,0,1,-100,0) but got matrix(1, 0, 0, 1, -200, 0): The value should be matrix(1,0,0,1,-100,0) at 0ms but got matrix(1, 0, 0, 1, -200, 0) expected -100 +/- 0.0001 but got -200
-FAIL transform: rotate assert_approx_equals: expected matrix(0.7071067811865476,-0.7071067811865475,0.7071067811865475,0.7071067811865476,0,0) but got matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0): The value should be matrix(0.7071067811865476,-0.7071067811865475,0.7071067811865475,0.7071067811865476,0,0) at 0ms but got matrix(6.12323e-17, -1, 1, 6.12323e-17, 0, 0) expected 0.7071067811865476 +/- 0.0001 but got 6.12323e-17
-FAIL transform: scale assert_approx_equals: expected matrix(-2,0,0,-2,0,0) but got matrix(-3, 0, 0, -3, 0, 0): The value should be matrix(-2,0,0,-2,0,0) at 0ms but got matrix(-3, 0, 0, -3, 0, 0) expected -2 +/- 0.0001 but got -3
-FAIL transform: skew assert_approx_equals: expected matrix(1,0.5773502691896257,-0.36397023426620234,1,0,0) but got matrix(1, 0.36397, -0.57735, 1, 0, 0): The value should be matrix(1,0.5773502691896257,-0.36397023426620234,1,0,0) at 0ms but got matrix(1, 0.36397, -0.57735, 1, 0, 0) expected 0.5773502691896257 +/- 0.0001 but got 0.36397
-FAIL transform: rotate on translate assert_approx_equals: expected matrix(0,1,-1,0,100,0) but got matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0): The value should be matrix(0,1,-1,0,100,0) at 0ms but got matrix(6.12323e-17, 1, -1, 6.12323e-17, 0, 0) expected 100 +/- 0.0001 but got 0
-FAIL transform: translate on rotate assert_approx_equals: expected matrix(0,1,-1,0,100,0) but got matrix(1, 0, 0, 1, 100, 0): The value should be matrix(0,1,-1,0,100,0) at 0ms but got matrix(1, 0, 0, 1, 100, 0) expected 0 +/- 0.0001 but got 1
-FAIL transform: rotate and translate on rotate assert_approx_equals: expected matrix(6.123233995736766e-17,1,-1,6.123233995736766e-17,0,0) but got matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 0): The value should be matrix(6.123233995736766e-17,1,-1,6.123233995736766e-17,0,0) at 0ms but got matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 0) expected 6.123233995736766e-17 +/- 0.0001 but got 0.707107
-FAIL transform: rotate on roate and translate assert_approx_equals: expected matrix(6.123233995736766e-17,1,-1,6.123233995736766e-17,6.123233995736766e-15,100) but got matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 0): The value should be matrix(6.123233995736766e-17,1,-1,6.123233995736766e-17,6.123233995736766e-15,100) at 0ms but got matrix(0.707107, 0.707107, -0.707107, 0.707107, 0, 0) expected 6.123233995736766e-17 +/- 0.0001 but got 0.707107
-FAIL transform: matrix assert_approx_equals: expected matrix(0,1,-1,0,100,0) but got matrix(1, 0, 0, 1, 100, 0): The value should be matrix(0,1,-1,0,100,0) at 0ms but got matrix(1, 0, 0, 1, 100, 0) expected 0 +/- 0.0001 but got 1
-FAIL transform: rotate3d assert_approx_equals: expected matrix3d(0.8535533905932737,0.1464466094067262,0.5,0,0.1464466094067262,0.8535533905932737,-0.5,0,-0.5,0.5,0.7071067811865476,0,0,0,0,1) but got matrix3d(0.5, 0.5, 0.707107, 0, 0.5, 0.5, -0.707107, 0, -0.707107, 0.707107, 6.12323e-17, 0, 0, 0, 0, 1): The value should be matrix3d(0.8535533905932737,0.1464466094067262,0.5,0,0.1464466094067262,0.8535533905932737,-0.5,0,-0.5,0.5,0.7071067811865476,0,0,0,0,1) at 0ms but got matrix3d(0.5, 0.5, 0.707107, 0, 0.5, 0.5, -0.707107, 0, -0.707107, 0.707107, 6.12323e-17, 0, 0, 0, 0, 1) expected 0.8535533905932737 +/- 0.0001 but got 0.5
-FAIL transform: matrix3d assert_approx_equals: expected matrix3d(0.8535533905932737,0.1464466094067262,0.5,0,0.1464466094067262,0.8535533905932737,-0.5,0,-0.5,0.5,0.7071067811865476,0,0,0,0,1) but got matrix3d(0.5, 0.5, 0.707107, 0, 0.5, 0.5, -0.707107, 0, -0.707107, 0.707107, 4.44089e-16, 0, 0, 0, 0, 1): The value should be matrix3d(0.8535533905932737,0.1464466094067262,0.5,0,0.1464466094067262,0.8535533905932737,-0.5,0,-0.5,0.5,0.7071067811865476,0,0,0,0,1) at 0ms but got matrix3d(0.5, 0.5, 0.707107, 0, 0.5, 0.5, -0.707107, 0, -0.707107, 0.707107, 4.44089e-16, 0, 0, 0, 0, 1) expected 0.8535533905932737 +/- 0.0001 but got 0.5
-FAIL transform: none assert_equals: dimension of the matrix: The value should be matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,1) at 0ms but got matrix(1, 0, 0, 1, 0, 0) expected 16 but got 6
-PASS transform: non-invertible matrices (non-invertible onto invertible)
-PASS transform: non-invertible matrices (invertible onto non-invertible)
-PASS transform: non-invertible matrices in matched transform lists (non-invertible onto invertible)
-PASS transform: non-invertible matrices in matched transform lists (invertible onto non-invertible)
-PASS transform: non-invertible matrices in mismatched transform lists (non-invertible onto invertible)
-PASS transform: non-invertible matrices in mismatched transform lists (invertible onto non-invertible)
-PASS transform-box (type: discrete) has testAccumulation function
-FAIL transform-box: "border-box" onto "fill-box" assert_equals: The value should be border-box at 0ms expected "border-box" but got "fill-box"
-PASS transform-box: "fill-box" onto "border-box"
-PASS transform-style (type: discrete) has testAccumulation function
-PASS transform-style: "preserve-3d" onto "flat"
-PASS transform-style: "flat" onto "preserve-3d"
-PASS rotate (type: rotateList) has testAccumulation function
-FAIL rotate without rotation axes assert_equals: The value should be -45deg at 0ms expected "-45deg" but got "-90deg"
-FAIL rotate with underlying transform assert_equals: The value should be 1 0 0 45deg at 0ms expected "1 0 0 45deg" but got "1 0 0 90deg"
-FAIL rotate with different rotation axes assert_approx_equals: expected 0.707107 0 0.707107 90deg but got 1 0 1 90deg: The value should be 0.707107 0 0.707107 90deg at 500ms but got 1 0 1 90deg expected 0.707107 +/- 0.0001 but got 1
-PASS translate (type: translateList) has testAccumulation function
-FAIL translate assert_equals: The value should be -100px at 0ms expected "-100px" but got "-200px"
-FAIL translate with transform assert_equals: The value should be -100px at 0ms expected "-100px" but got "-200px"
-PASS scale (type: scaleList) has testAccumulation function
-FAIL scale with two unspecified values assert_equals: The value should be -2 at 0ms expected "-2" but got "-3 1"
-FAIL scale with one unspecified value assert_equals: The value should be -2 -2 at 0ms expected "-2 -2" but got "-3 -3"
-FAIL scale assert_equals: The value should be 0 -1 -2 at 0ms expected "0 -1 -2" but got "-1 -2 -3"
-PASS unicode-bidi (type: discrete) has testAccumulation function
-PASS unicode-bidi: "bidi-override" onto "embed"
-PASS unicode-bidi: "embed" onto "bidi-override"
-PASS vector-effect (type: discrete) has testAccumulation function
-PASS vector-effect: "non-scaling-stroke" onto "none"
-PASS vector-effect: "none" onto "non-scaling-stroke"
-PASS visibility (type: visibility) has testAccumulation function
-FAIL visibility: onto "visible" assert_equals: The value should be visible at 1000ms expected "visible" but got "hidden"
-PASS visibility: onto "hidden"
-PASS white-space (type: discrete) has testAccumulation function
-PASS white-space: "nowrap" onto "pre"
-PASS white-space: "pre" onto "nowrap"
-PASS word-break (type: discrete) has testAccumulation function
-PASS word-break: "break-all" onto "keep-all"
-PASS word-break: "keep-all" onto "break-all"
-PASS word-spacing (type: lengthPercentageOrCalc) has testAccumulation function
-PASS word-spacing: length
-PASS word-spacing: length of rem
-FAIL word-spacing: percentage assert_equals: The value should be 130% at 0ms expected "130%" but got "0px"
-FAIL word-spacing: units "%" onto "px" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10px"
-FAIL word-spacing: units "px" onto "%" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10px"
-FAIL word-spacing: units "rem" onto "%" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "20px"
-FAIL word-spacing: units "%" onto "rem" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "20px"
-FAIL word-spacing: units "rem" onto "em" assert_equals: The value should be 40px at 0ms expected "40px" but got "20px"
-FAIL word-spacing: units "em" onto "rem" assert_equals: The value should be 40px at 0ms expected "40px" but got "20px"
-FAIL word-spacing: units "calc" onto "px" assert_equals: The value should be calc(30px + 20%) at 0ms expected "calc(30px + 20%)" but got "10px"
-FAIL word-spacing: calc assert_equals: The value should be calc(30px + 30%) at 0ms expected "calc(30px + 30%)" but got "0px"
-PASS will-change (type: discrete) has testAccumulation function
-PASS will-change: "contents" onto "scroll-position"
-PASS will-change: "scroll-position" onto "contents"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
deleted file mode 100644
index 0bdad94..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ /dev/null
@@ -1,578 +0,0 @@
-This is a testharness.js-based test.
-Found 574 tests; 532 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup
-PASS align-content (type: discrete) has testAddition function
-PASS align-content: "flex-end" onto "flex-start"
-PASS align-content: "flex-start" onto "flex-end"
-PASS align-items (type: discrete) has testAddition function
-PASS align-items: "flex-end" onto "flex-start"
-PASS align-items: "flex-start" onto "flex-end"
-PASS align-self (type: discrete) has testAddition function
-PASS align-self: "flex-end" onto "flex-start"
-PASS align-self: "flex-start" onto "flex-end"
-PASS backface-visibility (type: discrete) has testAddition function
-PASS backface-visibility: "hidden" onto "visible"
-PASS backface-visibility: "visible" onto "hidden"
-PASS background-attachment (type: discrete) has testAddition function
-PASS background-attachment: "local" onto "fixed"
-PASS background-attachment: "fixed" onto "local"
-PASS background-color (type: color) has testAddition function
-PASS background-color supports animating as color of rgb() with overflowed  from and to values
-PASS background-color supports animating as color of #RGB
-PASS background-color supports animating as color of hsl()
-PASS background-color supports animating as color of #RGBa
-PASS background-color supports animating as color of rgba()
-PASS background-color supports animating as color of hsla()
-PASS background-blend-mode (type: discrete) has testAddition function
-PASS background-blend-mode: "screen" onto "multiply"
-PASS background-blend-mode: "multiply" onto "screen"
-PASS background-clip (type: discrete) has testAddition function
-PASS background-clip: "content-box" onto "padding-box"
-PASS background-clip: "padding-box" onto "content-box"
-PASS background-image (type: discrete) has testAddition function
-PASS background-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS background-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS background-origin (type: discrete) has testAddition function
-PASS background-origin: "content-box" onto "padding-box"
-PASS background-origin: "padding-box" onto "content-box"
-PASS background-repeat (type: discrete) has testAddition function
-PASS background-repeat: "round" onto "space"
-PASS background-repeat: "space" onto "round"
-PASS border-bottom-color (type: color) has testAddition function
-PASS border-bottom-color supports animating as color of rgb() with overflowed  from and to values
-PASS border-bottom-color supports animating as color of #RGB
-PASS border-bottom-color supports animating as color of hsl()
-PASS border-bottom-color supports animating as color of #RGBa
-PASS border-bottom-color supports animating as color of rgba()
-PASS border-bottom-color supports animating as color of hsla()
-PASS border-bottom-style (type: discrete) has testAddition function
-PASS border-bottom-style: "solid" onto "dotted"
-PASS border-bottom-style: "dotted" onto "solid"
-PASS border-bottom-width (type: length) has testAddition function
-PASS border-bottom-width: length
-PASS border-bottom-width: length of rem
-PASS border-collapse (type: discrete) has testAddition function
-PASS border-collapse: "separate" onto "collapse"
-PASS border-collapse: "collapse" onto "separate"
-PASS border-image-outset (type: discrete) has testAddition function
-FAIL border-image-outset: "5 6 7 8" onto "1 2 3 4" assert_equals: The value should be 5 6 7 8 at 0ms expected "5 6 7 8" but got "6 8 10 12"
-FAIL border-image-outset: "1 2 3 4" onto "5 6 7 8" assert_equals: The value should be 1 2 3 4 at 0ms expected "1 2 3 4" but got "6 8 10 12"
-PASS border-image-repeat (type: discrete) has testAddition function
-FAIL border-image-repeat: "repeat repeat" onto "stretch stretch" assert_equals: The value should be repeat repeat at 0ms expected "repeat repeat" but got "repeat"
-FAIL border-image-repeat: "stretch stretch" onto "repeat repeat" assert_equals: The value should be stretch stretch at 0ms expected "stretch stretch" but got "stretch"
-PASS border-image-slice (type: discrete) has testAddition function
-FAIL border-image-slice: "5 6 7 8" onto "1 2 3 4" assert_equals: The value should be 5 6 7 8 at 0ms expected "5 6 7 8" but got "6 8 10 12"
-FAIL border-image-slice: "1 2 3 4" onto "5 6 7 8" assert_equals: The value should be 1 2 3 4 at 0ms expected "1 2 3 4" but got "6 8 10 12"
-PASS border-image-source (type: discrete) has testAddition function
-PASS border-image-source: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS border-image-source: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS border-image-width (type: discrete) has testAddition function
-FAIL border-image-width: "5 6 7 8" onto "1 2 3 4" assert_equals: The value should be 5 6 7 8 at 0ms expected "5 6 7 8" but got "6 8 10 12"
-FAIL border-image-width: "1 2 3 4" onto "5 6 7 8" assert_equals: The value should be 1 2 3 4 at 0ms expected "1 2 3 4" but got "6 8 10 12"
-PASS border-left-color (type: color) has testAddition function
-PASS border-left-color supports animating as color of rgb() with overflowed  from and to values
-PASS border-left-color supports animating as color of #RGB
-PASS border-left-color supports animating as color of hsl()
-PASS border-left-color supports animating as color of #RGBa
-PASS border-left-color supports animating as color of rgba()
-PASS border-left-color supports animating as color of hsla()
-PASS border-left-style (type: discrete) has testAddition function
-PASS border-left-style: "solid" onto "dotted"
-PASS border-left-style: "dotted" onto "solid"
-PASS border-left-width (type: length) has testAddition function
-PASS border-left-width: length
-PASS border-left-width: length of rem
-PASS border-right-color (type: color) has testAddition function
-PASS border-right-color supports animating as color of rgb() with overflowed  from and to values
-PASS border-right-color supports animating as color of #RGB
-PASS border-right-color supports animating as color of hsl()
-PASS border-right-color supports animating as color of #RGBa
-PASS border-right-color supports animating as color of rgba()
-PASS border-right-color supports animating as color of hsla()
-PASS border-right-style (type: discrete) has testAddition function
-PASS border-right-style: "solid" onto "dotted"
-PASS border-right-style: "dotted" onto "solid"
-PASS border-right-width (type: length) has testAddition function
-PASS border-right-width: length
-PASS border-right-width: length of rem
-PASS border-spacing (type: lengthPair) has testAddition function
-PASS border-spacing: length pair
-PASS border-spacing: length pair of rem
-PASS border-top-color (type: color) has testAddition function
-PASS border-top-color supports animating as color of rgb() with overflowed  from and to values
-PASS border-top-color supports animating as color of #RGB
-PASS border-top-color supports animating as color of hsl()
-PASS border-top-color supports animating as color of #RGBa
-PASS border-top-color supports animating as color of rgba()
-PASS border-top-color supports animating as color of hsla()
-PASS border-top-style (type: discrete) has testAddition function
-PASS border-top-style: "solid" onto "dotted"
-PASS border-top-style: "dotted" onto "solid"
-PASS border-top-width (type: length) has testAddition function
-PASS border-top-width: length
-PASS border-top-width: length of rem
-PASS box-shadow (type: boxShadowList) has testAddition function
-FAIL box-shadow: shadow assert_equals: The value should be rgb(0, 0, 0) 0px 0px 0px 0px, rgb(120, 120, 120) 10px 10px 10px 0px at 0ms expected "rgb(0, 0, 0) 0px 0px 0px 0px, rgb(120, 120, 120) 10px 10px 10px 0px" but got "rgb(120, 120, 120) 10px 10px 10px 0px"
-PASS box-sizing (type: discrete) has testAddition function
-PASS box-sizing: "border-box" onto "content-box"
-PASS box-sizing: "content-box" onto "border-box"
-PASS caption-side (type: discrete) has testAddition function
-PASS caption-side: "bottom" onto "top"
-PASS caption-side: "top" onto "bottom"
-PASS caret-color (type: color) has testAddition function
-PASS caret-color supports animating as color of rgb() with overflowed  from and to values
-PASS caret-color supports animating as color of #RGB
-PASS caret-color supports animating as color of hsl()
-PASS caret-color supports animating as color of #RGBa
-PASS caret-color supports animating as color of rgba()
-PASS caret-color supports animating as color of hsla()
-PASS clear (type: discrete) has testAddition function
-PASS clear: "right" onto "left"
-PASS clear: "left" onto "right"
-PASS clip (type: rect) has testAddition function
-PASS clip: rect
-PASS clip (type: discrete) has testAddition function
-PASS clip: "auto" onto "rect(10px, 10px, 10px, 10px)"
-PASS clip: "rect(10px, 10px, 10px, 10px)" onto "auto"
-PASS clip: "rect(10px, 10px, 10px, auto)" onto "rect(10px, 10px, 10px, 10px)"
-PASS clip: "rect(10px, 10px, 10px, 10px)" onto "rect(10px, 10px, 10px, auto)"
-PASS clip-rule (type: discrete) has testAddition function
-PASS clip-rule: "nonzero" onto "evenodd"
-PASS clip-rule: "evenodd" onto "nonzero"
-PASS color (type: color) has testAddition function
-PASS color supports animating as color of rgb() with overflowed  from and to values
-PASS color supports animating as color of #RGB
-PASS color supports animating as color of hsl()
-PASS color supports animating as color of #RGBa
-PASS color supports animating as color of rgba()
-PASS color supports animating as color of hsla()
-PASS color-interpolation (type: discrete) has testAddition function
-PASS color-interpolation: "auto" onto "linearRGB"
-FAIL color-interpolation: "linearRGB" onto "auto" assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-PASS color-interpolation-filters (type: discrete) has testAddition function
-FAIL color-interpolation-filters: "linearRGB" onto "sRGB" assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-FAIL color-interpolation-filters: "sRGB" onto "linearRGB" assert_equals: The value should be srgb at 0ms expected "srgb" but got "sRGB"
-PASS column-count (type: positiveInteger) has testAddition function
-PASS column-count: positive integer
-PASS column-count (type: discrete) has testAddition function
-PASS column-count: "10" onto "auto"
-PASS column-count: "auto" onto "10"
-PASS column-gap (type: length) has testAddition function
-PASS column-gap: length
-PASS column-gap: length of rem
-PASS column-gap (type: discrete) has testAddition function
-PASS column-gap: "200px" onto "normal"
-PASS column-gap: "normal" onto "200px"
-PASS column-rule-color (type: color) has testAddition function
-PASS column-rule-color supports animating as color of rgb() with overflowed  from and to values
-PASS column-rule-color supports animating as color of #RGB
-PASS column-rule-color supports animating as color of hsl()
-PASS column-rule-color supports animating as color of #RGBa
-PASS column-rule-color supports animating as color of rgba()
-PASS column-rule-color supports animating as color of hsla()
-PASS column-fill (type: discrete) has testAddition function
-PASS column-fill: "balance" onto "auto"
-PASS column-fill: "auto" onto "balance"
-PASS column-rule-style (type: discrete) has testAddition function
-PASS column-rule-style: "dotted" onto "none"
-PASS column-rule-style: "none" onto "dotted"
-PASS column-rule-width (type: length) has testAddition function
-PASS column-rule-width: length
-PASS column-rule-width: length of rem
-PASS column-width (type: length) has testAddition function
-PASS column-width: length
-PASS column-width: length of rem
-PASS column-width (type: discrete) has testAddition function
-PASS column-width: "1px" onto "auto"
-PASS column-width: "auto" onto "1px"
-PASS contain (type: discrete) has testAddition function
-PASS contain: "none" onto "strict"
-PASS contain: "strict" onto "none"
-PASS content (type: discrete) has testAddition function
-PASS content: ""b"" onto ""a""
-PASS content: ""a"" onto ""b""
-PASS counter-increment (type: discrete) has testAddition function
-PASS counter-increment: "ident-2 2" onto "ident-1 1"
-PASS counter-increment: "ident-1 1" onto "ident-2 2"
-PASS counter-reset (type: discrete) has testAddition function
-PASS counter-reset: "ident-2 2" onto "ident-1 1"
-PASS counter-reset: "ident-1 1" onto "ident-2 2"
-PASS cursor (type: discrete) has testAddition function
-PASS cursor: "wait" onto "pointer"
-PASS cursor: "pointer" onto "wait"
-PASS dominant-baseline (type: discrete) has testAddition function
-PASS dominant-baseline: "alphabetic" onto "ideographic"
-PASS dominant-baseline: "ideographic" onto "alphabetic"
-PASS empty-cells (type: discrete) has testAddition function
-PASS empty-cells: "hide" onto "show"
-PASS empty-cells: "show" onto "hide"
-PASS fill-opacity (type: opacity) has testAddition function
-PASS fill-opacity: [0, 1] number
-PASS fill-opacity: [0, 1] number (clamped)
-PASS fill-rule (type: discrete) has testAddition function
-PASS fill-rule: "nonzero" onto "evenodd"
-PASS fill-rule: "evenodd" onto "nonzero"
-PASS filter (type: filterList) has testAddition function
-FAIL filter: blur on blur assert_equals: The value should be blur(10px) blur(20px) at 0ms expected "blur(10px) blur(20px)" but got "blur(30px)"
-FAIL filter: different filter functions assert_equals: The value should be blur(10px) brightness(0.8) at 0ms expected "blur(10px) brightness(0.8)" but got "brightness(0.8)"
-PASS flex-basis (type: lengthPercentageOrCalc) has testAddition function
-PASS flex-basis: length
-PASS flex-basis: length of rem
-PASS flex-basis: percentage
-PASS flex-basis: units "%" onto "px"
-PASS flex-basis: units "px" onto "%"
-PASS flex-basis: units "rem" onto "%"
-PASS flex-basis: units "%" onto "rem"
-PASS flex-basis: units "rem" onto "em"
-PASS flex-basis: units "em" onto "rem"
-PASS flex-basis: units "calc" onto "px"
-PASS flex-basis: calc
-PASS flex-basis (type: discrete) has testAddition function
-PASS flex-basis: "10px" onto "auto"
-PASS flex-basis: "auto" onto "10px"
-PASS flex-direction (type: discrete) has testAddition function
-PASS flex-direction: "row-reverse" onto "row"
-PASS flex-direction: "row" onto "row-reverse"
-PASS flex-grow (type: positiveNumber) has testAddition function
-PASS flex-grow: positive number
-PASS flex-shrink (type: positiveNumber) has testAddition function
-PASS flex-shrink: positive number
-PASS flex-wrap (type: discrete) has testAddition function
-PASS flex-wrap: "wrap" onto "nowrap"
-PASS flex-wrap: "nowrap" onto "wrap"
-PASS flood-color (type: color) has testAddition function
-PASS flood-color supports animating as color of rgb() with overflowed  from and to values
-PASS flood-color supports animating as color of #RGB
-PASS flood-color supports animating as color of hsl()
-PASS flood-color supports animating as color of #RGBa
-PASS flood-color supports animating as color of rgba()
-PASS flood-color supports animating as color of hsla()
-PASS flood-opacity (type: opacity) has testAddition function
-PASS flood-opacity: [0, 1] number
-PASS flood-opacity: [0, 1] number (clamped)
-PASS font-stretch (type: percentage) has testAddition function
-FAIL font-stretch: percentage assert_equals: The value should be 130% at 0ms expected "130%" but got "70%"
-PASS font-style (type: discrete) has testAddition function
-FAIL font-style: "oblique" onto "italic" assert_equals: The value should be oblique at 0ms expected "oblique" but got "italic"
-PASS font-style: "italic" onto "oblique"
-PASS float (type: discrete) has testAddition function
-PASS float: "right" onto "left"
-PASS float: "left" onto "right"
-PASS font-family (type: discrete) has testAddition function
-PASS font-family: "verdana" onto "helvetica"
-PASS font-family: "helvetica" onto "verdana"
-PASS font-feature-settings (type: discrete) has testAddition function
-PASS font-feature-settings: "normal" onto ""liga" 5"
-PASS font-feature-settings: ""liga" 5" onto "normal"
-PASS font-kerning (type: discrete) has testAddition function
-PASS font-kerning: "normal" onto "auto"
-PASS font-kerning: "auto" onto "normal"
-PASS font-variant-caps (type: discrete) has testAddition function
-PASS font-variant-caps: "unicase" onto "small-caps"
-PASS font-variant-caps: "small-caps" onto "unicase"
-PASS font-variant-east-asian (type: discrete) has testAddition function
-PASS font-variant-east-asian: "proportional-width" onto "full-width"
-PASS font-variant-east-asian: "full-width" onto "proportional-width"
-PASS font-variant-ligatures (type: discrete) has testAddition function
-PASS font-variant-ligatures: "no-common-ligatures" onto "common-ligatures"
-PASS font-variant-ligatures: "common-ligatures" onto "no-common-ligatures"
-PASS font-variant-numeric (type: discrete) has testAddition function
-PASS font-variant-numeric: "oldstyle-nums" onto "lining-nums"
-PASS font-variant-numeric: "lining-nums" onto "oldstyle-nums"
-PASS font-variation-settings (type: fontVariationSettings) has testAddition function
-PASS font-variation-settings with composite type add
-PASS font-variation-settings (type: discrete) has testAddition function
-PASS font-variation-settings: ""wdth" 5" onto ""wght" 1.1, "wdth" 1"
-PASS font-variation-settings: ""wght" 1.1, "wdth" 1" onto ""wdth" 5"
-PASS font-variation-settings: "normal" onto ""wdth" 5"
-PASS font-variation-settings: ""wdth" 5" onto "normal"
-PASS grid-auto-columns (type: discrete) has testAddition function
-PASS grid-auto-columns: "5px" onto "1px"
-PASS grid-auto-columns: "1px" onto "5px"
-PASS grid-auto-flow (type: discrete) has testAddition function
-PASS grid-auto-flow: "column" onto "row"
-PASS grid-auto-flow: "row" onto "column"
-PASS grid-auto-rows (type: discrete) has testAddition function
-PASS grid-auto-rows: "5px" onto "1px"
-PASS grid-auto-rows: "1px" onto "5px"
-PASS grid-column-end (type: discrete) has testAddition function
-PASS grid-column-end: "5" onto "1"
-PASS grid-column-end: "1" onto "5"
-PASS grid-column-start (type: discrete) has testAddition function
-PASS grid-column-start: "5" onto "1"
-PASS grid-column-start: "1" onto "5"
-PASS grid-row-end (type: discrete) has testAddition function
-PASS grid-row-end: "5" onto "1"
-PASS grid-row-end: "1" onto "5"
-PASS grid-row-start (type: discrete) has testAddition function
-PASS grid-row-start: "5" onto "1"
-PASS grid-row-start: "1" onto "5"
-PASS grid-template-areas (type: discrete) has testAddition function
-PASS grid-template-areas: "none" onto "". . a b" ". .a b""
-FAIL grid-template-areas: "". . a b" ". .a b"" onto "none" assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
-PASS grid-template-columns (type: discrete) has testAddition function
-PASS grid-template-columns: "5px" onto "1px"
-PASS grid-template-columns: "1px" onto "5px"
-PASS grid-template-rows (type: discrete) has testAddition function
-PASS grid-template-rows: "5px" onto "1px"
-PASS grid-template-rows: "1px" onto "5px"
-PASS hyphens (type: discrete) has testAddition function
-FAIL hyphens: "auto" onto "manual" assert_equals: The value should be auto at 0ms expected "auto" but got "manual"
-PASS hyphens: "manual" onto "auto"
-PASS image-orientation (type: discrete) has testAddition function
-FAIL image-orientation: "90deg" onto "0deg" assert_equals: The value should be 90deg at 0ms expected "90deg" but got "0deg"
-PASS image-orientation: "0deg" onto "90deg"
-PASS isolation (type: discrete) has testAddition function
-PASS isolation: "isolate" onto "auto"
-PASS isolation: "auto" onto "isolate"
-PASS justify-content (type: discrete) has testAddition function
-PASS justify-content: "end" onto "start"
-PASS justify-content: "start" onto "end"
-PASS justify-items (type: discrete) has testAddition function
-PASS justify-items: "end" onto "start"
-PASS justify-items: "start" onto "end"
-PASS justify-self (type: discrete) has testAddition function
-PASS justify-self: "end" onto "start"
-PASS justify-self: "start" onto "end"
-PASS letter-spacing (type: length) has testAddition function
-PASS letter-spacing: length
-PASS letter-spacing: length of rem
-PASS lighting-color (type: color) has testAddition function
-PASS lighting-color supports animating as color of rgb() with overflowed  from and to values
-PASS lighting-color supports animating as color of #RGB
-PASS lighting-color supports animating as color of hsl()
-PASS lighting-color supports animating as color of #RGBa
-PASS lighting-color supports animating as color of rgba()
-PASS lighting-color supports animating as color of hsla()
-PASS list-style-image (type: discrete) has testAddition function
-PASS list-style-image: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS list-style-image: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS list-style-position (type: discrete) has testAddition function
-PASS list-style-position: "outside" onto "inside"
-PASS list-style-position: "inside" onto "outside"
-PASS list-style-type (type: discrete) has testAddition function
-PASS list-style-type: "square" onto "circle"
-PASS list-style-type: "circle" onto "square"
-PASS marker-end (type: discrete) has testAddition function
-PASS marker-end: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-end: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS marker-mid (type: discrete) has testAddition function
-PASS marker-mid: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-mid: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS marker-start (type: discrete) has testAddition function
-PASS marker-start: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS marker-start: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS mask (type: discrete) has testAddition function
-PASS mask: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS mask: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS mask-type (type: discrete) has testAddition function
-PASS mask-type: "luminance" onto "alpha"
-PASS mask-type: "alpha" onto "luminance"
-PASS mix-blend-mode (type: discrete) has testAddition function
-PASS mix-blend-mode: "screen" onto "multiply"
-PASS mix-blend-mode: "multiply" onto "screen"
-PASS object-fit (type: discrete) has testAddition function
-PASS object-fit: "contain" onto "fill"
-PASS object-fit: "fill" onto "contain"
-PASS order (type: integer) has testAddition function
-PASS order: integer
-PASS outline-color (type: color) has testAddition function
-PASS outline-color supports animating as color of rgb() with overflowed  from and to values
-PASS outline-color supports animating as color of #RGB
-PASS outline-color supports animating as color of hsl()
-PASS outline-color supports animating as color of #RGBa
-PASS outline-color supports animating as color of rgba()
-PASS outline-color supports animating as color of hsla()
-PASS outline-offset (type: length) has testAddition function
-FAIL outline-offset: length assert_equals: The value should be 20px at 0ms expected "20px" but got "0px"
-FAIL outline-offset: length of rem assert_equals: The value should be 20px at 0ms expected "20px" but got "0px"
-PASS outline-style (type: discrete) has testAddition function
-PASS outline-style: "dotted" onto "none"
-PASS outline-style: "none" onto "dotted"
-PASS outline-width (type: length) has testAddition function
-PASS outline-width: length
-PASS outline-width: length of rem
-PASS overflow-wrap (type: discrete) has testAddition function
-PASS overflow-wrap: "break-word" onto "normal"
-PASS overflow-wrap: "normal" onto "break-word"
-PASS overflow-x (type: discrete) has testAddition function
-PASS overflow-x: "hidden" onto "visible"
-PASS overflow-x: "visible" onto "hidden"
-PASS overflow-y (type: discrete) has testAddition function
-PASS overflow-y: "hidden" onto "visible"
-PASS overflow-y: "visible" onto "hidden"
-PASS page-break-after (type: discrete) has testAddition function
-PASS page-break-after: "auto" onto "always"
-PASS page-break-after: "always" onto "auto"
-PASS page-break-before (type: discrete) has testAddition function
-PASS page-break-before: "auto" onto "always"
-PASS page-break-before: "always" onto "auto"
-PASS page-break-inside (type: discrete) has testAddition function
-PASS page-break-inside: "avoid" onto "auto"
-PASS page-break-inside: "auto" onto "avoid"
-PASS paint-order (type: discrete) has testAddition function
-FAIL paint-order: "stroke" onto "fill" assert_equals: The value should be stroke at 0ms expected "stroke" but got "stroke fill markers"
-FAIL paint-order: "fill" onto "stroke" assert_equals: The value should be fill at 0ms expected "fill" but got "fill stroke markers"
-PASS perspective (type: length) has testAddition function
-PASS perspective: length
-PASS perspective: length of rem
-PASS perspective-origin (type: position) has testAddition function
-PASS perspective-origin: length pair
-PASS perspective-origin: length pair of rem
-PASS perspective-origin: position of percentage
-PASS pointer-events (type: discrete) has testAddition function
-PASS pointer-events: "none" onto "fill"
-PASS pointer-events: "fill" onto "none"
-PASS position (type: discrete) has testAddition function
-PASS position: "fixed" onto "absolute"
-PASS position: "absolute" onto "fixed"
-PASS quotes (type: discrete) has testAddition function
-PASS quotes: ""‘" "’" "“" "”"" onto ""“" "”" "‘" "’""
-PASS quotes: ""“" "”" "‘" "’"" onto ""‘" "’" "“" "”""
-PASS resize (type: discrete) has testAddition function
-PASS resize: "horizontal" onto "both"
-PASS resize: "both" onto "horizontal"
-PASS scroll-behavior (type: discrete) has testAddition function
-PASS scroll-behavior: "smooth" onto "auto"
-PASS scroll-behavior: "auto" onto "smooth"
-PASS shape-outside (type: discrete) has testAddition function
-PASS shape-outside: "url("http://localhost/test-2")" onto "url("http://localhost/test-1")"
-PASS shape-outside: "url("http://localhost/test-1")" onto "url("http://localhost/test-2")"
-PASS shape-rendering (type: discrete) has testAddition function
-FAIL shape-rendering: "crispEdges" onto "optimizeSpeed" assert_equals: The value should be crispedges at 0ms expected "crispedges" but got "crispEdges"
-FAIL shape-rendering: "optimizeSpeed" onto "crispEdges" assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS stop-color (type: color) has testAddition function
-PASS stop-color supports animating as color of rgb() with overflowed  from and to values
-PASS stop-color supports animating as color of #RGB
-PASS stop-color supports animating as color of hsl()
-PASS stop-color supports animating as color of #RGBa
-PASS stop-color supports animating as color of rgba()
-PASS stop-color supports animating as color of hsla()
-PASS stop-opacity (type: opacity) has testAddition function
-PASS stop-opacity: [0, 1] number
-PASS stop-opacity: [0, 1] number (clamped)
-PASS stroke-dasharray (type: dasharray) has testAddition function
-FAIL stroke-dasharray: dasharray assert_equals: The value should be 1, 2, 3, 4, 5 at 0ms expected "1, 2, 3, 4, 5" but got "7px, calc(2px + 30%), 5px, 10px, calc(5px + 30%), 3px, 8px, calc(3px + 30%), 6px, 11px, calc(1px + 30%), 4px, 9px, calc(4px + 30%), 7px"
-PASS stroke-dasharray (type: discrete) has testAddition function
-FAIL stroke-dasharray: "10, 20" onto "none" assert_equals: The value should be 10, 20 at 0ms expected "10, 20" but got "10px, 20px"
-PASS stroke-dasharray: "none" onto "10, 20"
-PASS stroke-linecap (type: discrete) has testAddition function
-PASS stroke-linecap: "square" onto "round"
-PASS stroke-linecap: "round" onto "square"
-PASS stroke-linejoin (type: discrete) has testAddition function
-PASS stroke-linejoin: "miter" onto "round"
-PASS stroke-linejoin: "round" onto "miter"
-PASS stroke-miterlimit (type: positiveNumber) has testAddition function
-PASS stroke-miterlimit: positive number
-PASS stroke-opacity (type: opacity) has testAddition function
-PASS stroke-opacity: [0, 1] number
-PASS stroke-opacity: [0, 1] number (clamped)
-PASS table-layout (type: discrete) has testAddition function
-PASS table-layout: "fixed" onto "auto"
-PASS table-layout: "auto" onto "fixed"
-PASS text-align (type: discrete) has testAddition function
-PASS text-align: "end" onto "start"
-PASS text-align: "start" onto "end"
-PASS text-align-last (type: discrete) has testAddition function
-PASS text-align-last: "end" onto "start"
-PASS text-align-last: "start" onto "end"
-PASS text-anchor (type: discrete) has testAddition function
-PASS text-anchor: "end" onto "middle"
-PASS text-anchor: "middle" onto "end"
-PASS text-combine-upright (type: discrete) has testAddition function
-PASS text-combine-upright: "none" onto "all"
-PASS text-combine-upright: "all" onto "none"
-PASS text-decoration-color (type: color) has testAddition function
-PASS text-decoration-color supports animating as color of rgb() with overflowed  from and to values
-PASS text-decoration-color supports animating as color of #RGB
-PASS text-decoration-color supports animating as color of hsl()
-PASS text-decoration-color supports animating as color of #RGBa
-PASS text-decoration-color supports animating as color of rgba()
-PASS text-decoration-color supports animating as color of hsla()
-PASS text-decoration-line (type: discrete) has testAddition function
-PASS text-decoration-line: "overline" onto "underline"
-PASS text-decoration-line: "underline" onto "overline"
-PASS text-decoration-style (type: discrete) has testAddition function
-PASS text-decoration-style: "dotted" onto "solid"
-PASS text-decoration-style: "solid" onto "dotted"
-PASS text-orientation (type: discrete) has testAddition function
-PASS text-orientation: "sideways" onto "upright"
-PASS text-orientation: "upright" onto "sideways"
-PASS text-overflow (type: discrete) has testAddition function
-PASS text-overflow: "ellipsis" onto "clip"
-PASS text-overflow: "clip" onto "ellipsis"
-PASS text-rendering (type: discrete) has testAddition function
-FAIL text-rendering: "optimizeLegibility" onto "optimizeSpeed" assert_equals: The value should be optimizelegibility at 0ms expected "optimizelegibility" but got "optimizeLegibility"
-FAIL text-rendering: "optimizeSpeed" onto "optimizeLegibility" assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS text-shadow (type: textShadowList) has testAddition function
-FAIL text-shadow: shadow assert_equals: The value should be rgb(0, 0, 0) 0px 0px 0px, rgb(120, 120, 120) 10px 10px 10px at 0ms expected "rgb(0, 0, 0) 0px 0px 0px, rgb(120, 120, 120) 10px 10px 10px" but got "rgb(120, 120, 120) 10px 10px 10px"
-PASS text-transform (type: discrete) has testAddition function
-PASS text-transform: "uppercase" onto "capitalize"
-PASS text-transform: "capitalize" onto "uppercase"
-PASS touch-action (type: discrete) has testAddition function
-PASS touch-action: "none" onto "auto"
-PASS touch-action: "auto" onto "none"
-PASS transform (type: transformList) has testAddition function
-PASS transform: translate
-PASS transform: rotate
-PASS transform: scale
-PASS transform: skew
-PASS transform: rotate on translate
-PASS transform: translate on rotate
-PASS transform: rotate on rotate and translate
-PASS transform: matrix
-PASS transform: rotate3d
-PASS transform: matrix3d
-PASS transform: non-invertible matrices
-PASS transform: non-invertible matrices in matched transform lists
-PASS transform: non-invertible matrices in mismatched transform lists
-PASS transform-box (type: discrete) has testAddition function
-FAIL transform-box: "border-box" onto "fill-box" assert_equals: The value should be border-box at 0ms expected "border-box" but got "fill-box"
-PASS transform-box: "fill-box" onto "border-box"
-PASS transform-style (type: discrete) has testAddition function
-PASS transform-style: "preserve-3d" onto "flat"
-PASS transform-style: "flat" onto "preserve-3d"
-PASS rotate (type: rotateList) has testAddition function
-PASS rotate without rotation axes
-PASS rotate with underlying transform
-FAIL rotate with different rotation axes assert_approx_equals: expected 0.57735 0.57735 0.57735 135deg but got 1 1 1 135deg: The value should be 0.57735 0.57735 0.57735 135deg at 500ms but got 1 1 1 135deg expected 0.57735 +/- 0.0001 but got 1
-PASS translate (type: translateList) has testAddition function
-PASS translate
-PASS translate with underlying transform
-FAIL translate with underlying percentage value assert_equals: The value should be -150px at 0ms expected "-150px" but got "calc(-200px + 50%)"
-PASS scale (type: scaleList) has testAddition function
-FAIL scale with two unspecified values assert_equals: The value should be -6 at 0ms expected "-6" but got "-6 2"
-PASS scale with one unspecified value
-PASS scale
-PASS unicode-bidi (type: discrete) has testAddition function
-PASS unicode-bidi: "bidi-override" onto "embed"
-PASS unicode-bidi: "embed" onto "bidi-override"
-PASS vector-effect (type: discrete) has testAddition function
-PASS vector-effect: "non-scaling-stroke" onto "none"
-PASS vector-effect: "none" onto "non-scaling-stroke"
-PASS visibility (type: visibility) has testAddition function
-FAIL visibility: onto "visible" assert_equals: The value should be visible at 1000ms expected "visible" but got "hidden"
-PASS visibility: onto "hidden"
-PASS white-space (type: discrete) has testAddition function
-PASS white-space: "nowrap" onto "pre"
-PASS white-space: "pre" onto "nowrap"
-PASS word-break (type: discrete) has testAddition function
-PASS word-break: "break-all" onto "keep-all"
-PASS word-break: "keep-all" onto "break-all"
-PASS word-spacing (type: lengthPercentageOrCalc) has testAddition function
-PASS word-spacing: length
-PASS word-spacing: length of rem
-FAIL word-spacing: percentage assert_equals: The value should be 130% at 0ms expected "130%" but got "0px"
-FAIL word-spacing: units "%" onto "px" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10px"
-FAIL word-spacing: units "px" onto "%" assert_equals: The value should be calc(10px + 10%) at 0ms expected "calc(10px + 10%)" but got "10px"
-FAIL word-spacing: units "rem" onto "%" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "20px"
-FAIL word-spacing: units "%" onto "rem" assert_equals: The value should be calc(20px + 10%) at 0ms expected "calc(20px + 10%)" but got "20px"
-PASS word-spacing: units "rem" onto "em"
-PASS word-spacing: units "em" onto "rem"
-FAIL word-spacing: units "calc" onto "px" assert_equals: The value should be calc(30px + 20%) at 0ms expected "calc(30px + 20%)" but got "10px"
-FAIL word-spacing: calc assert_equals: The value should be calc(30px + 30%) at 0ms expected "calc(30px + 30%)" but got "0px"
-PASS will-change (type: discrete) has testAddition function
-PASS will-change: "contents" onto "scroll-position"
-PASS will-change: "scroll-position" onto "contents"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
deleted file mode 100644
index dd7bded..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ /dev/null
@@ -1,720 +0,0 @@
-This is a testharness.js-based test.
-Found 716 tests; 639 PASS, 77 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup
-PASS align-content (type: discrete) has testInterpolation function
-PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
-PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
-PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
-PASS align-items (type: discrete) has testInterpolation function
-PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
-PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
-PASS align-items uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
-PASS align-self (type: discrete) has testInterpolation function
-PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
-PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
-PASS align-self uses discrete animation when animating between "flex-start" and "flex-end" with keyframe easing
-PASS backface-visibility (type: discrete) has testInterpolation function
-PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with linear easing
-PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with effect easing
-PASS backface-visibility uses discrete animation when animating between "visible" and "hidden" with keyframe easing
-PASS background-attachment (type: discrete) has testInterpolation function
-PASS background-attachment uses discrete animation when animating between "fixed" and "local" with linear easing
-PASS background-attachment uses discrete animation when animating between "fixed" and "local" with effect easing
-PASS background-attachment uses discrete animation when animating between "fixed" and "local" with keyframe easing
-PASS background-color (type: color) has testInterpolation function
-PASS background-color supports animating as color of rgb()
-PASS background-color supports animating as color of #RGB
-PASS background-color supports animating as color of hsl()
-PASS background-color supports animating as color of #RGBa
-PASS background-color supports animating as color of rgba()
-PASS background-color supports animating as color of hsla()
-PASS background-blend-mode (type: discrete) has testInterpolation function
-PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with linear easing
-PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with effect easing
-PASS background-blend-mode uses discrete animation when animating between "multiply" and "screen" with keyframe easing
-PASS background-clip (type: discrete) has testInterpolation function
-PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with linear easing
-PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with effect easing
-PASS background-clip uses discrete animation when animating between "padding-box" and "content-box" with keyframe easing
-PASS background-image (type: discrete) has testInterpolation function
-FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing assert_equals: The value should be url("http://localhost/test-1") at 499ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.499)"
-FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-FAIL background-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-PASS background-origin (type: discrete) has testInterpolation function
-PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with linear easing
-PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with effect easing
-PASS background-origin uses discrete animation when animating between "padding-box" and "content-box" with keyframe easing
-PASS background-repeat (type: discrete) has testInterpolation function
-PASS background-repeat uses discrete animation when animating between "space" and "round" with linear easing
-PASS background-repeat uses discrete animation when animating between "space" and "round" with effect easing
-PASS background-repeat uses discrete animation when animating between "space" and "round" with keyframe easing
-PASS border-bottom-color (type: color) has testInterpolation function
-PASS border-bottom-color supports animating as color of rgb()
-PASS border-bottom-color supports animating as color of #RGB
-PASS border-bottom-color supports animating as color of hsl()
-PASS border-bottom-color supports animating as color of #RGBa
-PASS border-bottom-color supports animating as color of rgba()
-PASS border-bottom-color supports animating as color of hsla()
-PASS border-bottom-style (type: discrete) has testInterpolation function
-PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with linear easing
-PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with effect easing
-PASS border-bottom-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
-PASS border-bottom-width (type: length) has testInterpolation function
-PASS border-bottom-width supports animating as a length
-PASS border-bottom-width supports animating as a length of rem
-PASS border-collapse (type: discrete) has testInterpolation function
-PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with linear easing
-PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with effect easing
-PASS border-collapse uses discrete animation when animating between "collapse" and "separate" with keyframe easing
-PASS border-image-outset (type: discrete) has testInterpolation function
-FAIL border-image-outset uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with linear easing assert_equals: The value should be 1 2 3 4 at 499ms expected "1 2 3 4" but got "2.996 3.996 4.996 5.996"
-FAIL border-image-outset uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with effect easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-FAIL border-image-outset uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with keyframe easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-PASS border-image-repeat (type: discrete) has testInterpolation function
-FAIL border-image-repeat uses discrete animation when animating between "stretch stretch" and "repeat repeat" with linear easing assert_equals: The value should be stretch stretch at 0ms expected "stretch stretch" but got "stretch"
-FAIL border-image-repeat uses discrete animation when animating between "stretch stretch" and "repeat repeat" with effect easing assert_equals: The value should be stretch stretch at 0ms expected "stretch stretch" but got "stretch"
-FAIL border-image-repeat uses discrete animation when animating between "stretch stretch" and "repeat repeat" with keyframe easing assert_equals: The value should be stretch stretch at 0ms expected "stretch stretch" but got "stretch"
-PASS border-image-slice (type: discrete) has testInterpolation function
-FAIL border-image-slice uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with linear easing assert_equals: The value should be 1 2 3 4 at 499ms expected "1 2 3 4" but got "2.996 3.996 4.996 5.996"
-FAIL border-image-slice uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with effect easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-FAIL border-image-slice uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with keyframe easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-PASS border-image-source (type: discrete) has testInterpolation function
-FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing assert_equals: The value should be url("http://localhost/test-1") at 499ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.499)"
-FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-FAIL border-image-source uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-PASS border-image-width (type: discrete) has testInterpolation function
-FAIL border-image-width uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with linear easing assert_equals: The value should be 1 2 3 4 at 499ms expected "1 2 3 4" but got "2.996 3.996 4.996 5.996"
-FAIL border-image-width uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with effect easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-FAIL border-image-width uses discrete animation when animating between "1 2 3 4" and "5 6 7 8" with keyframe easing assert_equals: The value should be 1 2 3 4 at 940ms expected "1 2 3 4" but got "2.71151 3.71151 4.71151 5.71151"
-PASS border-left-color (type: color) has testInterpolation function
-PASS border-left-color supports animating as color of rgb()
-PASS border-left-color supports animating as color of #RGB
-PASS border-left-color supports animating as color of hsl()
-PASS border-left-color supports animating as color of #RGBa
-PASS border-left-color supports animating as color of rgba()
-PASS border-left-color supports animating as color of hsla()
-PASS border-left-style (type: discrete) has testInterpolation function
-PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with linear easing
-PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with effect easing
-PASS border-left-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
-PASS border-left-width (type: length) has testInterpolation function
-PASS border-left-width supports animating as a length
-PASS border-left-width supports animating as a length of rem
-PASS border-right-color (type: color) has testInterpolation function
-PASS border-right-color supports animating as color of rgb()
-PASS border-right-color supports animating as color of #RGB
-PASS border-right-color supports animating as color of hsl()
-PASS border-right-color supports animating as color of #RGBa
-PASS border-right-color supports animating as color of rgba()
-PASS border-right-color supports animating as color of hsla()
-PASS border-right-style (type: discrete) has testInterpolation function
-PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with linear easing
-PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with effect easing
-PASS border-right-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
-PASS border-right-width (type: length) has testInterpolation function
-PASS border-right-width supports animating as a length
-PASS border-right-width supports animating as a length of rem
-PASS border-spacing (type: lengthPair) has testInterpolation function
-PASS border-spacing supports animating as a length pair
-PASS border-spacing supports animating as a length pair of rem
-PASS border-top-color (type: color) has testInterpolation function
-PASS border-top-color supports animating as color of rgb()
-PASS border-top-color supports animating as color of #RGB
-PASS border-top-color supports animating as color of hsl()
-PASS border-top-color supports animating as color of #RGBa
-PASS border-top-color supports animating as color of rgba()
-PASS border-top-color supports animating as color of hsla()
-PASS border-top-style (type: discrete) has testInterpolation function
-PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with linear easing
-PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with effect easing
-PASS border-top-style uses discrete animation when animating between "dotted" and "solid" with keyframe easing
-PASS border-top-width (type: length) has testInterpolation function
-PASS border-top-width supports animating as a length
-PASS border-top-width supports animating as a length of rem
-PASS box-shadow (type: boxShadowList) has testInterpolation function
-PASS box-shadow: from none to other
-PASS box-shadow: from other to none
-PASS box-shadow: single shadow
-PASS box-shadow: shadow list
-PASS box-shadow: mismatched list length (from shorter to longer)
-PASS box-shadow: mismatched list length (from longer to shorter)
-PASS box-shadow: with currentcolor
-PASS box-sizing (type: discrete) has testInterpolation function
-PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with linear easing
-PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with effect easing
-PASS box-sizing uses discrete animation when animating between "content-box" and "border-box" with keyframe easing
-PASS caption-side (type: discrete) has testInterpolation function
-PASS caption-side uses discrete animation when animating between "top" and "bottom" with linear easing
-PASS caption-side uses discrete animation when animating between "top" and "bottom" with effect easing
-PASS caption-side uses discrete animation when animating between "top" and "bottom" with keyframe easing
-PASS caret-color (type: color) has testInterpolation function
-PASS caret-color supports animating as color of rgb()
-PASS caret-color supports animating as color of #RGB
-PASS caret-color supports animating as color of hsl()
-PASS caret-color supports animating as color of #RGBa
-PASS caret-color supports animating as color of rgba()
-PASS caret-color supports animating as color of hsla()
-PASS clear (type: discrete) has testInterpolation function
-PASS clear uses discrete animation when animating between "left" and "right" with linear easing
-PASS clear uses discrete animation when animating between "left" and "right" with effect easing
-PASS clear uses discrete animation when animating between "left" and "right" with keyframe easing
-PASS clip (type: rect) has testInterpolation function
-PASS clip supports animating as a rect
-PASS clip (type: discrete) has testInterpolation function
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with linear easing
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with effect easing
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "auto" with keyframe easing
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with linear easing
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with effect easing
-PASS clip uses discrete animation when animating between "rect(10px, 10px, 10px, 10px)" and "rect(10px, 10px, 10px, auto)" with keyframe easing
-PASS clip-rule (type: discrete) has testInterpolation function
-PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with linear easing
-PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with effect easing
-PASS clip-rule uses discrete animation when animating between "evenodd" and "nonzero" with keyframe easing
-PASS color (type: color) has testInterpolation function
-PASS color supports animating as color of rgb()
-PASS color supports animating as color of #RGB
-PASS color supports animating as color of hsl()
-PASS color supports animating as color of #RGBa
-PASS color supports animating as color of rgba()
-PASS color supports animating as color of hsla()
-PASS color-interpolation (type: discrete) has testInterpolation function
-FAIL color-interpolation uses discrete animation when animating between "linearRGB" and "auto" with linear easing assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-FAIL color-interpolation uses discrete animation when animating between "linearRGB" and "auto" with effect easing assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-FAIL color-interpolation uses discrete animation when animating between "linearRGB" and "auto" with keyframe easing assert_equals: The value should be linearrgb at 0ms expected "linearrgb" but got "linearRGB"
-PASS color-interpolation-filters (type: discrete) has testInterpolation function
-FAIL color-interpolation-filters uses discrete animation when animating between "sRGB" and "linearRGB" with linear easing assert_equals: The value should be srgb at 0ms expected "srgb" but got "sRGB"
-FAIL color-interpolation-filters uses discrete animation when animating between "sRGB" and "linearRGB" with effect easing assert_equals: The value should be srgb at 0ms expected "srgb" but got "sRGB"
-FAIL color-interpolation-filters uses discrete animation when animating between "sRGB" and "linearRGB" with keyframe easing assert_equals: The value should be srgb at 0ms expected "srgb" but got "sRGB"
-PASS column-count (type: positiveInteger) has testInterpolation function
-PASS column-count supports animating as a positive integer
-PASS column-count (type: discrete) has testInterpolation function
-PASS column-count uses discrete animation when animating between "auto" and "10" with linear easing
-PASS column-count uses discrete animation when animating between "auto" and "10" with effect easing
-PASS column-count uses discrete animation when animating between "auto" and "10" with keyframe easing
-PASS column-gap (type: length) has testInterpolation function
-PASS column-gap supports animating as a length
-PASS column-gap supports animating as a length of rem
-PASS column-gap (type: discrete) has testInterpolation function
-PASS column-gap uses discrete animation when animating between "normal" and "200px" with linear easing
-PASS column-gap uses discrete animation when animating between "normal" and "200px" with effect easing
-PASS column-gap uses discrete animation when animating between "normal" and "200px" with keyframe easing
-PASS column-rule-color (type: color) has testInterpolation function
-PASS column-rule-color supports animating as color of rgb()
-PASS column-rule-color supports animating as color of #RGB
-PASS column-rule-color supports animating as color of hsl()
-PASS column-rule-color supports animating as color of #RGBa
-PASS column-rule-color supports animating as color of rgba()
-PASS column-rule-color supports animating as color of hsla()
-PASS column-fill (type: discrete) has testInterpolation function
-PASS column-fill uses discrete animation when animating between "auto" and "balance" with linear easing
-PASS column-fill uses discrete animation when animating between "auto" and "balance" with effect easing
-PASS column-fill uses discrete animation when animating between "auto" and "balance" with keyframe easing
-PASS column-rule-style (type: discrete) has testInterpolation function
-PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with linear easing
-PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with effect easing
-PASS column-rule-style uses discrete animation when animating between "none" and "dotted" with keyframe easing
-PASS column-rule-width (type: length) has testInterpolation function
-PASS column-rule-width supports animating as a length
-PASS column-rule-width supports animating as a length of rem
-PASS column-width (type: length) has testInterpolation function
-PASS column-width supports animating as a length
-PASS column-width supports animating as a length of rem
-PASS column-width (type: discrete) has testInterpolation function
-PASS column-width uses discrete animation when animating between "auto" and "1px" with linear easing
-PASS column-width uses discrete animation when animating between "auto" and "1px" with effect easing
-PASS column-width uses discrete animation when animating between "auto" and "1px" with keyframe easing
-PASS contain (type: discrete) has testInterpolation function
-PASS contain uses discrete animation when animating between "strict" and "none" with linear easing
-PASS contain uses discrete animation when animating between "strict" and "none" with effect easing
-PASS contain uses discrete animation when animating between "strict" and "none" with keyframe easing
-PASS content (type: discrete) has testInterpolation function
-PASS content uses discrete animation when animating between ""a"" and ""b"" with linear easing
-PASS content uses discrete animation when animating between ""a"" and ""b"" with effect easing
-PASS content uses discrete animation when animating between ""a"" and ""b"" with keyframe easing
-PASS counter-increment (type: discrete) has testInterpolation function
-PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing
-PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
-PASS counter-increment uses discrete animation when animating between "ident-1 1" and "ident-2 2" with keyframe easing
-PASS counter-reset (type: discrete) has testInterpolation function
-PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with linear easing
-PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with effect easing
-PASS counter-reset uses discrete animation when animating between "ident-1 1" and "ident-2 2" with keyframe easing
-PASS cursor (type: discrete) has testInterpolation function
-PASS cursor uses discrete animation when animating between "pointer" and "wait" with linear easing
-PASS cursor uses discrete animation when animating between "pointer" and "wait" with effect easing
-PASS cursor uses discrete animation when animating between "pointer" and "wait" with keyframe easing
-PASS dominant-baseline (type: discrete) has testInterpolation function
-PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with linear easing
-PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with effect easing
-PASS dominant-baseline uses discrete animation when animating between "ideographic" and "alphabetic" with keyframe easing
-PASS empty-cells (type: discrete) has testInterpolation function
-PASS empty-cells uses discrete animation when animating between "show" and "hide" with linear easing
-PASS empty-cells uses discrete animation when animating between "show" and "hide" with effect easing
-PASS empty-cells uses discrete animation when animating between "show" and "hide" with keyframe easing
-PASS fill-opacity (type: opacity) has testInterpolation function
-PASS fill-opacity supports animating as a [0, 1] number
-PASS fill-rule (type: discrete) has testInterpolation function
-PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with linear easing
-PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with effect easing
-PASS fill-rule uses discrete animation when animating between "evenodd" and "nonzero" with keyframe easing
-PASS filter (type: filterList) has testInterpolation function
-PASS filter: blur function
-PASS filter: hue-rotate function with same unit(deg)
-FAIL filter: hue-rotate function with different unit(deg -> rad) assert_equals: The value should be hue-rotate(50.0873rad) at 500ms expected "hue-rotate(50.0873rad)" but got "hue-rotate(2869.79deg)"
-PASS filter: drop-shadow function
-PASS filter: percentage or numeric-specifiable functions (number value)
-PASS filter: percentage or numeric-specifiable functions (percentage value)
-PASS filter: interpolate different length of filter-function-list with function which lacuna value is 1
-PASS filter: interpolate different length of filter-function-list with function which lacuna value is 0
-FAIL filter: interpolate different length of filter-function-list with drop-shadow function assert_equals: The value should be blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px at 500ms expected "blur(5px) drop-shadow(rgba(85, 0, 170, 0.6) 5px 5px 5px" but got "blur(5px) drop-shadow(rgba(0, 0, 255, 0.4) 5px 5px 5px)"
-PASS filter: interpolate from none
-PASS filter: url function (interpoalte as discrete)
-PASS flex-basis (type: lengthPercentageOrCalc) has testInterpolation function
-PASS flex-basis supports animating as a length
-PASS flex-basis supports animating as a length of rem
-PASS flex-basis supports animating as a percentage
-PASS flex-basis supports animating as combination units "px" and "%"
-PASS flex-basis supports animating as combination units "%" and "em"
-PASS flex-basis supports animating as combination units "em" and "rem"
-PASS flex-basis supports animating as combination units "px" and "calc"
-PASS flex-basis supports animating as a calc
-PASS flex-basis (type: discrete) has testInterpolation function
-PASS flex-basis uses discrete animation when animating between "auto" and "10px" with linear easing
-PASS flex-basis uses discrete animation when animating between "auto" and "10px" with effect easing
-PASS flex-basis uses discrete animation when animating between "auto" and "10px" with keyframe easing
-PASS flex-direction (type: discrete) has testInterpolation function
-PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with linear easing
-PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with effect easing
-PASS flex-direction uses discrete animation when animating between "row" and "row-reverse" with keyframe easing
-PASS flex-grow (type: positiveNumber) has testInterpolation function
-PASS flex-grow supports animating as a positive number
-PASS flex-shrink (type: positiveNumber) has testInterpolation function
-PASS flex-shrink supports animating as a positive number
-PASS flex-wrap (type: discrete) has testInterpolation function
-PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with linear easing
-PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with effect easing
-PASS flex-wrap uses discrete animation when animating between "nowrap" and "wrap" with keyframe easing
-PASS flood-color (type: color) has testInterpolation function
-PASS flood-color supports animating as color of rgb()
-PASS flood-color supports animating as color of #RGB
-PASS flood-color supports animating as color of hsl()
-PASS flood-color supports animating as color of #RGBa
-PASS flood-color supports animating as color of rgba()
-PASS flood-color supports animating as color of hsla()
-PASS flood-opacity (type: opacity) has testInterpolation function
-PASS flood-opacity supports animating as a [0, 1] number
-PASS font-stretch (type: percentage) has testInterpolation function
-FAIL font-stretch supports animating as a percentage assert_equals: The value should be 30% at 500ms expected "30%" but got "50%"
-PASS font-style (type: discrete) has testInterpolation function
-FAIL font-style uses discrete animation when animating between "italic" and "oblique" with linear easing assert_equals: The value should be oblique at 500ms expected "oblique" but got "italic"
-FAIL font-style uses discrete animation when animating between "italic" and "oblique" with effect easing assert_equals: The value should be oblique at 960ms expected "oblique" but got "italic"
-FAIL font-style uses discrete animation when animating between "italic" and "oblique" with keyframe easing assert_equals: The value should be oblique at 960ms expected "oblique" but got "italic"
-PASS float (type: discrete) has testInterpolation function
-PASS float uses discrete animation when animating between "left" and "right" with linear easing
-PASS float uses discrete animation when animating between "left" and "right" with effect easing
-PASS float uses discrete animation when animating between "left" and "right" with keyframe easing
-PASS font-family (type: discrete) has testInterpolation function
-PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with linear easing
-PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with effect easing
-PASS font-family uses discrete animation when animating between "helvetica" and "verdana" with keyframe easing
-PASS font-feature-settings (type: discrete) has testInterpolation function
-PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with linear easing
-PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with effect easing
-PASS font-feature-settings uses discrete animation when animating between ""liga" 5" and "normal" with keyframe easing
-PASS font-kerning (type: discrete) has testInterpolation function
-PASS font-kerning uses discrete animation when animating between "auto" and "normal" with linear easing
-PASS font-kerning uses discrete animation when animating between "auto" and "normal" with effect easing
-PASS font-kerning uses discrete animation when animating between "auto" and "normal" with keyframe easing
-PASS font-variant-caps (type: discrete) has testInterpolation function
-PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with linear easing
-PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with effect easing
-PASS font-variant-caps uses discrete animation when animating between "small-caps" and "unicase" with keyframe easing
-PASS font-variant-east-asian (type: discrete) has testInterpolation function
-PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with linear easing
-PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with effect easing
-PASS font-variant-east-asian uses discrete animation when animating between "full-width" and "proportional-width" with keyframe easing
-PASS font-variant-ligatures (type: discrete) has testInterpolation function
-PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with linear easing
-PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with effect easing
-PASS font-variant-ligatures uses discrete animation when animating between "common-ligatures" and "no-common-ligatures" with keyframe easing
-PASS font-variant-numeric (type: discrete) has testInterpolation function
-PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with linear easing
-PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with effect easing
-PASS font-variant-numeric uses discrete animation when animating between "lining-nums" and "oldstyle-nums" with keyframe easing
-PASS font-variation-settings (type: fontVariationSettings) has testInterpolation function
-PASS font-variation-settings supports animation as float
-FAIL font-variation-settings supports animation as float with multiple tags assert_array_equals: The computed values should be "wdth" 2,"wght" 1.2 at 250ms property 0, expected "\"wdth\" 2" but got "\"wdth\" 1"
-FAIL font-variation-settings supports animation as float with multiple duplicate tags assert_array_equals: The computed values should be "wdth" 2,"wght" 1.2 at 250ms property 0, expected "\"wdth\" 2" but got "\"wdth\" 1"
-PASS font-variation-settings (type: discrete) has testInterpolation function
-PASS font-variation-settings uses discrete animation when animating between ""wght" 1.1, "wdth" 1" and ""wdth" 5" with linear easing
-PASS font-variation-settings uses discrete animation when animating between ""wght" 1.1, "wdth" 1" and ""wdth" 5" with effect easing
-PASS font-variation-settings uses discrete animation when animating between ""wght" 1.1, "wdth" 1" and ""wdth" 5" with keyframe easing
-PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with linear easing
-PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with effect easing
-PASS font-variation-settings uses discrete animation when animating between ""wdth" 5" and "normal" with keyframe easing
-PASS grid-auto-columns (type: discrete) has testInterpolation function
-PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with linear easing
-PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with effect easing
-PASS grid-auto-columns uses discrete animation when animating between "1px" and "5px" with keyframe easing
-PASS grid-auto-flow (type: discrete) has testInterpolation function
-PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with linear easing
-PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with effect easing
-PASS grid-auto-flow uses discrete animation when animating between "row" and "column" with keyframe easing
-PASS grid-auto-rows (type: discrete) has testInterpolation function
-PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with linear easing
-PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with effect easing
-PASS grid-auto-rows uses discrete animation when animating between "1px" and "5px" with keyframe easing
-PASS grid-column-end (type: discrete) has testInterpolation function
-PASS grid-column-end uses discrete animation when animating between "1" and "5" with linear easing
-PASS grid-column-end uses discrete animation when animating between "1" and "5" with effect easing
-PASS grid-column-end uses discrete animation when animating between "1" and "5" with keyframe easing
-PASS grid-column-start (type: discrete) has testInterpolation function
-PASS grid-column-start uses discrete animation when animating between "1" and "5" with linear easing
-PASS grid-column-start uses discrete animation when animating between "1" and "5" with effect easing
-PASS grid-column-start uses discrete animation when animating between "1" and "5" with keyframe easing
-PASS grid-row-end (type: discrete) has testInterpolation function
-PASS grid-row-end uses discrete animation when animating between "1" and "5" with linear easing
-PASS grid-row-end uses discrete animation when animating between "1" and "5" with effect easing
-PASS grid-row-end uses discrete animation when animating between "1" and "5" with keyframe easing
-PASS grid-row-start (type: discrete) has testInterpolation function
-PASS grid-row-start uses discrete animation when animating between "1" and "5" with linear easing
-PASS grid-row-start uses discrete animation when animating between "1" and "5" with effect easing
-PASS grid-row-start uses discrete animation when animating between "1" and "5" with keyframe easing
-PASS grid-template-areas (type: discrete) has testInterpolation function
-FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with linear easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
-FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with effect easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
-FAIL grid-template-areas uses discrete animation when animating between "". . a b" ". .a b"" and "none" with keyframe easing assert_equals: The value should be ". . a b" ". .a b" at 0ms expected "\". . a b\" \". .a b\"" but got "\". . a b\" \". . a b\""
-PASS grid-template-columns (type: discrete) has testInterpolation function
-PASS grid-template-columns uses discrete animation when animating between "1px" and "5px" with linear easing
-PASS grid-template-columns uses discrete animation when animating between "1px" and "5px" with effect easing
-PASS grid-template-columns uses discrete animation when animating between "1px" and "5px" with keyframe easing
-PASS grid-template-rows (type: discrete) has testInterpolation function
-PASS grid-template-rows uses discrete animation when animating between "1px" and "5px" with linear easing
-PASS grid-template-rows uses discrete animation when animating between "1px" and "5px" with effect easing
-PASS grid-template-rows uses discrete animation when animating between "1px" and "5px" with keyframe easing
-PASS hyphens (type: discrete) has testInterpolation function
-FAIL hyphens uses discrete animation when animating between "manual" and "auto" with linear easing assert_equals: The value should be auto at 500ms expected "auto" but got "manual"
-FAIL hyphens uses discrete animation when animating between "manual" and "auto" with effect easing assert_equals: The value should be auto at 960ms expected "auto" but got "manual"
-FAIL hyphens uses discrete animation when animating between "manual" and "auto" with keyframe easing assert_equals: The value should be auto at 960ms expected "auto" but got "manual"
-PASS image-orientation (type: discrete) has testInterpolation function
-FAIL image-orientation uses discrete animation when animating between "0deg" and "90deg" with linear easing assert_equals: The value should be 90deg at 500ms expected "90deg" but got "0deg"
-FAIL image-orientation uses discrete animation when animating between "0deg" and "90deg" with effect easing assert_equals: The value should be 90deg at 960ms expected "90deg" but got "0deg"
-FAIL image-orientation uses discrete animation when animating between "0deg" and "90deg" with keyframe easing assert_equals: The value should be 90deg at 960ms expected "90deg" but got "0deg"
-PASS isolation (type: discrete) has testInterpolation function
-PASS isolation uses discrete animation when animating between "auto" and "isolate" with linear easing
-PASS isolation uses discrete animation when animating between "auto" and "isolate" with effect easing
-PASS isolation uses discrete animation when animating between "auto" and "isolate" with keyframe easing
-PASS justify-content (type: discrete) has testInterpolation function
-PASS justify-content uses discrete animation when animating between "start" and "end" with linear easing
-PASS justify-content uses discrete animation when animating between "start" and "end" with effect easing
-PASS justify-content uses discrete animation when animating between "start" and "end" with keyframe easing
-PASS justify-items (type: discrete) has testInterpolation function
-PASS justify-items uses discrete animation when animating between "start" and "end" with linear easing
-PASS justify-items uses discrete animation when animating between "start" and "end" with effect easing
-PASS justify-items uses discrete animation when animating between "start" and "end" with keyframe easing
-PASS justify-self (type: discrete) has testInterpolation function
-PASS justify-self uses discrete animation when animating between "start" and "end" with linear easing
-PASS justify-self uses discrete animation when animating between "start" and "end" with effect easing
-PASS justify-self uses discrete animation when animating between "start" and "end" with keyframe easing
-PASS letter-spacing (type: length) has testInterpolation function
-PASS letter-spacing supports animating as a length
-PASS letter-spacing supports animating as a length of rem
-PASS lighting-color (type: color) has testInterpolation function
-PASS lighting-color supports animating as color of rgb()
-PASS lighting-color supports animating as color of #RGB
-PASS lighting-color supports animating as color of hsl()
-PASS lighting-color supports animating as color of #RGBa
-PASS lighting-color supports animating as color of rgba()
-PASS lighting-color supports animating as color of hsla()
-PASS list-style-image (type: discrete) has testInterpolation function
-FAIL list-style-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing assert_equals: The value should be url("http://localhost/test-1") at 499ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.499)"
-FAIL list-style-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-FAIL list-style-image uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing assert_equals: The value should be url("http://localhost/test-1") at 940ms expected "url(\"http://localhost/test-1\")" but got "-webkit-cross-fade(url(\"http://localhost/test-1\"), url(\"http://localhost/test-2\"), 0.427878)"
-PASS list-style-position (type: discrete) has testInterpolation function
-PASS list-style-position uses discrete animation when animating between "inside" and "outside" with linear easing
-PASS list-style-position uses discrete animation when animating between "inside" and "outside" with effect easing
-PASS list-style-position uses discrete animation when animating between "inside" and "outside" with keyframe easing
-PASS list-style-type (type: discrete) has testInterpolation function
-PASS list-style-type uses discrete animation when animating between "circle" and "square" with linear easing
-PASS list-style-type uses discrete animation when animating between "circle" and "square" with effect easing
-PASS list-style-type uses discrete animation when animating between "circle" and "square" with keyframe easing
-PASS marker-end (type: discrete) has testInterpolation function
-PASS marker-end uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing
-PASS marker-end uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing
-PASS marker-end uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing
-PASS marker-mid (type: discrete) has testInterpolation function
-PASS marker-mid uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing
-PASS marker-mid uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing
-PASS marker-mid uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing
-PASS marker-start (type: discrete) has testInterpolation function
-PASS marker-start uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing
-PASS marker-start uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing
-PASS marker-start uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing
-PASS mask (type: discrete) has testInterpolation function
-PASS mask uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing
-PASS mask uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing
-PASS mask uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing
-PASS mask-type (type: discrete) has testInterpolation function
-PASS mask-type uses discrete animation when animating between "alpha" and "luminance" with linear easing
-PASS mask-type uses discrete animation when animating between "alpha" and "luminance" with effect easing
-PASS mask-type uses discrete animation when animating between "alpha" and "luminance" with keyframe easing
-PASS mix-blend-mode (type: discrete) has testInterpolation function
-PASS mix-blend-mode uses discrete animation when animating between "multiply" and "screen" with linear easing
-PASS mix-blend-mode uses discrete animation when animating between "multiply" and "screen" with effect easing
-PASS mix-blend-mode uses discrete animation when animating between "multiply" and "screen" with keyframe easing
-PASS object-fit (type: discrete) has testInterpolation function
-PASS object-fit uses discrete animation when animating between "fill" and "contain" with linear easing
-PASS object-fit uses discrete animation when animating between "fill" and "contain" with effect easing
-PASS object-fit uses discrete animation when animating between "fill" and "contain" with keyframe easing
-PASS order (type: integer) has testInterpolation function
-PASS order supports animating as an integer
-PASS outline-color (type: color) has testInterpolation function
-PASS outline-color supports animating as color of rgb()
-PASS outline-color supports animating as color of #RGB
-PASS outline-color supports animating as color of hsl()
-PASS outline-color supports animating as color of #RGBa
-PASS outline-color supports animating as color of rgba()
-PASS outline-color supports animating as color of hsla()
-PASS outline-offset (type: length) has testInterpolation function
-FAIL outline-offset supports animating as a length assert_equals: The value should be 30px at 500ms expected "30px" but got "0px"
-FAIL outline-offset supports animating as a length of rem assert_equals: The value should be 30px at 500ms expected "30px" but got "0px"
-PASS outline-style (type: discrete) has testInterpolation function
-PASS outline-style uses discrete animation when animating between "none" and "dotted" with linear easing
-PASS outline-style uses discrete animation when animating between "none" and "dotted" with effect easing
-PASS outline-style uses discrete animation when animating between "none" and "dotted" with keyframe easing
-PASS outline-width (type: length) has testInterpolation function
-PASS outline-width supports animating as a length
-PASS outline-width supports animating as a length of rem
-PASS overflow-wrap (type: discrete) has testInterpolation function
-PASS overflow-wrap uses discrete animation when animating between "normal" and "break-word" with linear easing
-PASS overflow-wrap uses discrete animation when animating between "normal" and "break-word" with effect easing
-PASS overflow-wrap uses discrete animation when animating between "normal" and "break-word" with keyframe easing
-PASS overflow-x (type: discrete) has testInterpolation function
-PASS overflow-x uses discrete animation when animating between "visible" and "hidden" with linear easing
-PASS overflow-x uses discrete animation when animating between "visible" and "hidden" with effect easing
-PASS overflow-x uses discrete animation when animating between "visible" and "hidden" with keyframe easing
-PASS overflow-y (type: discrete) has testInterpolation function
-PASS overflow-y uses discrete animation when animating between "visible" and "hidden" with linear easing
-PASS overflow-y uses discrete animation when animating between "visible" and "hidden" with effect easing
-PASS overflow-y uses discrete animation when animating between "visible" and "hidden" with keyframe easing
-PASS page-break-after (type: discrete) has testInterpolation function
-PASS page-break-after uses discrete animation when animating between "always" and "auto" with linear easing
-PASS page-break-after uses discrete animation when animating between "always" and "auto" with effect easing
-PASS page-break-after uses discrete animation when animating between "always" and "auto" with keyframe easing
-PASS page-break-before (type: discrete) has testInterpolation function
-PASS page-break-before uses discrete animation when animating between "always" and "auto" with linear easing
-PASS page-break-before uses discrete animation when animating between "always" and "auto" with effect easing
-PASS page-break-before uses discrete animation when animating between "always" and "auto" with keyframe easing
-PASS page-break-inside (type: discrete) has testInterpolation function
-PASS page-break-inside uses discrete animation when animating between "auto" and "avoid" with linear easing
-PASS page-break-inside uses discrete animation when animating between "auto" and "avoid" with effect easing
-PASS page-break-inside uses discrete animation when animating between "auto" and "avoid" with keyframe easing
-PASS paint-order (type: discrete) has testInterpolation function
-FAIL paint-order uses discrete animation when animating between "fill" and "stroke" with linear easing assert_equals: The value should be fill at 0ms expected "fill" but got "fill stroke markers"
-FAIL paint-order uses discrete animation when animating between "fill" and "stroke" with effect easing assert_equals: The value should be fill at 0ms expected "fill" but got "fill stroke markers"
-FAIL paint-order uses discrete animation when animating between "fill" and "stroke" with keyframe easing assert_equals: The value should be fill at 0ms expected "fill" but got "fill stroke markers"
-PASS perspective (type: length) has testInterpolation function
-PASS perspective supports animating as a length
-PASS perspective supports animating as a length of rem
-PASS perspective-origin (type: position) has testInterpolation function
-PASS perspective-origin supports animating as a length pair
-PASS perspective-origin supports animating as a length pair of rem
-PASS perspective-origin supports animating as a position of percent
-PASS pointer-events (type: discrete) has testInterpolation function
-PASS pointer-events uses discrete animation when animating between "fill" and "none" with linear easing
-PASS pointer-events uses discrete animation when animating between "fill" and "none" with effect easing
-PASS pointer-events uses discrete animation when animating between "fill" and "none" with keyframe easing
-PASS position (type: discrete) has testInterpolation function
-PASS position uses discrete animation when animating between "absolute" and "fixed" with linear easing
-PASS position uses discrete animation when animating between "absolute" and "fixed" with effect easing
-PASS position uses discrete animation when animating between "absolute" and "fixed" with keyframe easing
-PASS quotes (type: discrete) has testInterpolation function
-PASS quotes uses discrete animation when animating between ""“" "”" "‘" "’"" and ""‘" "’" "“" "”"" with linear easing
-PASS quotes uses discrete animation when animating between ""“" "”" "‘" "’"" and ""‘" "’" "“" "”"" with effect easing
-PASS quotes uses discrete animation when animating between ""“" "”" "‘" "’"" and ""‘" "’" "“" "”"" with keyframe easing
-PASS resize (type: discrete) has testInterpolation function
-PASS resize uses discrete animation when animating between "both" and "horizontal" with linear easing
-PASS resize uses discrete animation when animating between "both" and "horizontal" with effect easing
-PASS resize uses discrete animation when animating between "both" and "horizontal" with keyframe easing
-PASS scroll-behavior (type: discrete) has testInterpolation function
-PASS scroll-behavior uses discrete animation when animating between "auto" and "smooth" with linear easing
-PASS scroll-behavior uses discrete animation when animating between "auto" and "smooth" with effect easing
-PASS scroll-behavior uses discrete animation when animating between "auto" and "smooth" with keyframe easing
-PASS shape-outside (type: discrete) has testInterpolation function
-PASS shape-outside uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with linear easing
-PASS shape-outside uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with effect easing
-PASS shape-outside uses discrete animation when animating between "url("http://localhost/test-1")" and "url("http://localhost/test-2")" with keyframe easing
-PASS shape-rendering (type: discrete) has testInterpolation function
-FAIL shape-rendering uses discrete animation when animating between "optimizeSpeed" and "crispEdges" with linear easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-FAIL shape-rendering uses discrete animation when animating between "optimizeSpeed" and "crispEdges" with effect easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-FAIL shape-rendering uses discrete animation when animating between "optimizeSpeed" and "crispEdges" with keyframe easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS stop-color (type: color) has testInterpolation function
-PASS stop-color supports animating as color of rgb()
-PASS stop-color supports animating as color of #RGB
-PASS stop-color supports animating as color of hsl()
-PASS stop-color supports animating as color of #RGBa
-PASS stop-color supports animating as color of rgba()
-PASS stop-color supports animating as color of hsla()
-PASS stop-opacity (type: opacity) has testInterpolation function
-PASS stop-opacity supports animating as a [0, 1] number
-PASS stroke-dasharray (type: dasharray) has testInterpolation function
-PASS stroke-dasharray supports animating as a percentage
-FAIL stroke-dasharray supports animating as a positive number assert_equals: The value should be 1.3 at 500ms expected "1.3" but got "1.3px"
-FAIL stroke-dasharray supports animating as a dasharray (mismatched length) assert_equals: The value should be 6, 12, 8, 12, 10, 6, 10, 16, 4, 8, 14, 10 at 500ms expected "6, 12, 8, 12, 10, 6, 10, 16, 4, 8, 14, 10" but got "6px, 12px, 8px, 12px, 10px, 6px, 10px, 16px, 4px, 8px, 14px, 10px"
-FAIL stroke-dasharray supports animating as a dasharray (mixed number and percentage) assert_equals: The value should be 4, 40%, 4, 6 at 500ms expected "4, 40%, 4, 6" but got "4px, 40%, 4px, 6px"
-PASS stroke-dasharray (type: discrete) has testInterpolation function
-FAIL stroke-dasharray uses discrete animation when animating between "none" and "10, 20" with linear easing assert_equals: The value should be 10, 20 at 500ms expected "10, 20" but got "10px, 20px"
-FAIL stroke-dasharray uses discrete animation when animating between "none" and "10, 20" with effect easing assert_equals: The value should be 10, 20 at 960ms expected "10, 20" but got "10px, 20px"
-FAIL stroke-dasharray uses discrete animation when animating between "none" and "10, 20" with keyframe easing assert_equals: The value should be 10, 20 at 960ms expected "10, 20" but got "10px, 20px"
-PASS stroke-linecap (type: discrete) has testInterpolation function
-PASS stroke-linecap uses discrete animation when animating between "round" and "square" with linear easing
-PASS stroke-linecap uses discrete animation when animating between "round" and "square" with effect easing
-PASS stroke-linecap uses discrete animation when animating between "round" and "square" with keyframe easing
-PASS stroke-linejoin (type: discrete) has testInterpolation function
-PASS stroke-linejoin uses discrete animation when animating between "round" and "miter" with linear easing
-PASS stroke-linejoin uses discrete animation when animating between "round" and "miter" with effect easing
-PASS stroke-linejoin uses discrete animation when animating between "round" and "miter" with keyframe easing
-PASS stroke-miterlimit (type: positiveNumber) has testInterpolation function
-PASS stroke-miterlimit supports animating as a positive number
-PASS stroke-opacity (type: opacity) has testInterpolation function
-PASS stroke-opacity supports animating as a [0, 1] number
-PASS table-layout (type: discrete) has testInterpolation function
-PASS table-layout uses discrete animation when animating between "auto" and "fixed" with linear easing
-PASS table-layout uses discrete animation when animating between "auto" and "fixed" with effect easing
-PASS table-layout uses discrete animation when animating between "auto" and "fixed" with keyframe easing
-PASS text-align (type: discrete) has testInterpolation function
-PASS text-align uses discrete animation when animating between "start" and "end" with linear easing
-PASS text-align uses discrete animation when animating between "start" and "end" with effect easing
-PASS text-align uses discrete animation when animating between "start" and "end" with keyframe easing
-PASS text-align-last (type: discrete) has testInterpolation function
-PASS text-align-last uses discrete animation when animating between "start" and "end" with linear easing
-PASS text-align-last uses discrete animation when animating between "start" and "end" with effect easing
-PASS text-align-last uses discrete animation when animating between "start" and "end" with keyframe easing
-PASS text-anchor (type: discrete) has testInterpolation function
-PASS text-anchor uses discrete animation when animating between "middle" and "end" with linear easing
-PASS text-anchor uses discrete animation when animating between "middle" and "end" with effect easing
-PASS text-anchor uses discrete animation when animating between "middle" and "end" with keyframe easing
-PASS text-combine-upright (type: discrete) has testInterpolation function
-PASS text-combine-upright uses discrete animation when animating between "all" and "none" with linear easing
-PASS text-combine-upright uses discrete animation when animating between "all" and "none" with effect easing
-PASS text-combine-upright uses discrete animation when animating between "all" and "none" with keyframe easing
-PASS text-decoration-color (type: color) has testInterpolation function
-PASS text-decoration-color supports animating as color of rgb()
-PASS text-decoration-color supports animating as color of #RGB
-PASS text-decoration-color supports animating as color of hsl()
-PASS text-decoration-color supports animating as color of #RGBa
-PASS text-decoration-color supports animating as color of rgba()
-PASS text-decoration-color supports animating as color of hsla()
-PASS text-decoration-line (type: discrete) has testInterpolation function
-PASS text-decoration-line uses discrete animation when animating between "underline" and "overline" with linear easing
-PASS text-decoration-line uses discrete animation when animating between "underline" and "overline" with effect easing
-PASS text-decoration-line uses discrete animation when animating between "underline" and "overline" with keyframe easing
-PASS text-decoration-style (type: discrete) has testInterpolation function
-PASS text-decoration-style uses discrete animation when animating between "solid" and "dotted" with linear easing
-PASS text-decoration-style uses discrete animation when animating between "solid" and "dotted" with effect easing
-PASS text-decoration-style uses discrete animation when animating between "solid" and "dotted" with keyframe easing
-PASS text-orientation (type: discrete) has testInterpolation function
-PASS text-orientation uses discrete animation when animating between "upright" and "sideways" with linear easing
-PASS text-orientation uses discrete animation when animating between "upright" and "sideways" with effect easing
-PASS text-orientation uses discrete animation when animating between "upright" and "sideways" with keyframe easing
-PASS text-overflow (type: discrete) has testInterpolation function
-PASS text-overflow uses discrete animation when animating between "clip" and "ellipsis" with linear easing
-PASS text-overflow uses discrete animation when animating between "clip" and "ellipsis" with effect easing
-PASS text-overflow uses discrete animation when animating between "clip" and "ellipsis" with keyframe easing
-PASS text-rendering (type: discrete) has testInterpolation function
-FAIL text-rendering uses discrete animation when animating between "optimizeSpeed" and "optimizeLegibility" with linear easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-FAIL text-rendering uses discrete animation when animating between "optimizeSpeed" and "optimizeLegibility" with effect easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-FAIL text-rendering uses discrete animation when animating between "optimizeSpeed" and "optimizeLegibility" with keyframe easing assert_equals: The value should be optimizespeed at 0ms expected "optimizespeed" but got "optimizeSpeed"
-PASS text-shadow (type: textShadowList) has testInterpolation function
-PASS text-shadow: from none to other
-PASS text-shadow: from other to none
-PASS text-shadow: single shadow
-PASS text-shadow: shadow list
-PASS text-shadow: mismatched list length (from longer to shorter)
-PASS text-shadow: mismatched list length (from shorter to longer)
-PASS text-shadow: with currentcolor
-PASS text-transform (type: discrete) has testInterpolation function
-PASS text-transform uses discrete animation when animating between "capitalize" and "uppercase" with linear easing
-PASS text-transform uses discrete animation when animating between "capitalize" and "uppercase" with effect easing
-PASS text-transform uses discrete animation when animating between "capitalize" and "uppercase" with keyframe easing
-PASS touch-action (type: discrete) has testInterpolation function
-PASS touch-action uses discrete animation when animating between "auto" and "none" with linear easing
-PASS touch-action uses discrete animation when animating between "auto" and "none" with effect easing
-PASS touch-action uses discrete animation when animating between "auto" and "none" with keyframe easing
-PASS transform (type: transformList) has testInterpolation function
-PASS transform: translate
-PASS transform: rotate
-PASS transform: scale
-PASS transform: skew
-PASS transform: rotate and translate
-PASS transform: translate and rotate
-FAIL transform: extend shorter list (from) assert_approx_equals: expected matrix(-1,0,0,-1,-50,0) but got matrix(1, 0, 0, 1, 50, -3.67394e-14): The value should be matrix(-1,0,0,-1,-50,0) at 500ms but got matrix(1, 0, 0, 1, 50, -3.67394e-14) expected -1 +/- 0.0001 but got 1
-FAIL transform: extend shorter list (to) assert_approx_equals: expected matrix(-1,0,0,-1,-50,0) but got matrix(1, 0, 0, 1, 50, 0): The value should be matrix(-1,0,0,-1,-50,0) at 500ms but got matrix(1, 0, 0, 1, 50, 0) expected -1 +/- 0.0001 but got 1
-FAIL transform: mismatch order of translate and rotate assert_approx_equals: expected matrix(-0.7071067811865475,0.7071067811865476,-0.7071067811865476,-0.7071067811865475,100,50) but got matrix(0.707107, -0.707107, 0.707107, 0.707107, 100, 50): The value should be matrix(-0.7071067811865475,0.7071067811865476,-0.7071067811865476,-0.7071067811865475,100,50) at 500ms but got matrix(0.707107, -0.707107, 0.707107, 0.707107, 100, 50) expected -0.7071067811865475 +/- 0.0001 but got 0.707107
-FAIL transform: matrix assert_approx_equals: expected matrix(-0.7071067811865475,0.7071067811865476,-0.7071067811865476,-0.7071067811865475,100,50) but got matrix(0.707107, -0.707107, 0.707107, 0.707107, 100, 50): The value should be matrix(-0.7071067811865475,0.7071067811865476,-0.7071067811865476,-0.7071067811865475,100,50) at 500ms but got matrix(0.707107, -0.707107, 0.707107, 0.707107, 100, 50) expected -0.7071067811865475 +/- 0.0001 but got 0.707107
-PASS transform: rotate3d
-PASS transform: matrix3d
-PASS transform: mismatched 3D transforms
-PASS transform: rotateY
-PASS transform: non-invertible matrices
-FAIL transform: non-invertible matrices in matched transform lists assert_approx_equals: expected matrix(0,-1,1,0,250,0) but got matrix(0.705995, -0.708217, 0.708217, 0.705995, 274.95, 0): The value should be matrix(0,-1,1,0,250,0) at 499ms but got matrix(0.705995, -0.708217, 0.708217, 0.705995, 274.95, 0) expected 0 +/- 0.0001 but got 0.705995
-PASS transform: non-invertible matrices in mismatched transform lists
-PASS transform-box (type: discrete) has testInterpolation function
-FAIL transform-box uses discrete animation when animating between "fill-box" and "border-box" with linear easing assert_equals: The value should be border-box at 500ms expected "border-box" but got "view-box"
-FAIL transform-box uses discrete animation when animating between "fill-box" and "border-box" with effect easing assert_equals: The value should be border-box at 960ms expected "border-box" but got "view-box"
-FAIL transform-box uses discrete animation when animating between "fill-box" and "border-box" with keyframe easing assert_equals: The value should be border-box at 960ms expected "border-box" but got "view-box"
-PASS transform-style (type: discrete) has testInterpolation function
-PASS transform-style uses discrete animation when animating between "flat" and "preserve-3d" with linear easing
-PASS transform-style uses discrete animation when animating between "flat" and "preserve-3d" with effect easing
-PASS transform-style uses discrete animation when animating between "flat" and "preserve-3d" with keyframe easing
-PASS rotate (type: rotateList) has testInterpolation function
-PASS rotate without rotation axes
-PASS rotate with rotation axes
-PASS rotate with rotation axes and range over 360 degrees
-FAIL rotate with different rotation axes assert_approx_equals: expected 0 0.707107 0.707107 45deg but got 0 1 1 45deg: The value should be 0 0.707107 0.707107 45deg at 500ms but got 0 1 1 45deg expected 0.707107 +/- 0.0001 but got 1
-PASS translate (type: translateList) has testInterpolation function
-PASS translate with two unspecified values
-PASS translate with one unspecified value
-PASS translate with all three values specified
-FAIL translate with combination of percentages and lengths assert_equals: The value should be 200px -25.5px 200px at 500ms expected "200px -25.5px 200px" but got "200px calc(-50.5px + 25%) 200px"
-PASS scale (type: scaleList) has testInterpolation function
-FAIL scale with two unspecified values assert_equals: The value should be 4 at 500ms expected "4" but got "4 1"
-PASS scale with one unspecified value
-PASS scale
-PASS unicode-bidi (type: discrete) has testInterpolation function
-PASS unicode-bidi uses discrete animation when animating between "embed" and "bidi-override" with linear easing
-PASS unicode-bidi uses discrete animation when animating between "embed" and "bidi-override" with effect easing
-PASS unicode-bidi uses discrete animation when animating between "embed" and "bidi-override" with keyframe easing
-PASS vector-effect (type: discrete) has testInterpolation function
-PASS vector-effect uses discrete animation when animating between "none" and "non-scaling-stroke" with linear easing
-PASS vector-effect uses discrete animation when animating between "none" and "non-scaling-stroke" with effect easing
-PASS vector-effect uses discrete animation when animating between "none" and "non-scaling-stroke" with keyframe easing
-PASS visibility (type: visibility) has testInterpolation function
-PASS visibility uses visibility animation when animating from "visible" to "hidden"
-PASS visibility uses visibility animation when animating from "hidden" to "visible"
-PASS visibility uses visibility animation when animating from "hidden" to "collapse"
-PASS visibility uses visibility animation when animating from "visible" to "hidden" with easeInOutBack easing
-PASS white-space (type: discrete) has testInterpolation function
-PASS white-space uses discrete animation when animating between "pre" and "nowrap" with linear easing
-PASS white-space uses discrete animation when animating between "pre" and "nowrap" with effect easing
-PASS white-space uses discrete animation when animating between "pre" and "nowrap" with keyframe easing
-PASS word-break (type: discrete) has testInterpolation function
-PASS word-break uses discrete animation when animating between "keep-all" and "break-all" with linear easing
-PASS word-break uses discrete animation when animating between "keep-all" and "break-all" with effect easing
-PASS word-break uses discrete animation when animating between "keep-all" and "break-all" with keyframe easing
-PASS word-spacing (type: lengthPercentageOrCalc) has testInterpolation function
-PASS word-spacing supports animating as a length
-PASS word-spacing supports animating as a length of rem
-FAIL word-spacing supports animating as a percentage assert_equals: The value should be 30% at 500ms expected "30%" but got "0px"
-FAIL word-spacing supports animating as combination units "px" and "%" assert_equals: The value should be calc(5px + 10%) at 500ms expected "calc(5px + 10%)" but got "5px"
-FAIL word-spacing supports animating as combination units "%" and "em" assert_equals: The value should be calc(10px + 5%) at 500ms expected "calc(10px + 5%)" but got "10px"
-PASS word-spacing supports animating as combination units "em" and "rem"
-FAIL word-spacing supports animating as combination units "px" and "calc" assert_equals: The value should be calc(10px + 10%) at 500ms expected "calc(10px + 10%)" but got "5px"
-FAIL word-spacing supports animating as a calc assert_equals: The value should be calc(15px + 15%) at 500ms expected "calc(15px + 15%)" but got "0px"
-PASS will-change (type: discrete) has testInterpolation function
-PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with linear easing
-PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with effect easing
-PASS will-change uses discrete animation when animating between "scroll-position" and "contents" with keyframe easing
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/common/origin_policy/OWNERS b/third_party/blink/common/origin_policy/OWNERS
new file mode 100644
index 0000000..ec8b57e
--- /dev/null
+++ b/third_party/blink/common/origin_policy/OWNERS
@@ -0,0 +1,2 @@
+vogelheim@chromium.org
+mkwst@chromium.org
diff --git a/third_party/blink/public/common/origin_policy/OWNERS b/third_party/blink/public/common/origin_policy/OWNERS
new file mode 100644
index 0000000..cc8f52f4
--- /dev/null
+++ b/third_party/blink/public/common/origin_policy/OWNERS
@@ -0,0 +1 @@
+file://third_party/blink/common/origin_policy/OWNERS
diff --git a/third_party/blink/public/platform/web_surface_layer_bridge.h b/third_party/blink/public/platform/web_surface_layer_bridge.h
index 30e7f6da..ed484b0 100644
--- a/third_party/blink/public/platform/web_surface_layer_bridge.h
+++ b/third_party/blink/public/platform/web_surface_layer_bridge.h
@@ -37,6 +37,7 @@
   virtual void ClearSurfaceId() = 0;
   virtual void SetContentsOpaque(bool) = 0;
   virtual void CreateSurfaceLayer() = 0;
+  virtual const viz::SurfaceId& GetSurfaceId() const = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/public/platform/web_theme_engine.h b/third_party/blink/public/platform/web_theme_engine.h
index e8353732..d3253c4a 100644
--- a/third_party/blink/public/platform/web_theme_engine.h
+++ b/third_party/blink/public/platform/web_theme_engine.h
@@ -31,6 +31,7 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_THEME_ENGINE_H_
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_THEME_ENGINE_H_
 
+#include "base/time/time.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h"
 #include "third_party/blink/public/platform/web_size.h"
@@ -169,8 +170,8 @@
     int thumb_thickness;
     int scrollbar_margin;
     SkColor color;
-    double fade_out_delay_seconds;
-    double fade_out_duration_seconds;
+    base::TimeDelta fade_out_delay;
+    base::TimeDelta fade_out_duration;
   };
 
   // Gets the overlay scrollbar style. Not used on Mac.
@@ -178,8 +179,8 @@
     // Disable overlay scrollbar fade out (for non-composited scrollers) unless
     // explicitly enabled by the implementing child class. NOTE: these values
     // aren't used to control Mac fade out - that happens in ScrollAnimatorMac.
-    style->fade_out_delay_seconds = 0.0;
-    style->fade_out_duration_seconds = 0.0;
+    style->fade_out_delay = base::TimeDelta();
+    style->fade_out_duration = base::TimeDelta();
     // The other fields in this struct are used only on Android to draw solid
     // color scrollbars. On other platforms the scrollbars are painted in
     // NativeTheme so these fields are unused in non-Android WebThemeEngines.
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
index 9927d4f..70e6a88 100644
--- a/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
+++ b/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc
@@ -387,7 +387,7 @@
       std::make_unique<CSSVarCycleInterpolationType>(property, registration));
 
   for (const CSSSyntaxComponent& component : descriptor.Components()) {
-    if (component.repeatable_) {
+    if (component.IsRepeatable()) {
       // TODO(alancutter): Support animation of repeatable types.
       continue;
     }
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer.cc b/third_party/blink/renderer/core/clipboard/data_transfer.cc
index 1896a0e..43f6f8b 100644
--- a/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -372,7 +372,7 @@
   IntRect viewport_in_root_frame =
       EnclosingIntRect(frame.GetPage()->GetVisualViewport().VisibleRect());
   FloatRect absolute_viewport =
-      frame.View()->ConvertFromRootFrame(viewport_in_root_frame);
+      FloatRect(frame.View()->ConvertFromRootFrame(viewport_in_root_frame));
   return Intersection(absolute_viewport, absolute_rect);
 }
 
diff --git a/third_party/blink/renderer/core/css/css_syntax_descriptor.cc b/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
index 0ab312f..2056648 100644
--- a/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
+++ b/third_party/blink/renderer/core/css/css_syntax_descriptor.cc
@@ -96,8 +96,8 @@
   if (ConsumeCharacterAndWhitespace(input, '*', offset)) {
     if (offset != input.length())
       return;
-    syntax_components_.push_back(
-        CSSSyntaxComponent(CSSSyntaxType::kTokenStream, g_empty_string, false));
+    syntax_components_.push_back(CSSSyntaxComponent(
+        CSSSyntaxType::kTokenStream, g_empty_string, CSSSyntaxRepeat::kNone));
     return;
   }
 
@@ -118,15 +118,23 @@
       return;
     }
 
-    bool repeatable = ConsumeCharacterAndWhitespace(input, '+', offset);
+    CSSSyntaxRepeat repeat = CSSSyntaxRepeat::kNone;
+
+    if (ConsumeCharacterAndWhitespace(input, '+', offset))
+      repeat = CSSSyntaxRepeat::kSpaceSeparated;
+    else if (ConsumeCharacterAndWhitespace(input, '#', offset))
+      repeat = CSSSyntaxRepeat::kCommaSeparated;
+
     // <transform-list> is already a space separated list,
     // <transform-list>+ is invalid.
-    if (type == CSSSyntaxType::kTransformList && repeatable) {
+    // TODO(andruud): Is <transform-list># invalid?
+    if (type == CSSSyntaxType::kTransformList &&
+        repeat != CSSSyntaxRepeat::kNone) {
       syntax_components_.clear();
       return;
     }
     ConsumeWhitespace(input, offset);
-    syntax_components_.push_back(CSSSyntaxComponent(type, ident, repeatable));
+    syntax_components_.push_back(CSSSyntaxComponent(type, ident, repeat));
 
   } while (ConsumeCharacterAndWhitespace(input, '|', offset));
 
@@ -185,7 +193,7 @@
                                        CSSParserTokenRange range,
                                        const CSSParserContext* context) {
   // CSS-wide keywords are already handled by the CSSPropertyParser
-  if (syntax.repeatable_) {
+  if (syntax.repeat_ == CSSSyntaxRepeat::kSpaceSeparated) {
     CSSValueList* list = CSSValueList::CreateSpaceSeparated();
     while (!range.AtEnd()) {
       const CSSValue* value = ConsumeSingleType(syntax, range, context);
@@ -195,6 +203,16 @@
     }
     return list;
   }
+  if (syntax.repeat_ == CSSSyntaxRepeat::kCommaSeparated) {
+    CSSValueList* list = CSSValueList::CreateCommaSeparated();
+    do {
+      const CSSValue* value = ConsumeSingleType(syntax, range, context);
+      if (!value)
+        return nullptr;
+      list->Append(*value);
+    } while (CSSPropertyParserHelpers::ConsumeCommaIncludingWhitespace(range));
+    return list;
+  }
   const CSSValue* result = ConsumeSingleType(syntax, range, context);
   if (!range.AtEnd())
     return nullptr;
diff --git a/third_party/blink/renderer/core/css/css_syntax_descriptor.h b/third_party/blink/renderer/core/css/css_syntax_descriptor.h
index 55a9b060..02461aa 100644
--- a/third_party/blink/renderer/core/css/css_syntax_descriptor.h
+++ b/third_party/blink/renderer/core/css/css_syntax_descriptor.h
@@ -30,18 +30,23 @@
   kCustomIdent,
 };
 
+enum class CSSSyntaxRepeat { kNone, kSpaceSeparated, kCommaSeparated };
+
 struct CSSSyntaxComponent {
-  CSSSyntaxComponent(CSSSyntaxType type, const String& string, bool repeatable)
-      : type_(type), string_(string), repeatable_(repeatable) {}
+  CSSSyntaxComponent(CSSSyntaxType type,
+                     const String& string,
+                     CSSSyntaxRepeat repeat)
+      : type_(type), string_(string), repeat_(repeat) {}
 
   bool operator==(const CSSSyntaxComponent& a) const {
-    return type_ == a.type_ && string_ == a.string_ &&
-           repeatable_ == a.repeatable_;
+    return type_ == a.type_ && string_ == a.string_ && repeat_ == a.repeat_;
   }
 
+  bool IsRepeatable() const { return repeat_ != CSSSyntaxRepeat::kNone; }
+
   CSSSyntaxType type_;
   String string_;  // Only used when type_ is CSSSyntaxType::kIdent
-  bool repeatable_;
+  CSSSyntaxRepeat repeat_;
 };
 
 class CORE_EXPORT CSSSyntaxDescriptor {
diff --git a/third_party/blink/renderer/core/css/css_value_list.h b/third_party/blink/renderer/core/css/css_value_list.h
index 0dbc40ad..d1c0b3d 100644
--- a/third_party/blink/renderer/core/css/css_value_list.h
+++ b/third_party/blink/renderer/core/css/css_value_list.h
@@ -44,6 +44,10 @@
   static CSSValueList* CreateSlashSeparated() {
     return new CSSValueList(kSlashSeparator);
   }
+  static CSSValueList* CreateWithSeparatorFrom(const CSSValueList& list) {
+    return new CSSValueList(
+        static_cast<ValueListSeparator>(list.value_list_separator_));
+  }
 
   iterator begin() { return values_.begin(); }
   iterator end() { return values_.end(); }
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 6bace24c..a75cb362 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1657,8 +1657,9 @@
   }
 
   if (value.IsValueList()) {
-    CSSValueList* new_list = CSSValueList::CreateSpaceSeparated();
-    for (const CSSValue* inner_value : ToCSSValueList(value)) {
+    const CSSValueList& old_list = ToCSSValueList(value);
+    CSSValueList* new_list = CSSValueList::CreateWithSeparatorFrom(old_list);
+    for (const CSSValue* inner_value : old_list) {
       new_list->Append(ComputeRegisteredPropertyValue(
           css_to_length_conversion_data, *inner_value));
     }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 4783cd2..ab1a445 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -137,7 +137,6 @@
 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
 #include "third_party/blink/renderer/core/frame/frame_console.h"
 #include "third_party/blink/renderer/core/frame/history.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
 #include "third_party/blink/renderer/core/frame/intervention.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -1123,10 +1122,6 @@
                                       const ElementRegistrationOptions& options,
                                       ExceptionState& exception_state,
                                       V0CustomElement::NameSet valid_names) {
-  HostsUsingFeatures::CountMainWorldOnly(
-      script_state, *this,
-      HostsUsingFeatures::Feature::kDocumentRegisterElement);
-
   if (!RegistrationContext()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 21accab..2b8a010 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -87,7 +87,6 @@
 #include "third_party/blink/renderer/core/editing/visible_selection.h"
 #include "third_party/blink/renderer/core/events/focus_event.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -2709,11 +2708,7 @@
   return g_null_atom;
 }
 
-ShadowRoot* Element::createShadowRoot(const ScriptState* script_state,
-                                      ExceptionState& exception_state) {
-  HostsUsingFeatures::CountMainWorldOnly(
-      script_state, GetDocument(),
-      HostsUsingFeatures::Feature::kElementCreateShadowRoot);
+ShadowRoot* Element::createShadowRoot(ExceptionState& exception_state) {
   if (ShadowRoot* root = GetShadowRoot()) {
     if (root->IsUserAgent()) {
       exception_state.ThrowDOMException(
@@ -2765,14 +2760,9 @@
          tag_name == HTMLNames::spanTag;
 }
 
-ShadowRoot* Element::attachShadow(const ScriptState* script_state,
-                                  const ShadowRootInit& shadow_root_init_dict,
+ShadowRoot* Element::attachShadow(const ShadowRootInit& shadow_root_init_dict,
                                   ExceptionState& exception_state) {
   DCHECK(shadow_root_init_dict.hasMode());
-  HostsUsingFeatures::CountMainWorldOnly(
-      script_state, GetDocument(),
-      HostsUsingFeatures::Feature::kElementAttachShadow);
-
   if (!CanAttachShadowRoot()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 06c9fe5..dfcadf8 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -491,13 +491,8 @@
   // creation of multiple shadow roots is prohibited in any combination and
   // throws an exception.  Multiple shadow roots are allowed only when
   // createShadowRoot() is used without any parameters from JavaScript.
-  //
-  // TODO(esprehn): These take a ScriptState only for calling
-  // HostsUsingFeatures::countMainWorldOnly, which should be handled in the
-  // bindings instead so adding a ShadowRoot from C++ doesn't need one.
-  ShadowRoot* createShadowRoot(const ScriptState*, ExceptionState&);
-  ShadowRoot* attachShadow(const ScriptState*,
-                           const ShadowRootInit&,
+  ShadowRoot* createShadowRoot(ExceptionState&);
+  ShadowRoot* attachShadow(const ShadowRootInit&,
                            ExceptionState&);
 
   ShadowRoot& CreateV0ShadowRootForTesting() {
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl
index 5bd183d..534f5d1 100644
--- a/third_party/blink/renderer/core/dom/element.idl
+++ b/third_party/blink/renderer/core/dom/element.idl
@@ -66,7 +66,7 @@
     [RaisesException] boolean matches(DOMString selectors);
     [RaisesException, ImplementedAs=matches, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector(DOMString selectors); // historical alias of .matches
 
-    [RaisesException, CallWith=ScriptState, MeasureAs=ElementAttachShadow] ShadowRoot attachShadow(ShadowRootInit shadowRootInitDict);
+    [RaisesException, MeasureAs=ElementAttachShadow] ShadowRoot attachShadow(ShadowRootInit shadowRootInitDict);
     [Affects=Nothing, PerWorldBindings, ImplementedAs=OpenShadowRoot] readonly attribute ShadowRoot? shadowRoot;
 
     [Affects=Nothing] HTMLCollection getElementsByTagName(DOMString localName);
@@ -125,7 +125,7 @@
 
     // Non-standard API
     [MeasureAs=ElementScrollIntoViewIfNeeded] void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
-    [RuntimeEnabled=ShadowDOMV0, RaisesException, CallWith=ScriptState, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
+    [RuntimeEnabled=ShadowDOMV0, RaisesException, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
     [RuntimeEnabled=ShadowDOMV0] NodeList getDestinationInsertionPoints();
 
     // Experimental accessibility API
diff --git a/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc b/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
index fbd11ea..d9abe8a 100644
--- a/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
@@ -80,8 +80,8 @@
   FloatRect overflow_rect(scrolled_origin,
                           FloatSize(container->MaxLayoutOverflow()));
   FloatRect container_rect =
-      container->LocalToAbsoluteQuad(FloatQuad(overflow_rect))
-          .EnclosingBoundingBox();
+      FloatRect(container->LocalToAbsoluteQuad(FloatQuad(overflow_rect))
+                    .EnclosingBoundingBox());
 
   if (container_rect.IsEmpty())
     return FloatRect();
@@ -117,8 +117,9 @@
       const LayoutBlock* container = EnclosingScrollableAncestor(layout_object);
 
       // Compose the normalized rects.
-      FloatRect normalized_box_rect = ToNormalizedRect(
-          layout_object->AbsoluteBoundingBoxRect(), layout_object, container);
+      FloatRect normalized_box_rect =
+          ToNormalizedRect(FloatRect(layout_object->AbsoluteBoundingBoxRect()),
+                           layout_object, container);
       normalized_rect.Scale(normalized_box_rect.Width(),
                             normalized_box_rect.Height());
       normalized_rect.MoveBy(normalized_box_rect.Location());
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index caa84664..7ee2f0b 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -95,13 +95,15 @@
   CSPDirectiveList* directives = new CSPDirectiveList(policy, type, source);
   directives->Parse(begin, end, should_parse_wasm_eval);
 
-  if (!directives->CheckEval(
-          directives->OperativeDirective(directives->script_src_.Get()))) {
+  if (!directives->CheckEval(directives->OperativeDirective(
+          ContentSecurityPolicy::DirectiveType::kScriptSrc))) {
     String message =
         "Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
         "not an allowed source of script in the following Content Security "
         "Policy directive: \"" +
-        directives->OperativeDirective(directives->script_src_.Get())
+        directives
+            ->OperativeDirective(
+                ContentSecurityPolicy::DirectiveType::kScriptSrc)
             ->GetText() +
         "\".\n";
     directives->SetEvalDisabledErrorMessage(message);
@@ -117,7 +119,7 @@
 
 void CSPDirectiveList::ReportViolation(
     const String& directive_text,
-    const ContentSecurityPolicy::DirectiveType& effective_type,
+    const ContentSecurityPolicy::DirectiveType effective_type,
     const String& console_message,
     const KURL& blocked_url,
     ResourceRequest::RedirectStatus redirect_status) const {
@@ -135,7 +137,7 @@
 
 void CSPDirectiveList::ReportViolationWithFrame(
     const String& directive_text,
-    const ContentSecurityPolicy::DirectiveType& effective_type,
+    const ContentSecurityPolicy::DirectiveType effective_type,
     const String& console_message,
     const KURL& blocked_url,
     LocalFrame* frame) const {
@@ -152,7 +154,7 @@
 
 void CSPDirectiveList::ReportViolationWithLocation(
     const String& directive_text,
-    const ContentSecurityPolicy::DirectiveType& effective_type,
+    const ContentSecurityPolicy::DirectiveType effective_type,
     const String& console_message,
     const KURL& blocked_url,
     const String& context_url,
@@ -176,7 +178,7 @@
 
 void CSPDirectiveList::ReportEvalViolation(
     const String& directive_text,
-    const ContentSecurityPolicy::DirectiveType& effective_type,
+    const ContentSecurityPolicy::DirectiveType effective_type,
     const String& message,
     const KURL& blocked_url,
     ScriptState* script_state,
@@ -375,17 +377,6 @@
   return directive->Allows(type);
 }
 
-SourceListDirective* CSPDirectiveList::OperativeDirective(
-    SourceListDirective* directive) const {
-  return directive ? directive : default_src_.Get();
-}
-
-SourceListDirective* CSPDirectiveList::OperativeDirective(
-    SourceListDirective* directive,
-    SourceListDirective* override) const {
-  return directive ? directive : override;
-}
-
 bool CSPDirectiveList::CheckEvalAndReportViolation(
     SourceListDirective* directive,
     const String& console_message,
@@ -515,7 +506,7 @@
 bool CSPDirectiveList::CheckSourceAndReportViolation(
     SourceListDirective* directive,
     const KURL& url,
-    const ContentSecurityPolicy::DirectiveType& effective_type,
+    const ContentSecurityPolicy::DirectiveType effective_type,
     ResourceRequest::RedirectStatus redirect_status) const {
   if (!directive)
     return true;
@@ -608,7 +599,8 @@
     const String& context_url,
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy) const {
-  SourceListDirective* directive = OperativeDirective(script_src_.Get());
+  SourceListDirective* directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
     return CheckInlineAndReportViolation(
         directive,
@@ -626,10 +618,11 @@
     const String& context_url,
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy) const {
-  SourceListDirective* directive = OperativeDirective(script_src_.Get());
+  SourceListDirective* directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
     return CheckInlineAndReportViolation(
-        OperativeDirective(script_src_.Get()),
+        OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
         "Refused to execute inline event handler because it violates the "
         "following Content Security Policy directive: ",
         element, source, context_url, context_line, true, "sha256-...");
@@ -645,7 +638,8 @@
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy,
     const String& content) const {
-  SourceListDirective* directive = OperativeDirective(script_src_.Get());
+  SourceListDirective* directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
   if (IsMatchingNoncePresent(directive, nonce))
     return true;
   if (element && IsHTMLScriptElement(element) &&
@@ -672,7 +666,8 @@
     const WTF::OrdinalNumber& context_line,
     SecurityViolationReportingPolicy reporting_policy,
     const String& content) const {
-  SourceListDirective* directive = OperativeDirective(style_src_.Get());
+  SourceListDirective* directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kStyleSrc);
   if (IsMatchingNoncePresent(directive, nonce))
     return true;
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
@@ -694,13 +689,14 @@
     const String& content) const {
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
     return CheckEvalAndReportViolation(
-        OperativeDirective(script_src_.Get()),
+        OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
         "Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
         "not an allowed source of script in the following Content Security "
         "Policy directive: ",
         script_state, exception_status, content);
   }
-  return CheckEval(OperativeDirective(script_src_.Get()));
+  return CheckEval(
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
 }
 
 bool CSPDirectiveList::AllowWasmEval(
@@ -710,13 +706,14 @@
     const String& content) const {
   if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
     return CheckWasmEvalAndReportViolation(
-        OperativeDirective(script_src_.Get()),
+        OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
         "Refused to compile or instantiate WebAssembly module because "
         "'wasm-eval' is not an allowed source of script in the following "
         "Content Security Policy directive: ",
         script_state, exception_status, content);
   }
-  return CheckWasmEval(OperativeDirective(script_src_.Get()));
+  return CheckWasmEval(
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
 }
 
 bool CSPDirectiveList::AllowPluginType(
@@ -741,7 +738,8 @@
     ParserDisposition parser_disposition,
     ResourceRequest::RedirectStatus redirect_status,
     SecurityViolationReportingPolicy reporting_policy) const {
-  SourceListDirective* directive = OperativeDirective(script_src_.Get());
+  SourceListDirective* directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
   if (IsMatchingNoncePresent(directive, nonce))
     return true;
   if (parser_disposition == kNotParserInserted && AllowDynamic())
@@ -764,11 +762,14 @@
     return true;
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(object_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kObjectSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kObjectSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kObjectSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(object_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kObjectSrc),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowPrefetchFromSource(
@@ -777,11 +778,14 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(prefetch_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kPrefetchSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kPrefetchSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kPrefetchSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(prefetch_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kPrefetchSrc),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowFrameFromSource(
@@ -795,8 +799,8 @@
   // sources. So, we do this nested set of calls to 'operativeDirective()' to
   // grab 'frame-src' if it exists, 'child-src' if it doesn't, and 'defaut-src'
   // if neither are available.
-  SourceListDirective* which_directive = OperativeDirective(
-      frame_src_.Get(), OperativeDirective(child_src_.Get()));
+  SourceListDirective* which_directive =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kFrameSrc);
 
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
@@ -812,11 +816,13 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(img_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kImgSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kImgSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kImgSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(img_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(OperativeDirective(
+                               ContentSecurityPolicy::DirectiveType::kImgSrc),
+                           url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowStyleFromSource(
@@ -824,15 +830,19 @@
     const String& nonce,
     ResourceRequest::RedirectStatus redirect_status,
     SecurityViolationReportingPolicy reporting_policy) const {
-  if (IsMatchingNoncePresent(OperativeDirective(style_src_.Get()), nonce))
+  if (IsMatchingNoncePresent(
+          OperativeDirective(ContentSecurityPolicy::DirectiveType::kStyleSrc),
+          nonce))
     return true;
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(style_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kStyleSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kStyleSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kStyleSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(style_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(OperativeDirective(
+                               ContentSecurityPolicy::DirectiveType::kStyleSrc),
+                           url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowFontFromSource(
@@ -841,11 +851,13 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(font_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kFontSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kFontSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kFontSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(font_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(OperativeDirective(
+                               ContentSecurityPolicy::DirectiveType::kFontSrc),
+                           url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowMediaFromSource(
@@ -854,11 +866,13 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(media_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kMediaSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kMediaSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kMediaSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(media_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(OperativeDirective(
+                               ContentSecurityPolicy::DirectiveType::kMediaSrc),
+                           url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowManifestFromSource(
@@ -867,11 +881,14 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(manifest_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kManifestSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kManifestSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kManifestSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(manifest_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kManifestSrc),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowConnectToSource(
@@ -880,11 +897,14 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   OperativeDirective(connect_src_.Get()), url,
-                   ContentSecurityPolicy::DirectiveType::kConnectSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kConnectSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kConnectSrc,
                    redirect_status)
-             : CheckSource(OperativeDirective(connect_src_.Get()), url,
-                           redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kConnectSrc),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowFormAction(
@@ -893,10 +913,14 @@
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   form_action_.Get(), url,
-                   ContentSecurityPolicy::DirectiveType::kFormAction,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kFormAction),
+                   url, ContentSecurityPolicy::DirectiveType::kFormAction,
                    redirect_status)
-             : CheckSource(form_action_.Get(), url, redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kFormAction),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowBaseURI(
@@ -906,12 +930,18 @@
   bool result =
       reporting_policy == SecurityViolationReportingPolicy::kReport
           ? CheckSourceAndReportViolation(
-                base_uri_.Get(), url,
-                ContentSecurityPolicy::DirectiveType::kBaseURI, redirect_status)
-          : CheckSource(base_uri_.Get(), url, redirect_status);
+                OperativeDirective(
+                    ContentSecurityPolicy::DirectiveType::kBaseURI),
+                url, ContentSecurityPolicy::DirectiveType::kBaseURI,
+                redirect_status)
+          : CheckSource(OperativeDirective(
+                            ContentSecurityPolicy::DirectiveType::kBaseURI),
+                        url, redirect_status);
 
   if (result &&
-      !CheckSource(OperativeDirective(base_uri_.Get()), url, redirect_status)) {
+      !CheckSource(
+          OperativeDirective(ContentSecurityPolicy::DirectiveType::kBaseURI),
+          url, redirect_status)) {
     UseCounter::Count(policy_->GetDocument(),
                       WebFeature::kBaseWouldBeBlockedByDefaultSrc);
   }
@@ -923,43 +953,19 @@
     const KURL& url,
     ResourceRequest::RedirectStatus redirect_status,
     SecurityViolationReportingPolicy reporting_policy) const {
-  SourceListDirective* worker_src = OperativeDirective(
-      worker_src_.Get(), OperativeDirective(script_src_.Get()));
-
   if (AllowDynamicWorker())
     return true;
 
-  // In CSP2, workers are controlled via 'child-src'. CSP3 moves them to
-  // 'script-src'. In order to avoid breaking sites that allowed workers via
-  // 'child-src' that would have been blocked via 'script-src', we'll
-  // temporarily check whether a worker blocked via 'script-src' would have been
-  // allowed under 'child-src'. If the new 'worker-src' directive is present,
-  // however, we'll assume that the developer knows what they're asking for, and
-  // skip the extra fallback.
-  //
-  // That is, we'll block 'https://example.com/worker' given the policy
-  // "worker-src 'none'", "worker-src 'none'; child-src https://example.com",
-  // but we'll allow it given the policy
-  // "script-src https://not-example.com; child-src https://example.com"
-  // (because 'child-src' allows it) or "child-src https://not-example.com"
-  // (because the absent 'script-src' allows it).
-  //
-  // TODO(mkwst): Remove this once other vendors follow suit.
-  // https://crbug.com/662930
-  if (!CheckSource(worker_src, url, redirect_status) && !worker_src_ &&
-      child_src_ && CheckSource(child_src_, url, redirect_status)) {
-    Deprecation::CountDeprecation(
-        policy_->GetDocument(),
-        WebFeature::kChildSrcAllowedWorkerThatScriptSrcBlocked);
-    return true;
-  }
-
   return reporting_policy == SecurityViolationReportingPolicy::kReport
              ? CheckSourceAndReportViolation(
-                   worker_src, url,
-                   ContentSecurityPolicy::DirectiveType::kWorkerSrc,
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kWorkerSrc),
+                   url, ContentSecurityPolicy::DirectiveType::kWorkerSrc,
                    redirect_status)
-             : CheckSource(worker_src, url, redirect_status);
+             : CheckSource(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kWorkerSrc),
+                   url, redirect_status);
 }
 
 bool CSPDirectiveList::AllowAncestors(
@@ -967,42 +973,51 @@
     const KURL& url,
     SecurityViolationReportingPolicy reporting_policy) const {
   return reporting_policy == SecurityViolationReportingPolicy::kReport
-             ? CheckAncestorsAndReportViolation(frame_ancestors_.Get(), frame,
-                                                url)
-             : CheckAncestors(frame_ancestors_.Get(), frame);
+             ? CheckAncestorsAndReportViolation(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kFrameAncestors),
+                   frame, url)
+             : CheckAncestors(
+                   OperativeDirective(
+                       ContentSecurityPolicy::DirectiveType::kFrameAncestors),
+                   frame);
 }
 
-bool CSPDirectiveList::AllowHash(const CSPHashValue& hash_value,
-                                 ContentSecurityPolicy::InlineType type,
-                                 SourceListDirective* directive) const {
+bool CSPDirectiveList::AllowHash(
+    const CSPHashValue& hash_value,
+    const ContentSecurityPolicy::InlineType type,
+    const ContentSecurityPolicy::DirectiveType directive_type) const {
   if (type == ContentSecurityPolicy::InlineType::kAttribute) {
     if (!policy_->ExperimentalFeaturesEnabled())
       return false;
-    if (!CheckUnsafeHashesAllowed(OperativeDirective(directive)))
+    if (!CheckUnsafeHashesAllowed(OperativeDirective(directive_type)))
       return false;
   }
-  return CheckHash(OperativeDirective(directive), hash_value);
+  return CheckHash(OperativeDirective(directive_type), hash_value);
 }
 
 bool CSPDirectiveList::AllowScriptHash(
     const CSPHashValue& hash_value,
     ContentSecurityPolicy::InlineType type) const {
-  return AllowHash(hash_value, type, script_src_.Get());
+  return AllowHash(hash_value, type,
+                   ContentSecurityPolicy::DirectiveType::kScriptSrc);
 }
 
 bool CSPDirectiveList::AllowStyleHash(
     const CSPHashValue& hash_value,
     ContentSecurityPolicy::InlineType type) const {
-  return AllowHash(hash_value, type, style_src_.Get());
+  return AllowHash(hash_value, type,
+                   ContentSecurityPolicy::DirectiveType::kStyleSrc);
 }
 
 bool CSPDirectiveList::AllowDynamic() const {
-  return CheckDynamic(OperativeDirective(script_src_.Get()));
+  return CheckDynamic(
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
 }
 
 bool CSPDirectiveList::AllowDynamicWorker() const {
-  SourceListDirective* worker_src = OperativeDirective(
-      worker_src_.Get(), OperativeDirective(script_src_.Get()));
+  SourceListDirective* worker_src =
+      OperativeDirective(ContentSecurityPolicy::DirectiveType::kWorkerSrc);
   return CheckDynamic(worker_src);
 }
 
@@ -1411,54 +1426,125 @@
   }
 }
 
-SourceListDirective* CSPDirectiveList::OperativeDirective(
-    const ContentSecurityPolicy::DirectiveType& type) const {
-  switch (type) {
-    // Directives that do not have a default directive.
-    case ContentSecurityPolicy::DirectiveType::kBaseURI:
-      return base_uri_.Get();
-    case ContentSecurityPolicy::DirectiveType::kDefaultSrc:
-      return default_src_.Get();
-    case ContentSecurityPolicy::DirectiveType::kFrameAncestors:
-      return frame_ancestors_.Get();
-    case ContentSecurityPolicy::DirectiveType::kFormAction:
-      return form_action_.Get();
-    case ContentSecurityPolicy::DirectiveType::kNavigateTo:
-      return navigate_to_.Get();
-    // Directives that have one default directive.
-    case ContentSecurityPolicy::DirectiveType::kChildSrc:
-      return OperativeDirective(child_src_.Get());
+ContentSecurityPolicy::DirectiveType CSPDirectiveList::FallbackDirective(
+    const ContentSecurityPolicy::DirectiveType current_directive,
+    const ContentSecurityPolicy::DirectiveType original_directive) const {
+  switch (current_directive) {
     case ContentSecurityPolicy::DirectiveType::kConnectSrc:
-      return OperativeDirective(connect_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kFontSrc:
-      return OperativeDirective(font_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kImgSrc:
-      return OperativeDirective(img_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kManifestSrc:
-      return OperativeDirective(manifest_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kMediaSrc:
-      return OperativeDirective(media_src_.Get());
+    case ContentSecurityPolicy::DirectiveType::kPrefetchSrc:
     case ContentSecurityPolicy::DirectiveType::kObjectSrc:
-      return OperativeDirective(object_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kScriptSrc:
-      return OperativeDirective(script_src_.Get());
     case ContentSecurityPolicy::DirectiveType::kStyleSrc:
-      return OperativeDirective(style_src_.Get());
-    // Directives that default to 'child-src' (which defaults to 'default-src')
+      return ContentSecurityPolicy::DirectiveType::kDefaultSrc;
+
     case ContentSecurityPolicy::DirectiveType::kFrameSrc:
-      return OperativeDirective(frame_src_.Get(),
-                                OperativeDirective(child_src_.Get()));
-    // Directives that default to 'script-src' (which defaults to 'default-src')
     case ContentSecurityPolicy::DirectiveType::kWorkerSrc:
-      return OperativeDirective(worker_src_.Get(),
-                                OperativeDirective(script_src_.Get()));
+      return ContentSecurityPolicy::DirectiveType::kChildSrc;
+
+    // Because the fallback chain of child-src can be different if we are
+    // checking a worker or a frame request, we need to know the original type
+    // of the request to decide. These are the fallback chains for worker-src
+    // and frame-src specifically.
+
+    // worker-src > child-src > script-src > default-src
+    // frame-src > child-src > default-src
+
+    // Since there are some situations and tests that will operate on the
+    // `child-src` directive directly (like for example the EE subsumption
+    // algorithm), we consider the child-src > default-src fallback path as the
+    // "default" and the worker-src fallback path as an exception.
+    case ContentSecurityPolicy::DirectiveType::kChildSrc:
+      if (original_directive ==
+          ContentSecurityPolicy::DirectiveType::kWorkerSrc)
+        return ContentSecurityPolicy::DirectiveType::kScriptSrc;
+
+      return ContentSecurityPolicy::DirectiveType::kDefaultSrc;
+
     default:
-      return nullptr;
+      return ContentSecurityPolicy::DirectiveType::kUndefined;
   }
 }
 
+SourceListDirective* CSPDirectiveList::OperativeDirective(
+    const ContentSecurityPolicy::DirectiveType type,
+    ContentSecurityPolicy::DirectiveType original_type) const {
+  if (type == ContentSecurityPolicy::DirectiveType::kUndefined) {
+    return nullptr;
+  }
+
+  SourceListDirective* directive;
+  if (original_type == ContentSecurityPolicy::DirectiveType::kUndefined) {
+    original_type = type;
+  }
+
+  switch (type) {
+    case ContentSecurityPolicy::DirectiveType::kBaseURI:
+      directive = base_uri_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kDefaultSrc:
+      directive = default_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kFrameAncestors:
+      directive = frame_ancestors_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kFormAction:
+      directive = form_action_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kNavigateTo:
+      directive = navigate_to_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kChildSrc:
+      directive = child_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kConnectSrc:
+      directive = connect_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kFontSrc:
+      directive = font_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kImgSrc:
+      directive = img_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kManifestSrc:
+      directive = manifest_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kMediaSrc:
+      directive = media_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kObjectSrc:
+      directive = object_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kPrefetchSrc:
+      directive = prefetch_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kScriptSrc:
+      directive = script_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kStyleSrc:
+      directive = style_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kFrameSrc:
+      directive = frame_src_;
+      break;
+    case ContentSecurityPolicy::DirectiveType::kWorkerSrc:
+      directive = worker_src_;
+      break;
+    default:
+      return nullptr;
+  }
+
+  // if the directive does not exist, rely on the fallback directive
+  return directive ? directive
+                   : OperativeDirective(FallbackDirective(type, original_type),
+                                        original_type);
+}
+
 SourceListDirectiveVector CSPDirectiveList::GetSourceVector(
-    const ContentSecurityPolicy::DirectiveType& type,
+    const ContentSecurityPolicy::DirectiveType type,
     const CSPDirectiveListVector& policies) {
   SourceListDirectiveVector source_list_directives;
   for (const auto& policy : policies) {
@@ -1476,7 +1562,7 @@
   // A white-list of directives that we consider for subsumption.
   // See more about source lists here:
   // https://w3c.github.io/webappsec-csp/#framework-directive-source-list
-  ContentSecurityPolicy::DirectiveType directives[] = {
+  static ContentSecurityPolicy::DirectiveType directives[] = {
       ContentSecurityPolicy::DirectiveType::kChildSrc,
       ContentSecurityPolicy::DirectiveType::kConnectSrc,
       ContentSecurityPolicy::DirectiveType::kFontSrc,
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
index 16a5e70..2d55db6 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.h
@@ -231,21 +231,21 @@
                        Member<CSPDirectiveType>&,
                        bool should_parse_wasm_eval = false);
 
-  SourceListDirective* OperativeDirective(SourceListDirective*) const;
-  SourceListDirective* OperativeDirective(SourceListDirective*,
-                                          SourceListDirective* override) const;
+  ContentSecurityPolicy::DirectiveType FallbackDirective(
+      const ContentSecurityPolicy::DirectiveType current_directive,
+      const ContentSecurityPolicy::DirectiveType original_directive) const;
   void ReportViolation(const String& directive_text,
-                       const ContentSecurityPolicy::DirectiveType&,
+                       const ContentSecurityPolicy::DirectiveType,
                        const String& console_message,
                        const KURL& blocked_url,
                        ResourceRequest::RedirectStatus) const;
   void ReportViolationWithFrame(const String& directive_text,
-                                const ContentSecurityPolicy::DirectiveType&,
+                                const ContentSecurityPolicy::DirectiveType,
                                 const String& console_message,
                                 const KURL& blocked_url,
                                 LocalFrame*) const;
   void ReportViolationWithLocation(const String& directive_text,
-                                   const ContentSecurityPolicy::DirectiveType&,
+                                   const ContentSecurityPolicy::DirectiveType,
                                    const String& console_message,
                                    const KURL& blocked_url,
                                    const String& context_url,
@@ -253,7 +253,7 @@
                                    Element*,
                                    const String& source) const;
   void ReportEvalViolation(const String& directive_text,
-                           const ContentSecurityPolicy::DirectiveType&,
+                           const ContentSecurityPolicy::DirectiveType,
                            const String& message,
                            const KURL& blocked_url,
                            ScriptState*,
@@ -300,11 +300,10 @@
                                      bool is_script,
                                      const String& hash_value) const;
 
-  bool CheckSourceAndReportViolation(
-      SourceListDirective*,
-      const KURL&,
-      const ContentSecurityPolicy::DirectiveType&,
-      ResourceRequest::RedirectStatus) const;
+  bool CheckSourceAndReportViolation(SourceListDirective*,
+                                     const KURL&,
+                                     const ContentSecurityPolicy::DirectiveType,
+                                     ResourceRequest::RedirectStatus) const;
   bool CheckMediaTypeAndReportViolation(MediaListDirective*,
                                         const String& type,
                                         const String& type_attribute,
@@ -320,19 +319,22 @@
   bool DenyIfEnforcingPolicy() const { return IsReportOnly(); }
 
   // This function returns a SourceListDirective of a given type
-  // or if it is not defined, the default SourceListDirective for that type.
+  // or if it is not defined, the fallback SourceListDirective for that type.
   SourceListDirective* OperativeDirective(
-      const ContentSecurityPolicy::DirectiveType&) const;
+      const ContentSecurityPolicy::DirectiveType type,
+      ContentSecurityPolicy::DirectiveType original_type =
+          ContentSecurityPolicy::DirectiveType::kUndefined) const;
 
   // This function aggregates from a vector of policies all operative
   // SourceListDirectives of a given type into a vector.
   static SourceListDirectiveVector GetSourceVector(
-      const ContentSecurityPolicy::DirectiveType&,
+      const ContentSecurityPolicy::DirectiveType,
       const CSPDirectiveListVector& policies);
 
-  bool AllowHash(const CSPHashValue&,
-                 ContentSecurityPolicy::InlineType,
-                 SourceListDirective* directive) const;
+  bool AllowHash(
+      const CSPHashValue& hash_value,
+      const ContentSecurityPolicy::InlineType type,
+      const ContentSecurityPolicy::DirectiveType directive_type) const;
 
   Member<ContentSecurityPolicy> policy_;
 
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
index 8093956..a7cbc6d 100644
--- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
+++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -88,8 +88,8 @@
     // Report-only
     Member<CSPDirectiveList> directive_list =
         CreateList(test.list, kContentSecurityPolicyHeaderTypeReport);
-    Member<SourceListDirective> script_src =
-        directive_list->OperativeDirective(directive_list->script_src_.Get());
+    Member<SourceListDirective> script_src = directive_list->OperativeDirective(
+        ContentSecurityPolicy::DirectiveType::kScriptSrc);
     EXPECT_EQ(test.expected,
               directive_list->IsMatchingNoncePresent(script_src, test.nonce));
     // Empty/null strings are always not present, regardless of the policy.
@@ -99,8 +99,8 @@
     // Enforce
     directive_list =
         CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
-    script_src =
-        directive_list->OperativeDirective(directive_list->script_src_.Get());
+    script_src = directive_list->OperativeDirective(
+        ContentSecurityPolicy::DirectiveType::kScriptSrc);
     EXPECT_EQ(test.expected,
               directive_list->IsMatchingNoncePresent(script_src, test.nonce));
     // Empty/null strings are always not present, regardless of the policy.
@@ -564,14 +564,14 @@
       // When 'worker-src' is not present, 'child-src' can allow a worker when
       // present.
       {"child-src https://example.test", true},
-      {"child-src https://not-example.test", true},
+      {"child-src https://not-example.test", false},
       {"script-src https://example.test", true},
       {"script-src https://not-example.test", false},
       {"child-src https://example.test; script-src https://example.test", true},
       {"child-src https://example.test; script-src https://not-example.test",
        true},
       {"child-src https://not-example.test; script-src https://example.test",
-       true},
+       false},
       {"child-src https://not-example.test; script-src "
        "https://not-example.test",
        false},
@@ -869,7 +869,7 @@
     kDefault,
     kNoDefault,
     kChildAndDefault,
-    kScriptAndDefault
+    kChildAndScriptAndDefault
   };
 
   struct TestCase {
@@ -893,7 +893,8 @@
       {ContentSecurityPolicy::DirectiveType::kFormAction, kNoDefault},
       // Directive with multiple default directives.
       {ContentSecurityPolicy::DirectiveType::kFrameSrc, kChildAndDefault},
-      {ContentSecurityPolicy::DirectiveType::kWorkerSrc, kScriptAndDefault},
+      {ContentSecurityPolicy::DirectiveType::kWorkerSrc,
+       kChildAndScriptAndDefault},
   };
 
   // Initial set-up.
@@ -922,7 +923,7 @@
 
     std::stringstream all_except_this;
     std::stringstream all_except_child_src_and_this;
-    std::stringstream all_except_script_src_and_this;
+    std::stringstream all_except_child_src_and_script_src_and_this;
     for (const auto& subtest : cases) {
       if (subtest.directive == test.directive)
         continue;
@@ -936,9 +937,11 @@
                                       << directive_name << ".com; ";
       }
       if (subtest.directive !=
-          ContentSecurityPolicy::DirectiveType::kScriptSrc) {
-        all_except_script_src_and_this << directive_name << " http://"
-                                       << directive_name << ".com; ";
+              ContentSecurityPolicy::DirectiveType::kChildSrc &&
+          subtest.directive !=
+              ContentSecurityPolicy::DirectiveType::kScriptSrc) {
+        all_except_child_src_and_script_src_and_this
+            << directive_name << " http://" << directive_name << ".com; ";
       }
     }
     CSPDirectiveList* all_except_this_list = CreateList(
@@ -946,8 +949,8 @@
     CSPDirectiveList* all_except_child_src_and_this_list =
         CreateList(all_except_child_src_and_this.str().c_str(),
                    kContentSecurityPolicyHeaderTypeEnforce);
-    CSPDirectiveList* all_except_script_src_and_this_list =
-        CreateList(all_except_script_src_and_this.str().c_str(),
+    CSPDirectiveList* all_except_child_src_and_script_src_and_this_list =
+        CreateList(all_except_child_src_and_script_src_and_this.str().c_str(),
                    kContentSecurityPolicyHeaderTypeEnforce);
 
     switch (test.type) {
@@ -971,12 +974,17 @@
         EXPECT_EQ(sources.size(), 1u);
         EXPECT_EQ(sources[0]->host_, "default-src.com");
         break;
-      case kScriptAndDefault:
+      case kChildAndScriptAndDefault:
         sources =
             all_except_this_list->OperativeDirective(test.directive)->list_;
         EXPECT_EQ(sources.size(), 1u);
+        EXPECT_EQ(sources[0]->host_, "child-src.com");
+        sources = all_except_child_src_and_this_list
+                      ->OperativeDirective(test.directive)
+                      ->list_;
+        EXPECT_EQ(sources.size(), 1u);
         EXPECT_EQ(sources[0]->host_, "script-src.com");
-        sources = all_except_script_src_and_this_list
+        sources = all_except_child_src_and_script_src_and_this_list
                       ->OperativeDirective(test.directive)
                       ->list_;
         EXPECT_EQ(sources.size(), 1u);
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 5599616..951ebdde 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -697,7 +697,7 @@
   if (PlaceholderFrame()) {
     DCHECK(GetDocument().Printing());
     context.DrawImage(PlaceholderFrame()->Bitmap().get(), Image::kSyncDecode,
-                      PixelSnappedIntRect(r));
+                      FloatRect(PixelSnappedIntRect(r)));
     return;
   }
 
@@ -718,7 +718,7 @@
         snapshot = snapshot->MakeUnaccelerated();
         DCHECK(!snapshot->IsTextureBacked());
         context.DrawImage(snapshot.get(), Image::kSyncDecode,
-                          PixelSnappedIntRect(r), &src_rect,
+                          FloatRect(PixelSnappedIntRect(r)), &src_rect,
                           composite_operator);
       }
     }
diff --git a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
index 6f2bfba..2e46e60 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_field_element.cc
@@ -155,11 +155,11 @@
                                       int ax_maximum) {
   // On accessibility, DateTimeFieldElement acts like spin button.
   setAttribute(roleAttr, AtomicString("spinbutton"));
-  setAttribute(aria_valuetextAttr, AtomicString(VisibleValue()));
+  setAttribute(aria_placeholderAttr, AtomicString(Placeholder()));
   setAttribute(aria_valueminAttr, AtomicString::Number(ax_minimum));
   setAttribute(aria_valuemaxAttr, AtomicString::Number(ax_maximum));
 
-  setAttribute(aria_helpAttr, AtomicString(ax_help_text));
+  setAttribute(aria_labelAttr, AtomicString(ax_help_text));
   SetShadowPseudoId(pseudo);
   AppendChild(Text::Create(GetDocument(), VisibleValue()));
 }
@@ -218,10 +218,11 @@
   if (HasValue()) {
     setAttribute(aria_valuenowAttr,
                  AtomicString::Number(ValueForARIAValueNow()));
+    setAttribute(aria_valuetextAttr, AtomicString(new_visible_value));
   } else {
     removeAttribute(aria_valuenowAttr);
+    removeAttribute(aria_valuetextAttr);
   }
-  setAttribute(aria_valuetextAttr, AtomicString(new_visible_value));
 
   if (event_behavior == kDispatchEvent && field_owner_)
     field_owner_->FieldValueChanged();
diff --git a/third_party/blink/renderer/core/html/forms/date_time_field_element.h b/third_party/blink/renderer/core/html/forms/date_time_field_element.h
index 94e41be7..f6cd41e 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_field_element.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_field_element.h
@@ -64,6 +64,7 @@
   virtual bool HasValue() const = 0;
   bool IsDisabled() const;
   virtual float MaximumWidth(const ComputedStyle&);
+  virtual String Placeholder() const = 0;
   virtual void PopulateDateTimeFieldsState(DateTimeFieldsState&) = 0;
   void RemoveEventHandler() { field_owner_ = nullptr; }
   void SetDisabled();
diff --git a/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc b/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
index 33268c4..21e1612 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
@@ -164,6 +164,10 @@
   return range_.maximum;
 }
 
+String DateTimeNumericFieldElement::Placeholder() const {
+  return placeholder_;
+}
+
 void DateTimeNumericFieldElement::SetEmptyValue(EventBehavior event_behavior) {
   if (IsDisabled())
     return;
diff --git a/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h b/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
index eeb5fb5..ffd9fca 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
@@ -79,6 +79,7 @@
   bool HasValue() const final;
   void Initialize(const AtomicString& pseudo, const String& ax_help_text);
   int Maximum() const;
+  String Placeholder() const override;
   void SetEmptyValue(EventBehavior = kDispatchNoEvent) final;
   void SetValueAsInteger(int, EventBehavior = kDispatchNoEvent) override;
   int ValueAsInteger() const final;
diff --git a/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc b/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
index 5039df9f..25a3c57 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.cc
@@ -120,6 +120,10 @@
   UpdateVisibleValue(event_behavior);
 }
 
+String DateTimeSymbolicFieldElement::Placeholder() const {
+  return VisibleEmptyValue();
+}
+
 void DateTimeSymbolicFieldElement::StepDown() {
   if (HasValue()) {
     if (!IndexIsInRange(--selected_index_))
diff --git a/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h b/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
index 8f51540..59cf9e95 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_symbolic_field_element.h
@@ -60,6 +60,7 @@
   // DateTimeFieldElement functions.
   void HandleKeyboardEvent(KeyboardEvent*) final;
   float MaximumWidth(const ComputedStyle&) override;
+  String Placeholder() const override;
   void StepDown() final;
   void StepUp() final;
   String Value() const final;
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
index e50eee5..30d948e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -863,8 +863,8 @@
 
   auto layout_tree_node = protocol::DOMSnapshot::LayoutTreeNode::create()
                               .setDomNodeIndex(node_index)
-                              .setBoundingBox(BuildRectForFloatRect(
-                                  layout_object->AbsoluteBoundingBoxRect()))
+                              .setBoundingBox(BuildRectForFloatRect(FloatRect(
+                                  layout_object->AbsoluteBoundingBoxRect())))
                               .build();
 
   int style_index = GetStyleIndexForNode(node);
@@ -918,8 +918,8 @@
   int index = layout_tree_snapshot_->getNodeIndex()->length();
   layout_tree_snapshot_->getNodeIndex()->addItem(node_index);
   layout_tree_snapshot_->getStyles()->addItem(BuildStylesForNode(node));
-  layout_tree_snapshot_->getBounds()->addItem(
-      BuildRectForFloatRect2(layout_object->AbsoluteBoundingBoxRect()));
+  layout_tree_snapshot_->getBounds()->addItem(BuildRectForFloatRect2(
+      FloatRect(layout_object->AbsoluteBoundingBoxRect())));
   auto* text_box_snapshot = layout_tree_snapshot_->getTextBoxes();
 
   String text = layout_object->IsText() ? ToLayoutText(layout_object)->GetText()
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index e7ebb8d9..6fe27de 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -37,6 +37,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h"
+#include "services/network/public/mojom/websocket.mojom-blink.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/public/platform/web_effective_connection_type.h"
 #include "third_party/blink/public/platform/web_mixed_content_context_type.h"
@@ -74,8 +75,6 @@
 #include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
 #include "third_party/blink/renderer/platform/network/http_header_map.h"
 #include "third_party/blink/renderer/platform/network/network_state_notifier.h"
-#include "third_party/blink/renderer/platform/network/websocket_handshake_request.h"
-#include "third_party/blink/renderer/platform/network/websocket_handshake_response.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
@@ -1220,11 +1219,14 @@
 void InspectorNetworkAgent::WillSendWebSocketHandshakeRequest(
     ExecutionContext*,
     unsigned long identifier,
-    const WebSocketHandshakeRequest* request) {
+    network::mojom::blink::WebSocketHandshakeRequest* request) {
   DCHECK(request);
+  HTTPHeaderMap headers;
+  for (auto& header : request->headers)
+    headers.Add(AtomicString(header->name), AtomicString(header->value));
   std::unique_ptr<protocol::Network::WebSocketRequest> request_object =
       protocol::Network::WebSocketRequest::create()
-          .setHeaders(BuildObjectForHeaders(request->HeaderFields()))
+          .setHeaders(BuildObjectForHeaders(headers))
           .build();
   GetFrontend()->webSocketWillSendHandshakeRequest(
       IdentifiersFactory::SubresourceRequestId(identifier),
@@ -1234,24 +1236,41 @@
 void InspectorNetworkAgent::DidReceiveWebSocketHandshakeResponse(
     ExecutionContext*,
     unsigned long identifier,
-    const WebSocketHandshakeRequest* request,
-    const WebSocketHandshakeResponse* response) {
+    network::mojom::blink::WebSocketHandshakeRequest* request,
+    network::mojom::blink::WebSocketHandshakeResponse* response) {
   DCHECK(response);
+
+  HTTPHeaderMap response_headers;
+  for (auto& header : response->headers) {
+    HTTPHeaderMap::AddResult add_result = response_headers.Add(
+        AtomicString(header->name), AtomicString(header->value));
+    if (!add_result.is_new_entry) {
+      // Protocol expects the "\n" separated format.
+      add_result.stored_value->value =
+          add_result.stored_value->value + "\n" + header->value;
+    }
+  }
+
   std::unique_ptr<protocol::Network::WebSocketResponse> response_object =
       protocol::Network::WebSocketResponse::create()
-          .setStatus(response->StatusCode())
-          .setStatusText(response->StatusText())
-          .setHeaders(BuildObjectForHeaders(response->HeaderFields()))
+          .setStatus(response->status_code)
+          .setStatusText(response->status_text)
+          .setHeaders(BuildObjectForHeaders(response_headers))
           .build();
+  if (!response->headers_text.IsEmpty())
+    response_object->setHeadersText(response->headers_text);
 
-  if (!response->HeadersText().IsEmpty())
-    response_object->setHeadersText(response->HeadersText());
   if (request) {
-    response_object->setRequestHeaders(
-        BuildObjectForHeaders(request->HeaderFields()));
-    if (!request->HeadersText().IsEmpty())
-      response_object->setRequestHeadersText(request->HeadersText());
+    HTTPHeaderMap request_headers;
+    for (auto& header : request->headers) {
+      request_headers.Add(AtomicString(header->name),
+                          AtomicString(header->value));
+    }
+    response_object->setRequestHeaders(BuildObjectForHeaders(request_headers));
+    if (!request->headers_text.IsEmpty())
+      response_object->setRequestHeadersText(request->headers_text);
   }
+
   GetFrontend()->webSocketHandshakeResponseReceived(
       IdentifiersFactory::SubresourceRequestId(identifier),
       CurrentTimeTicksInSeconds(), std::move(response_object));
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.h b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
index db6291ff..ccee3be 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
@@ -41,6 +41,15 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
+namespace network {
+namespace mojom {
+namespace blink {
+class WebSocketHandshakeResponse;
+class WebSocketHandshakeRequest;
+}  // namespace blink
+}  // namespace mojom
+}  // namespace network
+
 namespace blink {
 
 class Document;
@@ -57,8 +66,6 @@
 class ThreadableLoaderClient;
 class XHRReplayData;
 class XMLHttpRequest;
-class WebSocketHandshakeRequest;
-class WebSocketHandshakeResponse;
 class WorkerGlobalScope;
 
 class CORE_EXPORT InspectorNetworkAgent final
@@ -154,13 +161,15 @@
                           unsigned long identifier,
                           const KURL& request_url,
                           const String&);
-  void WillSendWebSocketHandshakeRequest(ExecutionContext*,
-                                         unsigned long identifier,
-                                         const WebSocketHandshakeRequest*);
-  void DidReceiveWebSocketHandshakeResponse(ExecutionContext*,
-                                            unsigned long identifier,
-                                            const WebSocketHandshakeRequest*,
-                                            const WebSocketHandshakeResponse*);
+  void WillSendWebSocketHandshakeRequest(
+      ExecutionContext*,
+      unsigned long identifier,
+      network::mojom::blink::WebSocketHandshakeRequest*);
+  void DidReceiveWebSocketHandshakeResponse(
+      ExecutionContext*,
+      unsigned long identifier,
+      network::mojom::blink::WebSocketHandshakeRequest*,
+      network::mojom::blink::WebSocketHandshakeResponse*);
   void DidCloseWebSocket(ExecutionContext*, unsigned long identifier);
   void DidReceiveWebSocketFrame(unsigned long identifier,
                                 int op_code,
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
index 081cc88..778ffee 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -1016,7 +1016,8 @@
 
 FloatRect LayoutBoxModelObject::ComputeStickyConstrainingRect() const {
   if (Layer()->AncestorOverflowLayer()->IsRootLayer()) {
-    return View()->GetFrameView()->LayoutViewport()->VisibleContentRect();
+    return FloatRect(
+        View()->GetFrameView()->LayoutViewport()->VisibleContentRect());
   }
 
   LayoutBox* enclosing_clipping_box =
diff --git a/third_party/blink/renderer/core/layout/layout_progress.cc b/third_party/blink/renderer/core/layout/layout_progress.cc
index d818339..83fe6ed2 100644
--- a/third_party/blink/renderer/core/layout/layout_progress.cc
+++ b/third_party/blink/renderer/core/layout/layout_progress.cc
@@ -31,9 +31,6 @@
 LayoutProgress::LayoutProgress(HTMLProgressElement* element)
     : LayoutBlockFlow(element),
       position_(HTMLProgressElement::kInvalidPosition),
-      animation_start_time_(0),
-      animation_repeat_interval_(0),
-      animation_duration_(0),
       animating_(false),
       animation_timer_(
           element->GetDocument().GetTaskRunner(TaskType::kInternalDefault),
@@ -62,10 +59,11 @@
 }
 
 double LayoutProgress::AnimationProgress() const {
-  return animating_ ? (fmod((CurrentTime() - animation_start_time_),
-                            animation_duration_) /
-                       animation_duration_)
-                    : 0;
+  if (!animating_)
+    return 0;
+  TimeDelta elapsed = CurrentTimeTicks() - animation_start_time_;
+  return (elapsed % animation_duration_).InSecondsF() /
+         animation_duration_.InSecondsF();
 }
 
 bool LayoutProgress::IsDeterminate() const {
@@ -93,14 +91,14 @@
   animation_repeat_interval_ =
       LayoutTheme::GetTheme().AnimationRepeatIntervalForProgressBar();
 
-  bool animating =
-      !IsDeterminate() && Style()->HasAppearance() && animation_duration_ > 0;
+  bool animating = !IsDeterminate() && Style()->HasAppearance() &&
+                   animation_duration_ > TimeDelta();
   if (animating == animating_)
     return;
 
   animating_ = animating;
   if (animating_) {
-    animation_start_time_ = CurrentTime();
+    animation_start_time_ = CurrentTimeTicks();
     animation_timer_.StartOneShot(animation_repeat_interval_, FROM_HERE);
   } else {
     animation_timer_.Stop();
diff --git a/third_party/blink/renderer/core/layout/layout_progress.h b/third_party/blink/renderer/core/layout/layout_progress.h
index 6e606be..ab8a0cbd 100644
--- a/third_party/blink/renderer/core/layout/layout_progress.h
+++ b/third_party/blink/renderer/core/layout/layout_progress.h
@@ -58,9 +58,9 @@
   void UpdateAnimationState();
 
   double position_;
-  double animation_start_time_;
-  double animation_repeat_interval_;
-  double animation_duration_;
+  TimeTicks animation_start_time_;
+  TimeDelta animation_repeat_interval_;
+  TimeDelta animation_duration_;
   bool animating_;
   TaskRunnerTimer<LayoutProgress> animation_timer_;
 
diff --git a/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h b/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
index 053df44..fe60d6d1 100644
--- a/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
+++ b/third_party/blink/renderer/core/layout/layout_scrollbar_theme.h
@@ -60,11 +60,11 @@
         .ShouldSnapBackToDragOrigin(scrollbar, event);
   }
 
-  double InitialAutoscrollTimerDelay() override {
+  TimeDelta InitialAutoscrollTimerDelay() override {
     return ScrollbarTheme::DeprecatedStaticGetTheme()
         .InitialAutoscrollTimerDelay();
   }
-  double AutoscrollTimerDelay() override {
+  TimeDelta AutoscrollTimerDelay() override {
     return ScrollbarTheme::DeprecatedStaticGetTheme().AutoscrollTimerDelay();
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc
index fe2ee59..4bd730e 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -582,12 +582,12 @@
 
 void LayoutTheme::AdjustMenuListStyle(ComputedStyle&, Element*) const {}
 
-double LayoutTheme::AnimationRepeatIntervalForProgressBar() const {
-  return 0;
+TimeDelta LayoutTheme::AnimationRepeatIntervalForProgressBar() const {
+  return TimeDelta();
 }
 
-double LayoutTheme::AnimationDurationForProgressBar() const {
-  return 0;
+TimeDelta LayoutTheme::AnimationDurationForProgressBar() const {
+  return TimeDelta();
 }
 
 bool LayoutTheme::ShouldHaveSpinButton(HTMLInputElement* input_element) const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h
index 59baded..363ef2d9a 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -206,9 +206,9 @@
   virtual void AdjustProgressBarBounds(ComputedStyle& style) const {}
 
   // Returns the repeat interval of the animation for the progress bar.
-  virtual double AnimationRepeatIntervalForProgressBar() const;
+  virtual TimeDelta AnimationRepeatIntervalForProgressBar() const;
   // Returns the duration of the animation for the progress bar.
-  virtual double AnimationDurationForProgressBar() const;
+  virtual TimeDelta AnimationDurationForProgressBar() const;
 
   // Returns size of one slider tick mark for a horizontal track.
   // For vertical tracks we rotate it and use it. i.e. Width is always length
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 4b9acaf..1c2a0a8 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_default.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -381,16 +381,17 @@
 }
 
 //
-// Following values are come from default of GTK+
+// The following values come from the defaults of GTK+.
 //
 static const int kProgressAnimationFrames = 10;
-static const double kProgressAnimationInterval = 0.125;
+static constexpr TimeDelta kProgressAnimationInterval =
+    TimeDelta::FromMilliseconds(125);
 
-double LayoutThemeDefault::AnimationRepeatIntervalForProgressBar() const {
+TimeDelta LayoutThemeDefault::AnimationRepeatIntervalForProgressBar() const {
   return kProgressAnimationInterval;
 }
 
-double LayoutThemeDefault::AnimationDurationForProgressBar() const {
+TimeDelta LayoutThemeDefault::AnimationDurationForProgressBar() const {
   return kProgressAnimationInterval * kProgressAnimationFrames *
          2;  // "2" for back and forth
 }
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.h b/third_party/blink/renderer/core/layout/layout_theme_default.h
index 1d9b1fb..994d74e 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_default.h
+++ b/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -107,8 +107,8 @@
   void AdjustMenuListStyle(ComputedStyle&, Element*) const override;
   void AdjustMenuListButtonStyle(ComputedStyle&, Element*) const override;
 
-  double AnimationRepeatIntervalForProgressBar() const override;
-  double AnimationDurationForProgressBar() const override;
+  TimeDelta AnimationRepeatIntervalForProgressBar() const override;
+  TimeDelta AnimationDurationForProgressBar() const override;
 
   // These methods define the padding for the MenuList's inner block.
   int PopupInternalPaddingStart(const ComputedStyle&) const override;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.h b/third_party/blink/renderer/core/layout/layout_theme_mac.h
index 3313d7d..6ec0a66 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_mac.h
+++ b/third_party/blink/renderer/core/layout/layout_theme_mac.h
@@ -86,9 +86,9 @@
   bool PopsMenuBySpaceKey() const final { return true; }
 
   // Returns the repeat interval of the animation for the progress bar.
-  double AnimationRepeatIntervalForProgressBar() const override;
+  TimeDelta AnimationRepeatIntervalForProgressBar() const override;
   // Returns the duration of the animation for the progress bar.
-  double AnimationDurationForProgressBar() const override;
+  TimeDelta AnimationDurationForProgressBar() const override;
 
   Color SystemColor(CSSValueID) const override;
 
@@ -153,7 +153,8 @@
 
   // We estimate the animation rate of a Mac OS X progress bar is 33 fps.
   // Hard code the value here because we haven't found API for it.
-  static constexpr double kProgressAnimationFrameRate = 0.033;
+  static constexpr TimeDelta kProgressAnimationFrameRate =
+      TimeDelta::FromMilliseconds(33);
   // Mac OS X progress bar animation seems to have 256 frames.
   static constexpr double kProgressAnimationNumFrames = 256;
 
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 a4721094..00c31f0 100644
--- a/third_party/blink/renderer/core/layout/layout_theme_mac.mm
+++ b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -697,11 +697,13 @@
   return kSizes;
 }
 
-double LayoutThemeMac::AnimationRepeatIntervalForProgressBar() const {
+constexpr TimeDelta LayoutThemeMac::kProgressAnimationFrameRate;
+
+TimeDelta LayoutThemeMac::AnimationRepeatIntervalForProgressBar() const {
   return kProgressAnimationFrameRate;
 }
 
-double LayoutThemeMac::AnimationDurationForProgressBar() const {
+TimeDelta LayoutThemeMac::AnimationDurationForProgressBar() const {
   return kProgressAnimationNumFrames * kProgressAnimationFrameRate;
 }
 
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 bbefd250..a8d94c6a 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
@@ -455,12 +455,6 @@
           line_offset = line_info.LineBfcOffset().line_offset -
                         ConstraintSpace().BfcOffset().line_offset;
         }
-        if (IsRtl(Style().Direction())) {
-          LayoutUnit container_inline_size =
-              ConstraintSpace().AvailableSize().inline_size;
-          LayoutUnit line_end_offset = line_offset + line_info.AvailableWidth();
-          line_offset = container_inline_size - line_end_offset;
-        }
         line_offset += line_info.TextIndent();
 
         // We need to subtract the line offset, in order to ignore
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc
index b70b02a..376a48caf 100644
--- a/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -134,14 +134,14 @@
 
   // Some task queues may have repeating v8 tasks that run forever so we impose
   // a hard (virtual) time limit.
-  void RunTasksForPeriod(double delay_ms) {
+  void RunTasksForPeriod(TimeDelta delay) {
     TimeAdvance();
     scheduler::GetSingleThreadTaskRunnerForTesting()->PostDelayedTask(
         FROM_HERE,
         WTF::Bind(
             &ScrollbarsTestWithVirtualTimer::StopVirtualTimeAndExitRunLoop,
             WTF::Unretained(this)),
-        TimeDelta::FromMillisecondsD(delay_ms));
+        delay);
     test::EnterRunLoop();
   }
 };
@@ -1168,9 +1168,7 @@
 TEST_F(ScrollbarsTestWithVirtualTimer, TestNonCompositedOverlayScrollbarsFade) {
 #endif
   TimeAdvance();
-  constexpr double kMockOverlayFadeOutDelayInSeconds = 5.0;
-  constexpr double kMockOverlayFadeOutDelayMS =
-      kMockOverlayFadeOutDelayInSeconds * 1000;
+  constexpr TimeDelta kMockOverlayFadeOutDelay = TimeDelta::FromSeconds(5);
 
   ScrollbarTheme& theme = GetScrollbarTheme();
   // This test relies on mock overlay scrollbars.
@@ -1178,13 +1176,12 @@
   ASSERT_TRUE(theme.UsesOverlayScrollbars());
   ScrollbarThemeOverlayMock& mock_overlay_theme =
       (ScrollbarThemeOverlayMock&)theme;
-  mock_overlay_theme.SetOverlayScrollbarFadeOutDelay(
-      kMockOverlayFadeOutDelayInSeconds);
+  mock_overlay_theme.SetOverlayScrollbarFadeOutDelay(kMockOverlayFadeOutDelay);
 
   WebView().Resize(WebSize(640, 480));
   SimRequest request("https://example.com/test.html", "text/html");
   LoadURL("https://example.com/test.html");
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   request.Complete(R"HTML(
     <!DOCTYPE html>
     <style>
@@ -1219,14 +1216,14 @@
   DCHECK(!scrollable_area->UsesCompositedScrolling());
 
   EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   EXPECT_TRUE(scrollable_area->ScrollbarsHiddenIfOverlay());
 
   scrollable_area->SetScrollOffset(ScrollOffset(10, 10), kProgrammaticScroll,
                                    kScrollBehaviorInstant);
 
   EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   EXPECT_TRUE(scrollable_area->ScrollbarsHiddenIfOverlay());
 
   MainFrame().ExecuteScript(WebScriptSource(
@@ -1240,7 +1237,7 @@
   Compositor().BeginFrame();
 
   EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   EXPECT_TRUE(scrollable_area->ScrollbarsHiddenIfOverlay());
 
   // Non-composited scrollbars don't fade out while mouse is over.
@@ -1249,13 +1246,13 @@
                                    kScrollBehaviorInstant);
   EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
   scrollable_area->MouseEnteredScrollbar(*scrollable_area->VerticalScrollbar());
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
   scrollable_area->MouseExitedScrollbar(*scrollable_area->VerticalScrollbar());
-  RunTasksForPeriod(kMockOverlayFadeOutDelayMS);
+  RunTasksForPeriod(kMockOverlayFadeOutDelay);
   EXPECT_TRUE(scrollable_area->ScrollbarsHiddenIfOverlay());
 
-  mock_overlay_theme.SetOverlayScrollbarFadeOutDelay(0.0);
+  mock_overlay_theme.SetOverlayScrollbarFadeOutDelay(TimeDelta());
 }
 
 typedef bool TestParamOverlayScrollbar;
@@ -1283,8 +1280,8 @@
     }
   }
   void GetOverlayScrollbarStyle(ScrollbarStyle* style) override {
-    style->fade_out_delay_seconds = 0;
-    style->fade_out_duration_seconds = 0;
+    style->fade_out_delay = TimeDelta();
+    style->fade_out_duration = TimeDelta();
     style->thumb_thickness = 3;
     style->scrollbar_margin = 0;
     style->color = SkColorSetARGB(128, 64, 64, 64);
@@ -2058,7 +2055,7 @@
 
   SimRequest request("https://example.com/test.html", "text/html");
   LoadURL("https://example.com/test.html");
-  RunTasksForPeriod(1000);
+  RunTasksForPeriod(TimeDelta::FromMilliseconds(1000));
   request.Complete(R"HTML(
     <!DOCTYPE html>
     <style>
@@ -2104,15 +2101,15 @@
   ASSERT_EQ(scrollbar->PressedPart(), ScrollbarPart::kForwardButtonEndPart);
 
   // Wait for 2 delay.
-  RunTasksForPeriod(1000);
-  RunTasksForPeriod(1000);
+  RunTasksForPeriod(TimeDelta::FromMilliseconds(1000));
+  RunTasksForPeriod(TimeDelta::FromMilliseconds(1000));
   // Change #big size.
   MainFrame().ExecuteScript(WebScriptSource(
       "document.getElementById('big').style.height = '1000px';"));
   Compositor().BeginFrame();
 
-  RunTasksForPeriod(1000);
-  RunTasksForPeriod(1000);
+  RunTasksForPeriod(TimeDelta::FromMilliseconds(1000));
+  RunTasksForPeriod(TimeDelta::FromMilliseconds(1000));
 
   // Keep Scrolling.
   EXPECT_GT(scrollable_area->ScrollOffsetInt().Height(), 200);
diff --git a/third_party/blink/renderer/core/layout/shapes/shape.cc b/third_party/blink/renderer/core/layout/shapes/shape.cc
index 717fbfa2..22bee37 100644
--- a/third_party/blink/renderer/core/layout/shapes/shape.cc
+++ b/third_party/blink/renderer/core/layout/shapes/shape.cc
@@ -261,8 +261,8 @@
   canvas->save();
   canvas->clear(SK_ColorTRANSPARENT);
 
-  image->Draw(canvas.get(), flags, image_dest_rect, image_source_rect,
-              kDoNotRespectImageOrientation,
+  image->Draw(canvas.get(), flags, FloatRect(image_dest_rect),
+              image_source_rect, kDoNotRespectImageOrientation,
               Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
 
   return StaticBitmapImage::ConvertToArrayBufferContents(
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index 90aaf9c..c084ec5 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -272,7 +272,8 @@
 
     const auto& chunk_state = chunk.properties.GetPropertyTreeState();
     for (auto touch_action_rect : hit_test_data->touch_action_rects) {
-      auto rect = FloatClipRect(PixelSnappedIntRect(touch_action_rect.rect));
+      auto rect =
+          FloatClipRect(FloatRect(PixelSnappedIntRect(touch_action_rect.rect)));
       if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state,
                                                      rect)) {
         continue;
diff --git a/third_party/blink/renderer/core/paint/block_painter_test.cc b/third_party/blink/renderer/core/paint/block_painter_test.cc
index 736076b8..779abf9 100644
--- a/third_party/blink/renderer/core/paint/block_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/block_painter_test.cc
@@ -133,7 +133,7 @@
       scroll_hit_test_chunk.properties.Transform();
   EXPECT_EQ(nullptr, scroll_hit_test_transform->ScrollNode());
   auto* scroll_hit_test_clip = scroll_hit_test_chunk.properties.Clip();
-  EXPECT_EQ(LayoutRect::InfiniteIntRect(),
+  EXPECT_EQ(FloatRect(LayoutRect::InfiniteIntRect()),
             scroll_hit_test_clip->ClipRect().Rect());
 
   // The scrolled contents should be scrolled and clipped.
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc
index 09b4c9d7..441e273 100644
--- a/third_party/blink/renderer/core/paint/box_painter_base.cc
+++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -431,8 +431,9 @@
 
   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
                "data",
-               InspectorPaintImageEvent::Data(node, *info.image, image->Rect(),
-                                              image_border.Rect()));
+               InspectorPaintImageEvent::Data(node, *info.image,
+                                              FloatRect(image->Rect()),
+                                              FloatRect(image_border.Rect())));
 
   // Since there is no way for the developer to specify decode behavior, use
   // kSync by default.
@@ -545,10 +546,11 @@
   // resource locator is given such as "//:0", so still check for image.
   if (info.should_paint_image && !geometry.SnappedDestRect().IsEmpty() &&
       image) {
-    TRACE_EVENT1(
-        TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data",
-        InspectorPaintImageEvent::Data(node, *info.image, image->Rect(),
-                                       FloatRect(scrolled_paint_rect)));
+    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
+                 "data",
+                 InspectorPaintImageEvent::Data(
+                     node, *info.image, FloatRect(image->Rect()),
+                     FloatRect(scrolled_paint_rect)));
     context.DrawTiledImage(image,
                            FloatSize(geometry.UnsnappedDestRect().Size()),
                            FloatRect(geometry.SnappedDestRect()),
diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper_test.cc b/third_party/blink/renderer/core/paint/clip_path_clipper_test.cc
index 88530ea..e89559d 100644
--- a/third_party/blink/renderer/core/paint/clip_path_clipper_test.cc
+++ b/third_party/blink/renderer/core/paint/clip_path_clipper_test.cc
@@ -23,7 +23,7 @@
   base::Optional<FloatRect> bounding_box =
       ClipPathClipper::LocalClipPathBoundingBox(object);
   ASSERT_TRUE(bounding_box.has_value());
-  EXPECT_EQ(LayoutRect::InfiniteIntRect(), *bounding_box);
+  EXPECT_EQ(FloatRect(LayoutRect::InfiniteIntRect()), *bounding_box);
 }
 
 }  // unnamed namespace
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index 191c0b4..3ebe037 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -3248,11 +3248,11 @@
   // If the visible content rect is empty, then it makes no sense to map it back
   // since there is nothing to map.
   if (!visible_content_rect.IsEmpty()) {
-    local_interest_rect =
+    local_interest_rect = FloatRect(
         anchor_layout_object
             ->AbsoluteToLocalQuad(visible_content_rect,
                                   kUseTransforms | kTraverseDocumentBoundaries)
-            .EnclosingBoundingBox();
+            .EnclosingBoundingBox());
     local_interest_rect.Move(-offset_from_anchor_layout_object);
     // TODO(chrishtr): the code below is a heuristic, instead we should detect
     // and return whether the mapping failed.  In some cases,
diff --git a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
index 17c8d8c..472ac46 100644
--- a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
+++ b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
@@ -25,6 +25,9 @@
 
 }  // namespace
 
+constexpr TimeDelta FirstMeaningfulPaintDetector::kNetwork2QuietWindowTimeout;
+constexpr TimeDelta FirstMeaningfulPaintDetector::kNetwork0QuietWindowTimeout;
+
 FirstMeaningfulPaintDetector& FirstMeaningfulPaintDetector::From(
     Document& document) {
   return PaintTiming::From(document).GetFirstMeaningfulPaintDetector();
@@ -43,9 +46,9 @@
           this,
           &FirstMeaningfulPaintDetector::Network2QuietTimerFired) {
   if (GetDocument() && GetDocument()->GetSettings()) {
-    network2_quiet_window_seconds_ =
-        GetDocument()->GetSettings()->GetFMPNetworkQuietTimeout();
-    network0_quiet_window_seconds_ = network2_quiet_window_seconds_;
+    network2_quiet_window_timeout_ = TimeDelta::FromSecondsD(
+        GetDocument()->GetSettings()->GetFMPNetworkQuietTimeout());
+    network0_quiet_window_timeout_ = network2_quiet_window_timeout_;
   }
 }
 
@@ -142,13 +145,13 @@
     // If activeConnections < 2 and the timer is already running, current
     // 2-quiet window continues; the timer shouldn't be restarted.
     if (active_connections == 2 || !network2_quiet_timer_.IsActive()) {
-      network2_quiet_timer_.StartOneShot(network2_quiet_window_seconds_,
+      network2_quiet_timer_.StartOneShot(network2_quiet_window_timeout_,
                                          FROM_HERE);
     }
   }
   if (!network0_quiet_reached_ && active_connections == 0) {
     // This restarts 0-quiet timer if it's already running.
-    network0_quiet_timer_.StartOneShot(network0_quiet_window_seconds_,
+    network0_quiet_timer_.StartOneShot(network0_quiet_window_timeout_,
                                        FROM_HERE);
   }
 }
diff --git a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
index 5a86fed47..be4f3b59 100644
--- a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
+++ b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
@@ -59,8 +59,10 @@
 
   // The page is n-quiet if there are no more than n active network requests for
   // this duration of time.
-  static constexpr double kNetwork2QuietWindowSeconds = 0.5;
-  static constexpr double kNetwork0QuietWindowSeconds = 0.5;
+  static constexpr TimeDelta kNetwork2QuietWindowTimeout =
+      TimeDelta::FromSecondsD(0.5);
+  static constexpr TimeDelta kNetwork0QuietWindowTimeout =
+      TimeDelta::FromSecondsD(0.5);
 
   Document* GetDocument();
   int ActiveConnections();
@@ -81,8 +83,8 @@
   TimeTicks provisional_first_meaningful_paint_swap_;
   double max_significance_so_far_ = 0.0;
   double accumulated_significance_while_having_blank_text_ = 0.0;
-  double network2_quiet_window_seconds_ = kNetwork2QuietWindowSeconds;
-  double network0_quiet_window_seconds_ = kNetwork0QuietWindowSeconds;
+  TimeDelta network2_quiet_window_timeout_ = kNetwork2QuietWindowTimeout;
+  TimeDelta network0_quiet_window_timeout_ = kNetwork0QuietWindowTimeout;
   unsigned prev_layout_object_count_ = 0;
   bool seen_first_meaningful_paint_candidate_ = false;
   bool network0_quiet_reached_ = false;
diff --git a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
index f9414e4..756ad3f 100644
--- a/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
+++ b/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
@@ -18,7 +18,7 @@
 class FirstMeaningfulPaintDetectorTest : public PageTestBase {
  protected:
   void SetUp() override {
-    platform_->AdvanceClockSeconds(1);
+    platform_->AdvanceClock(TimeDelta::FromSeconds(1));
     PageTestBase::SetUp();
     ResetNetworkQuietTimer();
   }
@@ -32,7 +32,7 @@
   }
 
   TimeTicks AdvanceClockAndGetTime() {
-    platform_->AdvanceClockSeconds(1);
+    platform_->AdvanceClock(TimeDelta::FromSeconds(1));
     return CurrentTimeTicks();
   }
 
@@ -42,7 +42,7 @@
   }
 
   void SimulateLayoutAndPaint(int new_elements) {
-    platform_->AdvanceClockSeconds(0.001);
+    platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
     StringBuilder builder;
     for (int i = 0; i < new_elements; i++)
       builder.Append("<span>a</span>");
@@ -85,21 +85,21 @@
   bool HadNetwork2Quiet() { return Detector().network2_quiet_reached_; }
 
   void ClearFirstPaintSwapPromise() {
-    platform_->AdvanceClockSeconds(0.001);
+    platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
     GetPaintTiming().ReportSwapTime(PaintEvent::kFirstPaint,
                                     WebLayerTreeView::SwapResult::kDidSwap,
                                     CurrentTimeTicks());
   }
 
   void ClearFirstContentfulPaintSwapPromise() {
-    platform_->AdvanceClockSeconds(0.001);
+    platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
     GetPaintTiming().ReportSwapTime(PaintEvent::kFirstContentfulPaint,
                                     WebLayerTreeView::SwapResult::kDidSwap,
                                     CurrentTimeTicks());
   }
 
   void ClearProvisionalFirstMeaningfulPaintSwapPromise() {
-    platform_->AdvanceClockSeconds(0.001);
+    platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
     ClearProvisionalFirstMeaningfulPaintSwapPromise(CurrentTimeTicks());
   }
 
@@ -128,10 +128,12 @@
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
       platform_;
 
-  static constexpr double kNetwork0QuietWindowSeconds =
-      FirstMeaningfulPaintDetector::kNetwork0QuietWindowSeconds;
-  static constexpr double kNetwork2QuietWindowSeconds =
-      FirstMeaningfulPaintDetector::kNetwork2QuietWindowSeconds;
+  TimeDelta GetNetwork0QuietWindowTimeout() {
+    return FirstMeaningfulPaintDetector::kNetwork0QuietWindowTimeout;
+  }
+  TimeDelta GetNetwork2QuietWindowTimeout() {
+    return FirstMeaningfulPaintDetector::kNetwork2QuietWindowTimeout;
+  }
 };
 
 TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) {
@@ -260,7 +262,7 @@
   SimulateLayoutAndPaint(10);
   EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
   ClearProvisionalFirstMeaningfulPaintSwapPromise();
-  platform_->AdvanceClockSeconds(0.001);
+  platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
   MarkFirstContentfulPaintAndClearSwapPromise();
   SimulateNetworkStable();
   EXPECT_GE(GetPaintTiming().FirstMeaningfulPaintRendered(),
@@ -329,16 +331,18 @@
   EXPECT_FALSE(IsNetwork0QuietTimerActive());
 
   SetActiveConnections(0);
-  platform_->RunForPeriodSeconds(kNetwork0QuietWindowSeconds - 0.1);
+  platform_->RunForPeriod(GetNetwork0QuietWindowTimeout() -
+                          TimeDelta::FromMilliseconds(100));
   EXPECT_TRUE(IsNetwork0QuietTimerActive());
   EXPECT_FALSE(HadNetwork0Quiet());
 
   SetActiveConnections(0);  // This should reset the 0-quiet timer.
-  platform_->RunForPeriodSeconds(kNetwork0QuietWindowSeconds - 0.1);
+  platform_->RunForPeriod(GetNetwork0QuietWindowTimeout() -
+                          TimeDelta::FromMilliseconds(100));
   EXPECT_TRUE(IsNetwork0QuietTimerActive());
   EXPECT_FALSE(HadNetwork0Quiet());
 
-  platform_->RunForPeriodSeconds(0.1001);
+  platform_->RunForPeriod(TimeDelta::FromMicroseconds(100100));
   EXPECT_TRUE(HadNetwork0Quiet());
 }
 
@@ -349,17 +353,19 @@
   EXPECT_FALSE(IsNetwork2QuietTimerActive());
 
   SetActiveConnections(2);
-  platform_->RunForPeriodSeconds(kNetwork2QuietWindowSeconds - 0.1);
+  platform_->RunForPeriod(GetNetwork2QuietWindowTimeout() -
+                          TimeDelta::FromMilliseconds(100));
   EXPECT_TRUE(IsNetwork2QuietTimerActive());
   EXPECT_FALSE(HadNetwork2Quiet());
 
   SetActiveConnections(2);  // This should reset the 2-quiet timer.
-  platform_->RunForPeriodSeconds(kNetwork2QuietWindowSeconds - 0.1);
+  platform_->RunForPeriod(GetNetwork2QuietWindowTimeout() -
+                          TimeDelta::FromMilliseconds(100));
   EXPECT_TRUE(IsNetwork2QuietTimerActive());
   EXPECT_FALSE(HadNetwork2Quiet());
 
   SetActiveConnections(1);  // This should not reset the 2-quiet timer.
-  platform_->RunForPeriodSeconds(0.1001);
+  platform_->RunForPeriod(TimeDelta::FromMicroseconds(100100));
   EXPECT_TRUE(HadNetwork2Quiet());
 }
 
@@ -408,7 +414,7 @@
   MarkFirstContentfulPaintAndClearSwapPromise();
   SimulateLayoutAndPaint(1);
   EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
-  platform_->AdvanceClockSeconds(0.001);
+  platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
   SimulateLayoutAndPaint(10);
   EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 2U);
   // Having outstanding swap promises should defer setting FMP.
@@ -438,7 +444,7 @@
   EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
   ClearProvisionalFirstMeaningfulPaintSwapPromise();
   TimeTicks after_first_meaningful_paint_candidate = AdvanceClockAndGetTime();
-  platform_->AdvanceClockSeconds(0.001);
+  platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
   GetPaintTiming().MarkFirstContentfulPaint();
   // FCP > FMP candidate, but still waiting for FCP swap.
   SimulateNetworkStable();
@@ -467,14 +473,14 @@
   // Simulate only network 2-quiet so provisional FMP will be set on next
   // layout.
   TimeTicks pre_stable_timestamp = AdvanceClockAndGetTime();
-  platform_->AdvanceClockSeconds(0.001);
+  platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
   SimulateNetwork2Quiet();
   EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
   EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
 
   // Force another FMP candidate while there is a pending swap promise and the
   // network 2-quiet FMP non-swap timestamp is set.
-  platform_->AdvanceClockSeconds(0.001);
+  platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
   SimulateLayoutAndPaint(10);
   EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
 
diff --git a/third_party/blink/renderer/core/paint/image_painter.cc b/third_party/blink/renderer/core/paint/image_painter.cc
index a779381..43ba924 100644
--- a/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/third_party/blink/renderer/core/paint/image_painter.cc
@@ -153,7 +153,7 @@
   if (!image || image->IsNull())
     return;
 
-  FloatRect src_rect = image->Rect();
+  FloatRect src_rect = FloatRect(image->Rect());
   // If the content rect requires clipping, adjust |srcRect| and
   // |pixelSnappedDestRect| over using a clip.
   if (!content_rect.Contains(dest_rect)) {
@@ -161,8 +161,8 @@
     pixel_snapped_content_rect.Intersect(pixel_snapped_dest_rect);
     if (pixel_snapped_content_rect.IsEmpty())
       return;
-    src_rect =
-        MapRect(pixel_snapped_content_rect, pixel_snapped_dest_rect, src_rect);
+    src_rect = MapRect(FloatRect(pixel_snapped_content_rect),
+                       FloatRect(pixel_snapped_dest_rect), src_rect);
     pixel_snapped_dest_rect = pixel_snapped_content_rect;
   }
 
@@ -181,7 +181,7 @@
                 image->paint_image_id())
           : Image::kUnspecifiedDecode;
   context.DrawImage(
-      image.get(), decode_mode, pixel_snapped_dest_rect, &src_rect,
+      image.get(), decode_mode, FloatRect(pixel_snapped_dest_rect), &src_rect,
       SkBlendMode::kSrcOver,
       LayoutObject::ShouldRespectImageOrientation(&layout_image_));
 }
diff --git a/third_party/blink/renderer/core/paint/list_marker_painter.cc b/third_party/blink/renderer/core/paint/list_marker_painter.cc
index eb95c3a..01cf5a5 100644
--- a/third_party/blink/renderer/core/paint/list_marker_painter.cc
+++ b/third_party/blink/renderer/core/paint/list_marker_painter.cc
@@ -37,10 +37,10 @@
   context.SetStrokeThickness(1.0f);
   switch (style.ListStyleType()) {
     case EListStyleType::kDisc:
-      context.FillEllipse(marker);
+      context.FillEllipse(FloatRect(marker));
       break;
     case EListStyleType::kCircle:
-      context.StrokeEllipse(marker);
+      context.StrokeEllipse(FloatRect(marker));
       break;
     case EListStyleType::kSquare:
       context.FillRect(marker);
@@ -144,7 +144,7 @@
   }
 
   TextRunPaintInfo text_run_paint_info(text_run);
-  text_run_paint_info.bounds = EnclosingIntRect(marker);
+  text_run_paint_info.bounds = FloatRect(EnclosingIntRect(marker));
   const SimpleFontData* font_data =
       layout_list_marker_.Style()->GetFont().PrimaryFont();
   IntPoint text_origin =
@@ -175,7 +175,7 @@
       ConstructTextRun(font, suffix_str, 2, layout_list_marker_.StyleRef(),
                        layout_list_marker_.Style()->Direction());
   TextRunPaintInfo suffix_run_info(suffix_run);
-  suffix_run_info.bounds = EnclosingIntRect(marker);
+  suffix_run_info.bounds = FloatRect(EnclosingIntRect(marker));
 
   if (layout_list_marker_.Style()->IsLeftToRightDirection()) {
     context.DrawText(font, text_run_paint_info, text_origin);
diff --git a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
index 2b7998e..aa56f62 100644
--- a/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
+++ b/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
@@ -100,7 +100,8 @@
 
   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
                "data",
-               InspectorPaintImageEvent::Data(node, *style_image, image->Rect(),
+               InspectorPaintImageEvent::Data(node, *style_image,
+                                              FloatRect(image->Rect()),
                                               FloatRect(border_image_rect)));
 
   ScopedInterpolationQuality interpolation_quality_scope(
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc
index 94b3a8d..7e32057 100644
--- a/third_party/blink/renderer/core/paint/theme_painter_default.cc
+++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -482,7 +482,7 @@
       LayoutTheme::IsPressed(cancel_button_object.GetNode())
           ? cancel_pressed_image
           : cancel_image,
-      Image::kSyncDecode, painting_rect);
+      Image::kSyncDecode, FloatRect(painting_rect));
   return false;
 }
 
diff --git a/third_party/blink/renderer/core/paint/theme_painter_mac.mm b/third_party/blink/renderer/core/paint/theme_painter_mac.mm
index ed7918e..9e9cb2a 100644
--- a/third_party/blink/renderer/core/paint/theme_painter_mac.mm
+++ b/third_party/blink/renderer/core/paint/theme_painter_mac.mm
@@ -325,7 +325,7 @@
   PaintSliderTicks(o, paint_info, r);
 
   float zoom_level = o.StyleRef().EffectiveZoom();
-  FloatRect unzoomed_rect = r;
+  FloatRect unzoomed_rect(r);
 
   if (o.StyleRef().Appearance() == kSliderHorizontalPart ||
       o.StyleRef().Appearance() == kMediaSliderPart) {
diff --git a/third_party/blink/renderer/core/probe/CoreProbes.pidl b/third_party/blink/renderer/core/probe/CoreProbes.pidl
index 375b294..a0eb96f 100644
--- a/third_party/blink/renderer/core/probe/CoreProbes.pidl
+++ b/third_party/blink/renderer/core/probe/CoreProbes.pidl
@@ -59,8 +59,6 @@
   class HTMLDocumentParser;
   class ScheduledNavigation;
   class ThreadableLoaderClient;
-  class WebSocketHandshakeRequest;
-  class WebSocketHandshakeResponse;
   class WorkerInspectorProxy;
   class XMLHttpRequest;
 
@@ -128,8 +126,8 @@
   void didStartWorker(ExecutionContext*, WorkerInspectorProxy* proxy, bool waitingForDebugger);
   void workerTerminated(ExecutionContext*, WorkerInspectorProxy* proxy);
   void didCreateWebSocket([Keep] ExecutionContext*, unsigned long identifier, const KURL& requestURL, const String& protocol);
-  void willSendWebSocketHandshakeRequest([Keep] ExecutionContext*, unsigned long identifier, const WebSocketHandshakeRequest* request);
-  void didReceiveWebSocketHandshakeResponse([Keep] ExecutionContext*, unsigned long identifier, const WebSocketHandshakeRequest* request, const WebSocketHandshakeResponse* response);
+  void willSendWebSocketHandshakeRequest([Keep] ExecutionContext*, unsigned long identifier, network::mojom::blink::WebSocketHandshakeRequest* request);
+  void didReceiveWebSocketHandshakeResponse([Keep] ExecutionContext*, unsigned long identifier, network::mojom::blink::WebSocketHandshakeRequest* request, network::mojom::blink::WebSocketHandshakeResponse* response);
   void didCloseWebSocket([Keep] ExecutionContext*, unsigned long identifier);
   void didReceiveWebSocketFrame(ExecutionContext*, unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
   void didSendWebSocketFrame(ExecutionContext*, unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
diff --git a/third_party/blink/renderer/core/probe/core_probes.h b/third_party/blink/renderer/core/probe/core_probes.h
index affb944a..8ae705f 100644
--- a/third_party/blink/renderer/core/probe/core_probes.h
+++ b/third_party/blink/renderer/core/probe/core_probes.h
@@ -36,6 +36,15 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/platform/probe/platform_probes.h"
 
+namespace network {
+namespace mojom {
+namespace blink {
+class WebSocketHandshakeResponse;
+class WebSocketHandshakeRequest;
+}  // namespace blink
+}  // namespace mojom
+}  // namespace network
+
 namespace blink {
 
 class CoreProbeSink;
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 65967f6..cfbb9f3 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -398,7 +398,7 @@
     canvas->scale(1, -1);
   }
   DrawForContainer(canvas, PaintFlags(), FloatSize(container_size), 1,
-                   draw_dst_rect, draw_src_rect, url);
+                   FloatRect(draw_dst_rect), FloatRect(draw_src_rect), url);
   return recorder.finishRecordingAsPicture();
 }
 
@@ -414,7 +414,7 @@
   PaintRecorder recorder;
   cc::PaintCanvas* canvas = recorder.beginRecording(container_rect);
   DrawForContainer(canvas, PaintFlags(), FloatSize(container_rect.Size()), 1,
-                   container_rect, container_rect, url);
+                   FloatRect(container_rect), FloatRect(container_rect), url);
   builder.set_paint_record(recorder.finishRecordingAsPicture(), container_rect,
                            PaintImage::GetNextContentId());
 }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index ebae2b3..6b619ff 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -779,7 +779,7 @@
   if (IsWebArea() || layout_object_->IsListMarkerIncludingNG())
     return false;
 
-  // Using the help text, title or accessibility description (so we
+  // Using the title or accessibility description (so we
   // check if there's some kind of accessible name for the element)
   // to decide an element's visibility is not as definitive as
   // previous checks, so this should remain as one of the last.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 12db852e..5d81e818 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1722,6 +1722,21 @@
 // New AX name calculation.
 //
 
+String AXNodeObject::GetName(AXNameFrom& name_from,
+                             AXObjectVector* name_objects) const {
+  String name = AXObject::GetName(name_from, name_objects);
+  if (RoleValue() == kSpinButtonRole && DatetimeAncestor()) {
+    // Fields inside a datetime control need to merge the field name with
+    // the name of the <input> element.
+    name_objects->clear();
+    String input_name = DatetimeAncestor()->GetName(name_from, name_objects);
+    if (!input_name.IsEmpty())
+      return name + " " + input_name;
+  }
+
+  return name;
+}
+
 String AXNodeObject::TextAlternative(bool recursive,
                                      bool in_aria_labelled_by_traversal,
                                      AXObjectSet& visited,
@@ -2953,7 +2968,24 @@
       description_objects->push_back(related_objects[i]->object);
   }
 
-  return CollapseWhitespace(result);
+  result = CollapseWhitespace(result);
+
+  if (RoleValue() == kSpinButtonRole && DatetimeAncestor()) {
+    // Fields inside a datetime control need to merge the field description
+    // with the description of the <input> element.
+    const AXObject* datetime_ancestor = DatetimeAncestor();
+    AXNameFrom name_from;
+    datetime_ancestor->GetName(name_from, nullptr);
+    description_objects->clear();
+    String ancestor_description = DatetimeAncestor()->Description(
+        name_from, description_from, description_objects);
+    if (!result.IsEmpty() && !ancestor_description.IsEmpty())
+      return result + " " + ancestor_description;
+    if (!ancestor_description.IsEmpty())
+      return ancestor_description;
+  }
+
+  return result;
 }
 
 // Based on
@@ -3181,7 +3213,7 @@
     return native_placeholder;
 
   const AtomicString& aria_placeholder =
-      ToHTMLElement(node)->FastGetAttribute(aria_placeholderAttr);
+      GetAOMPropertyOrARIAAttribute(AOMStringProperty::kPlaceholder);
   if (!aria_placeholder.IsEmpty())
     return aria_placeholder;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
index cd546cb..cfe6489 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -157,6 +157,7 @@
   AccessibilityRole AriaRoleAttribute() const final;
 
   // AX name calculation.
+  String GetName(AXNameFrom&, AXObjectVector* name_objects) const override;
   String TextAlternative(bool recursive,
                          bool in_aria_labelled_by_traversal,
                          AXObjectSet& visited,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 7d3fcaf1..0bc1753 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1119,6 +1119,26 @@
   return nullptr;
 }
 
+const AXObject* AXObject::DatetimeAncestor(int max_levels_to_check) const {
+  switch (RoleValue()) {
+    case kDateTimeRole:
+    case kDateRole:
+    case kInputTimeRole:
+    case kTimeRole:
+      return this;
+    default:
+      break;
+  }
+
+  if (max_levels_to_check == 0)
+    return nullptr;
+
+  if (AXObject* parent = ParentObject())
+    return parent->DatetimeAncestor(max_levels_to_check - 1);
+
+  return nullptr;
+}
+
 bool AXObject::LastKnownIsIgnoredValue() const {
   if (last_known_is_ignored_value_ == kDefaultBehavior) {
     last_known_is_ignored_value_ =
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 16c101e3..46f3c35 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -558,6 +558,7 @@
   bool IsDescendantOfLeafNode() const;
   AXObject* LeafNodeAncestor() const;
   bool IsDescendantOfDisabledNode() const;
+  const AXObject* DatetimeAncestor(int max_levels_to_check = 3) const;
   const AXObject* DisabledAncestor() const;
   bool LastKnownIsIgnoredValue() const;
   void SetLastKnownIsIgnoredValue(bool);
diff --git a/third_party/blink/renderer/modules/locks/lock_manager.cc b/third_party/blink/renderer/modules/locks/lock_manager.cc
index 3f5746e..b8f4334 100644
--- a/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -189,6 +189,8 @@
   ExecutionContext* context = ExecutionContext::From(script_state);
   DCHECK(context->IsContextThread());
 
+  // 5. If origin is an opaque origin, then reject promise with a
+  // "SecurityError" DOMException.
   if (!context->GetSecurityOrigin()->CanAccessLocks()) {
     exception_state.ThrowSecurityError(
         "Access to the Locks API is denied in this context.");
@@ -209,6 +211,17 @@
 
   mojom::blink::LockMode mode = Lock::StringToMode(options.mode());
 
+  // 6. Otherwise, if name starts with U+002D HYPHEN-MINUS (-), then reject
+  // promise with a "NotSupportedError" DOMException.
+  if (name.StartsWith("-")) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+                                      "Names cannot start with '-'.");
+    return ScriptPromise();
+  }
+
+  // 7. Otherwise, if both options’ steal dictionary member and option’s
+  // ifAvailable dictionary member are true, then reject promise with a
+  // "NotSupportedError" DOMException.
   if (options.steal() && options.ifAvailable()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
@@ -216,12 +229,9 @@
     return ScriptPromise();
   }
 
-  if (name.StartsWith("-")) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
-                                      "Names cannot start with '-'.");
-    return ScriptPromise();
-  }
-
+  // 8. Otherwise, if options’ steal dictionary member is true and option’s mode
+  // dictionary member is not "exclusive", then reject promise with a
+  // "NotSupportedError" DOMException.
   if (options.steal() && mode != mojom::blink::LockMode::EXCLUSIVE) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
@@ -229,13 +239,16 @@
     return ScriptPromise();
   }
 
+  // 9. Otherwise, if option’s signal dictionary member is present, and either
+  // of options’ steal dictionary member or options’ ifAvailable dictionary
+  // member is true, then reject promise with a "NotSupportedError"
+  // DOMException.
   if (options.hasSignal() && options.ifAvailable()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
         "The 'signal' and 'ifAvailable' options cannot be used together.");
     return ScriptPromise();
   }
-
   if (options.hasSignal() && options.steal()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
@@ -243,6 +256,8 @@
     return ScriptPromise();
   }
 
+  // 10. Otherwise, if options’ signal dictionary member is present and its
+  // aborted flag is set, then reject promise with an "AbortError" DOMException.
   if (options.hasSignal() && options.signal()->aborted()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
                                       kRequestAbortedMessage);
@@ -259,11 +274,20 @@
   ScriptPromise promise = resolver->Promise();
 
   mojom::blink::LockRequestPtr request_ptr;
+  // 11.1. Let request be the result of running the steps to request a lock with
+  // promise, the current agent, environment’s id, origin, callback, name,
+  // options’ mode dictionary member, options’ ifAvailable dictionary member,
+  // and options’ steal dictionary member.
   LockRequestImpl* request = new LockRequestImpl(
       callback, resolver, name, mode, mojo::MakeRequest(&request_ptr), this);
   AddPendingRequest(request);
 
+  // 11.2. If options’ signal dictionary member is present, then add the
+  // following abort steps to options’ signal dictionary member:
   if (options.hasSignal()) {
+    // 11.2.1. Enqueue the steps to abort the request request to the lock task
+    // queue.
+    // 11.2.2. Reject promise with an "AbortError" DOMException.
     options.signal()->AddAlgorithm(WTF::Bind(&LockRequestImpl::Abort,
                                              WrapWeakPersistent(request),
                                              String(kRequestAbortedMessage)));
@@ -271,6 +295,7 @@
 
   service_->RequestLock(name, mode, wait, std::move(request_ptr));
 
+  // 12. Return promise.
   return promise;
 }
 
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc
index daec48ca..795677a 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -97,11 +97,9 @@
   }
   if (name == "background-sync")
     return CreatePermissionDescriptor(PermissionName::BACKGROUND_SYNC);
-  // TODO(riju): Remove runtime flag check when Generic Sensor feature is
-  // stable.
   if (name == "ambient-light-sensor" || name == "accelerometer" ||
       name == "gyroscope" || name == "magnetometer") {
-    if (!OriginTrials::sensorEnabled(ExecutionContext::From(script_state))) {
+    if (!RuntimeEnabledFeatures::SensorEnabled()) {
       exception_state.ThrowTypeError("GenericSensor flag is not enabled.");
       return nullptr;
     }
diff --git a/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl b/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
index 9f8e943..16caeb0 100644
--- a/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
+++ b/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-interface
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Constructor(optional SpatialSensorOptions sensorOptions),
     ConstructorCallWith=ExecutionContext,
     SecureContext,
diff --git a/third_party/blink/renderer/modules/sensor/accelerometer.idl b/third_party/blink/renderer/modules/sensor/accelerometer.idl
index 822afc43..34c5608 100644
--- a/third_party/blink/renderer/modules/sensor/accelerometer.idl
+++ b/third_party/blink/renderer/modules/sensor/accelerometer.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/accelerometer/#accelerometer-interface
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Constructor(optional SpatialSensorOptions sensorOptions),
     ConstructorCallWith=ExecutionContext,
     SecureContext,
diff --git a/third_party/blink/renderer/modules/sensor/gyroscope.idl b/third_party/blink/renderer/modules/sensor/gyroscope.idl
index b121251d..944961a 100644
--- a/third_party/blink/renderer/modules/sensor/gyroscope.idl
+++ b/third_party/blink/renderer/modules/sensor/gyroscope.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/gyroscope/#gyroscope-interface
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Constructor(optional SpatialSensorOptions sensorOptions),
     ConstructorCallWith=ExecutionContext,
     RaisesException=Constructor,
diff --git a/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl b/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
index b9f7e927..4489426 100644
--- a/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
+++ b/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/accelerometer/#linearaccelerationsensor
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Constructor(optional SpatialSensorOptions sensorOptions),
     ConstructorCallWith=ExecutionContext,
     SecureContext,
diff --git a/third_party/blink/renderer/modules/sensor/orientation_sensor.idl b/third_party/blink/renderer/modules/sensor/orientation_sensor.idl
index d0a028a..ecf5ce6 100644
--- a/third_party/blink/renderer/modules/sensor/orientation_sensor.idl
+++ b/third_party/blink/renderer/modules/sensor/orientation_sensor.idl
@@ -8,7 +8,7 @@
 typedef (Float32Array or Float64Array or DOMMatrix) RotationMatrixType;
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     SecureContext,
     Exposed=Window
 ] interface OrientationSensor : Sensor {
diff --git a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
index 8a6362a..0b7f746a 100644
--- a/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
+++ b/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/orientation-sensor/#relativeorientationsensor-interface
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Constructor(optional SpatialSensorOptions sensorOptions),
     ConstructorCallWith=ExecutionContext,
     SecureContext,
diff --git a/third_party/blink/renderer/modules/sensor/sensor.idl b/third_party/blink/renderer/modules/sensor/sensor.idl
index 6ea6e8a5..f33dec6 100644
--- a/third_party/blink/renderer/modules/sensor/sensor.idl
+++ b/third_party/blink/renderer/modules/sensor/sensor.idl
@@ -8,7 +8,7 @@
 [
     ActiveScriptWrappable,
     SecureContext,
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     Exposed=Window
 ] interface Sensor : EventTarget {
     [MeasureAs=GenericSensorActivated] readonly attribute boolean activated;
diff --git a/third_party/blink/renderer/modules/sensor/sensor_error_event.idl b/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
index 64769adc..919151d4 100644
--- a/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
+++ b/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
@@ -6,7 +6,7 @@
 // https://w3c.github.io/sensors/#sensorerrorevent
 
 [
-    OriginTrialEnabled=Sensor,
+    RuntimeEnabled=Sensor,
     SecureContext,
     Constructor(DOMString type, SensorErrorEventInit eventInitDict),
     Exposed=Window
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 2e083d8..7d639dbd 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
@@ -4667,8 +4667,8 @@
   PaintFlags flags;
   // TODO(ccameron): WebGL should produce sRGB images.
   // https://crbug.com/672299
-  image->Draw(resource_provider->Canvas(), flags, dest_rect, src_rect,
-              kDoNotRespectImageOrientation,
+  image->Draw(resource_provider->Canvas(), flags, FloatRect(dest_rect),
+              FloatRect(src_rect), kDoNotRespectImageOrientation,
               Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
   return resource_provider->Snapshot();
 }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
index 2307134..ecb2f0d 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -58,7 +58,6 @@
 #include "third_party/blink/renderer/modules/websockets/websocket_handle_impl.h"
 #include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
 #include "third_party/blink/renderer/platform/network/network_log.h"
-#include "third_party/blink/renderer/platform/network/websocket_handshake_request.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -580,7 +579,7 @@
 
 void WebSocketChannelImpl::DidStartOpeningHandshake(
     WebSocketHandle* handle,
-    scoped_refptr<WebSocketHandshakeRequest> request) {
+    network::mojom::blink::WebSocketHandshakeRequestPtr request) {
   NETWORK_DVLOG(1) << this << " DidStartOpeningHandshake(" << handle << ")";
 
   DCHECK(handle_);
@@ -597,7 +596,7 @@
 
 void WebSocketChannelImpl::DidFinishOpeningHandshake(
     WebSocketHandle* handle,
-    const WebSocketHandshakeResponse* response) {
+    network::mojom::blink::WebSocketHandshakeResponsePtr response) {
   NETWORK_DVLOG(1) << this << " DidFinishOpeningHandshake(" << handle << ")";
 
   DCHECK(handle_);
@@ -608,7 +607,8 @@
       TRACE_EVENT_SCOPE_THREAD, "data",
       InspectorWebSocketEvent::Data(GetExecutionContext(), identifier_));
   probe::didReceiveWebSocketHandshakeResponse(
-      GetExecutionContext(), identifier_, handshake_request_.get(), response);
+      GetExecutionContext(), identifier_, handshake_request_.get(),
+      response.get());
   handshake_request_ = nullptr;
 }
 
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
index 8bf476f..d7e4af0a 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -55,7 +55,6 @@
 
 namespace blink {
 
-class WebSocketHandshakeRequest;
 class WebSocketHandshakeThrottle;
 
 // This is an implementation of WebSocketChannel. This is created on the main
@@ -163,9 +162,10 @@
                   const String& extensions) override;
   void DidStartOpeningHandshake(
       WebSocketHandle*,
-      scoped_refptr<WebSocketHandshakeRequest>) override;
-  void DidFinishOpeningHandshake(WebSocketHandle*,
-                                 const WebSocketHandshakeResponse*) override;
+      network::mojom::blink::WebSocketHandshakeRequestPtr) override;
+  void DidFinishOpeningHandshake(
+      WebSocketHandle*,
+      network::mojom::blink::WebSocketHandshakeResponsePtr) override;
   void DidFail(WebSocketHandle*, const String& message) override;
   void DidReceiveData(WebSocketHandle*,
                       bool fin,
@@ -213,7 +213,7 @@
       connection_handle_for_scheduler_;
 
   std::unique_ptr<SourceLocation> location_at_construction_;
-  scoped_refptr<WebSocketHandshakeRequest> handshake_request_;
+  network::mojom::blink::WebSocketHandshakeRequestPtr handshake_request_;
   std::unique_ptr<WebSocketHandshakeThrottle> handshake_throttle_;
   // This field is only initialised if the object is still waiting for a
   // throttle response when DidConnect is called.
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_client.h b/third_party/blink/renderer/modules/websockets/websocket_handle_client.h
index 405411c..1896d2f 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_handle_client.h
+++ b/third_party/blink/renderer/modules/websockets/websocket_handle_client.h
@@ -31,12 +31,11 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_HANDLE_CLIENT_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_HANDLE_CLIENT_H_
 
+#include "services/network/public/mojom/websocket.mojom-blink.h"
 #include "third_party/blink/renderer/modules/websockets/websocket_handle.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 
 namespace blink {
-class WebSocketHandshakeRequest;
-class WebSocketHandshakeResponse;
 
 class WebSocketHandleClient {
  public:
@@ -49,13 +48,14 @@
   // This notification can be omitted when the inspector is not active.
   virtual void DidStartOpeningHandshake(
       WebSocketHandle*,
-      scoped_refptr<WebSocketHandshakeRequest>) = 0;
+      network::mojom::blink::WebSocketHandshakeRequestPtr) = 0;
 
   // Called when the browser finishes the opening handshake.
   // This notification precedes didConnect.
   // This notification can be omitted when the inspector is not active.
-  virtual void DidFinishOpeningHandshake(WebSocketHandle*,
-                                         const WebSocketHandshakeResponse*) = 0;
+  virtual void DidFinishOpeningHandshake(
+      WebSocketHandle*,
+      network::mojom::blink::WebSocketHandshakeResponsePtr) = 0;
 
   // Called when the browser is required to fail the connection.
   // |message| can be displayed in the inspector, but should not be passed
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
index 55040bc..079a508 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
@@ -9,8 +9,6 @@
 #include "third_party/blink/renderer/modules/websockets/websocket_handle_client.h"
 #include "third_party/blink/renderer/platform/network/http_names.h"
 #include "third_party/blink/renderer/platform/network/network_log.h"
-#include "third_party/blink/renderer/platform/network/websocket_handshake_request.h"
-#include "third_party/blink/renderer/platform/network/websocket_handshake_response.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -154,33 +152,14 @@
     network::mojom::blink::WebSocketHandshakeRequestPtr request) {
   NETWORK_DVLOG(1) << this << " OnStartOpeningHandshake("
                    << request->url.GetString() << ")";
-
-  scoped_refptr<WebSocketHandshakeRequest> request_to_pass =
-      WebSocketHandshakeRequest::Create(request->url);
-  for (size_t i = 0; i < request->headers.size(); ++i) {
-    const network::mojom::blink::HttpHeaderPtr& header = request->headers[i];
-    request_to_pass->AddHeaderField(AtomicString(header->name),
-                                    AtomicString(header->value));
-  }
-  request_to_pass->SetHeadersText(request->headers_text);
-  client_->DidStartOpeningHandshake(this, request_to_pass);
+  client_->DidStartOpeningHandshake(this, std::move(request));
 }
 
 void WebSocketHandleImpl::OnFinishOpeningHandshake(
     network::mojom::blink::WebSocketHandshakeResponsePtr response) {
   NETWORK_DVLOG(1) << this << " OnFinishOpeningHandshake("
                    << response->url.GetString() << ")";
-
-  WebSocketHandshakeResponse response_to_pass;
-  response_to_pass.SetStatusCode(response->status_code);
-  response_to_pass.SetStatusText(response->status_text);
-  for (size_t i = 0; i < response->headers.size(); ++i) {
-    const network::mojom::blink::HttpHeaderPtr& header = response->headers[i];
-    response_to_pass.AddHeaderField(AtomicString(header->name),
-                                    AtomicString(header->value));
-  }
-  response_to_pass.SetHeadersText(response->headers_text);
-  client_->DidFinishOpeningHandshake(this, &response_to_pass);
+  client_->DidFinishOpeningHandshake(this, std::move(response));
 }
 
 void WebSocketHandleImpl::OnAddChannelResponse(const String& protocol,
diff --git a/third_party/blink/renderer/platform/geometry/float_quad.h b/third_party/blink/renderer/platform/geometry/float_quad.h
index b392aa72..26922ce 100644
--- a/third_party/blink/renderer/platform/geometry/float_quad.h
+++ b/third_party/blink/renderer/platform/geometry/float_quad.h
@@ -61,6 +61,12 @@
         p3_(in_rect.MaxX(), in_rect.MaxY()),
         p4_(in_rect.X(), in_rect.MaxY()) {}
 
+  explicit FloatQuad(const IntRect& in_rect)
+      : p1_(in_rect.Location()),
+        p2_(in_rect.MaxX(), in_rect.Y()),
+        p3_(in_rect.MaxX(), in_rect.MaxY()),
+        p4_(in_rect.X(), in_rect.MaxY()) {}
+
   // Converts from an array of four SkPoints, as from SkMatrix::mapRectToQuad.
   explicit FloatQuad(const SkPoint (&)[4]);
 
diff --git a/third_party/blink/renderer/platform/geometry/float_rect.cc b/third_party/blink/renderer/platform/geometry/float_rect.cc
index 34741d1b..95fe5b7c 100644
--- a/third_party/blink/renderer/platform/geometry/float_rect.cc
+++ b/third_party/blink/renderer/platform/geometry/float_rect.cc
@@ -116,6 +116,17 @@
          other.X() < MaxX() && Y() < other.MaxY() && other.Y() < MaxY();
 }
 
+bool FloatRect::Intersects(const IntRect& other) const {
+  // Checking emptiness handles negative widths as well as zero.
+  return !IsEmpty() && !other.IsEmpty() && X() < other.MaxX() &&
+         other.X() < MaxX() && Y() < other.MaxY() && other.Y() < MaxY();
+}
+
+bool FloatRect::Contains(const IntRect& other) const {
+  return X() <= other.X() && MaxX() >= other.MaxX() && Y() <= other.Y() &&
+         MaxY() >= other.MaxY();
+}
+
 bool FloatRect::Contains(const FloatRect& other) const {
   return X() <= other.X() && MaxX() >= other.MaxX() && Y() <= other.Y() &&
          MaxY() >= other.MaxY();
@@ -129,6 +140,23 @@
          MaxY() > point.Y();
 }
 
+void FloatRect::Intersect(const IntRect& other) {
+  float left = std::max(X(), static_cast<float>(other.X()));
+  float top = std::max(Y(), static_cast<float>(other.Y()));
+  float right = std::min(MaxX(), static_cast<float>(other.MaxX()));
+  float bottom = std::min(MaxY(), static_cast<float>(other.MaxY()));
+
+  // Return a clean empty rectangle for non-intersecting cases.
+  if (left >= right || top >= bottom) {
+    left = 0;
+    top = 0;
+    right = 0;
+    bottom = 0;
+  }
+
+  SetLocationAndSizeFromEdges(left, top, right, bottom);
+}
+
 void FloatRect::Intersect(const FloatRect& other) {
   float left = std::max(X(), other.X());
   float top = std::max(Y(), other.Y());
diff --git a/third_party/blink/renderer/platform/geometry/float_rect.h b/third_party/blink/renderer/platform/geometry/float_rect.h
index 26f2628..3434286 100644
--- a/third_party/blink/renderer/platform/geometry/float_rect.h
+++ b/third_party/blink/renderer/platform/geometry/float_rect.h
@@ -67,7 +67,7 @@
       : location_(location), size_(size) {}
   FloatRect(float x, float y, float width, float height)
       : location_(FloatPoint(x, y)), size_(FloatSize(width, height)) {}
-  FloatRect(const IntRect&);
+  explicit FloatRect(const IntRect&);
   explicit FloatRect(const LayoutRect&);
   FloatRect(const SkRect&);
 
@@ -136,10 +136,13 @@
                       location_.Y() + size_.Height());
   }  // typically bottomRight
 
+  bool Intersects(const IntRect&) const;
   bool Intersects(const FloatRect&) const;
+  bool Contains(const IntRect&) const;
   bool Contains(const FloatRect&) const;
   bool Contains(const FloatPoint&, ContainsMode = kInsideOrOnStroke) const;
 
+  void Intersect(const IntRect&);
   void Intersect(const FloatRect&);
   // Set this rect to be the intersection of itself and the argument rect
   // using edge-inclusive geometry. If the two rectangles overlap but the
diff --git a/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc b/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc
index 59bcb6bd..62e832a 100644
--- a/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc
+++ b/third_party/blink/renderer/platform/geometry/float_rounded_rect.cc
@@ -42,6 +42,9 @@
 FloatRoundedRect::FloatRoundedRect(const FloatRect& rect, const Radii& radii)
     : rect_(rect), radii_(radii) {}
 
+FloatRoundedRect::FloatRoundedRect(const IntRect& rect, const Radii& radii)
+    : rect_(FloatRect(rect)), radii_(radii) {}
+
 FloatRoundedRect::FloatRoundedRect(const FloatRect& rect,
                                    const FloatSize& top_left,
                                    const FloatSize& top_right,
diff --git a/third_party/blink/renderer/platform/geometry/float_rounded_rect.h b/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
index 13aef59..edd2c53 100644
--- a/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
+++ b/third_party/blink/renderer/platform/geometry/float_rounded_rect.h
@@ -111,6 +111,7 @@
 
   FloatRoundedRect() = default;
   explicit FloatRoundedRect(const FloatRect&, const Radii& = Radii());
+  explicit FloatRoundedRect(const IntRect&, const Radii& = Radii());
   FloatRoundedRect(float x, float y, float width, float height);
   FloatRoundedRect(const FloatRect&,
                    const FloatSize& top_left,
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index fcf9f73..9324f1d 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -876,7 +876,7 @@
   if (ContextDisabled() || !image)
     return;
 
-  const FloatRect src = src_ptr ? *src_ptr : image->Rect();
+  const FloatRect src = src_ptr ? *src_ptr : FloatRect(image->Rect());
 
   PaintFlags image_flags = ImmutableState()->FillFlags();
   image_flags.setBlendMode(op);
@@ -908,7 +908,8 @@
 
   DCHECK(dest.IsRenderable());
 
-  const FloatRect visible_src = Intersection(src_rect, image->Rect());
+  const FloatRect visible_src =
+      Intersection(src_rect, FloatRect(image->Rect()));
   if (dest.IsEmpty() || visible_src.IsEmpty())
     return;
 
@@ -1044,6 +1045,16 @@
   DrawPath(path_to_fill.GetSkPath(), ImmutableState()->FillFlags());
 }
 
+void GraphicsContext::FillRect(const IntRect& rect) {
+  FillRect(FloatRect(rect));
+}
+
+void GraphicsContext::FillRect(const IntRect& rect,
+                               const Color& color,
+                               SkBlendMode xfer_mode) {
+  FillRect(FloatRect(rect), color, xfer_mode);
+}
+
 void GraphicsContext::FillRect(const FloatRect& rect) {
   if (ContextDisabled())
     return;
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h
index 7f31307..bcde727 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -189,6 +189,10 @@
   void FillEllipse(const FloatRect&);
   void StrokeEllipse(const FloatRect&);
 
+  void FillRect(const IntRect&);
+  void FillRect(const IntRect&,
+                const Color&,
+                SkBlendMode = SkBlendMode::kSrcOver);
   void FillRect(const FloatRect&);
   void FillRect(const FloatRect&,
                 const Color&,
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc
index 146eb83..8e5da1d 100644
--- a/third_party/blink/renderer/platform/graphics/image.cc
+++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -368,7 +368,7 @@
   flags.setColor(SK_ColorBLACK);
   flags.setBlendMode(composite_op);
   flags.setFilterQuality(
-      context.ComputeFilterQuality(this, dest_rect, subset_rect));
+      context.ComputeFilterQuality(this, dest_rect, FloatRect(subset_rect)));
   flags.setAntiAlias(context.ShouldAntialias());
   flags.setShader(CreatePatternShader(
       image, local_matrix, flags,
diff --git a/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
index 7d0d44db..13bfe20 100644
--- a/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
@@ -54,9 +54,9 @@
   // get in OnFirstSurfaceActivation. We need it so that we properly get a
   // WillDraw, which then pushes the first compositor frame.
   current_surface_id_ = viz::SurfaceId(
-      frame_sink_id_, parent_local_surface_id_allocator_.GenerateId());
-  surface_layer_->SetPrimarySurfaceId(current_surface_id_,
-                                      cc::DeadlinePolicy::UseDefaultDeadline());
+      frame_sink_id_,
+      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
+
   surface_layer_->SetStretchContentToFillBounds(true);
   surface_layer_->SetIsDrawable(true);
 
@@ -123,9 +123,6 @@
     observer_->OnSurfaceIdUpdated(surface_info.id());
   }
 
-  // TODO(lethalantidote): Discuss and remove for both Canvas and Video uses.
-  surface_layer_->SetBounds(surface_info.size_in_pixels());
-
   surface_layer_->SetContentsOpaque(opaque_);
 }
 
@@ -137,4 +134,12 @@
   opaque_ = opaque;
 }
 
+const viz::FrameSinkId& SurfaceLayerBridge::GetFrameSinkId() const {
+  return frame_sink_id_;
+}
+
+const viz::SurfaceId& SurfaceLayerBridge::GetSurfaceId() const {
+  return current_surface_id_;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h b/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h
index dea3d52..68f3d64 100644
--- a/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h
+++ b/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h
@@ -47,10 +47,8 @@
   cc::Layer* GetCcLayer() const override;
   void ClearSurfaceId() override;
   void SetContentsOpaque(bool) override;
-
-  const viz::FrameSinkId& GetFrameSinkId() const override {
-    return frame_sink_id_;
-  }
+  const viz::FrameSinkId& GetFrameSinkId() const override;
+  const viz::SurfaceId& GetSurfaceId() const override;
 
  private:
   scoped_refptr<cc::SurfaceLayer> surface_layer_;
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index 83128b0..def2db0c 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -1552,20 +1552,20 @@
 
 void NormalPage::VerifyObjectStartBitmapIsConsistentWithPayload() {
 #if DCHECK_IS_ON()
-  Address current_allocation_point =
-      ArenaForNormalPage()->CurrentAllocationPoint();
-  DCHECK(!current_allocation_point ||
-         (PageFromObject(current_allocation_point) != this));
-
   HeapObjectHeader* current_header =
       reinterpret_cast<HeapObjectHeader*>(Payload());
-  object_start_bit_map()->Iterate([&current_header](Address object_address) {
+  object_start_bit_map()->Iterate([this,
+                                   &current_header](Address object_address) {
     const HeapObjectHeader* object_header =
         reinterpret_cast<HeapObjectHeader*>(object_address);
     DCHECK_EQ(object_header, current_header);
     DCHECK(object_header->IsValidOrZapped());
     current_header = reinterpret_cast<HeapObjectHeader*>(object_address +
                                                          object_header->size());
+    // Skip over allocation area.
+    if (reinterpret_cast<Address>(current_header) ==
+        ArenaForNormalPage()->CurrentAllocationPoint())
+      current_header += ArenaForNormalPage()->RemainingAllocationSize();
   });
 #endif  // DCHECK_IS_ON()
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index 6e5acfba..3c42b95 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -428,7 +428,7 @@
 }
 
 NOINLINE void RawResourceClientStateChecker::SetSerializedCachedMetadata() {
-  SECURITY_CHECK(state_ == kResponseReceived);
+  SECURITY_CHECK(state_ == kResponseReceived || state_ == kDataReceived);
   state_ = kSetSerializedCachedMetadata;
 }
 
diff --git a/third_party/blink/renderer/platform/network/BUILD.gn b/third_party/blink/renderer/platform/network/BUILD.gn
index 9a299e9..c8925e32 100644
--- a/third_party/blink/renderer/platform/network/BUILD.gn
+++ b/third_party/blink/renderer/platform/network/BUILD.gn
@@ -62,10 +62,6 @@
     "parsed_content_type.h",
     "server_timing_header.cc",
     "server_timing_header.h",
-    "websocket_handshake_request.cc",
-    "websocket_handshake_request.h",
-    "websocket_handshake_response.cc",
-    "websocket_handshake_response.h",
   ]
 
   sources += get_target_outputs(":http_names")
diff --git a/third_party/blink/renderer/platform/network/websocket_handshake_request.cc b/third_party/blink/renderer/platform/network/websocket_handshake_request.cc
deleted file mode 100644
index bed9513..0000000
--- a/third_party/blink/renderer/platform/network/websocket_handshake_request.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#include "third_party/blink/renderer/platform/network/websocket_handshake_request.h"
-
-namespace blink {
-
-WebSocketHandshakeRequest::WebSocketHandshakeRequest(const KURL& url)
-    : url_(url) {}
-
-WebSocketHandshakeRequest::WebSocketHandshakeRequest() = default;
-
-WebSocketHandshakeRequest::WebSocketHandshakeRequest(
-    const WebSocketHandshakeRequest& request)
-    : url_(request.url_),
-      header_fields_(request.header_fields_),
-      headers_text_(request.headers_text_) {}
-
-WebSocketHandshakeRequest::~WebSocketHandshakeRequest() = default;
-
-void WebSocketHandshakeRequest::AddAndMergeHeader(HTTPHeaderMap* map,
-                                                  const AtomicString& name,
-                                                  const AtomicString& value) {
-  HTTPHeaderMap::AddResult result = map->Add(name, value);
-  if (!result.is_new_entry) {
-    // Inspector expects the "\n" separated format.
-    result.stored_value->value =
-        result.stored_value->value + "\n" + String(value);
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/network/websocket_handshake_request.h b/third_party/blink/renderer/platform/network/websocket_handshake_request.h
deleted file mode 100644
index 6c99c8c..0000000
--- a/third_party/blink/renderer/platform/network/websocket_handshake_request.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_REQUEST_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_REQUEST_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/network/http_header_map.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class HTTPHeaderMap;
-
-class PLATFORM_EXPORT WebSocketHandshakeRequest final
-    : public RefCounted<WebSocketHandshakeRequest> {
- public:
-  static scoped_refptr<WebSocketHandshakeRequest> Create(const KURL& url) {
-    return base::AdoptRef(new WebSocketHandshakeRequest(url));
-  }
-  static scoped_refptr<WebSocketHandshakeRequest> Create() {
-    return base::AdoptRef(new WebSocketHandshakeRequest);
-  }
-  static scoped_refptr<WebSocketHandshakeRequest> Create(
-      const WebSocketHandshakeRequest& request) {
-    return base::AdoptRef(new WebSocketHandshakeRequest(request));
-  }
-  virtual ~WebSocketHandshakeRequest();
-
-  void AddAndMergeHeader(const AtomicString& name, const AtomicString& value) {
-    AddAndMergeHeader(&header_fields_, name, value);
-  }
-
-  // Merges the existing value with |value| in |map| if |map| already has
-  // |name|.  Associates |value| with |name| in |map| otherwise.
-  // This function builds data for inspector.
-  static void AddAndMergeHeader(HTTPHeaderMap* /* map */,
-                                const AtomicString& name,
-                                const AtomicString& value);
-
-  void AddHeaderField(const AtomicString& name, const AtomicString& value) {
-    header_fields_.Add(name, value);
-  }
-
-  KURL Url() const { return url_; }
-  void SetURL(const KURL& url) { url_ = url; }
-  const HTTPHeaderMap& HeaderFields() const { return header_fields_; }
-  const String& HeadersText() const { return headers_text_; }
-  void SetHeadersText(const String& text) { headers_text_ = text; }
-
- private:
-  WebSocketHandshakeRequest(const KURL&);
-  WebSocketHandshakeRequest();
-  WebSocketHandshakeRequest(const WebSocketHandshakeRequest&);
-
-  KURL url_;
-  HTTPHeaderMap header_fields_;
-  String headers_text_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_REQUEST_H_
diff --git a/third_party/blink/renderer/platform/network/websocket_handshake_response.cc b/third_party/blink/renderer/platform/network/websocket_handshake_response.cc
deleted file mode 100644
index 1ded9d5..0000000
--- a/third_party/blink/renderer/platform/network/websocket_handshake_response.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#include "third_party/blink/renderer/platform/network/websocket_handshake_response.h"
-
-#include "third_party/blink/renderer/platform/network/websocket_handshake_request.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
-
-namespace blink {
-
-WebSocketHandshakeResponse::WebSocketHandshakeResponse() = default;
-
-WebSocketHandshakeResponse::~WebSocketHandshakeResponse() = default;
-
-int WebSocketHandshakeResponse::StatusCode() const {
-  return status_code_;
-}
-
-void WebSocketHandshakeResponse::SetStatusCode(int status_code) {
-  DCHECK_GE(status_code, 100);
-  DCHECK_LT(status_code, 600);
-  status_code_ = status_code;
-}
-
-const String& WebSocketHandshakeResponse::StatusText() const {
-  return status_text_;
-}
-
-void WebSocketHandshakeResponse::SetStatusText(const String& status_text) {
-  status_text_ = status_text;
-}
-
-const HTTPHeaderMap& WebSocketHandshakeResponse::HeaderFields() const {
-  return header_fields_;
-}
-
-void WebSocketHandshakeResponse::AddHeaderField(const AtomicString& name,
-                                                const AtomicString& value) {
-  WebSocketHandshakeRequest::AddAndMergeHeader(&header_fields_, name, value);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/network/websocket_handshake_response.h b/third_party/blink/renderer/platform/network/websocket_handshake_response.h
deleted file mode 100644
index 35ce3c6..0000000
--- a/third_party/blink/renderer/platform/network/websocket_handshake_response.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_RESPONSE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_RESPONSE_H_
-
-#include "third_party/blink/renderer/platform/network/http_header_map.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT WebSocketHandshakeResponse final {
- public:
-  WebSocketHandshakeResponse();
-  ~WebSocketHandshakeResponse();
-
-  int StatusCode() const;
-  void SetStatusCode(int);
-  const String& StatusText() const;
-  void SetStatusText(const String&);
-  const HTTPHeaderMap& HeaderFields() const;
-  void AddHeaderField(const AtomicString& name, const AtomicString& value);
-  const String& HeadersText() const { return headers_text_; }
-  void SetHeadersText(const String& text) { headers_text_ = text; }
-
- private:
-  int status_code_;
-  String status_text_;
-  HTTPHeaderMap header_fields_;
-  String headers_text_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_WEBSOCKET_HANDSHAKE_RESPONSE_H_
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 24470fa..20cbe61f 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -317,6 +317,12 @@
       name: "CSSOverscrollBehavior",
       status: "stable",
     },
+    // Do not ship CSSPaintAPIArguments without shipping CSSVariables2 first.
+    //
+    // CSSPaintAPIArguments depends on parts of the the 'CSS Properties and
+    // Values API Level 1', specification (section 'Supported syntax strings').
+    // That specification is implemented behind the runtime enabled feature
+    // CSSVariables2.
     {
       name: "CSSPaintAPIArguments",
       status: "experimental",
@@ -1126,8 +1132,7 @@
     },
     {
       name: "Sensor",
-      origin_trial_feature_name: "GenericSensor",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "SensorExtraClasses",
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc
index a39e6d77..24ea07a 100644
--- a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_impl_unittest.cc
@@ -19,6 +19,7 @@
 #include "base/task/sequence_manager/real_time_domain.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/task/sequence_manager/task_queue_selector.h"
+#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
 #include "base/task/sequence_manager/work_queue.h"
 #include "base/task/sequence_manager/work_queue_sets.h"
 #include "base/test/simple_test_tick_clock.h"
@@ -50,7 +51,14 @@
 // To avoid symbol collisions in jumbo builds.
 namespace sequence_manager_impl_unittest {
 
-class SequenceManagerTestBase : public testing::Test {
+enum class TestType : int {
+  kCustom = 0,
+  kUseMockTaskRunner = 1,
+  kUseMessageLoop = 2,
+  kUseMessagePump = 3,
+};
+
+class SequenceManagerTestBase : public testing::TestWithParam<TestType> {
  protected:
   void TearDown() override {
     // SequenceManager should be deleted before an underlying task runner.
@@ -75,12 +83,16 @@
 
 // SequenceManagerImpl uses TestMockTimeTaskRunner which controls
 // both task execution and mock clock.
+// TODO(kraynov): Make this class to support all TestTypes.
+// It will allow us to re-run tests in various environments before we'll
+// eventually move to MessagePump and remove current ThreadControllerImpl.
 class SequenceManagerTest : public SequenceManagerTestBase {
  public:
   void DeleteSequenceManagerTask() { manager_.reset(); }
 
  protected:
   void SetUp() override {
+    ASSERT_EQ(GetParam(), TestType::kUseMockTaskRunner);
     test_task_runner_ = WrapRefCounted(new TestMockTimeTaskRunner(
         TestMockTimeTaskRunner::Type::kBoundToThread));
     // A null clock triggers some assertions.
@@ -134,9 +146,25 @@
 
 // SequenceManagerImpl is being initialized with real MessageLoop
 // at cost of less control over a task runner.
+// It also runs a version with experimental MessagePump support.
+// TODO(kraynov): Generalize as many tests as possible to run it
+// in all supported environments.
 class SequenceManagerTestWithMessageLoop : public SequenceManagerTestBase {
  protected:
   void SetUp() override {
+    switch (GetParam()) {
+      case TestType::kUseMessageLoop:
+        SetUpWithMessageLoop();
+        break;
+      case TestType::kUseMessagePump:
+        SetUpWithMessagePump();
+        break;
+      default:
+        FAIL();
+    }
+  }
+
+  void SetUpWithMessageLoop() {
     message_loop_.reset(new MessageLoop());
     // A null clock triggers some assertions.
     mock_clock_.Advance(TimeDelta::FromMilliseconds(1));
@@ -146,6 +174,17 @@
         message_loop_.get(), ThreadTaskRunnerHandle::Get(), &mock_clock_);
   }
 
+  void SetUpWithMessagePump() {
+    mock_clock_.Advance(TimeDelta::FromMilliseconds(1));
+    start_time_ = mock_clock_.NowTicks();
+    manager_ = std::make_unique<SequenceManagerForTest>(
+        std::make_unique<ThreadControllerWithMessagePumpImpl>(&mock_clock_));
+    // ThreadControllerWithMessagePumpImpl doesn't provide a default tas runner.
+    scoped_refptr<TaskQueue> default_task_queue =
+        manager_->CreateTaskQueue<TestTaskQueue>(TaskQueue::Spec("default"));
+    manager_->SetDefaultTaskRunner(default_task_queue);
+  }
+
   const TickClock* GetTickClock() { return &mock_clock_; }
 
   std::unique_ptr<MessageLoop> message_loop_;
@@ -155,9 +194,22 @@
 class SequenceManagerTestWithCustomInitialization
     : public SequenceManagerTestWithMessageLoop {
  protected:
-  void SetUp() override {}
+  void SetUp() override { ASSERT_EQ(GetParam(), TestType::kCustom); }
 };
 
+INSTANTIATE_TEST_CASE_P(,
+                        SequenceManagerTest,
+                        testing::Values(TestType::kUseMockTaskRunner));
+
+INSTANTIATE_TEST_CASE_P(,
+                        SequenceManagerTestWithMessageLoop,
+                        testing::Values(TestType::kUseMessageLoop,
+                                        TestType::kUseMessagePump));
+
+INSTANTIATE_TEST_CASE_P(,
+                        SequenceManagerTestWithCustomInitialization,
+                        testing::Values(TestType::kCustom));
+
 void PostFromNestedRunloop(SingleThreadTaskRunner* runner,
                            std::vector<std::pair<OnceClosure, bool>>* tasks) {
   for (std::pair<OnceClosure, bool>& pair : *tasks) {
@@ -172,7 +224,7 @@
 
 void NopTask() {}
 
-TEST_F(SequenceManagerTestWithCustomInitialization,
+TEST_P(SequenceManagerTestWithCustomInitialization,
        NowCalledMinimumNumberOfTimesToComputeTaskDurations) {
   message_loop_.reset(new MessageLoop());
   // This memory is managed by the SequenceManager, but we need to hold a
@@ -213,7 +265,7 @@
   voter->SetQueueEnabled(false);
 }
 
-TEST_F(SequenceManagerTest, SingleQueuePosting) {
+TEST_P(SequenceManagerTest, SingleQueuePosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -225,7 +277,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
 }
 
-TEST_F(SequenceManagerTest, MultiQueuePosting) {
+TEST_P(SequenceManagerTest, MultiQueuePosting) {
   CreateTaskQueues(3u);
 
   std::vector<EnqueueOrder> run_order;
@@ -240,7 +292,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u));
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, NonNestableTaskPosting) {
+TEST_P(SequenceManagerTestWithMessageLoop, NonNestableTaskPosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -251,7 +303,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop,
+TEST_P(SequenceManagerTestWithMessageLoop,
        NonNestableTaskExecutesInExpectedOrder) {
   CreateTaskQueues(1u);
 
@@ -267,7 +319,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u));
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop,
+TEST_P(SequenceManagerTestWithMessageLoop,
        NonNestableTasksDoesntExecuteInNestedLoop) {
   CreateTaskQueues(1u);
 
@@ -310,7 +362,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTestWithMessageLoop, TaskQueueDisabledFromNestedLoop) {
+TEST_P(SequenceManagerTestWithMessageLoop, TaskQueueDisabledFromNestedLoop) {
   CreateTaskQueues(1u);
   std::vector<EnqueueOrder> run_order;
 
@@ -338,7 +390,7 @@
   EXPECT_THAT(run_order, ElementsAre(2u, 1u, 3u));
 }
 
-TEST_F(SequenceManagerTest, HasPendingImmediateWork_ImmediateTask) {
+TEST_P(SequenceManagerTest, HasPendingImmediateWork_ImmediateTask) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -362,7 +414,7 @@
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 }
 
-TEST_F(SequenceManagerTest, HasPendingImmediateWork_DelayedTask) {
+TEST_P(SequenceManagerTest, HasPendingImmediateWork_DelayedTask) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -384,7 +436,7 @@
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 }
 
-TEST_F(SequenceManagerTest, DelayedTaskPosting) {
+TEST_P(SequenceManagerTest, DelayedTaskPosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -406,7 +458,7 @@
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 }
 
-TEST_F(SequenceManagerTest, DelayedTaskExecutedInOneMessageLoopTask) {
+TEST_P(SequenceManagerTest, DelayedTaskExecutedInOneMessageLoopTask) {
   CreateTaskQueues(1u);
 
   runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
@@ -417,7 +469,7 @@
   EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount());
 }
 
-TEST_F(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
+TEST_P(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -447,7 +499,7 @@
   EXPECT_THAT(run_order, ElementsAre(3u, 2u, 1u));
 }
 
-TEST_F(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
+TEST_P(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -477,7 +529,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
 }
 
-TEST_F(SequenceManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
+TEST_P(SequenceManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -503,7 +555,7 @@
 
 int TestObject::destructor_count__ = 0;
 
-TEST_F(SequenceManagerTest, PendingDelayedTasksRemovedOnShutdown) {
+TEST_P(SequenceManagerTest, PendingDelayedTasksRemovedOnShutdown) {
   CreateTaskQueues(1u);
 
   TestObject::destructor_count__ = 0;
@@ -519,7 +571,7 @@
   EXPECT_EQ(2, TestObject::destructor_count__);
 }
 
-TEST_F(SequenceManagerTest, InsertAndRemoveFence) {
+TEST_P(SequenceManagerTest, InsertAndRemoveFence) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -539,7 +591,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, RemovingFenceForDisabledQueueDoesNotPostDoWork) {
+TEST_P(SequenceManagerTest, RemovingFenceForDisabledQueueDoesNotPostDoWork) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -553,7 +605,7 @@
   EXPECT_FALSE(test_task_runner_->HasPendingTask());
 }
 
-TEST_F(SequenceManagerTest, EnablingFencedQueueDoesNotPostDoWork) {
+TEST_P(SequenceManagerTest, EnablingFencedQueueDoesNotPostDoWork) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -567,7 +619,7 @@
   EXPECT_FALSE(test_task_runner_->HasPendingTask());
 }
 
-TEST_F(SequenceManagerTest, DenyRunning_BeforePosting) {
+TEST_P(SequenceManagerTest, DenyRunning_BeforePosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -585,7 +637,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, DenyRunning_AfterPosting) {
+TEST_P(SequenceManagerTest, DenyRunning_AfterPosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -603,7 +655,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, DenyRunning_AfterRemovingFence) {
+TEST_P(SequenceManagerTest, DenyRunning_AfterRemovingFence) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -622,7 +674,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, RemovingFenceWithDelayedTask) {
+TEST_P(SequenceManagerTest, RemovingFenceWithDelayedTask) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -644,7 +696,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, RemovingFenceWithMultipleDelayedTasks) {
+TEST_P(SequenceManagerTest, RemovingFenceWithMultipleDelayedTasks) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -671,7 +723,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u));
 }
 
-TEST_F(SequenceManagerTest, InsertFencePreventsDelayedTasksFromRunning) {
+TEST_P(SequenceManagerTest, InsertFencePreventsDelayedTasksFromRunning) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -684,7 +736,7 @@
   EXPECT_TRUE(run_order.empty());
 }
 
-TEST_F(SequenceManagerTest, MultipleFences) {
+TEST_P(SequenceManagerTest, MultipleFences) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -703,7 +755,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
 }
 
-TEST_F(SequenceManagerTest, InsertFenceThenImmediatlyRemoveDoesNotBlock) {
+TEST_P(SequenceManagerTest, InsertFenceThenImmediatlyRemoveDoesNotBlock) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
   runners_[0]->RemoveFence();
@@ -716,7 +768,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u));
 }
 
-TEST_F(SequenceManagerTest, InsertFencePostThenRemoveDoesNotBlock) {
+TEST_P(SequenceManagerTest, InsertFencePostThenRemoveDoesNotBlock) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -729,7 +781,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u));
 }
 
-TEST_F(SequenceManagerTest, MultipleFencesWithInitiallyEmptyQueue) {
+TEST_P(SequenceManagerTest, MultipleFencesWithInitiallyEmptyQueue) {
   CreateTaskQueues(1u);
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
 
@@ -742,7 +794,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u));
 }
 
-TEST_F(SequenceManagerTest, BlockedByFence) {
+TEST_P(SequenceManagerTest, BlockedByFence) {
   CreateTaskQueues(1u);
   EXPECT_FALSE(runners_[0]->BlockedByFence());
 
@@ -763,7 +815,7 @@
   EXPECT_FALSE(runners_[0]->BlockedByFence());
 }
 
-TEST_F(SequenceManagerTest, BlockedByFence_BothTypesOfFence) {
+TEST_P(SequenceManagerTest, BlockedByFence_BothTypesOfFence) {
   CreateTaskQueues(1u);
 
   runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask));
@@ -790,7 +842,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTest, DelayedFence_DelayedTasks) {
+TEST_P(SequenceManagerTest, DelayedFence_DelayedTasks) {
   CreateTaskQueues(1u);
 
   std::vector<TimeTicks> run_times;
@@ -825,7 +877,7 @@
               ElementsAre(start_time_ + TimeDelta::FromMilliseconds(300)));
 }
 
-TEST_F(SequenceManagerTest, DelayedFence_ImmediateTasks) {
+TEST_P(SequenceManagerTest, DelayedFence_ImmediateTasks) {
   CreateTaskQueues(1u);
 
   std::vector<TimeTicks> run_times;
@@ -857,7 +909,7 @@
                           start_time_ + TimeDelta::FromMilliseconds(500)));
 }
 
-TEST_F(SequenceManagerTest, DelayedFence_RemovedFenceDoesNotActivate) {
+TEST_P(SequenceManagerTest, DelayedFence_RemovedFenceDoesNotActivate) {
   CreateTaskQueues(1u);
 
   std::vector<TimeTicks> run_times;
@@ -889,7 +941,7 @@
                   start_time_ + TimeDelta::FromMilliseconds(400)));
 }
 
-TEST_F(SequenceManagerTest, DelayedFence_TakeIncomingImmediateQueue) {
+TEST_P(SequenceManagerTest, DelayedFence_TakeIncomingImmediateQueue) {
   // This test checks that everything works correctly when a work queue
   // is swapped with an immediate incoming queue and a delayed fence
   // is activated, forcing a different queue to become active.
@@ -945,7 +997,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTest, ReentrantPosting) {
+TEST_P(SequenceManagerTest, ReentrantPosting) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -956,7 +1008,7 @@
   EXPECT_THAT(run_order, ElementsAre(3u, 2u, 1u));
 }
 
-TEST_F(SequenceManagerTest, NoTasksAfterShutdown) {
+TEST_P(SequenceManagerTest, NoTasksAfterShutdown) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -973,7 +1025,7 @@
   runner->PostTask(FROM_HERE, BindOnce(&TestTask, 1, run_order));
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, PostFromThread) {
+TEST_P(SequenceManagerTestWithMessageLoop, PostFromThread) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -994,7 +1046,7 @@
                                        Unretained(runner.get()), run_count));
 }
 
-TEST_F(SequenceManagerTest, DoWorkCantPostItselfMultipleTimes) {
+TEST_P(SequenceManagerTest, DoWorkCantPostItselfMultipleTimes) {
   CreateTaskQueues(1u);
 
   int run_count = 0;
@@ -1006,7 +1058,7 @@
   EXPECT_EQ(1, run_count);
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, PostFromNestedRunloop) {
+TEST_P(SequenceManagerTestWithMessageLoop, PostFromNestedRunloop) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -1025,7 +1077,7 @@
   EXPECT_THAT(run_order, ElementsAre(0u, 2u, 1u));
 }
 
-TEST_F(SequenceManagerTest, WorkBatching) {
+TEST_P(SequenceManagerTest, WorkBatching) {
   CreateTaskQueues(1u);
 
   manager_->SetWorkBatchSize(2);
@@ -1054,7 +1106,7 @@
   MOCK_METHOD1(WillProcessTask, void(const PendingTask& task));
 };
 
-TEST_F(SequenceManagerTestWithMessageLoop, TaskObserverAdding) {
+TEST_P(SequenceManagerTestWithMessageLoop, TaskObserverAdding) {
   CreateTaskQueues(1u);
   MockTaskObserver observer;
 
@@ -1070,7 +1122,7 @@
   RunLoop().RunUntilIdle();
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, TaskObserverRemoving) {
+TEST_P(SequenceManagerTestWithMessageLoop, TaskObserverRemoving) {
   CreateTaskQueues(1u);
   MockTaskObserver observer;
   manager_->SetWorkBatchSize(2);
@@ -1090,7 +1142,7 @@
   manager->RemoveTaskObserver(observer);
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, TaskObserverRemovingInsideTask) {
+TEST_P(SequenceManagerTestWithMessageLoop, TaskObserverRemovingInsideTask) {
   CreateTaskQueues(1u);
   MockTaskObserver observer;
   manager_->SetWorkBatchSize(3);
@@ -1104,7 +1156,7 @@
   RunLoop().RunUntilIdle();
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, QueueTaskObserverAdding) {
+TEST_P(SequenceManagerTestWithMessageLoop, QueueTaskObserverAdding) {
   CreateTaskQueues(2u);
   MockTaskObserver observer;
 
@@ -1120,7 +1172,7 @@
   RunLoop().RunUntilIdle();
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, QueueTaskObserverRemoving) {
+TEST_P(SequenceManagerTestWithMessageLoop, QueueTaskObserverRemoving) {
   CreateTaskQueues(1u);
   MockTaskObserver observer;
   manager_->SetWorkBatchSize(2);
@@ -1141,7 +1193,7 @@
   queue->RemoveTaskObserver(observer);
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop,
+TEST_P(SequenceManagerTestWithMessageLoop,
        QueueTaskObserverRemovingInsideTask) {
   CreateTaskQueues(1u);
   MockTaskObserver observer;
@@ -1155,14 +1207,14 @@
   RunLoop().RunUntilIdle();
 }
 
-TEST_F(SequenceManagerTest, ThreadCheckAfterTermination) {
+TEST_P(SequenceManagerTest, ThreadCheckAfterTermination) {
   CreateTaskQueues(1u);
   EXPECT_TRUE(runners_[0]->RunsTasksInCurrentSequence());
   manager_.reset();
   EXPECT_TRUE(runners_[0]->RunsTasksInCurrentSequence());
 }
 
-TEST_F(SequenceManagerTest, TimeDomain_NextScheduledRunTime) {
+TEST_P(SequenceManagerTest, TimeDomain_NextScheduledRunTime) {
   CreateTaskQueues(2u);
   test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMicroseconds(10000));
   LazyNow lazy_now_1(GetTickClock());
@@ -1205,7 +1257,7 @@
             manager_->GetRealTimeDomain()->DelayTillNextTask(&lazy_now_2));
 }
 
-TEST_F(SequenceManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) {
+TEST_P(SequenceManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) {
   CreateTaskQueues(3u);
 
   TimeDelta delay1 = TimeDelta::FromMilliseconds(50);
@@ -1221,7 +1273,7 @@
             manager_->GetRealTimeDomain()->DelayTillNextTask(&lazy_now));
 }
 
-TEST_F(SequenceManagerTest, DeleteSequenceManagerInsideATask) {
+TEST_P(SequenceManagerTest, DeleteSequenceManagerInsideATask) {
   CreateTaskQueues(1u);
 
   runners_[0]->PostTask(
@@ -1233,7 +1285,7 @@
   RunLoop().RunUntilIdle();
 }
 
-TEST_F(SequenceManagerTest, GetAndClearSystemIsQuiescentBit) {
+TEST_P(SequenceManagerTest, GetAndClearSystemIsQuiescentBit) {
   CreateTaskQueues(3u);
 
   scoped_refptr<TaskQueue> queue0 =
@@ -1265,7 +1317,7 @@
   EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
 }
 
-TEST_F(SequenceManagerTest, HasPendingImmediateWork) {
+TEST_P(SequenceManagerTest, HasPendingImmediateWork) {
   CreateTaskQueues(1u);
 
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
@@ -1276,7 +1328,7 @@
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
 }
 
-TEST_F(SequenceManagerTest, HasPendingImmediateWork_DelayedTasks) {
+TEST_P(SequenceManagerTest, HasPendingImmediateWork_DelayedTasks) {
   CreateTaskQueues(1u);
 
   EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately());
@@ -1307,7 +1359,7 @@
   test_task_runner->FastForwardBy(TimeDelta::FromMilliseconds(1));
 }
 
-TEST_F(SequenceManagerTest, ImmediateAndDelayedTaskInterleaving) {
+TEST_P(SequenceManagerTest, ImmediateAndDelayedTaskInterleaving) {
   CreateTaskQueues(1u);
 
   std::vector<EnqueueOrder> run_order;
@@ -1334,7 +1386,7 @@
   EXPECT_THAT(run_order, ElementsAreArray(expected_run_order));
 }
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) {
   CreateTaskQueues(1u);
 
@@ -1351,7 +1403,7 @@
   EXPECT_THAT(run_order, ElementsAre(2u, 3u, 1u));
 }
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) {
   CreateTaskQueues(2u);
 
@@ -1368,7 +1420,7 @@
   EXPECT_THAT(run_order, ElementsAre(2u, 3u, 1u));
 }
 
-TEST_F(SequenceManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
+TEST_P(SequenceManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
   CreateTaskQueues(2u);
 
   std::vector<EnqueueOrder> run_order;
@@ -1397,7 +1449,7 @@
   run_loop->Run();
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, QuitWhileNested) {
+TEST_P(SequenceManagerTestWithMessageLoop, QuitWhileNested) {
   // This test makes sure we don't continue running a work batch after a nested
   // run loop has been exited in the middle of the batch.
   CreateTaskQueues(1u);
@@ -1427,7 +1479,7 @@
   std::vector<int> sequence_numbers_;
 };
 
-TEST_F(SequenceManagerTest, SequenceNumSetWhenTaskIsPosted) {
+TEST_P(SequenceManagerTest, SequenceNumSetWhenTaskIsPosted) {
   CreateTaskQueues(1u);
 
   SequenceNumberCapturingTaskObserver observer;
@@ -1454,7 +1506,7 @@
   manager_->RemoveTaskObserver(&observer);
 }
 
-TEST_F(SequenceManagerTest, NewTaskQueues) {
+TEST_P(SequenceManagerTest, NewTaskQueues) {
   CreateTaskQueues(1u);
 
   scoped_refptr<TaskQueue> queue1 = CreateTaskQueue();
@@ -1474,7 +1526,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
 }
 
-TEST_F(SequenceManagerTest, ShutdownTaskQueue) {
+TEST_P(SequenceManagerTest, ShutdownTaskQueue) {
   CreateTaskQueues(1u);
 
   scoped_refptr<TaskQueue> queue1 = CreateTaskQueue();
@@ -1496,7 +1548,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 3u));
 }
 
-TEST_F(SequenceManagerTest, ShutdownTaskQueue_WithDelayedTasks) {
+TEST_P(SequenceManagerTest, ShutdownTaskQueue_WithDelayedTasks) {
   CreateTaskQueues(2u);
 
   // Register three delayed tasks
@@ -1521,7 +1573,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTest, ShutdownTaskQueue_InTasks) {
+TEST_P(SequenceManagerTest, ShutdownTaskQueue_InTasks) {
   CreateTaskQueues(3u);
 
   std::vector<EnqueueOrder> run_order;
@@ -1546,7 +1598,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTestWithMessageLoop, ShutdownTaskQueueInNestedLoop) {
+TEST_P(SequenceManagerTestWithMessageLoop, ShutdownTaskQueueInNestedLoop) {
   CreateTaskQueues(1u);
 
   // We retain a reference to the task queue even when the manager has deleted
@@ -1575,7 +1627,7 @@
   // Just make sure that we don't crash.
 }
 
-TEST_F(SequenceManagerTest, TimeDomainsAreIndependant) {
+TEST_P(SequenceManagerTest, TimeDomainsAreIndependant) {
   CreateTaskQueues(2u);
 
   TimeTicks start_time_ticks = manager_->NowTicks();
@@ -1622,7 +1674,7 @@
   manager_->UnregisterTimeDomain(domain_b.get());
 }
 
-TEST_F(SequenceManagerTest, TimeDomainMigration) {
+TEST_P(SequenceManagerTest, TimeDomainMigration) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time_ticks = manager_->NowTicks();
@@ -1663,7 +1715,7 @@
   manager_->UnregisterTimeDomain(domain_b.get());
 }
 
-TEST_F(SequenceManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) {
+TEST_P(SequenceManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time_ticks = manager_->NowTicks();
@@ -1688,7 +1740,7 @@
   manager_->UnregisterTimeDomain(domain_b.get());
 }
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        PostDelayedTasksReverseOrderAlternatingTimeDomains) {
   CreateTaskQueues(1u);
 
@@ -1737,7 +1789,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTest, TaskQueueObserver_ImmediateTask) {
+TEST_P(SequenceManagerTest, TaskQueueObserver_ImmediateTask) {
   CreateTaskQueues(1u);
 
   MockTaskQueueObserver observer;
@@ -1762,7 +1814,7 @@
   runners_[0]->ShutdownTaskQueue();
 }
 
-TEST_F(SequenceManagerTest, TaskQueueObserver_DelayedTask) {
+TEST_P(SequenceManagerTest, TaskQueueObserver_DelayedTask) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time = manager_->NowTicks();
@@ -1807,7 +1859,7 @@
   runners_[0]->ShutdownTaskQueue();
 }
 
-TEST_F(SequenceManagerTest, TaskQueueObserver_DelayedTaskMultipleQueues) {
+TEST_P(SequenceManagerTest, TaskQueueObserver_DelayedTaskMultipleQueues) {
   CreateTaskQueues(2u);
 
   MockTaskQueueObserver observer;
@@ -1861,7 +1913,7 @@
   runners_[1]->ShutdownTaskQueue();
 }
 
-TEST_F(SequenceManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) {
+TEST_P(SequenceManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) {
   // This test checks that when delayed work becomes available
   // the notification still fires. This usually happens when time advances
   // and task becomes available in the middle of the scheduling code.
@@ -1910,7 +1962,7 @@
   WeakPtrFactory<CancelableTask> weak_factory_;
 };
 
-TEST_F(SequenceManagerTest, TaskQueueObserver_SweepCanceledDelayedTasks) {
+TEST_P(SequenceManagerTest, TaskQueueObserver_SweepCanceledDelayedTasks) {
   CreateTaskQueues(1u);
 
   MockTaskQueueObserver observer;
@@ -1955,7 +2007,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTest, NumberOfPendingTasksOnChromiumRunLoop) {
+TEST_P(SequenceManagerTest, NumberOfPendingTasksOnChromiumRunLoop) {
   CreateTaskQueues(1u);
 
   // NOTE because tasks posted to the chromiumrun loop are not cancellable, we
@@ -2046,7 +2098,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) {
   CreateTaskQueues(1u);
 
@@ -2070,7 +2122,7 @@
   EXPECT_LT(ratio, 1.1);
 }
 
-TEST_F(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
+TEST_P(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
   CreateTaskQueues(1u);
 
   QuadraticTask quadratic_immediate_task(runners_[0], TimeDelta(),
@@ -2097,7 +2149,7 @@
   EXPECT_LT(ratio, 0.1);
 }
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) {
   CreateTaskQueues(2u);
 
@@ -2121,7 +2173,7 @@
   EXPECT_LT(ratio, 1.1);
 }
 
-TEST_F(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
+TEST_P(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
   CreateTaskQueues(2u);
 
   QuadraticTask quadratic_immediate_task(runners_[0], TimeDelta(),
@@ -2148,7 +2200,7 @@
   EXPECT_LT(ratio, 0.1);
 }
 
-TEST_F(SequenceManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) {
+TEST_P(SequenceManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) {
   CreateTaskQueues(1u);
 
   EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
@@ -2162,7 +2214,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) {
+TEST_P(SequenceManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) {
   CreateTaskQueues(2u);
 
   TestTaskQueue* queue0 = runners_[0].get();
@@ -2196,7 +2248,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTestWithMessageLoop,
+TEST_P(SequenceManagerTestWithMessageLoop,
        CurrentlyExecutingTaskQueue_NestedLoop) {
   CreateTaskQueues(3u);
 
@@ -2229,7 +2281,7 @@
   EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
 }
 
-TEST_F(SequenceManagerTestWithMessageLoop, BlameContextAttribution) {
+TEST_P(SequenceManagerTestWithMessageLoop, BlameContextAttribution) {
   using trace_analyzer::Query;
 
   CreateTaskQueues(1u);
@@ -2254,7 +2306,7 @@
   EXPECT_EQ(2u, events.size());
 }
 
-TEST_F(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasks) {
+TEST_P(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasks) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time = manager_->NowTicks();
@@ -2305,7 +2357,7 @@
   EXPECT_THAT(run_times, ElementsAre(start_time + delay1, start_time + delay4));
 }
 
-TEST_F(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasksReversePostOrder) {
+TEST_P(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasksReversePostOrder) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time = manager_->NowTicks();
@@ -2356,7 +2408,7 @@
   EXPECT_THAT(run_times, ElementsAre(start_time + delay1, start_time + delay4));
 }
 
-TEST_F(SequenceManagerTest, TimeDomainWakeUpOnlyCancelledIfAllUsesCancelled) {
+TEST_P(SequenceManagerTest, TimeDomainWakeUpOnlyCancelledIfAllUsesCancelled) {
   CreateTaskQueues(1u);
 
   TimeTicks start_time = manager_->NowTicks();
@@ -2417,7 +2469,7 @@
   EXPECT_THAT(run_times, ElementsAre(start_time + delay3, start_time + delay4));
 }
 
-TEST_F(SequenceManagerTest, TaskQueueVoters) {
+TEST_P(SequenceManagerTest, TaskQueueVoters) {
   CreateTaskQueues(1u);
 
   // The task queue should be initially enabled.
@@ -2463,7 +2515,7 @@
   EXPECT_TRUE(runners_[0]->IsQueueEnabled());
 }
 
-TEST_F(SequenceManagerTest, ShutdownQueueBeforeEnabledVoterDeleted) {
+TEST_P(SequenceManagerTest, ShutdownQueueBeforeEnabledVoterDeleted) {
   CreateTaskQueues(1u);
 
   scoped_refptr<TaskQueue> queue = CreateTaskQueue();
@@ -2478,7 +2530,7 @@
   voter.reset();
 }
 
-TEST_F(SequenceManagerTest, ShutdownQueueBeforeDisabledVoterDeleted) {
+TEST_P(SequenceManagerTest, ShutdownQueueBeforeDisabledVoterDeleted) {
   CreateTaskQueues(1u);
 
   scoped_refptr<TaskQueue> queue = CreateTaskQueue();
@@ -2493,7 +2545,7 @@
   voter.reset();
 }
 
-TEST_F(SequenceManagerTest, SweepCanceledDelayedTasks) {
+TEST_P(SequenceManagerTest, SweepCanceledDelayedTasks) {
   CreateTaskQueues(1u);
 
   CancelableTask task1(GetTickClock());
@@ -2541,7 +2593,7 @@
   EXPECT_EQ(0u, runners_[0]->GetNumberOfPendingTasks());
 }
 
-TEST_F(SequenceManagerTest, DelayTillNextTask) {
+TEST_P(SequenceManagerTest, DelayTillNextTask) {
   CreateTaskQueues(2u);
 
   LazyNow lazy_now(GetTickClock());
@@ -2567,7 +2619,7 @@
   EXPECT_EQ(TimeDelta(), manager_->DelayTillNextTask(&lazy_now));
 }
 
-TEST_F(SequenceManagerTest, DelayTillNextTask_Disabled) {
+TEST_P(SequenceManagerTest, DelayTillNextTask_Disabled) {
   CreateTaskQueues(1u);
 
   std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
@@ -2579,7 +2631,7 @@
   EXPECT_EQ(TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now));
 }
 
-TEST_F(SequenceManagerTest, DelayTillNextTask_Fence) {
+TEST_P(SequenceManagerTest, DelayTillNextTask_Fence) {
   CreateTaskQueues(1u);
 
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
@@ -2589,7 +2641,7 @@
   EXPECT_EQ(TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now));
 }
 
-TEST_F(SequenceManagerTest, DelayTillNextTask_FenceUnblocking) {
+TEST_P(SequenceManagerTest, DelayTillNextTask_FenceUnblocking) {
   CreateTaskQueues(1u);
 
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
@@ -2600,7 +2652,7 @@
   EXPECT_EQ(TimeDelta(), manager_->DelayTillNextTask(&lazy_now));
 }
 
-TEST_F(SequenceManagerTest, DelayTillNextTask_DelayedTaskReady) {
+TEST_P(SequenceManagerTest, DelayTillNextTask_DelayedTaskReady) {
   CreateTaskQueues(1u);
 
   runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
@@ -2623,7 +2675,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTestWithMessageLoop, DelayedTaskRunsInNestedMessageLoop) {
+TEST_P(SequenceManagerTestWithMessageLoop, DelayedTaskRunsInNestedMessageLoop) {
   CreateTaskQueues(1u);
   RunLoop run_loop;
   runners_[0]->PostTask(FROM_HERE,
@@ -2645,7 +2697,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTestWithMessageLoop,
+TEST_P(SequenceManagerTestWithMessageLoop,
        DelayedNestedMessageLoopDoesntPreventTasksRunning) {
   CreateTaskQueues(1u);
   RunLoop run_loop;
@@ -2659,7 +2711,7 @@
   run_loop.Run();
 }
 
-TEST_F(SequenceManagerTest, CouldTaskRun_DisableAndReenable) {
+TEST_P(SequenceManagerTest, CouldTaskRun_DisableAndReenable) {
   CreateTaskQueues(1u);
 
   EnqueueOrder enqueue_order = manager_->GetNextSequenceNumber();
@@ -2674,7 +2726,7 @@
   EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
 }
 
-TEST_F(SequenceManagerTest, CouldTaskRun_Fence) {
+TEST_P(SequenceManagerTest, CouldTaskRun_Fence) {
   CreateTaskQueues(1u);
 
   EnqueueOrder enqueue_order = manager_->GetNextSequenceNumber();
@@ -2690,7 +2742,7 @@
   EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
 }
 
-TEST_F(SequenceManagerTest, CouldTaskRun_FenceBeforeThenAfter) {
+TEST_P(SequenceManagerTest, CouldTaskRun_FenceBeforeThenAfter) {
   CreateTaskQueues(1u);
 
   runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow);
@@ -2702,7 +2754,7 @@
   EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
 }
 
-TEST_F(SequenceManagerTest, DelayedDoWorkNotPostedForDisabledQueue) {
+TEST_P(SequenceManagerTest, DelayedDoWorkNotPostedForDisabledQueue) {
   CreateTaskQueues(1u);
 
   runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
@@ -2722,7 +2774,7 @@
             test_task_runner_->NextPendingTaskDelay());
 }
 
-TEST_F(SequenceManagerTest, DisablingQueuesChangesDelayTillNextDoWork) {
+TEST_P(SequenceManagerTest, DisablingQueuesChangesDelayTillNextDoWork) {
   CreateTaskQueues(3u);
   runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                TimeDelta::FromMilliseconds(1));
@@ -2756,7 +2808,7 @@
   EXPECT_FALSE(test_task_runner_->HasPendingTask());
 }
 
-TEST_F(SequenceManagerTest, GetNextScheduledWakeUp) {
+TEST_P(SequenceManagerTest, GetNextScheduledWakeUp) {
   CreateTaskQueues(1u);
 
   EXPECT_EQ(nullopt, runners_[0]->GetNextScheduledWakeUp());
@@ -2789,7 +2841,7 @@
   EXPECT_EQ(start_time + delay2, runners_[0]->GetNextScheduledWakeUp());
 }
 
-TEST_F(SequenceManagerTest, SetTimeDomainForDisabledQueue) {
+TEST_P(SequenceManagerTest, SetTimeDomainForDisabledQueue) {
   CreateTaskQueues(1u);
 
   MockTaskQueueObserver observer;
@@ -2839,7 +2891,7 @@
 }
 }  // namespace
 
-TEST_F(SequenceManagerTest, ProcessTasksWithoutTaskTimeObservers) {
+TEST_P(SequenceManagerTest, ProcessTasksWithoutTaskTimeObservers) {
   CreateTaskQueues(1u);
   int start_counter = 0;
   int complete_counter = 0;
@@ -2867,7 +2919,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u));
 }
 
-TEST_F(SequenceManagerTest, ProcessTasksWithTaskTimeObservers) {
+TEST_P(SequenceManagerTest, ProcessTasksWithTaskTimeObservers) {
   CreateTaskQueues(1u);
   int start_counter = 0;
   int complete_counter = 0;
@@ -2916,7 +2968,7 @@
   UnsetOnTaskHandlers(runners_[0]);
 }
 
-TEST_F(SequenceManagerTest, GracefulShutdown) {
+TEST_P(SequenceManagerTest, GracefulShutdown) {
   std::vector<TimeTicks> run_times;
   scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
   WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr();
@@ -2957,7 +3009,7 @@
   EXPECT_EQ(0u, manager_->QueuesToDeleteCount());
 }
 
-TEST_F(SequenceManagerTest, GracefulShutdown_ManagerDeletedInFlight) {
+TEST_P(SequenceManagerTest, GracefulShutdown_ManagerDeletedInFlight) {
   std::vector<TimeTicks> run_times;
   scoped_refptr<TestTaskQueue> control_tq = CreateTaskQueue();
   std::vector<scoped_refptr<TestTaskQueue>> main_tqs;
@@ -3001,7 +3053,7 @@
                           start_time_ + TimeDelta::FromMilliseconds(200)));
 }
 
-TEST_F(SequenceManagerTest,
+TEST_P(SequenceManagerTest,
        GracefulShutdown_ManagerDeletedWithQueuesToShutdown) {
   std::vector<TimeTicks> run_times;
   scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
@@ -3038,7 +3090,7 @@
                           start_time_ + TimeDelta::FromMilliseconds(200)));
 }
 
-TEST_F(SequenceManagerTestWithCustomInitialization, DefaultTaskRunnerSupport) {
+TEST_P(SequenceManagerTestWithCustomInitialization, DefaultTaskRunnerSupport) {
   MessageLoop message_loop;
   scoped_refptr<SingleThreadTaskRunner> original_task_runner =
       message_loop.task_runner();
@@ -3054,7 +3106,7 @@
   DCHECK_EQ(original_task_runner, message_loop.task_runner());
 }
 
-TEST_F(SequenceManagerTest, CanceledTasksInQueueCantMakeOtherTasksSkipAhead) {
+TEST_P(SequenceManagerTest, CanceledTasksInQueueCantMakeOtherTasksSkipAhead) {
   CreateTaskQueues(2u);
 
   CancelableTask task1(GetTickClock());
@@ -3080,7 +3132,7 @@
   EXPECT_THAT(run_order, ElementsAre(1u, 2u));
 }
 
-TEST_F(SequenceManagerTest, TaskQueueDeletedOnAnotherThread) {
+TEST_P(SequenceManagerTest, TaskQueueDeletedOnAnotherThread) {
   std::vector<TimeTicks> run_times;
   scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
 
@@ -3159,7 +3211,7 @@
 
 }  // namespace
 
-TEST_F(SequenceManagerTest, TaskQueueUsedInTaskDestructorAfterShutdown) {
+TEST_P(SequenceManagerTest, TaskQueueUsedInTaskDestructorAfterShutdown) {
   // This test checks that when a task is posted to a shutdown queue and
   // destroyed, it can try to post a task to the same queue without deadlocks.
   scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
diff --git a/third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper_unittest.cc
index fbcd2e0..9d0c5e6 100644
--- a/third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/idle_canceled_delayed_task_sweeper_unittest.cc
@@ -6,8 +6,7 @@
 
 #include "base/task/sequence_manager/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "components/viz/test/ordered_simple_task_runner.h"
+#include "base/test/scoped_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h"
 #include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
@@ -30,12 +29,14 @@
                                            public IdleHelper::Delegate {
  public:
   IdleCanceledDelayedTaskSweeperTest()
-      : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)),
+      : task_environment_(
+            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
+            base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED),
         scheduler_helper_(new MainThreadSchedulerHelper(
             base::sequence_manager::SequenceManagerForTest::Create(
                 nullptr,
-                mock_task_runner_,
-                &clock_),
+                task_environment_.GetMainThreadTaskRunner(),
+                task_environment_.GetMockTickClock()),
             nullptr)),
         idle_helper_(
             new IdleHelper(scheduler_helper_.get(),
@@ -49,16 +50,15 @@
             new IdleCanceledDelayedTaskSweeper(scheduler_helper_.get(),
                                                idle_helper_->IdleTaskRunner())),
         default_task_queue_(scheduler_helper_->DefaultMainThreadTaskQueue()) {
-    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
+    // Null clock might trigger some assertions.
+    task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
   }
 
   ~IdleCanceledDelayedTaskSweeperTest() override = default;
 
   void TearDown() override {
     // Check that all tests stop posting tasks.
-    mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-    while (mock_task_runner_->RunUntilIdle()) {
-    }
+    task_environment_.FastForwardUntilNoTasksRemain();
   }
 
   // IdleHelper::Delegate implementation:
@@ -73,8 +73,7 @@
   void OnPendingTasksChanged(bool has_tasks) override {}
 
  protected:
-  base::SimpleTestTickClock clock_;
-  scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
   std::unique_ptr<MainThreadSchedulerHelper> scheduler_helper_;
   std::unique_ptr<IdleHelper> idle_helper_;
@@ -122,9 +121,9 @@
   // Give the IdleCanceledDelayedTaskSweeper a chance to run but don't let
   // the first non canceled delayed task run.  This is important because the
   // canceled tasks would get removed by TaskQueueImpl::WakeUpForDelayedWork.
-  clock_.Advance(base::TimeDelta::FromSeconds(40));
+  task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(40));
   idle_helper_->EnableLongIdlePeriod();
-  mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(40));
+  task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(40));
 
   EXPECT_EQ(1u, default_task_queue_->GetNumberOfPendingTasks());
 }
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
index 75aee0e..3f3590b 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc
@@ -11,8 +11,8 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
+#include "base/test/null_task_runner.h"
 #include "base/test/simple_test_tick_clock.h"
-#include "components/viz/test/ordered_simple_task_runner.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h"
@@ -31,11 +31,10 @@
 
   void SetUp() override {
     clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
-    mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true);
+    null_task_runner_ = base::MakeRefCounted<base::NullTaskRunner>();
     scheduler_.reset(new MainThreadSchedulerImpl(
         base::sequence_manager::SequenceManagerForTest::Create(
-            nullptr, mock_task_runner_, &clock_),
+            nullptr, null_task_runner_, &clock_),
         base::nullopt));
     task_queue_throttler_ = scheduler_->task_queue_throttler();
     start_time_ = clock_.NowTicks();
@@ -56,7 +55,7 @@
 
  protected:
   base::SimpleTestTickClock clock_;
-  scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
+  scoped_refptr<base::NullTaskRunner> null_task_runner_;
   std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
   TaskQueueThrottler* task_queue_throttler_;  // NOT OWNED
   base::TimeTicks start_time_;
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area.cc b/third_party/blink/renderer/platform/scroll/scrollable_area.cc
index 18752a52..85939d3 100644
--- a/third_party/blink/renderer/platform/scroll/scrollable_area.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollable_area.cc
@@ -613,9 +613,9 @@
   SetScrollbarsHiddenIfOverlay(false);
   needs_show_scrollbar_layers_ = true;
 
-  const double time_until_disable =
-      GetPageScrollbarTheme().OverlayScrollbarFadeOutDelaySeconds() +
-      GetPageScrollbarTheme().OverlayScrollbarFadeOutDurationSeconds();
+  const TimeDelta time_until_disable =
+      GetPageScrollbarTheme().OverlayScrollbarFadeOutDelay() +
+      GetPageScrollbarTheme().OverlayScrollbarFadeOutDuration();
 
   // If the overlay scrollbars don't fade out, don't do anything. This is the
   // case for the mock overlays used in tests and on Mac, where the fade-out is
@@ -623,7 +623,7 @@
   // We also don't fade out overlay scrollbar for popup since we don't create
   // compositor for popup and thus they don't appear on hover so users without
   // a wheel can't scroll if they fade out.
-  if (!time_until_disable || GetChromeClient()->IsPopup())
+  if (time_until_disable.is_zero() || GetChromeClient()->IsPopup())
     return;
 
   if (!fade_overlay_scrollbars_timer_) {
diff --git a/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc b/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc
index 54a44e7..0f47eea5 100644
--- a/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc
@@ -289,7 +289,7 @@
 
   ScrollbarThemeOverlayMock& theme =
       (ScrollbarThemeOverlayMock&)scrollable_area->GetPageScrollbarTheme();
-  theme.SetOverlayScrollbarFadeOutDelay(1);
+  theme.SetOverlayScrollbarFadeOutDelay(TimeDelta::FromSeconds(1));
   Scrollbar* scrollbar = Scrollbar::CreateForTesting(
       scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);
 
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar.cc b/third_party/blink/renderer/platform/scroll/scrollbar.cc
index 221f201..73e8cfd 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollbar.cc
@@ -172,7 +172,7 @@
   return PressedPos() >= thumb_pos && PressedPos() < thumb_pos + thumb_length;
 }
 
-void Scrollbar::AutoscrollPressedPart(double delay) {
+void Scrollbar::AutoscrollPressedPart(TimeDelta delay) {
   if (!scrollable_area_)
     return;
 
@@ -211,7 +211,7 @@
   }
 }
 
-void Scrollbar::StartTimerIfNeeded(double delay) {
+void Scrollbar::StartTimerIfNeeded(TimeDelta delay) {
   // Don't do anything for the thumb.
   if (pressed_part_ == kThumbPart)
     return;
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar.h b/third_party/blink/renderer/platform/scroll/scrollbar.h
index d558b1a0..780489e 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar.h
@@ -203,9 +203,9 @@
             ScrollbarTheme* = nullptr);
 
   void AutoscrollTimerFired(TimerBase*);
-  void StartTimerIfNeeded(double delay);
+  void StartTimerIfNeeded(TimeDelta delay);
   void StopTimerIfNeeded();
-  void AutoscrollPressedPart(double delay);
+  void AutoscrollPressedPart(TimeDelta delay);
   ScrollDirectionPhysical PressedPartScrollDirectionPhysical();
   ScrollGranularity PressedPartScrollGranularity();
 
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc b/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc
index a04b45d..a3352cc 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc
@@ -252,14 +252,14 @@
 #endif
 }
 
-double ScrollbarTheme::OverlayScrollbarFadeOutDelaySeconds() const {
+TimeDelta ScrollbarTheme::OverlayScrollbarFadeOutDelay() const {
   // On Mac, fading is controlled by the painting code in ScrollAnimatorMac.
-  return 0.0;
+  return TimeDelta();
 }
 
-double ScrollbarTheme::OverlayScrollbarFadeOutDurationSeconds() const {
+TimeDelta ScrollbarTheme::OverlayScrollbarFadeOutDuration() const {
   // On Mac, fading is controlled by the painting code in ScrollAnimatorMac.
-  return 0.0;
+  return TimeDelta();
 }
 
 int ScrollbarTheme::ThumbPosition(const Scrollbar& scrollbar,
@@ -362,6 +362,14 @@
   }
 }
 
+TimeDelta ScrollbarTheme::InitialAutoscrollTimerDelay() {
+  return TimeDelta::FromMilliseconds(250);
+}
+
+TimeDelta ScrollbarTheme::AutoscrollTimerDelay() {
+  return TimeDelta::FromMilliseconds(50);
+}
+
 ScrollbarTheme& ScrollbarTheme::DeprecatedStaticGetTheme() {
   if (ScrollbarTheme::MockScrollbarsEnabled()) {
     if (RuntimeEnabledFeatures::OverlayScrollbarsEnabled()) {
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme.h b/third_party/blink/renderer/platform/scroll/scrollbar_theme.h
index 3aa272e..d1f4289 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme.h
@@ -117,8 +117,8 @@
   int ThumbPosition(const Scrollbar& scrollbar) {
     return ThumbPosition(scrollbar, scrollbar.CurrentPos());
   }
-  virtual double OverlayScrollbarFadeOutDelaySeconds() const;
-  virtual double OverlayScrollbarFadeOutDurationSeconds() const;
+  virtual TimeDelta OverlayScrollbarFadeOutDelay() const;
+  virtual TimeDelta OverlayScrollbarFadeOutDuration() const;
   // The position the thumb would have, relative to the track, at the specified
   // scroll position.
   virtual int ThumbPosition(const Scrollbar&, float scroll_position);
@@ -181,8 +181,8 @@
     return std::numeric_limits<int>::max();
   }
 
-  virtual double InitialAutoscrollTimerDelay() { return 0.25; }
-  virtual double AutoscrollTimerDelay() { return 0.05; }
+  virtual TimeDelta InitialAutoscrollTimerDelay();
+  virtual TimeDelta AutoscrollTimerDelay();
 
   virtual IntRect ConstrainTrackRectToTrackPieces(const Scrollbar&,
                                                   const IntRect& rect) {
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h b/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h
index 797052e..4259a285 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h
@@ -58,8 +58,8 @@
   // Mac queues up scrollbar paint timers.
   bool ShouldDisableInvisibleScrollbars() const override { return false; }
 
-  double InitialAutoscrollTimerDelay() override;
-  double AutoscrollTimerDelay() override;
+  TimeDelta InitialAutoscrollTimerDelay() override;
+  TimeDelta AutoscrollTimerDelay() override;
 
   void PaintTickmarks(GraphicsContext&,
                       const Scrollbar&,
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm b/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm
index 7d61ce2..d15d6f263 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm
@@ -169,12 +169,12 @@
   }
 }
 
-double ScrollbarThemeMac::InitialAutoscrollTimerDelay() {
-  return g_initial_button_delay;
+TimeDelta ScrollbarThemeMac::InitialAutoscrollTimerDelay() {
+  return TimeDelta::FromSecondsD(g_initial_button_delay);
 }
 
-double ScrollbarThemeMac::AutoscrollTimerDelay() {
-  return g_autoscroll_button_delay;
+TimeDelta ScrollbarThemeMac::AutoscrollTimerDelay() {
+  return TimeDelta::FromSecondsD(g_autoscroll_button_delay);
 }
 
 bool ScrollbarThemeMac::ShouldDragDocumentInsteadOfThumb(
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc
index 05cd4876..33121af3 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc
@@ -82,25 +82,25 @@
   return true;
 }
 
-double ScrollbarThemeOverlay::OverlayScrollbarFadeOutDelaySeconds() const {
+TimeDelta ScrollbarThemeOverlay::OverlayScrollbarFadeOutDelay() const {
   // TODO(bokan): Unit tests run without a theme engine. This is normally fine
   // because they expect to use ScrollbarThemeMock which doesn't use a theme
   // engine.  If overlays are turned on though, this class is used even if mock
   // scrollbars are on. We should either provide mock out a web theme engine for
   // unit tests or provide a mock version of this class.
   if (!Platform::Current()->ThemeEngine())
-    return 0.0;
+    return TimeDelta();
   WebThemeEngine::ScrollbarStyle style;
   Platform::Current()->ThemeEngine()->GetOverlayScrollbarStyle(&style);
-  return style.fade_out_delay_seconds;
+  return style.fade_out_delay;
 }
 
-double ScrollbarThemeOverlay::OverlayScrollbarFadeOutDurationSeconds() const {
+TimeDelta ScrollbarThemeOverlay::OverlayScrollbarFadeOutDuration() const {
   if (!Platform::Current()->ThemeEngine())
-    return 0.0;
+    return TimeDelta();
   WebThemeEngine::ScrollbarStyle style;
   Platform::Current()->ThemeEngine()->GetOverlayScrollbarStyle(&style);
-  return style.fade_out_duration_seconds;
+  return style.fade_out_duration;
 }
 
 int ScrollbarThemeOverlay::ThumbLength(const Scrollbar& scrollbar) {
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h
index 18c4748c..b36d9cc 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h
@@ -56,8 +56,8 @@
   int ScrollbarThickness(ScrollbarControlSize) override;
   int ScrollbarMargin() const override;
   bool UsesOverlayScrollbars() const override;
-  double OverlayScrollbarFadeOutDelaySeconds() const override;
-  double OverlayScrollbarFadeOutDurationSeconds() const override;
+  TimeDelta OverlayScrollbarFadeOutDelay() const override;
+  TimeDelta OverlayScrollbarFadeOutDuration() const override;
 
   int ThumbLength(const Scrollbar&) override;
 
diff --git a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h
index d27b0dc..0a38a31 100644
--- a/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h
+++ b/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h
@@ -38,17 +38,14 @@
 class PLATFORM_EXPORT ScrollbarThemeOverlayMock : public ScrollbarThemeOverlay {
  public:
   ScrollbarThemeOverlayMock()
-      : ScrollbarThemeOverlay(3, 4, kDisallowHitTest, Color(128, 128, 128)),
-        delay_in_seconds_(0.0) {}
+      : ScrollbarThemeOverlay(3, 4, kDisallowHitTest, Color(128, 128, 128)) {}
 
-  double OverlayScrollbarFadeOutDelaySeconds() const override {
-    return delay_in_seconds_;
+  TimeDelta OverlayScrollbarFadeOutDelay() const override { return delay_; }
+  TimeDelta OverlayScrollbarFadeOutDuration() const override {
+    return TimeDelta();
   }
-  double OverlayScrollbarFadeOutDurationSeconds() const override { return 0.0; }
 
-  void SetOverlayScrollbarFadeOutDelay(double delay_in_seconds) {
-    delay_in_seconds_ = delay_in_seconds;
-  }
+  void SetOverlayScrollbarFadeOutDelay(TimeDelta delay) { delay_ = delay; }
 
   void PaintThumb(GraphicsContext& gc,
                   const Scrollbar& scrollbar,
@@ -66,7 +63,7 @@
   int MinimumThumbLength(const Scrollbar&) override { return 7; }
 
  private:
-  double delay_in_seconds_;
+  TimeDelta delay_;
   bool IsMockTheme() const final { return true; }
 };
 
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc b/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc
index e894de1..472f049d 100644
--- a/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc
+++ b/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc
@@ -94,8 +94,12 @@
 
 void TestingPlatformSupportWithMockScheduler::RunForPeriodSeconds(
     double seconds) {
-  const base::TimeTicks deadline =
-      clock_.NowTicks() + base::TimeDelta::FromSecondsD(seconds);
+  RunForPeriod(base::TimeDelta::FromSecondsD(seconds));
+}
+
+void TestingPlatformSupportWithMockScheduler::RunForPeriod(
+    base::TimeDelta period) {
+  const base::TimeTicks deadline = clock_.NowTicks() + period;
 
   for (;;) {
     // If we've run out of immediate work then fast forward to the next delayed
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h b/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h
index e33d459..9ab8bec 100644
--- a/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h
+++ b/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h
@@ -52,8 +52,9 @@
   // time elapsed will typically much less than |seconds| because delays between
   // timers are fast forwarded.
   void RunForPeriodSeconds(double seconds);
+  void RunForPeriod(base::TimeDelta period);
 
-  // Advances |m_clock| by |seconds|.
+  // Advances |clock_| by |seconds|.
   void AdvanceClockSeconds(double seconds);
   void AdvanceClock(base::TimeDelta duration);
 
diff --git a/tools/binary_size/libsupersize/html_report.py b/tools/binary_size/libsupersize/html_report.py
index 076a9639..e49134c 100644
--- a/tools/binary_size/libsupersize/html_report.py
+++ b/tools/binary_size/libsupersize/html_report.py
@@ -57,6 +57,8 @@
 _SPECIAL_CHAR_REGEX = re.compile(r'(::|(?:\.*\/)+|#)')
 # Insert zero-width space after capture group
 _ZERO_WIDTH_SPACE = r'\1\u200b'
+# Capture mustache variables (ie: "{{name}}")
+_MUSTACHE_VAR_REGEX = re.compile(r'{{(\w+)}}')
 
 # The display name of the bucket where we put symbols without path.
 _NAME_SMALL_SYMBOL_BUCKET = '(Other)'
@@ -322,14 +324,31 @@
   shutil.copy(os.path.join(template_src, 'D3SymbolTreeMap.js'), dest_dir)
 
 
-def _CopyTreeViewTemplateFiles(template_src, dest_dir, size_header):
+def _CopyTreeViewTemplateFiles(template_src, dest_dir, **kwargs):
+  """Copy and format template files for the tree view UI.
+
+  The index.html file uses basic mustache syntax to denote where strings
+  should be replaced. Only variable tags are supported.
+
+  Args:
+    template_src: Path to the directory containing the template files.
+    dest_dir: Path to the directory where the outputted files will be saved.
+    kwags: Dict of key-value pairs which will be used to replace {{<key>}}
+      strings in the index.html template.
+
+  Throws:
+    KeyError: thrown if a variable tag does not have a corresponding kwarg.
+  """
   _MakeDirIfDoesNotExist(dest_dir)
   shutil.copy(os.path.join(template_src, 'options.css'), dest_dir)
+  shutil.copy(os.path.join(template_src, 'infocard.css'), dest_dir)
   shutil.copy(os.path.join(template_src, 'state.js'), dest_dir)
 
   with open(os.path.join(dest_dir, 'index.html'), 'w') as out_html, \
         open(os.path.join(template_src, 'index.html'), 'r') as in_html:
-    out_html.write(in_html.read().replace('{{size_header}}', size_header))
+    html_text = _MUSTACHE_VAR_REGEX.sub(lambda m: kwargs[m.group(1)],
+                                        in_html.read())
+    out_html.write(html_text)
 
   with open(os.path.join(dest_dir, 'tree.js'), 'w') as out_js, \
         open(os.path.join(template_src, 'ui.js'), 'r') as ui, \
@@ -384,7 +403,8 @@
     size_header = 'Delta size' if args.diff_with else 'Size'
 
     template_src = os.path.join(os.path.dirname(__file__), 'template_tree_view')
-    _CopyTreeViewTemplateFiles(template_src, args.report_dir,size_header)
+    _CopyTreeViewTemplateFiles(template_src, args.report_dir,
+                               size_header=size_header)
     logging.info('Creating JSON objects')
     tree_root = _MakeTreeViewList(symbols, args.min_symbol_size)
 
diff --git a/tools/binary_size/libsupersize/template_tree_view/index.html b/tools/binary_size/libsupersize/template_tree_view/index.html
index 48479243..9a63632 100644
--- a/tools/binary_size/libsupersize/template_tree_view/index.html
+++ b/tools/binary_size/libsupersize/template_tree_view/index.html
@@ -51,19 +51,28 @@
             color: #202124;
             font-size: 22px;
         }
-
         .subtitle {
             font-weight: 500;
             color: #5f6368;
             font-size: 13px;
         }
-
-        .subhead {
+        .subhead, .subhead-2 {
             font-family: "Google Sans", Arial, sans-serif;
             font-weight: 500;
-            font-size: 14px;
+            font-size: 16px;
             color: #3c4043;
         }
+        .subhead-2 {
+            font-size: 14px;
+        }
+        .body-2 {
+            font-weight: 400;
+            font-size: 14px;
+        }
+        .caption {
+            font-size: 12px;
+            color: #5f6368;
+        }
 
         ul {
             list-style-type: none;
@@ -90,6 +99,7 @@
         }
 
         .icon {
+            display: block;
             margin-right: 6px;
         }
 
@@ -133,7 +143,7 @@
             flex: 1;
         }
 
-        .size {
+        .size, .percent {
             margin-left: 16px;
             text-align: right;
             color: #5f6368;
@@ -143,7 +153,6 @@
             color: #ea4335;
         }
     </style>
-    <link href="options.css" rel="stylesheet">
     <script defer src="state.js"></script>
     <script defer src="tree.js"></script>
     <script defer async onload="loadTree(tree_data);" src="data.js"></script>
@@ -178,6 +187,7 @@
             </svg>
         </button>
     </header>
+    <link href="options.css" rel="stylesheet">
     <form id="options" class="options" method="GET">
         <header class="form-bar">
             <button type="button" class="icon-button toggle-options" title="Close">
@@ -188,31 +198,100 @@
         </header>
 
         <h2 class="subhead">Size options</h2>
-        <div class="select-wrapper">
-            <select id="byteunit" name="byteunit" data-dynamic>
+        <p class="select-wrapper">
+            <select id="byteunit" name="byteunit">
                 <option value="B">B - bytes</option>
                 <option value="KiB">KiB - kilibytes</option>
                 <option value="MiB" selected>MiB - megabytes</option>
                 <option value="GiB">GiB - gigabytes</option>
             </select>
             <label class="select-label" for="byteunit">Byte unit</label>
-        </div>
+        </p>
         <p class="checkbox-wrapper">
             <input type="checkbox" id="methodcount" name="method_count" value="on">
             <label class="checkbox-label" for="methodcount">Show dex method count rather than size</label>
         </p>
 
-        <h2 class="subhead">Group symbols by</h2>
-        <p class="radio-wrapper">
+        <fieldset class="radio-wrapper">
+            <legend class="subhead">Group symbols by</legend>
             <input type="radio" id="sourcepath" name="group_by" value="source_path" checked>
             <label class="radio-label" for="sourcepath">Source path</label>
             <input type="radio" id="component" name="group_by" value="component">
             <label class="radio-label" for="component">Component</label>
-        </p>
+        </fieldset>
 
-        <p style="text-align:right">
-            <button class="filled-button" type="submit">Update</button>
-        </p>
+        <fieldset class="checkbox-wrapper" id="types-filter">
+            <legend class="subhead">Symbol types to show</legend>
+            <input type="checkbox" id="filterbss" name="type" value="b" checked>
+            <label class="checkbox-label" for="filterbss">
+                Uninitialized data (.bss)
+            </label>
+            <input type="checkbox" id="filterdata" name="type" value="d" checked>
+            <label class="checkbox-label" for="filterdata">
+                Initialized data (.data)
+            </label>
+            <input type="checkbox" id="filterrodata" name="type" value="r" checked>
+            <label class="checkbox-label" for="filterrodata">
+                Read-only data (.rodata)
+            </label>
+            <input type="checkbox" id="filtertext" name="type" value="t" checked>
+            <label class="checkbox-label" for="filtertext">
+                Code (.text)
+            </label>
+            <input type="checkbox" id="filtervtable" name="type" value="v" checked>
+            <label class="checkbox-label" for="filtervtable">
+                Vtable entries
+            </label>
+            <input type="checkbox" id="filtergen" name="type" value="*" checked>
+            <label class="checkbox-label" for="filtergen">
+                Generated Symbols (typeinfo, thunks, etc)
+            </label>
+            <input type="checkbox" id="filterdexnon" name="type" value="x" checked>
+            <label class="checkbox-label" for="filterdexnon">
+                Dex non-method entries
+            </label>
+            <input type="checkbox" id="filterdex" name="type" value="m" checked>
+            <label class="checkbox-label" for="filterdex">
+                Dex methods
+            </label>
+            <input type="checkbox" id="filterpak" name="type" value="p" checked>
+            <label class="checkbox-label" for="filterpak">
+                Locale Pak Entries
+            </label>
+            <input type="checkbox" id="filterpaknon" name="type" value="P" checked>
+            <label class="checkbox-label" for="filterpaknon">
+                Non-Locale Pak Entries
+            </label>
+            <input type="checkbox" id="filterother" name="type" value="o" checked>
+            <label class="checkbox-label" for="filterother">
+                Other Entries
+            </label>
+        </fieldset>
+
+        <fieldset>
+            <legend class="subhead">Advanced filters</legend>
+            <p class="input-wrapper">
+                <input type="number" id="minsize" name="min_size" value="0" min="0">
+                <label class="input-label" for="minsize">
+                    Minimum size (bytes)
+                </label>
+            </p>
+            <fieldset>
+                <legend class="subhead-2">Regular expressions</legend>
+                <div class="input-wrapper">
+                    <input class="input-regex" type="text" id="includeregex" name="include" placeholder=".+@.+">
+                    <label class="input-label" for="includeregex">
+                        Symbols must contain
+                    </label>
+                </div>
+                <div class="input-wrapper">
+                    <input class="input-regex" type="text" id="excluderegex" name="exclude" placeholder="\(.+\)">
+                    <label class="input-label" for="excluderegex">
+                            Symbols must exclude
+                    </label>
+                </div>
+            </fieldset>
+        </fieldset>
     </form>
     <div class="symbols">
         <div hidden id="icons">
@@ -224,12 +303,12 @@
             <svg class='icon componenticon' height='24' width='24' fill='#5f6368'>
                 <title>Component</title>
                 <path d="M9,13.75c-2.34,0-7,1.17-7,3.5V19h14v-1.75C16,14.92,11.34,13.75,9,13.75z M4.34,17c0.84-0.58,2.87-1.25,4.66-1.25
-                         s3.82,0.67,4.66,1.25H4.34z"/>
+                         s3.82,0.67,4.66,1.25H4.34z" />
                 <path d="M9,12c1.93,0,3.5-1.57,3.5-3.5C12.5,6.57,10.93,5,9,5S5.5,6.57,5.5,8.5C5.5,10.43,7.07,12,9,12z M9,7
-                         c0.83,0,1.5,0.67,1.5,1.5S9.83,10,9,10S7.5,9.33,7.5,8.5S8.17,7,9,7z"/>
-                <path d="M16.04,13.81C17.2,14.65,18,15.77,18,17.25V19h4v-1.75C22,15.23,18.5,14.08,16.04,13.81z"/>
+                         c0.83,0,1.5,0.67,1.5,1.5S9.83,10,9,10S7.5,9.33,7.5,8.5S8.17,7,9,7z" />
+                <path d="M16.04,13.81C17.2,14.65,18,15.77,18,17.25V19h4v-1.75C22,15.23,18.5,14.08,16.04,13.81z" />
                 <path d="M15,12c1.93,0,3.5-1.57,3.5-3.5C18.5,6.57,16.93,5,15,5c-0.54,0-1.04,0.13-1.5,0.35c0.63,0.89,1,1.98,1,3.15
-                         s-0.37,2.26-1,3.15C13.96,11.87,14.46,12,15,12z"/>
+                         s-0.37,2.26-1,3.15C13.96,11.87,14.46,12,15,12z" />
             </svg>
             <svg class="icon fileicon" height="24" width="24" fill="#5f6368">
                 <title>File</title>
@@ -315,6 +394,88 @@
             <ul id="symboltree" class="tree" role="tree" aria-labelledby="headline"></ul>
         </main>
     </div>
+    <link href="infocard.css" rel="stylesheet">
+    <footer class="infocard infocard-container open" id="infocardcontainer" hidden>
+        <canvas class="type-pie-info" height="80" width="80"></canvas>
+        <header class="header-info">
+            <h4 class="subhead size-info">N bytes</h4>
+            <p class="body-2 path-info">path/to/<span class="symbol-name-info">symbol</span></p>
+        </header>
+        <table class="type-breakdown-info">
+            <thead>
+                <tr>
+                    <th class="subhead-2">Type</th>
+                    <th class="subhead-2 size">Total size</th>
+                    <th class="subhead-2 percent">Percent</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr class="bss-info">
+                    <th scope="row">.bss</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="data-info">
+                    <th scope="row">.data and .data.*</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="rodata-info">
+                    <th scope="row">.rodata</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="text-info">
+                    <th scope="row">.text</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="vtable-info">
+                    <th scope="row">Vtable entry</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="gen-info">
+                    <th scope="row">Generated symbols</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="dexnon-info">
+                    <th scope="row">Dex non-method entries</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="dex-info">
+                    <th scope="row">Dex methods</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="pak-info">
+                    <th scope="row">Locale pak entries</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="paknon-info">
+                    <th scope="row">Non-locale pak entries</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+                <tr class="other-info">
+                    <th scope="row">Other entries</th>
+                    <td class="size">0</td>
+                    <td class="percent">0%</td>
+                </tr>
+            </tbody>
+        </table>
+    </footer>
+    <footer class="infocard infocard-symbol" id="infocardsymbol" hidden>
+        <div class="icon-info"></div>
+        <header class="header-info">
+            <h4 class="subhead size-info">N bytes</h4>
+            <p class="body-2 path-info">path/to/<span class="symbol-name-info">symbol</span></p>
+        </header>
+        <p class="caption type-info">Initialized data (.data)</p>
+    </footer>
 </body>
 
 </html>
\ No newline at end of file
diff --git a/tools/binary_size/libsupersize/template_tree_view/infocard.css b/tools/binary_size/libsupersize/template_tree_view/infocard.css
new file mode 100644
index 0000000..efe222c8
--- /dev/null
+++ b/tools/binary_size/libsupersize/template_tree_view/infocard.css
@@ -0,0 +1,86 @@
+/* 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. */
+
+.infocard {
+  display: grid;
+  position: fixed;
+  padding: 16px;
+  margin: 0 auto;
+  bottom: 8px;
+  left: 8px;
+  right: 8px;
+  max-width: 512px;
+  max-height: 50vh;
+  overflow-y: auto;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 1px 2px #3c40434d, 0 1px 3px 1px #3c404326;
+}
+.infocard-container {
+  grid-template-areas: 'header icon' 'type type';
+  grid-template-columns: auto 80px;
+  grid-column-gap: 16px;
+  grid-row-gap: 8px;
+}
+.infocard-symbol {
+  grid-template-areas: 'icon header' 'type type';
+  grid-template-columns: 40px auto;
+  grid-column-gap: 16px;
+}
+
+.infocard[hidden] {
+  display: none;
+}
+@media (min-width: 700px) {
+  .show-options .infocard {
+    right: 256px;
+  }
+}
+
+.icon-info {
+  grid-area: icon;
+  align-self: center;
+  padding: 8px 2px 8px 8px;
+  border-radius: 50%;
+}
+.header-info {
+  grid-area: header;
+}
+.size-info {
+  margin: 0 0 2px;
+  color: #202124;
+}
+.path-info {
+  margin: 0 0 8px;
+  word-break: break-word;
+}
+.symbol-name-info {
+  font-weight: 500;
+}
+.type-info {
+  grid-area: type;
+  margin-bottom: 0;
+}
+
+.type-pie-info {
+  grid-area: icon;
+  align-self: center;
+  background: #5f6368;
+  border-radius: 50%;
+}
+.type-breakdown-info {
+  grid-area: type;
+  border-top: 1px solid #dadce0;
+  padding-top: 8px;
+  clear: right;
+}
+
+th {
+  text-align: left;
+}
+th[scope='row'],
+td {
+  font-weight: normal;
+  font-size: 14px;
+}
diff --git a/tools/binary_size/libsupersize/template_tree_view/options.css b/tools/binary_size/libsupersize/template_tree_view/options.css
index 6bbfc0b0..17087ab 100644
--- a/tools/binary_size/libsupersize/template_tree_view/options.css
+++ b/tools/binary_size/libsupersize/template_tree_view/options.css
@@ -13,6 +13,7 @@
 
 /** Black overlay shown on smaller screens when options is visible. */
 .scrim {
+  z-index: 5; /* Side panel layer */
   position: fixed;
   top: 0;
   left: 0;
@@ -23,9 +24,11 @@
 
 /** Options side panel */
 .options {
+  z-index: 5; /* Side panel layer */
   display: none;
   grid-area: options;
   padding: 0 16px;
+  overflow-y: auto;
   position: fixed;
   right: 0;
   top: 0;
@@ -35,6 +38,19 @@
   box-shadow: 0 1px 2px #3c40434d, 0 2px 6px 2px #3c404326;
 }
 
+fieldset {
+  border: 0;
+  padding: 0;
+  margin: 2em 0 1em;
+}
+.options fieldset:first-of-type {
+  margin-top: 1em;
+}
+legend {
+  margin: 1em 0;
+  padding: 0;
+}
+
 .icon-list li {
   display: flex;
   justify-content: space-between;
@@ -93,21 +109,28 @@
   box-shadow: 0 1px 2px #3c40434d, 0 1px 3px 1px #3c404326;
 }
 
-/** <select> elements */
+/** <input type='text'> or <select> elements */
+.input-wrapper,
 .select-wrapper {
   position: relative;
   border-top-left-radius: 4px;
   border-top-right-radius: 4px;
   background: rgba(0, 0, 0, 0.04);
+  margin-bottom: 1em;
 }
+input[type='text'],
+input[type='number'],
 select {
+  box-sizing: border-box;
   -webkit-appearance: none;
   font: inherit;
   background: transparent;
   border: 0;
-  padding: 20px 8px 13px;
+  padding: 20px 12px 13px;
   width: 100%;
+  caret-color: #1a73e8;
 }
+.input-label,
 .select-label {
   position: absolute;
   z-index: -1;
@@ -132,6 +155,8 @@
   border-color: currentColor transparent transparent transparent;
   transition: transform 0.2s ease-out;
 }
+input[type='text']:focus + .input-label,
+input[type='number']:focus + .input-label,
 select:focus + .select-label {
   color: #1a73e8;
   bottom: -2px;
@@ -142,10 +167,12 @@
 }
 
 /** <input type='checkbox' or 'radio'> elements */
-input[type='checkbox'], input[type='radio'] {
+input[type='checkbox'],
+input[type='radio'] {
   display: none;
 }
-.checkbox-label, .radio-label {
+.checkbox-label,
+.radio-label {
   display: block;
   position: relative;
   padding-left: 34px;
@@ -153,13 +180,16 @@
   cursor: pointer;
   font-size: 14px;
 }
-.checkbox-label::before, .checkbox-label::after,
-.radio-label::before, .radio-label::after {
+.checkbox-label::before,
+.checkbox-label::after,
+.radio-label::before,
+.radio-label::after {
   position: absolute;
   content: '';
   border: 2px solid currentColor;
 }
-.checkbox-label::before, .radio-label::before {
+.checkbox-label::before,
+.radio-label::before {
   width: 14px;
   height: 14px;
   border-radius: 2px;
diff --git a/tools/binary_size/libsupersize/template_tree_view/state.js b/tools/binary_size/libsupersize/template_tree_view/state.js
index 0de25a62..f5291af75d 100644
--- a/tools/binary_size/libsupersize/template_tree_view/state.js
+++ b/tools/binary_size/libsupersize/template_tree_view/state.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// @ts-check
 'use strict';
 
 /**
@@ -36,6 +37,7 @@
   },
 };
 
+/** Build utilities for working with the state. */
 function _initState() {
   /**
    * State is represented in the query string and
@@ -44,7 +46,7 @@
    */
   let _filterParams = new URLSearchParams(location.search.slice(1));
 
-  const state = {
+  const state = Object.freeze({
     /**
      * Returns a string from the current query string state.
      * Can optionally restrict valid values for the query.
@@ -61,7 +63,7 @@
     get(key, options = {}) {
       const [val = null] = state.getAll(key, {
         default: options.default ? [options.default] : null,
-        valid: options.value,
+        valid: options.valid,
       });
       return val;
     },
@@ -94,34 +96,19 @@
     has(key) {
       return _filterParams.has(key);
     },
-    /**
-     * Set the value in the state, overriding any existing value. Afterwards
-     * display the new state in the URL by replacing the current history entry.
-     * @param {string} name
-     * @param {string} value
-     */
-    set(name, value) {
-      _filterParams.set(name, value);
-      state.setAll(_filterParams);
-    },
-    /**
-     * Replaces the current state with a new list of values. Afterwards
-     * display the new state in the URL by replacing the current history entry.
-     * @param {Iterable<[string, string]>} entries Iterator of key-value pairs
-     */
-    setAll(entries) {
-      _filterParams = new URLSearchParams(entries);
-      history.replaceState(null, null, '?' + _filterParams.toString());
-    },
-  };
+  });
 
   // Update form inputs to reflect the state from URL.
-  for (const input of form.elements) {
-    if (input.name) {
-      const value = _filterParams.get(input.name);
+  for (const element of form.elements) {
+    if (element.name) {
+      const input = /** @type {HTMLInputElement} */ (element);
+      const values = _filterParams.getAll(input.name);
+      const [value] = values;
       if (value) {
         switch (input.type) {
           case 'checkbox':
+            input.checked = values.includes(input.value);
+            break;
           case 'radio':
             input.checked = value === input.value;
             break;
@@ -133,23 +120,17 @@
     }
   }
 
+  // Update the state when the form changes.
+  form.addEventListener('change', event => {
+    _filterParams = new URLSearchParams(new FormData(event.currentTarget));
+    history.replaceState(null, null, '?' + _filterParams.toString());
+  });
+
   return state;
 }
 
-function _startListeners(state) {
-  /**
-   * Some form inputs can be changed without needing to refresh the tree.
-   * When these inputs change, update the state and the change event can
-   * be subscribed to elsewhere in the code.
-   * @param {Event} event Change event fired when a dynamic value is updated
-   */
-  function _onDynamicValueChange(event) {
-    const {name, value} = event.currentTarget;
-    state.set(name, value);
-  }
-  for (const dynamicInput of document.querySelectorAll('form [data-dynamic]')) {
-    dynamicInput.addEventListener('change', _onDynamicValueChange);
-  }
+function _startListeners() {
+  const _SHOW_OPTIONS_STORAGE_KEY = 'show-options';
 
   /**
    * The settings dialog on the side can be toggled on and off by elements with
@@ -157,12 +138,12 @@
    */
   function _toggleOptions() {
     const openedOptions = document.body.classList.toggle('show-options');
-    localStorage.setItem('show-options', openedOptions);
+    localStorage.setItem(_SHOW_OPTIONS_STORAGE_KEY, openedOptions.toString());
   }
   for (const button of document.getElementsByClassName('toggle-options')) {
     button.addEventListener('click', _toggleOptions);
   }
-  if (localStorage.getItem('show-options') === 'true') {
+  if (localStorage.getItem(_SHOW_OPTIONS_STORAGE_KEY) === 'true') {
     document.body.classList.add('show-options');
   }
 
@@ -171,12 +152,15 @@
    */
   function setMethodCountModeUI() {
     const sizeHeader = document.getElementById('size-header');
+    const typesFilterContainer = document.getElementById('types-filter');
     if (form.method_count.checked) {
       sizeHeader.textContent = 'Methods';
       form.byteunit.setAttribute('disabled', '');
+      typesFilterContainer.setAttribute('disabled', '');
     } else {
       sizeHeader.textContent = sizeHeader.dataset.value;
       form.byteunit.removeAttribute('disabled', '');
+      typesFilterContainer.removeAttribute('disabled');
     }
   }
   setMethodCountModeUI();
@@ -185,4 +169,4 @@
 
 /** Utilities for working with the state */
 const state = _initState();
-_startListeners(state);
+_startListeners();
diff --git a/tools/binary_size/libsupersize/template_tree_view/tree-worker.js b/tools/binary_size/libsupersize/template_tree_view/tree-worker.js
index 815db3fc5..c168802 100644
--- a/tools/binary_size/libsupersize/template_tree_view/tree-worker.js
+++ b/tools/binary_size/libsupersize/template_tree_view/tree-worker.js
@@ -36,14 +36,17 @@
  */
 
 /**
- * @typedef {object} TreeNode Node object used to represent the file tree
+ * @typedef {object} TreeNode Node object used to represent the file tree. Can
+ * represent either a folder, file, component, or symbol.
  * @prop {TreeNode[]} children Child tree nodes
  * @prop {TreeNode | null} parent Parent tree node. null if this is a root node.
- * @prop {string} idPath
- * @prop {string} shortName
- * @prop {number} size
- * @prop {string} type
- * @prop {{ [type: string]: number }} childSizes
+ * @prop {string} idPath Full path to this node.
+ * @prop {string} shortName Name of this node, included in idPath.
+ * @prop {number} size Byte size of this node and its children.
+ * @prop {string} type Type of this node. If this node has children, the string
+ * may have a second character to denote the most common child.
+ * @prop {{[type: string]: number}} childSizes The sizes of the children
+ * of this node, split by the types of the children.
  */
 
 /**
@@ -64,6 +67,7 @@
 const _DIRECTORY_TYPE = 'D';
 const _COMPONENT_TYPE = 'C';
 const _FILE_TYPE = 'F';
+const _KNOWN_TYPES = new Set('bdrtv*xmpPo');
 
 /**
  * Return the basename of the pathname 'path'. In a file path, this is the name
@@ -242,13 +246,12 @@
     );
     // build child nodes for this file's symbols and attach to self
     for (const symbol of fileNode[_KEYS.FILE_SYMBOLS]) {
-      const size = methodCountMode ? 1 : symbol[_KEYS.SIZE];
       const symbolNode = createNode(
         {
           idPath: idPath + ':' + symbol[_KEYS.SYMBOL_NAME],
           shortName: symbol[_KEYS.SYMBOL_NAME],
-          size,
-          type: symbol[_KEYS.TYPE],
+          size: methodCountMode ? 1 : symbol[_KEYS.SIZE],
+          type: _KNOWN_TYPES.has(symbol[_KEYS.TYPE]) ? symbol[_KEYS.TYPE] : 'o',
         },
         sep
       );
@@ -271,6 +274,59 @@
 }
 
 /**
+ * Parse the options represented as a query string, into an object.
+ * Includes checks for valid values.
+ * @param {string} options Query string
+ */
+function parseOptions(options) {
+  const params = new URLSearchParams(options);
+
+  const groupBy = params.get('group_by') || 'source_path';
+  const methodCountMode = params.has('method_count');
+
+  let minSymbolSize = Number(params.get('min_size'));
+  if (Number.isNaN(minSymbolSize)) {
+    minSymbolSize = 0;
+  }
+
+  const includeRegex = params.get('include');
+  const excludeRegex = params.get('exclude');
+
+  /** @type {Set<string>} */
+  let typeFilter;
+  if (methodCountMode) typeFilter = new Set('m');
+  else {
+    const types = params.getAll('type');
+    typeFilter = new Set(types.length === 0 ? _KNOWN_TYPES : types);
+  }
+
+  /** Ensure symbol size is past the minimum */
+  const checkSize = s => Math.abs(s.size) >= minSymbolSize;
+  /** Ensure the symbol size wasn't filtered out */
+  const checkType = s => typeFilter.has(s.type);
+  const filters = [checkSize, checkType];
+
+  if (includeRegex) {
+    const regex = new RegExp(includeRegex);
+    filters.push(s => regex.test(s.idPath));
+  }
+  if (excludeRegex) {
+    const regex = new RegExp(excludeRegex);
+    filters.push(s => !regex.test(s.idPath));
+  }
+
+  /**
+   * Check that a symbol node passes all the filters in the filters array.
+   * @param {TreeNode} symbol
+   */
+  function filterTest(symbol) {
+    return filters.every(fn => fn(symbol));
+  }
+
+  return {groupBy, methodCountMode, filterTest};
+}
+
+/**
  * Assemble a tree when this worker receives a message.
  * @param {MessageEvent} event Event for when this worker receives a message.
  */
@@ -281,16 +337,7 @@
    * flat list of files, and options represented as a query string.
    */
   const {tree, options} = JSON.parse(event.data);
-
-  const params = new URLSearchParams(options);
-  const groupBy = params.get('group_by') || 'source_path';
-  const methodCountMode = params.has('method_count');
-  let typeFilter;
-  if (methodCountMode) typeFilter = new Set('m');
-  else {
-    const types = params.getAll('types');
-    typeFilter = new Set(types.length === 0 ? 'bdrtv*xmpPo' : types);
-  }
+  const {groupBy, methodCountMode, filterTest} = parseOptions(options);
 
   const getPathMap = {
     component(fileEntry) {
@@ -311,7 +358,7 @@
     sep: sepMap[groupBy],
     methodCountMode,
     getPath: getPathMap[groupBy],
-    filterTest: s => typeFilter.has(s.type),
+    filterTest,
   });
 
   // @ts-ignore
diff --git a/tools/binary_size/libsupersize/template_tree_view/ui.js b/tools/binary_size/libsupersize/template_tree_view/ui.js
index 0c1d5d3..67a15717 100644
--- a/tools/binary_size/libsupersize/template_tree_view/ui.js
+++ b/tools/binary_size/libsupersize/template_tree_view/ui.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// @ts-check
 'use strict';
 
 /**
@@ -26,9 +27,10 @@
 
   const _icons = document.getElementById('icons');
   /**
-   * @enum {SVGSVGElement} Icon elements that correspond to each symbol type.
+   * @type {{[type:string]: SVGSVGElement}} Icon elements
+   * that correspond to each symbol type.
    */
-  const _SYMBOL_ICONS = {
+  const SYMBOL_ICONS = {
     D: _icons.querySelector('.foldericon'),
     C: _icons.querySelector('.componenticon'),
     F: _icons.querySelector('.fileicon'),
@@ -47,13 +49,33 @@
   const _CONTAINER_TYPES = new Set('DCF');
 
   // Templates for tree nodes in the UI.
+  /** @type {HTMLTemplateElement} Template for leaves in the tree */
   const _leafTemplate = document.getElementById('treeitem');
+  /** @type {HTMLTemplateElement} Template for trees */
   const _treeTemplate = document.getElementById('treefolder');
 
+  // Infocard elements
+  const _containerInfocard = document.getElementById('infocardcontainer');
+  const _symbolInfocard = document.getElementById('infocardsymbol');
+
   const _symbolTree = document.getElementById('symboltree');
 
-  /** HTMLCollection of all nodes. Updates itself automatically. */
+  /**
+   * @type {HTMLCollectionOf<HTMLAnchorElement | HTMLSpanElement>}
+   * HTMLCollection of all nodes. Updates itself automatically.
+   */
   const _liveNodeList = document.getElementsByClassName('node');
+  /**
+   * @type {HTMLCollectionOf<HTMLSpanElement>}
+   * HTMLCollection of all size elements. Updates itself automatically.
+   */
+  const _liveSizeSpanList = document.getElementsByClassName('size');
+
+  /** @type {CanvasRenderingContext2D} Pie chart canvas from infocard */
+  const _ctx = _containerInfocard
+    .querySelector('.type-pie-info')
+    .getContext('2d');
+  const _tableBody = _containerInfocard.querySelector('tbody');
 
   /**
    * @type {WeakMap<HTMLElement, Readonly<TreeNode>>}
@@ -64,31 +86,207 @@
   const _uiNodeData = new WeakMap();
 
   /**
-   * Replace the contexts of the size element for a tree node.
+   * @type {{[type:string]: HTMLTableRowElement}} Rows in the container infocard
+   * that represent a particular symbol type.
+   */
+  const _INFO_ROWS = {
+    b: _containerInfocard.querySelector('.bss-info'),
+    d: _containerInfocard.querySelector('.data-info'),
+    r: _containerInfocard.querySelector('.rodata-info'),
+    t: _containerInfocard.querySelector('.text-info'),
+    v: _containerInfocard.querySelector('.vtable-info'),
+    '*': _containerInfocard.querySelector('.gen-info'),
+    x: _containerInfocard.querySelector('.dexnon-info'),
+    m: _containerInfocard.querySelector('.dex-info'),
+    p: _containerInfocard.querySelector('.pak-info'),
+    P: _containerInfocard.querySelector('.paknon-info'),
+    o: _containerInfocard.querySelector('.other-info'),
+  };
+
+  /**
+   * Draw a slice of a pie chart.
+   * @param {CanvasRenderingContext2D} ctx
+   * @param {number} angleStart Starting angle, in radians.
+   * @param {number} percentage Percentage of circle to draw.
+   * @param {string} color Color of the pie slice.
+   * @returns {number} Ending angle, in radians.
+   */
+  function _drawSlice(ctx, angleStart, percentage, color) {
+    const arcLength = percentage * 2 * Math.PI;
+    const angleEnd = angleStart + arcLength;
+    if (arcLength === 0) return angleEnd;
+
+    ctx.fillStyle = color;
+    // Move cursor to center, where line will start
+    ctx.beginPath();
+    ctx.moveTo(40, 40);
+    // Move cursor to start of arc then draw arc
+    ctx.arc(40, 40, 40, angleStart, angleEnd);
+    // Move cursor back to center
+    ctx.closePath();
+    ctx.fill();
+
+    return angleEnd;
+  }
+
+  /**
+   * Update a row in the breakdown table with the given values.
+   * @param {HTMLTableRowElement} row
+   * @param {number} size Total size of the symbols of a given type in a
+   * container.
+   * @param {number} percentage How much the size represents in relation to the
+   * total size of the symbols in the container.
+   */
+  function _updateBreakdownRow(row, size, percentage) {
+    if (size === 0) {
+      if (row.parentElement != null) {
+        _tableBody.removeChild(row);
+      }
+    } else {
+      _tableBody.appendChild(row);
+    }
+
+    const sizeColumn = row.querySelector('.size');
+    const percentColumn = row.querySelector('.percent');
+
+    sizeColumn.textContent = size.toLocaleString(undefined, {
+      minimumFractionDigits: 2,
+      maximumFractionDigits: 2,
+      useGrouping: true,
+    });
+    percentColumn.textContent = percentage.toLocaleString(undefined, {
+      style: 'percent',
+      minimumFractionDigits: 2,
+      maximumFractionDigits: 2,
+    });
+  }
+
+  function _updateHeader(infocard, symbol) {
+    infocard.removeAttribute('hidden');
+    const _getSizeLabels = state.has('method_count')
+      ? _getMethodCountContents
+      : _getSizeContents;
+    const {title, element} = _getSizeLabels(symbol.size);
+
+    const sizeInfo = infocard.querySelector('.size-info');
+    dom.replace(
+      sizeInfo,
+      dom.createFragment([
+        document.createTextNode(title),
+        document.createTextNode(' ('),
+        element,
+        document.createTextNode(')'),
+      ])
+    );
+
+    if (symbol.size < 0) {
+      sizeInfo.classList.add('negative');
+    } else {
+      sizeInfo.classList.remove('negative');
+    }
+
+    const [path] = symbol.idPath.split(symbol.shortName, 1);
+    const boldShortName = document.createElement('span');
+    boldShortName.className = 'symbol-name-info';
+    boldShortName.textContent = symbol.shortName;
+    dom.replace(
+      infocard.querySelector('.path-info'),
+      dom.createFragment([document.createTextNode(path), boldShortName])
+    );
+  }
+
+  function _updateInfocard(symbol) {
+    if (_CONTAINER_TYPES.has(symbol.type[0])) {
+      _updateHeader(_containerInfocard, symbol);
+      _symbolInfocard.setAttribute('hidden', '');
+
+      let angleStart = 0;
+      let otherSize = 0;
+      const extraRows = {..._INFO_ROWS};
+      const sizeEntries = Object.entries(symbol.childSizes).sort(
+        (a, b) => b[1] - a[1]
+      );
+      for (const [type, size] of sizeEntries) {
+        const icon = _getIconTemplate(type, false);
+        if (type === 'o') {
+          otherSize += size;
+        } else {
+          const color = icon.getAttribute('fill');
+          const percentage = size / symbol.size;
+
+          angleStart = _drawSlice(_ctx, angleStart, percentage, color);
+
+          _updateBreakdownRow(_INFO_ROWS[type], size, percentage);
+          delete extraRows[type];
+        }
+      }
+
+      for (const row of Object.values(extraRows)) {
+        _updateBreakdownRow(row, 0, 0);
+      }
+      const otherPercentage = otherSize / symbol.size;
+      _updateBreakdownRow(_INFO_ROWS.o, otherSize, otherPercentage);
+      _drawSlice(
+        _ctx,
+        angleStart,
+        otherPercentage,
+        SYMBOL_ICONS.o.getAttribute('fill')
+      );
+    } else {
+      _updateHeader(_symbolInfocard, symbol);
+      _containerInfocard.setAttribute('hidden', '');
+
+      const icon = _getIconTemplate(symbol.type[0]);
+      const iconInfo = _symbolInfocard.querySelector('.icon-info');
+      iconInfo.style.backgroundColor = icon.getAttribute('fill');
+      icon.setAttribute('fill', '#fff');
+      dom.replace(iconInfo, icon);
+
+      const title = icon.querySelector('title').textContent;
+      _symbolInfocard.querySelector('.type-info').textContent = title;
+    }
+  }
+
+  let _pendingFrame;
+  function _showInfocardOnHover(event) {
+    const symbol = _uiNodeData.get(event.currentTarget);
+    cancelAnimationFrame(_pendingFrame);
+    _pendingFrame = requestAnimationFrame(() => _updateInfocard(symbol));
+  }
+  function _showInfocardOnFocus(event) {
+    const symbol = _uiNodeData.get(event.target);
+    cancelAnimationFrame(_pendingFrame);
+    _pendingFrame = requestAnimationFrame(() => _updateInfocard(symbol));
+  }
+
+  /**
+   * Create the contents for the size element of a tree node..
    * If in method count mode, size instead represents the amount of methods in
    * the node. In this case, don't append a unit at the end.
-   * @param {HTMLElement} sizeElement Element that should display the count
    * @param {number} methodCount Number of methods to use for the count text
+   * @returns {{title:string,element:Node}} Object with hover text title and
+   * size element body. Can be consumed by `_applySizeFunc()`
    */
-  function _setMethodCountContents(sizeElement, methodCount) {
+  function _getMethodCountContents(methodCount) {
     const methodStr = methodCount.toLocaleString(undefined, {
       useGrouping: true,
     });
 
-    const textNode = document.createTextNode(methodStr);
-    dom.replace(sizeElement, textNode);
-    sizeElement.title = `${methodStr} methods`;
+    return {
+      element: document.createTextNode(methodStr),
+      title: `${methodStr} method${methodCount === 1 ? '' : 's'}`,
+    };
   }
 
   /**
-   * Replace the contexts of the size element for a tree node.
-   * The unit to use is selected from the current state,
-   * and the original number of bytes will be displayed as
-   * hover text over the element.
-   * @param {HTMLElement} sizeElement Element that should display the size
+   * Create the contents for the size element of a tree node.
+   * The unit to use is selected from the current state, and the original number
+   * of bytes will be displayed as hover text over the element.
    * @param {number} bytes Number of bytes to use for the size text
+   * @returns {{title:string,element:Node}} Object with hover text title and
+   * size element body. Can be consumed by `_applySizeFunc()`
    */
-  function _setSizeContents(sizeElement, bytes) {
+  function _getSizeContents(bytes) {
     // Get unit from query string, will fallback for invalid query
     const suffix = state.get('byteunit', {
       default: 'MiB',
@@ -107,10 +305,37 @@
     const suffixElement = document.createElement('small');
     suffixElement.textContent = suffix;
 
+    return {
+      element: dom.createFragment([textNode, suffixElement]),
+      title: bytes.toLocaleString(undefined, {useGrouping: true}) + ' bytes',
+    };
+  }
+
+  /**
+   * Returns the SVG icon template element corresponding to the given type.
+   * @param {string} type Symbol type character.
+   * @param {boolean} clone Set to false if you don't want a copy of the
+   * SVG template.
+   * @returns {SVGSVGElement}
+   */
+  function _getIconTemplate(type, clone = true) {
+    const iconTemplate = SYMBOL_ICONS[type] || SYMBOL_ICONS.o;
+    return clone ? iconTemplate.cloneNode(true) : iconTemplate;
+  }
+
+  /**
+   * Replace the contexts of the size element for a tree node, using a
+   * predefined function which returns a title string and DOM element.
+   * @param {(size: number) => ({title:string,element:Node})} sizeFunc
+   * @param {HTMLElement} sizeElement Element that should display the size
+   * @param {number} bytes Number of bytes to use for the size text
+   */
+  function _applySizeFunc(sizeFunc, sizeElement, bytes) {
+    const {title, element} = sizeFunc(bytes);
+
     // Replace the contents of '.size' and change its title
-    dom.replace(sizeElement, dom.createFragment([textNode, suffixElement]));
-    sizeElement.title =
-      bytes.toLocaleString(undefined, {useGrouping: true}) + ' bytes';
+    dom.replace(sizeElement, element);
+    sizeElement.title = title;
 
     if (bytes < 0) {
       sizeElement.classList.add('negative');
@@ -144,6 +369,7 @@
   function _toggleTreeElement(event) {
     event.preventDefault();
 
+    /** @type {HTMLAnchorElement | HTMLSpanElement} */
     const link = event.currentTarget;
     const element = link.parentElement;
     const group = link.nextElementSibling;
@@ -171,6 +397,7 @@
    * @param {KeyboardEvent} event
    */
   function _handleKeyNavigation(event) {
+    /** @type {HTMLAnchorElement | HTMLSpanElement} */
     const link = event.target;
     const focusIndex = Array.prototype.indexOf.call(_liveNodeList, link);
 
@@ -286,7 +513,7 @@
    * node object has any children. Trees use a slightly different template
    * and have click event listeners attached.
    * @param {TreeNode} data Data to use for the UI.
-   * @returns {HTMLElement}
+   * @returns {DocumentFragment}
    */
   function newTreeElement(data) {
     const isLeaf = data.children.length === 0;
@@ -294,15 +521,15 @@
     const element = document.importNode(template.content, true);
 
     // Associate clickable node & tree data
+    /** @type {HTMLAnchorElement | HTMLSpanElement} */
     const link = element.querySelector('.node');
     _uiNodeData.set(link, Object.freeze(data));
 
     // Icons are predefined in the HTML through hidden SVG elements
     const type = data.type[0];
-    const iconTemplate = _SYMBOL_ICONS[type] || _SYMBOL_ICONS.o;
-    const icon = iconTemplate.cloneNode(true);
+    const icon = _getIconTemplate(type);
     if (_CONTAINER_TYPES.has(type)) {
-      const symbolIcon = _SYMBOL_ICONS[data.type[1]] || _SYMBOL_ICONS.o;
+      const symbolIcon = _getIconTemplate(data.type[1], false);
       const symbolColor = symbolIcon.getAttribute('fill');
       const symbolName = symbolIcon.querySelector('title').textContent;
 
@@ -313,16 +540,18 @@
     link.insertBefore(icon, link.firstElementChild);
 
     // Set the symbol name and hover text
+    /** @type {HTMLSpanElement} */
     const symbolName = element.querySelector('.symbol-name');
     symbolName.textContent = data.shortName;
     symbolName.title = data.idPath;
 
     // Set the byte size and hover text
-    const _setSize = state.has('method_count')
-      ? _setMethodCountContents
-      : _setSizeContents;
-    _setSize(element.querySelector('.size'), data.size);
+    const _getSizeLabels = state.has('method_count')
+      ? _getMethodCountContents
+      : _getSizeContents;
+    _applySizeFunc(_getSizeLabels, element.querySelector('.size'), data.size);
 
+    link.addEventListener('mouseover', _showInfocardOnHover);
     if (!isLeaf) {
       link.addEventListener('click', _toggleTreeElement);
     }
@@ -333,13 +562,14 @@
   // When the `byteunit` state changes, update all .size elements in the page
   form.byteunit.addEventListener('change', event => {
     // Update existing size elements with the new unit
-    for (const sizeElement of document.getElementsByClassName('size')) {
+    for (const sizeElement of _liveSizeSpanList) {
       const data = _uiNodeData.get(sizeElement.parentElement);
-      _setSizeContents(sizeElement, data.size);
+      _applySizeFunc(_getSizeContents, sizeElement, data.size);
     }
   });
 
   _symbolTree.addEventListener('keydown', _handleKeyNavigation);
+  _symbolTree.addEventListener('focusin', _showInfocardOnFocus);
 
   self.newTreeElement = newTreeElement;
   self._symbolTree = _symbolTree;
@@ -359,7 +589,9 @@
    * @param {{data:{root:TreeNode,meta:object}}} param0
    */
   worker.onmessage = ({data}) => {
+    /** @type {DocumentFragment} */
     const root = newTreeElement(data);
+    /** @type {HTMLAnchorElement} */
     const node = root.querySelector('.node');
     // Expand the root UI node
     node.click();
@@ -380,9 +612,9 @@
     );
   }
 
+  form.addEventListener('change', () => loadTree(tree_data));
   form.addEventListener('submit', event => {
     event.preventDefault();
-    state.setAll(new FormData(event.currentTarget));
     loadTree(tree_data);
   });
 
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py
index 7388a7ef..23c58cd1 100755
--- a/tools/checkperms/checkperms.py
+++ b/tools/checkperms/checkperms.py
@@ -321,7 +321,8 @@
 
 
 def check_files(root, files):
-  gen = (check_file(root, f) for f in files if not is_ignored(f))
+  gen = (check_file(root, f) for f in files
+         if not is_ignored(f) and not os.path.isdir(f))
   return filter(None, gen)
 
 
diff --git a/tools/metrics/histograms/README.md b/tools/metrics/histograms/README.md
index 7f556cd9..138fa98 100644
--- a/tools/metrics/histograms/README.md
+++ b/tools/metrics/histograms/README.md
@@ -308,6 +308,10 @@
 the values emitted to are correct.  Finally, for count histograms, make sure
 that buckets capture enough precision for your needs over the range.
 
+Pro tip: You can filter the set of histograms shown on `chrome://histograms` by
+specifying a prefix. For example, `chrome://histograms/Extensions.Load` will
+show only histograms whose names match the pattern "Extensions.Load*".
+
 In addition to testing interactively, you can have unit tests examine the
 values emitted to histograms.  See [histogram_tester.h](https://cs.chromium.org/chromium/src/base/test/metrics/histogram_tester.h)
 for details.
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml
index f073e63..f9b1fd5 100644
--- a/tools/metrics/rappor/rappor.xml
+++ b/tools/metrics/rappor/rappor.xml
@@ -2498,22 +2498,6 @@
   </summary>
 </rappor-metric>
 
-<rappor-metric name="WebComponents.DocumentRegisterElement"
-    type="ETLD_PLUS_ONE">
-  <owner>kojii@chromium.org</owner>
-  <summary>
-    The host of a URL that used Document::RegisterElement().
-  </summary>
-</rappor-metric>
-
-<rappor-metric name="WebComponents.ElementCreateShadowRoot"
-    type="ETLD_PLUS_ONE">
-  <owner>kojii@chromium.org</owner>
-  <summary>
-    The host of a URL that used Element::CreateShadowRoot().
-  </summary>
-</rappor-metric>
-
 <rappor-metric name="WebComponents.EventPath" type="ETLD_PLUS_ONE">
   <owner>kojii@chromium.org</owner>
   <summary>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index a7dbc301..11b2602 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -15,7 +15,6 @@
 crbug.com/764868 [ Android_One ] blink_perf.bindings/structured-clone-json-serialize.html [ Skip ]
 crbug.com/764868 [ Android_One ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ]
 crbug.com/764868 [ Android_One ] blink_perf.bindings/structured-clone-json-deserialize.html [ Skip ]
-crbug.com/856864 [ Win ] blink_perf.bindings/* [ Skip ]
 
 # Benchmark: blink_perf.canvas
 crbug.com/593973 [ Android_Svelte ] blink_perf.canvas/* [ Skip ]
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h
index 4ac7d66..9763077b 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate.h
+++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -112,7 +112,9 @@
 
   virtual int GetTableRowCount() const = 0;
   virtual int GetTableColCount() const = 0;
+  virtual std::vector<int32_t> GetColHeaderNodeIds() const = 0;
   virtual std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const = 0;
+  virtual std::vector<int32_t> GetRowHeaderNodeIds() const = 0;
   virtual std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const = 0;
   virtual int32_t GetCellId(int32_t row_index, int32_t col_index) const = 0;
   virtual int32_t CellIdToIndex(int32_t cell_id) const = 0;
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index ad6ae9a..8b86e76 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -401,20 +401,26 @@
 SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayForRelation(
     const ax::mojom::IntListAttribute& attribute) {
   std::vector<int32_t> id_list = GetIntListAttribute(attribute);
-  SAFEARRAY* propertyvalue =
-      SafeArrayCreateVector(VT_UNKNOWN, 0, id_list.size());
+  SAFEARRAY* propertyvalue = CreateUIAElementsArrayFromIdVector(id_list);
+  return propertyvalue;
+}
+
+SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayFromIdVector(
+    std::vector<int32_t>& ids) {
+  SAFEARRAY* uia_array = SafeArrayCreateVector(VT_UNKNOWN, 0, ids.size());
 
   LONG i = 0;
-  for (int32_t node_id : id_list) {
-    AXPlatformNodeWin* node =
+  for (const auto& node_id : ids) {
+    AXPlatformNodeWin* node_win =
         static_cast<AXPlatformNodeWin*>(delegate_->GetFromNodeID(node_id));
-    DCHECK(node);
-    node->AddRef();
-    SafeArrayPutElement(propertyvalue, &i, node);
+    DCHECK(node_win);
+    node_win->AddRef();
+    SafeArrayPutElement(uia_array, &i,
+                        static_cast<IRawElementProviderSimple*>(node_win));
     ++i;
   }
 
-  return propertyvalue;
+  return uia_array;
 }
 
 //
@@ -1441,6 +1447,79 @@
 }
 
 //
+// IGridItemProvider implementation.
+//
+
+STDMETHODIMP AXPlatformNodeWin::get_Column(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableColumn();
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_ColumnSpan(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableColumnSpan();
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_ContainingGrid(
+    IRawElementProviderSimple** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  AXPlatformNodeBase* table = GetTable();
+  if (!table)
+    return E_FAIL;
+
+  auto* node_win = static_cast<AXPlatformNodeWin*>(table);
+  node_win->AddRef();
+  *result = static_cast<IRawElementProviderSimple*>(node_win);
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_Row(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableRow();
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_RowSpan(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableRowSpan();
+  return S_OK;
+}
+
+//
+// IGridProvider implementation.
+//
+
+STDMETHODIMP AXPlatformNodeWin::GetItem(int row,
+                                        int column,
+                                        IRawElementProviderSimple** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  AXPlatformNodeBase* cell = GetTableCell(row, column);
+  if (!cell)
+    return E_INVALIDARG;
+
+  auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
+  node_win->AddRef();
+  *result = static_cast<IRawElementProviderSimple*>(node_win);
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_RowCount(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableRowCount();
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_ColumnCount(int* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  *result = GetTableColumnCount();
+  return S_OK;
+}
+
+//
 // IScrollItemProvider implementation.
 //
 
@@ -1559,6 +1638,69 @@
 }
 
 //
+// ITableItemProvider methods.
+//
+
+STDMETHODIMP AXPlatformNodeWin::GetColumnHeaderItems(SAFEARRAY** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  if (!IsCellOrTableHeaderRole(GetData().role) || !GetTable())
+    return E_FAIL;
+
+  std::vector<int32_t> column_header_ids =
+      delegate_->GetColHeaderNodeIds(GetTableColumn());
+  if (column_header_ids.empty())
+    return S_FALSE;
+  *result = CreateUIAElementsArrayFromIdVector(column_header_ids);
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::GetRowHeaderItems(SAFEARRAY** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  if (!IsCellOrTableHeaderRole(GetData().role) || !GetTable())
+    return E_FAIL;
+
+  std::vector<int32_t> row_header_ids =
+      delegate_->GetRowHeaderNodeIds(GetTableRow());
+  if (row_header_ids.empty())
+    return S_FALSE;
+  *result = CreateUIAElementsArrayFromIdVector(row_header_ids);
+  return S_OK;
+}
+
+//
+// ITableProvider methods.
+//
+
+STDMETHODIMP AXPlatformNodeWin::GetColumnHeaders(SAFEARRAY** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  if (!GetTable())
+    return E_FAIL;
+
+  std::vector<int32_t> column_header_ids = delegate_->GetColHeaderNodeIds();
+  *result = CreateUIAElementsArrayFromIdVector(column_header_ids);
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::GetRowHeaders(SAFEARRAY** result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+
+  if (!GetTable())
+    return E_FAIL;
+
+  std::vector<int32_t> row_header_ids = delegate_->GetRowHeaderNodeIds();
+  *result = CreateUIAElementsArrayFromIdVector(row_header_ids);
+  return S_OK;
+}
+
+STDMETHODIMP AXPlatformNodeWin::get_RowOrColumnMajor(RowOrColumnMajor* result) {
+  COM_OBJECT_VALIDATE_1_ARG(result);
+  return E_NOTIMPL;
+}
+
+//
 // IToggleProvider implementation.
 //
 
@@ -2844,7 +2986,19 @@
       break;
 
     case UIA_GridPatternId:
+      if (IsTableLikeRole(data.role)) {
+        AddRef();
+        *result = static_cast<IRawElementProviderSimple*>(this);
+      }
+      break;
+
     case UIA_GridItemPatternId:
+      if (IsCellOrTableHeaderRole(data.role)) {
+        AddRef();
+        *result = static_cast<IRawElementProviderSimple*>(this);
+      }
+      break;
+
     case UIA_MultipleViewPatternId:
       break;
 
@@ -2862,8 +3016,22 @@
       break;
 
     case UIA_SynchronizedInputPatternId:
+      break;
+
     case UIA_TablePatternId:
+      if (IsTableLikeRole(data.role)) {
+        AddRef();
+        *result = static_cast<IRawElementProviderSimple*>(this);
+      }
+      break;
+
     case UIA_TableItemPatternId:
+      if (IsCellOrTableHeaderRole(data.role)) {
+        AddRef();
+        *result = static_cast<IRawElementProviderSimple*>(this);
+      }
+      break;
+
     case UIA_TransformPatternId:
       break;
 
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index abc3008..50d010f 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -242,12 +242,16 @@
                         public IAccessibleTable2,
                         public IAccessibleTableCell,
                         public IExpandCollapseProvider,
+                        public IGridItemProvider,
+                        public IGridProvider,
                         public IRangeValueProvider,
                         public IRawElementProviderSimple,
                         public IScrollItemProvider,
                         public ISelectionItemProvider,
                         public ISelectionProvider,
                         public IServiceProvider,
+                        public ITableItemProvider,
+                        public ITableProvider,
                         public IToggleProvider,
                         public IValueProvider,
                         public AXPlatformNodeBase {
@@ -264,11 +268,15 @@
     COM_INTERFACE_ENTRY(IAccessibleTable2)
     COM_INTERFACE_ENTRY(IAccessibleTableCell)
     COM_INTERFACE_ENTRY(IExpandCollapseProvider)
+    COM_INTERFACE_ENTRY(IGridItemProvider)
+    COM_INTERFACE_ENTRY(IGridProvider)
     COM_INTERFACE_ENTRY(IRangeValueProvider)
     COM_INTERFACE_ENTRY(IRawElementProviderSimple)
     COM_INTERFACE_ENTRY(IScrollItemProvider)
     COM_INTERFACE_ENTRY(ISelectionItemProvider)
     COM_INTERFACE_ENTRY(ISelectionProvider)
+    COM_INTERFACE_ENTRY(ITableItemProvider)
+    COM_INTERFACE_ENTRY(ITableProvider)
     COM_INTERFACE_ENTRY(IToggleProvider)
     COM_INTERFACE_ENTRY(IValueProvider)
     COM_INTERFACE_ENTRY(IServiceProvider)
@@ -443,6 +451,32 @@
   STDMETHODIMP get_ExpandCollapseState(ExpandCollapseState* result) override;
 
   //
+  // IGridItemProvider methods.
+  //
+
+  STDMETHODIMP get_Column(int* result) override;
+
+  STDMETHODIMP get_ColumnSpan(int* result) override;
+
+  STDMETHODIMP get_ContainingGrid(IRawElementProviderSimple** result) override;
+
+  STDMETHODIMP get_Row(int* result) override;
+
+  STDMETHODIMP get_RowSpan(int* result) override;
+
+  //
+  // IGridProvider methods.
+  //
+
+  STDMETHODIMP GetItem(int row,
+                       int column,
+                       IRawElementProviderSimple** result) override;
+
+  STDMETHODIMP get_RowCount(int* result) override;
+
+  STDMETHODIMP get_ColumnCount(int* result) override;
+
+  //
   // IScrollItemProvider methods.
   //
 
@@ -474,6 +508,24 @@
   STDMETHODIMP get_IsSelectionRequired(BOOL* result) override;
 
   //
+  // ITableItemProvider methods.
+  //
+
+  STDMETHODIMP GetColumnHeaderItems(SAFEARRAY** result) override;
+
+  STDMETHODIMP GetRowHeaderItems(SAFEARRAY** result) override;
+
+  //
+  // ITableProvider methods.
+  //
+
+  STDMETHODIMP GetColumnHeaders(SAFEARRAY** result) override;
+
+  STDMETHODIMP GetRowHeaders(SAFEARRAY** result) override;
+
+  STDMETHODIMP get_RowOrColumnMajor(RowOrColumnMajor* result) override;
+
+  //
   // IToggleProvider methods.
   //
 
@@ -929,6 +981,10 @@
   SAFEARRAY* CreateUIAElementsArrayForRelation(
       const ax::mojom::IntListAttribute& attribute);
 
+  // Return an array of automation elements given a vector
+  // of |AXNode| ids.
+  SAFEARRAY* CreateUIAElementsArrayFromIdVector(std::vector<int32_t>& ids);
+
   void AddAlertTarget();
   void RemoveAlertTarget();
 
diff --git a/ui/accessibility/platform/ax_system_caret_win.cc b/ui/accessibility/platform/ax_system_caret_win.cc
index be740fa..82135e3e 100644
--- a/ui/accessibility/platform/ax_system_caret_win.cc
+++ b/ui/accessibility/platform/ax_system_caret_win.cc
@@ -125,14 +125,22 @@
   return 0;
 }
 
+std::vector<int32_t> AXSystemCaretWin::GetColHeaderNodeIds() const {
+  return {};
+}
+
 std::vector<int32_t> AXSystemCaretWin::GetColHeaderNodeIds(
     int32_t col_index) const {
-  return std::vector<int32_t>();
+  return {};
+}
+
+std::vector<int32_t> AXSystemCaretWin::GetRowHeaderNodeIds() const {
+  return {};
 }
 
 std::vector<int32_t> AXSystemCaretWin::GetRowHeaderNodeIds(
     int32_t row_index) const {
-  return std::vector<int32_t>();
+  return {};
 }
 
 int32_t AXSystemCaretWin::GetCellId(int32_t row_index,
diff --git a/ui/accessibility/platform/ax_system_caret_win.h b/ui/accessibility/platform/ax_system_caret_win.h
index 3e96bb5e..9a5c18d 100644
--- a/ui/accessibility/platform/ax_system_caret_win.h
+++ b/ui/accessibility/platform/ax_system_caret_win.h
@@ -49,7 +49,9 @@
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   int GetTableRowCount() const override;
   int GetTableColCount() const override;
+  std::vector<int32_t> GetColHeaderNodeIds() const override;
   std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override;
+  std::vector<int32_t> GetRowHeaderNodeIds() const override;
   std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override;
   int32_t GetCellId(int32_t row_index, int32_t col_index) const override;
   int32_t CellIdToIndex(int32_t cell_id) const override;
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index 581d0c1..3b2bcae1 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -222,6 +222,20 @@
   return table_info->col_count;
 }
 
+std::vector<int32_t> TestAXNodeWrapper::GetColHeaderNodeIds() const {
+  ui::AXTableInfo* table_info = tree_->GetTableInfo(node_);
+  if (!table_info)
+    return std::vector<int32_t>();
+
+  std::vector<std::vector<int32_t>> headers = table_info->col_headers;
+  std::vector<int32_t> all_ids;
+  for (const auto col_ids : headers) {
+    all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+  }
+
+  return all_ids;
+}
+
 std::vector<int32_t> TestAXNodeWrapper::GetColHeaderNodeIds(
     int32_t col_index) const {
   AXTableInfo* table_info = tree_->GetTableInfo(node_);
@@ -234,6 +248,20 @@
   return table_info->col_headers[col_index];
 }
 
+std::vector<int32_t> TestAXNodeWrapper::GetRowHeaderNodeIds() const {
+  ui::AXTableInfo* table_info = tree_->GetTableInfo(node_);
+  if (!table_info)
+    return std::vector<int32_t>();
+
+  std::vector<std::vector<int32_t>> headers = table_info->row_headers;
+  std::vector<int32_t> all_ids;
+  for (const auto col_ids : headers) {
+    all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+  }
+
+  return all_ids;
+}
+
 std::vector<int32_t> TestAXNodeWrapper::GetRowHeaderNodeIds(
     int32_t row_index) const {
   AXTableInfo* table_info = tree_->GetTableInfo(node_);
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h
index d436ec3..8cf31cac 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -46,7 +46,9 @@
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   int GetTableRowCount() const override;
   int GetTableColCount() const override;
+  std::vector<int32_t> GetColHeaderNodeIds() const override;
   std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override;
+  std::vector<int32_t> GetRowHeaderNodeIds() const override;
   std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override;
   int32_t GetCellId(int32_t row_index, int32_t col_index) const override;
   int32_t CellIdToIndex(int32_t cell_id) const override;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index a6b637c..221f7ee 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -454,12 +454,6 @@
   display: none;
 }
 
-.cloud-import-combo-button {
-  height: 32px;
-  margin: 8px;
-  position: relative;
-}
-
 .cloud-import-combo-button > .buttons {
   display: flex;
 }
diff --git a/ui/gl/gl_surface_egl_x11.cc b/ui/gl/gl_surface_egl_x11.cc
index 78fa83f..e1e05ce 100644
--- a/ui/gl/gl_surface_egl_x11.cc
+++ b/ui/gl/gl_surface_egl_x11.cc
@@ -52,6 +52,8 @@
 }
 
 void NativeViewGLSurfaceEGLX11::Destroy() {
+  NativeViewGLSurfaceEGL::Destroy();
+
   if (window_) {
     if (PlatformEventSource* source = PlatformEventSource::GetInstance())
       source->RemovePlatformEventDispatcher(this);
@@ -61,8 +63,6 @@
     window_ = 0;
     XFlush(x11_display);
   }
-
-  NativeViewGLSurfaceEGL::Destroy();
 }
 
 EGLConfig NativeViewGLSurfaceEGLX11::GetConfig() {
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc
index a098c1b5..4fc637c 100644
--- a/ui/views/accessibility/native_view_accessibility_auralinux.cc
+++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -127,12 +127,16 @@
 
   int GetTableColCount() const override { return 0; }
 
+  std::vector<int32_t> GetColHeaderNodeIds() const override { return {}; }
+
   std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override {
-    return std::vector<int32_t>();
+    return {};
   }
 
+  std::vector<int32_t> GetRowHeaderNodeIds() const override { return {}; }
+
   std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override {
-    return std::vector<int32_t>();
+    return {};
   }
 
   int32_t GetCellId(int32_t row_index, int32_t col_index) const override {
diff --git a/ui/views/accessibility/native_view_accessibility_base.cc b/ui/views/accessibility/native_view_accessibility_base.cc
index 84f0f70..53389dd 100644
--- a/ui/views/accessibility/native_view_accessibility_base.cc
+++ b/ui/views/accessibility/native_view_accessibility_base.cc
@@ -355,14 +355,22 @@
   return 0;
 }
 
+std::vector<int32_t> NativeViewAccessibilityBase::GetColHeaderNodeIds() const {
+  return {};
+}
+
 std::vector<int32_t> NativeViewAccessibilityBase::GetColHeaderNodeIds(
     int32_t col_index) const {
-  return std::vector<int32_t>();
+  return {};
+}
+
+std::vector<int32_t> NativeViewAccessibilityBase::GetRowHeaderNodeIds() const {
+  return {};
 }
 
 std::vector<int32_t> NativeViewAccessibilityBase::GetRowHeaderNodeIds(
     int32_t row_index) const {
-  return std::vector<int32_t>();
+  return {};
 }
 
 int32_t NativeViewAccessibilityBase::GetCellId(int32_t row_index,
diff --git a/ui/views/accessibility/native_view_accessibility_base.h b/ui/views/accessibility/native_view_accessibility_base.h
index bdfb2f4..dc7e5e575 100644
--- a/ui/views/accessibility/native_view_accessibility_base.h
+++ b/ui/views/accessibility/native_view_accessibility_base.h
@@ -54,7 +54,9 @@
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   int GetTableRowCount() const override;
   int GetTableColCount() const override;
+  std::vector<int32_t> GetColHeaderNodeIds() const override;
   std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override;
+  std::vector<int32_t> GetRowHeaderNodeIds() const override;
   std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override;
   int32_t GetCellId(int32_t row_index, int32_t col_index) const override;
   int32_t CellIdToIndex(int32_t cell_id) const override;
diff --git a/webrunner/service/context_provider/context_provider_impl.cc b/webrunner/service/context_provider/context_provider_impl.cc
index f989316..926e1fdb 100644
--- a/webrunner/service/context_provider/context_provider_impl.cc
+++ b/webrunner/service/context_provider/context_provider_impl.cc
@@ -5,6 +5,7 @@
 #include "webrunner/service/context_provider/context_provider_impl.h"
 
 #include <fuchsia/sys/cpp/fidl.h>
+#include <lib/zx/job.h>
 #include <zircon/processargs.h>
 
 #include <utility>
@@ -14,7 +15,6 @@
 #include "base/command_line.h"
 #include "base/fuchsia/default_job.h"
 #include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/scoped_zx_handle.h"
 #include "base/logging.h"
 #include "base/process/launch.h"
 #include "webrunner/service/switches.h"
@@ -56,14 +56,14 @@
   // Transfer the ContextRequest handle to a well-known location in the child
   // process' handle table.
   base::LaunchOptions launch_options;
-  base::ScopedZxHandle context_handle(context_request.TakeChannel().release());
+  zx::channel context_handle(context_request.TakeChannel());
   launch_options.handles_to_transfer.push_back(
       {PA_HND(PA_USER0, 0), context_handle.get()});
 
   // Isolate the child Context processes by containing them within their own
   // respective jobs.
-  base::ScopedZxHandle job;
-  zx_status_t status = zx_job_create(base::GetDefaultJob(), 0, job.receive());
+  zx::job job;
+  zx_status_t status = zx::job::create(*base::GetDefaultJob(), 0, &job);
   ZX_CHECK(status == ZX_OK, status) << "zx_job_create";
 
   ignore_result(launch_.Run(launch_options));