diff --git a/DEPS b/DEPS
index a93f6ad6..df7b97d 100644
--- a/DEPS
+++ b/DEPS
@@ -127,11 +127,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': '1179d5dfaf8d0a2a7c6c8f7e997dd267b118d5db',
+  'skia_revision': 'b2565b18d03e1d33ff59cbb2dddc5920451ee660',
   # 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': 'dd689541d3815d64b4b39f6a41603248c71aa00e',
+  'v8_revision': '67e3f02c0ad461789b2d5e74ad05743c6695e5e9',
   # 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.
@@ -139,7 +139,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': '4b314eefc839f688cf2367b2cc288a8e954d1c4f',
+  'angle_revision': '5de69e91bd939f8c2acc3ccab095d770bf378481',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -190,7 +190,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': 'afd6d361b5b7d49c86bbfa29b3680270d79b12a0',
+  'catapult_revision': '3c7b056c0c8bee3b6649194c55d083be1cb9c3ba',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -254,7 +254,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '31ac9850ad0f9594639ff035140766204de352e1',
+  'dawn_revision': '2dfb3f01e77d1dff4ce611fe8d00c9a11b235f78',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -738,7 +738,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '87c513372ff3d8deec6bb013fac5d62520a695d0',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a0a1dcc9585331d677966a2b7ea09aab1b13f4fb',
       'condition': 'checkout_linux',
   },
 
@@ -1102,7 +1102,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '1eac440c17182b34622517e6efb60ad7b0038b4a',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '65cf8a9b97757fbcc503370100b4dbfb9df77419',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1276,7 +1276,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '2c7964832eacfddceb467da385c0dfe89a5b8d7d',
+    Var('webrtc_git') + '/src.git' + '@' + '25fb765367e1ac7481d43cf846947eff327181de',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1317,7 +1317,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@00be6aaa4a3e0b9af3ef05987c2681c72ce20534',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@72565d358a645aa30087844e419463928d669351',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni
index b11550a..75e8d20 100644
--- a/android_webview/system_webview_apk_tmpl.gni
+++ b/android_webview/system_webview_apk_tmpl.gni
@@ -32,8 +32,18 @@
 
     if (!_use_trichrome_library) {
       shared_libraries = [ "//android_webview:libwebviewchromium" ]
+      deps += [
+        "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
+      ]
+      loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
+
       if (build_apk_secondary_abi && android_64bit_target_cpu) {
         secondary_abi_shared_libraries = [ "//android_webview:libwebviewchromium($android_secondary_abi_toolchain)" ]
+        _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+        deps += [ _trampoline ]
+        _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
+        secondary_abi_loadable_modules =
+            [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
       }
     } else {
       uncompress_shared_libraries = true
@@ -42,6 +52,11 @@
       # architecture.
       if (android_64bit_target_cpu) {
         shared_libraries = [ "//android_webview:monochrome" ]
+        deps += [
+          "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
+        ]
+        loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
+
         if (build_apk_secondary_abi) {
           secondary_native_lib_placeholders = [ "libdummy.so" ]
         }
diff --git a/android_webview/tools/apk_merger.py b/android_webview/tools/apk_merger.py
index 14ef0d6d..76b679c 100755
--- a/android_webview/tools/apk_merger.py
+++ b/android_webview/tools/apk_merger.py
@@ -201,11 +201,12 @@
   assets_path = 'base/assets' if args.bundle else 'assets'
   exclude_files_64 = ['%s/snapshot_blob_32.bin' % assets_path,
                       GetTargetAbiPath(args.apk_32bit, args.shared_library)]
-  # TODO(benmason): Remove when libcrashpad_handler.so
-  # is no longer a separate lib.
   if 'libcrashpad_handler.so' in expected_files:
     exclude_files_64.append(
         GetTargetAbiPath(args.apk_32bit, 'libcrashpad_handler.so'))
+  if 'libcrashpad_handler_trampoline.so' in expected_files:
+    exclude_files_64.append(
+        GetTargetAbiPath(args.apk_32bit, 'libcrashpad_handler_trampoline.so'))
   UnpackApk(args.apk_64bit, tmp_dir_64, exclude_files_64)
   UnpackApk(args.apk_32bit, tmp_dir_32)
 
diff --git a/apps/test/app_window_waiter.cc b/apps/test/app_window_waiter.cc
index beae24c..8c72aec6 100644
--- a/apps/test/app_window_waiter.cc
+++ b/apps/test/app_window_waiter.cc
@@ -4,6 +4,7 @@
 
 #include "apps/test/app_window_waiter.h"
 
+#include "base/task/post_task.h"
 #include "extensions/browser/app_window/app_window.h"
 #include "extensions/browser/app_window/native_app_window.h"
 
@@ -25,7 +26,7 @@
     return window_;
 
   wait_type_ = WAIT_FOR_ADDED;
-  run_loop_.reset(new base::RunLoop);
+  run_loop_ = std::make_unique<base::RunLoop>();
   run_loop_->Run();
 
   return window_;
@@ -37,7 +38,21 @@
     return window_;
 
   wait_type_ = WAIT_FOR_SHOWN;
-  run_loop_.reset(new base::RunLoop);
+  run_loop_ = std::make_unique<base::RunLoop>();
+  run_loop_->Run();
+
+  return window_;
+}
+
+extensions::AppWindow* AppWindowWaiter::WaitForShownWithTimeout(
+    base::TimeDelta timeout) {
+  window_ = registry_->GetCurrentAppWindowForApp(app_id_);
+  if (window_ && !window_->is_hidden())
+    return window_;
+
+  wait_type_ = WAIT_FOR_SHOWN;
+  run_loop_ = std::make_unique<base::RunLoop>();
+  base::PostDelayedTask(FROM_HERE, run_loop_->QuitClosure(), timeout);
   run_loop_->Run();
 
   return window_;
@@ -49,7 +64,7 @@
     return window_;
 
   wait_type_ = WAIT_FOR_ACTIVATED;
-  run_loop_.reset(new base::RunLoop);
+  run_loop_ = std::make_unique<base::RunLoop>();
   run_loop_->Run();
 
   return window_;
diff --git a/apps/test/app_window_waiter.h b/apps/test/app_window_waiter.h
index 4c82240e..a382ae2 100644
--- a/apps/test/app_window_waiter.h
+++ b/apps/test/app_window_waiter.h
@@ -34,6 +34,10 @@
   // Waits for an AppWindow of the app to be shown.
   extensions::AppWindow* WaitForShown();
 
+  // Waits for an AppWindow of the app to be shown or returns nullptr if the
+  // given timeout expires.
+  extensions::AppWindow* WaitForShownWithTimeout(base::TimeDelta timeout);
+
   // Waits for an AppWindow of the app to be activated.
   extensions::AppWindow* WaitForActivated();
 
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index ef7b2f75..861e76e3 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1309,6 +1309,7 @@
     "//chromeos/dbus",
     "//chromeos/dbus:power_manager_proto",
     "//chromeos/dbus/services:services",
+    "//chromeos/dbus/system_clock",
 
     # TODO(stevenjb): Remove this dependency, https://crbug.com/644355.
     "//chromeos/network",
@@ -2153,6 +2154,7 @@
     # TODO(stevenjb): Investigate whether this is OK. https://crbug.com/644336.
     "//chromeos/audio",
     "//chromeos/dbus:test_support",
+    "//chromeos/dbus/system_clock",
 
     # TODO(stevenjb): Remove this dependency, https://crbug.com/644355.
     "//chromeos/network:test_support",
diff --git a/ash/DEPS b/ash/DEPS
index b96c3866..56f0244 100644
--- a/ash/DEPS
+++ b/ash/DEPS
@@ -67,7 +67,7 @@
   "+chromeos/dbus/power_policy_controller.h",
   "+chromeos/dbus/session_manager_client.h",
   "+chromeos/dbus/shill_device_client.h",
-  "+chromeos/dbus/system_clock_client.h",
+  "+chromeos/dbus/system_clock",
   # TODO(jamescook): Eliminate this. http://crbug.com/644355
   "+chromeos/network",
   "+chromeos/services/assistant/public" ,
diff --git a/ash/ash_service.cc b/ash/ash_service.cc
index 4e5643b0..30c5b58 100644
--- a/ash/ash_service.cc
+++ b/ash/ash_service.cc
@@ -18,7 +18,7 @@
 #include "chromeos/audio/cras_audio_handler.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_policy_controller.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/network/network_connect.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/system/fake_statistics_provider.h"
@@ -153,8 +153,7 @@
   // dbus::Thread, dbus::Bus and required clients directly.
   chromeos::DBusThreadManager::Initialize(chromeos::DBusThreadManager::kShared);
   dbus::Bus* bus = chromeos::DBusThreadManager::Get()->GetSystemBus();
-  bool use_fakes = chromeos::DBusThreadManager::Get()->IsUsingFakes();
-  CHECK(bus || use_fakes);
+  chromeos::SystemClockClient::Initialize(bus);
 
   chromeos::PowerPolicyController::Initialize(
       chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
diff --git a/ash/contained_shell/contained_shell_controller.cc b/ash/contained_shell/contained_shell_controller.cc
index f393288..c0507ff1 100644
--- a/ash/contained_shell/contained_shell_controller.cc
+++ b/ash/contained_shell/contained_shell_controller.cc
@@ -10,6 +10,7 @@
 #include "ash/shell.h"
 #include "components/account_id/account_id.h"
 #include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
 
 #include <utility>
 
@@ -32,12 +33,22 @@
 }
 
 bool ContainedShellController::IsEnabled() {
-  // TODO(ltenorio): Also check the ash.contained_shell.enabled pref here when
-  // it's available.
-  return base::FeatureList::IsEnabled(features::kContainedShell);
+  if (!base::FeatureList::IsEnabled(features::kContainedShell))
+    return false;
+
+  PrefService* prefs =
+      Shell::Get()->session_controller()->GetPrimaryUserPrefService();
+
+  DCHECK(prefs) << "PrefService should not be null when reading Contained "
+                   "Shell pref. This usually happens when calling "
+                   "ContainedShellController::IsEnabled() before sign in.";
+  return prefs->GetBoolean(prefs::kContainedShellEnabled);
 }
 
-void ContainedShellController::LaunchContainedShell() {
+void ContainedShellController::LaunchContainedShellIfEnabled() {
+  if (!IsEnabled())
+    return;
+
   contained_shell_client_->LaunchContainedShell(Shell::Get()
                                                     ->session_controller()
                                                     ->GetPrimaryUserSession()
diff --git a/ash/contained_shell/contained_shell_controller.h b/ash/contained_shell/contained_shell_controller.h
index 81d985ca..dab6c3b8 100644
--- a/ash/contained_shell/contained_shell_controller.h
+++ b/ash/contained_shell/contained_shell_controller.h
@@ -33,9 +33,13 @@
   // Returns if the Contained Shell is enabled for the current user.
   bool IsEnabled();
 
-  // Starts the ContainedShell feature by sending LaunchContainedShell
-  // request to ContainedShellClient.
-  void LaunchContainedShell();
+  // Tries to start the Contained Shell feature by sending a
+  // LaunchContainedShell command to the ContainedShellClient. We will only
+  // launch if |IsEnabled()| is true, so it's safe to call this every time a
+  // successful sign in happens.
+  // Warning: This method should not be called before sign in since the prefs
+  // would not be initialized.
+  void LaunchContainedShellIfEnabled();
 
   // mojom::ContainedShellController:
   void SetClient(mojom::ContainedShellClientPtr client) override;
diff --git a/ash/shell.cc b/ash/shell.cc
index e95dedf..497af0d 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -1431,10 +1431,8 @@
   // the controller when the session is active. https://crbug.com/464118
   drag_drop_controller_->set_enabled(is_session_active);
 
-  if (base::FeatureList::IsEnabled(features::kContainedShell) &&
-      is_session_active) {
-    contained_shell_controller_->LaunchContainedShell();
-  }
+  if (is_session_active)
+    contained_shell_controller_->LaunchContainedShellIfEnabled();
 }
 
 void Shell::OnLoginStatusChanged(LoginStatus login_status) {
diff --git a/ash/system/model/clock_model.cc b/ash/system/model/clock_model.cc
index 8115c713..bbaa8cd3 100644
--- a/ash/system/model/clock_model.cc
+++ b/ash/system/model/clock_model.cc
@@ -8,20 +8,22 @@
 #include "ash/shell.h"
 #include "ash/system/model/clock_observer.h"
 #include "ash/system/model/system_tray_model.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
 
 namespace ash {
 
 ClockModel::ClockModel() : hour_clock_type_(base::GetHourClockType()) {
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(this);
+  // SystemClockClient may be null in tests.
+  if (chromeos::SystemClockClient::Get()) {
+    chromeos::SystemClockClient::Get()->AddObserver(this);
+    can_set_time_ = chromeos::SystemClockClient::Get()->CanSetTime();
+  }
   chromeos::system::TimezoneSettings::GetInstance()->AddObserver(this);
-  can_set_time_ =
-      chromeos::DBusThreadManager::Get()->GetSystemClockClient()->CanSetTime();
 }
 
 ClockModel::~ClockModel() {
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
-      this);
+  // SystemClockClient may be null in tests.
+  if (chromeos::SystemClockClient::Get())
+    chromeos::SystemClockClient::Get()->RemoveObserver(this);
   chromeos::system::TimezoneSettings::GetInstance()->RemoveObserver(this);
 }
 
diff --git a/ash/system/model/clock_model.h b/ash/system/model/clock_model.h
index e413cd5c..7620354 100644
--- a/ash/system/model/clock_model.h
+++ b/ash/system/model/clock_model.h
@@ -8,7 +8,7 @@
 #include "base/i18n/time_formatting.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/settings/timezone_settings.h"
 
 namespace ash {
diff --git a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
index 646285e..3f1dcdc 100644
--- a/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
+++ b/ash/wm/tablet_mode/tablet_mode_controller_unittest.cc
@@ -11,10 +11,13 @@
 #include "ash/accelerometer/accelerometer_reader.h"
 #include "ash/accelerometer/accelerometer_types.h"
 #include "ash/app_list/app_list_controller_impl.h"
+#include "ash/app_list/test/app_list_test_helper.h"
+#include "ash/app_list/views/app_list_view.h"
 #include "ash/display/screen_orientation_controller.h"
 #include "ash/public/cpp/app_types.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/tablet_mode.h"
+#include "ash/public/cpp/window_properties.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/overview/overview_controller.h"
@@ -29,6 +32,7 @@
 #include "chromeos/dbus/fake_power_manager_client.h"
 #include "services/ws/public/cpp/input_devices/input_device_client_test_api.h"
 #include "ui/aura/client/aura_constants.h"
+#include "ui/base/hit_test.h"
 #include "ui/display/manager/display_manager.h"
 #include "ui/display/screen.h"
 #include "ui/display/test/display_manager_test_api.h"
@@ -1234,6 +1238,89 @@
   EXPECT_TRUE(GetDeferBoundsUpdates(extra_right_window.get()));
 }
 
+// Test that if before tablet mode, the active window is a transient child of a
+// window snapped on the left, then split view is activated with the parent
+// snapped on the left.
+TEST_F(TabletModeControllerTest, StartTabletActiveTransientChildOfLeftSnap) {
+  SplitViewController* split_view_controller =
+      Shell::Get()->split_view_controller();
+  std::unique_ptr<aura::Window> parent = CreateDesktopWindowSnappedLeft();
+  std::unique_ptr<aura::Window> child =
+      CreateTestWindow(gfx::Rect(), aura::client::WINDOW_TYPE_POPUP);
+  ::wm::AddTransientChild(parent.get(), child.get());
+  ::wm::ActivateWindow(parent.get());
+  ::wm::ActivateWindow(child.get());
+  tablet_mode_controller()->EnableTabletModeWindowManager(true);
+  EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller->state());
+  EXPECT_EQ(parent.get(), split_view_controller->left_window());
+  EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting());
+  EXPECT_FALSE(GetDeferBoundsUpdates(parent.get()));
+}
+
+// Test that if before tablet mode, the active window is the app list and the
+// previous window is snapped on the left, then split view is activated with the
+// previous window on the left.
+TEST_F(TabletModeControllerTest, StartTabletActiveAppListPreviousLeftSnap) {
+  SplitViewController* split_view_controller =
+      Shell::Get()->split_view_controller();
+  std::unique_ptr<aura::Window> window = CreateDesktopWindowSnappedLeft();
+  ::wm::ActivateWindow(window.get());
+  Shell::Get()->app_list_controller()->ShowAppList();
+  ASSERT_TRUE(::wm::IsActiveWindow(
+      GetAppListTestHelper()->GetAppListView()->GetWidget()->GetNativeView()));
+  tablet_mode_controller()->EnableTabletModeWindowManager(true);
+  EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller->state());
+  EXPECT_EQ(window.get(), split_view_controller->left_window());
+  EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting());
+  EXPECT_FALSE(GetDeferBoundsUpdates(window.get()));
+}
+
+// Test that if before tablet mode, the active window is being dragged and the
+// previous window is snapped on the left, then split view is activated with the
+// previous window on the left.
+TEST_F(TabletModeControllerTest, StartTabletActiveDraggedPreviousLeftSnap) {
+  SplitViewController* split_view_controller =
+      Shell::Get()->split_view_controller();
+  std::unique_ptr<aura::Window> dragged_window = CreateTestWindow();
+  wm::WindowState* dragged_window_state =
+      wm::GetWindowState(dragged_window.get());
+  dragged_window_state->CreateDragDetails(
+      gfx::Point(), HTNOWHERE,
+      ::wm::WindowMoveSource::WINDOW_MOVE_SOURCE_MOUSE);
+  dragged_window_state->OnDragStarted(HTNOWHERE);
+  ASSERT_TRUE(dragged_window_state->is_dragged());
+  std::unique_ptr<aura::Window> snapped_window =
+      CreateDesktopWindowSnappedLeft();
+  ::wm::ActivateWindow(snapped_window.get());
+  ::wm::ActivateWindow(dragged_window.get());
+  tablet_mode_controller()->EnableTabletModeWindowManager(true);
+  EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller->state());
+  EXPECT_EQ(snapped_window.get(), split_view_controller->left_window());
+  EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting());
+  EXPECT_FALSE(GetDeferBoundsUpdates(snapped_window.get()));
+}
+
+// Test that if before tablet mode, the active window is hidden from overview
+// and the previous window is snapped on the left, then split view is activated
+// with the previous window on the left.
+TEST_F(TabletModeControllerTest,
+       StartTabletActiveHiddenFromOverviewPreviousLeftSnap) {
+  SplitViewController* split_view_controller =
+      Shell::Get()->split_view_controller();
+  std::unique_ptr<aura::Window> window_hidden_from_overview =
+      CreateTestWindow();
+  window_hidden_from_overview->SetProperty(kHideInOverviewKey, true);
+  std::unique_ptr<aura::Window> snapped_window =
+      CreateDesktopWindowSnappedLeft();
+  ::wm::ActivateWindow(snapped_window.get());
+  ::wm::ActivateWindow(window_hidden_from_overview.get());
+  tablet_mode_controller()->EnableTabletModeWindowManager(true);
+  EXPECT_EQ(SplitViewController::LEFT_SNAPPED, split_view_controller->state());
+  EXPECT_EQ(snapped_window.get(), split_view_controller->left_window());
+  EXPECT_TRUE(Shell::Get()->overview_controller()->IsSelecting());
+  EXPECT_FALSE(GetDeferBoundsUpdates(snapped_window.get()));
+}
+
 // Test that if overview is triggered on entering tablet mode, then the app list
 // can still be successfully shown and actually seen.
 TEST_F(TabletModeControllerTest, AppListWorksAfterEnteringTabletForOverview) {
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
index 275dfa9e..b332f404 100644
--- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc
+++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -301,64 +301,76 @@
 }
 
 void TabletModeWindowManager::ArrangeWindowsForTabletMode() {
-  // We want the build mru list to include windows on the lock screen.
+  // |split_view_eligible_windows| is for determining split view layout.
+  // |activatable_windows| includes all windows to be tracked, and that includes
+  // windows on the lock screen via |scoped_skip_user_session_blocked_check|.
+  MruWindowTracker::WindowList split_view_eligible_windows =
+      Shell::Get()->mru_window_tracker()->BuildWindowForCycleList();
   ScopedSkipUserSessionBlockedCheck scoped_skip_user_session_blocked_check;
-
-  MruWindowTracker::WindowList windows =
+  MruWindowTracker::WindowList activatable_windows =
       Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
 
-  // Specifically check for the case of no windows, so that subsequent logic can
-  // refer to the active window and assume it exists.
-  if (windows.empty())
-    return;
-
-  const mojom::WindowStateType active_window_state_type =
-      wm::GetWindowState(windows[0])->GetStateType();
-
-  // If the active window is ARC or not snapped, then just maximize all windows.
-  if (static_cast<ash::AppType>(windows[0]->GetProperty(
+  // If split_view_eligible_windows[0] does not exist or is ARC or not snapped,
+  // then just maximize all windows.
+  if (split_view_eligible_windows.empty() ||
+      static_cast<ash::AppType>(split_view_eligible_windows[0]->GetProperty(
           aura::client::kAppType)) == AppType::ARC_APP ||
-      (active_window_state_type != mojom::WindowStateType::LEFT_SNAPPED &&
-       active_window_state_type != mojom::WindowStateType::RIGHT_SNAPPED)) {
-    for (auto* window : windows)
+      !wm::GetWindowState(split_view_eligible_windows[0])->IsSnapped()) {
+    for (auto* window : activatable_windows)
       TrackWindow(window);
     return;
   }
 
-  // Carry over the snapped active window to split view, along with the previous
-  // window if it exists, is snapped on the opposite side, and is not ARC.
+  // Carry over split_view_eligible_windows[0] to split view, along with
+  // split_view_eligible_windows[1] if it exists, is snapped on the opposite
+  // side, and is not ARC.
   const bool prev_win_not_arc =
-      windows.size() > 1u && static_cast<ash::AppType>(windows[1]->GetProperty(
-                                 aura::client::kAppType)) != AppType::ARC_APP;
+      split_view_eligible_windows.size() > 1u &&
+      static_cast<ash::AppType>(split_view_eligible_windows[1]->GetProperty(
+          aura::client::kAppType)) != AppType::ARC_APP;
   std::vector<SplitViewController::SnapPosition> snap_positions;
-  if (active_window_state_type == mojom::WindowStateType::LEFT_SNAPPED) {
-    // The active window snapped on the left shall go there in split view.
+  if (wm::GetWindowState(split_view_eligible_windows[0])->GetStateType() ==
+      mojom::WindowStateType::LEFT_SNAPPED) {
+    // split_view_eligible_windows[0] goes on the left.
     snap_positions.push_back(SplitViewController::LEFT);
 
-    if (prev_win_not_arc && wm::GetWindowState(windows[1])->GetStateType() ==
-                                mojom::WindowStateType::RIGHT_SNAPPED) {
-      // The previous window snapped on the right shall go there in split view.
+    if (prev_win_not_arc &&
+        wm::GetWindowState(split_view_eligible_windows[1])->GetStateType() ==
+            mojom::WindowStateType::RIGHT_SNAPPED) {
+      // split_view_eligible_windows[1] goes on the right.
       snap_positions.push_back(SplitViewController::RIGHT);
     }
   } else {
-    DCHECK_EQ(mojom::WindowStateType::RIGHT_SNAPPED, active_window_state_type);
+    DCHECK_EQ(
+        mojom::WindowStateType::RIGHT_SNAPPED,
+        wm::GetWindowState(split_view_eligible_windows[0])->GetStateType());
 
-    // The active window snapped on the right shall go there in split view.
+    // split_view_eligible_windows[0] goes on the right.
     snap_positions.push_back(SplitViewController::RIGHT);
 
-    if (prev_win_not_arc && wm::GetWindowState(windows[1])->GetStateType() ==
-                                mojom::WindowStateType::LEFT_SNAPPED) {
-      // The previous window snapped on the left shall go there in split view.
+    if (prev_win_not_arc &&
+        wm::GetWindowState(split_view_eligible_windows[1])->GetStateType() ==
+            mojom::WindowStateType::LEFT_SNAPPED) {
+      // split_view_eligible_windows[1] goes on the left.
       snap_positions.push_back(SplitViewController::LEFT);
     }
   }
+
+  for (auto* window : activatable_windows) {
+    bool snap = false;
+    for (size_t i = 0u; i < snap_positions.size(); ++i) {
+      if (window == split_view_eligible_windows[i]) {
+        snap = true;
+        break;
+      }
+    }
+    TrackWindow(window, snap, /*animate_bounds_on_attach=*/false);
+  }
   SplitViewController* split_view_controller =
       Shell::Get()->split_view_controller();
-  for (size_t i = 0u; i < windows.size(); ++i) {
-    const bool snap = i < snap_positions.size();
-    TrackWindow(windows[i], snap, /*animate_bounds_on_attach=*/false);
-    if (snap)
-      split_view_controller->SnapWindow(windows[i], snap_positions[i]);
+  for (size_t i = 0u; i < snap_positions.size(); ++i) {
+    split_view_controller->SnapWindow(split_view_eligible_windows[i],
+                                      snap_positions[i]);
   }
 }
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 49e9b8e..97e3b0c 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -3170,7 +3170,6 @@
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java",
       "test/android/javatests/src/org/chromium/base/test/BaseTestResult.java",
       "test/android/javatests/src/org/chromium/base/test/LifetimeAssertRule.java",
-      "test/android/javatests/src/org/chromium/base/test/DestroyActivitiesRule.java",
       "test/android/javatests/src/org/chromium/base/test/ScreenshotOnFailureStatement.java",
       "test/android/javatests/src/org/chromium/base/test/SetUpTestRule.java",
       "test/android/javatests/src/org/chromium/base/test/SetUpStatement.java",
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
index 3b7c2b8..af3dc2f 100644
--- a/base/android/build_info.cc
+++ b/base/android/build_info.cc
@@ -75,7 +75,8 @@
       firebase_app_id_(StrDupParam(params, 18)),
       custom_themes_(StrDupParam(params, 19)),
       resources_version_(StrDupParam(params, 20)),
-      extracted_file_suffix_(params[21]) {}
+      extracted_file_suffix_(params[21]),
+      is_at_least_q_(GetIntParam(params, 22)) {}
 
 // static
 BuildInfo* BuildInfo::GetInstance() {
diff --git a/base/android/build_info.h b/base/android/build_info.h
index 9eec5aa..96be7ee 100644
--- a/base/android/build_info.h
+++ b/base/android/build_info.h
@@ -122,6 +122,8 @@
     return sdk_int_;
   }
 
+  bool is_at_least_q() const { return is_at_least_q_; }
+
  private:
   friend struct BuildInfoSingletonTraits;
 
@@ -154,6 +156,7 @@
   const char* const resources_version_;
   // Not needed by breakpad.
   const std::string extracted_file_suffix_;
+  const bool is_at_least_q_;
 
   DISALLOW_COPY_AND_ASSIGN(BuildInfo);
 };
diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java
index d83db2f6..775c316a 100644
--- a/base/android/java/src/org/chromium/base/ApplicationStatus.java
+++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
@@ -216,7 +216,7 @@
         }
     }
 
-    public static boolean isInitialized() {
+    private static boolean isInitialized() {
         synchronized (sActivityInfo) {
             return sCurrentApplicationState != ApplicationState.UNKNOWN;
         }
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index 3ad002d..df0034f 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -57,13 +57,29 @@
         BuildInfo buildInfo = getInstance();
         String hostPackageName = ContextUtils.getApplicationContext().getPackageName();
         return new String[] {
-                Build.BRAND, Build.DEVICE, Build.ID, Build.MANUFACTURER, Build.MODEL,
-                String.valueOf(Build.VERSION.SDK_INT), Build.TYPE, Build.BOARD, hostPackageName,
-                String.valueOf(buildInfo.hostVersionCode), buildInfo.hostPackageLabel,
-                buildInfo.packageName, String.valueOf(buildInfo.versionCode), buildInfo.versionName,
-                buildInfo.androidBuildFingerprint, buildInfo.gmsVersionCode,
-                buildInfo.installerPackageName, buildInfo.abiString, BuildConfig.FIREBASE_APP_ID,
-                buildInfo.customThemes, buildInfo.resourcesVersion, buildInfo.extractedFileSuffix,
+                Build.BRAND,
+                Build.DEVICE,
+                Build.ID,
+                Build.MANUFACTURER,
+                Build.MODEL,
+                String.valueOf(Build.VERSION.SDK_INT),
+                Build.TYPE,
+                Build.BOARD,
+                hostPackageName,
+                String.valueOf(buildInfo.hostVersionCode),
+                buildInfo.hostPackageLabel,
+                buildInfo.packageName,
+                String.valueOf(buildInfo.versionCode),
+                buildInfo.versionName,
+                buildInfo.androidBuildFingerprint,
+                buildInfo.gmsVersionCode,
+                buildInfo.installerPackageName,
+                buildInfo.abiString,
+                BuildConfig.FIREBASE_APP_ID,
+                buildInfo.customThemes,
+                buildInfo.resourcesVersion,
+                buildInfo.extractedFileSuffix,
+                isAtLeastQ() ? "1" : "0",
         };
     }
 
diff --git a/base/bind.h b/base/bind.h
index 5adc68c..df287dc 100644
--- a/base/bind.h
+++ b/base/bind.h
@@ -6,6 +6,7 @@
 #define BASE_BIND_H_
 
 #include <functional>
+#include <memory>
 #include <utility>
 
 #include "base/bind_internal.h"
@@ -386,6 +387,11 @@
   return internal::OwnedWrapper<T>(o);
 }
 
+template <typename T>
+static inline internal::OwnedWrapper<T> Owned(std::unique_ptr<T>&& ptr) {
+  return internal::OwnedWrapper<T>(std::move(ptr));
+}
+
 // Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr)
 // through a Callback. Logically, this signifies a destructive transfer of
 // the state of the argument into the target function.  Invoking
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 261a2e8..b2f1c3c 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <functional>
+#include <memory>
 #include <tuple>
 #include <type_traits>
 #include <utility>
@@ -103,26 +104,15 @@
   T functor_;
 };
 
-// An alternate implementation is to avoid the destructive copy, and instead
-// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to
-// a class that is essentially a std::unique_ptr<>.
-//
-// The current implementation has the benefit though of leaving ParamTraits<>
-// fully in callback_internal.h as well as avoiding type conversions during
-// storage.
 template <typename T>
 class OwnedWrapper {
  public:
   explicit OwnedWrapper(T* o) : ptr_(o) {}
-  ~OwnedWrapper() { delete ptr_; }
-  T* get() const { return ptr_; }
-  OwnedWrapper(OwnedWrapper&& other) {
-    ptr_ = other.ptr_;
-    other.ptr_ = NULL;
-  }
+  explicit OwnedWrapper(std::unique_ptr<T>&& ptr) : ptr_(std::move(ptr)) {}
+  T* get() const { return ptr_.get(); }
 
  private:
-  mutable T* ptr_;
+  std::unique_ptr<T> ptr_;
 };
 
 // PassedWrapper is a copyable adapter for a scoper that ignores const.
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index a19f39f..161927f 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -699,7 +699,7 @@
 }
 
 // Test Owned() support.
-TEST_F(BindTest, OwnedForRepeating) {
+TEST_F(BindTest, OwnedForRepeatingRawPtr) {
   int deletes = 0;
   DeleteCounter* counter = new DeleteCounter(&deletes);
 
@@ -723,7 +723,7 @@
   EXPECT_EQ(1, deletes);
 }
 
-TEST_F(BindTest, OwnedForOnce) {
+TEST_F(BindTest, OwnedForOnceRawPtr) {
   int deletes = 0;
   DeleteCounter* counter = new DeleteCounter(&deletes);
 
@@ -744,6 +744,52 @@
   EXPECT_EQ(1, deletes);
 }
 
+TEST_F(BindTest, OwnedForRepeatingUniquePtr) {
+  int deletes = 0;
+  auto counter = std::make_unique<DeleteCounter>(&deletes);
+  DeleteCounter* raw_counter = counter.get();
+
+  // If we don't capture, delete happens on Callback destruction/reset.
+  // return the same value.
+  RepeatingCallback<DeleteCounter*()> no_capture_cb = BindRepeating(
+      &PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
+  ASSERT_EQ(raw_counter, no_capture_cb.Run());
+  ASSERT_EQ(raw_counter, no_capture_cb.Run());
+  EXPECT_EQ(0, deletes);
+  no_capture_cb.Reset();  // This should trigger a delete.
+  EXPECT_EQ(1, deletes);
+
+  deletes = 0;
+  counter = std::make_unique<DeleteCounter>(&deletes);
+  RepeatingClosure own_object_cb =
+      BindRepeating(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
+  own_object_cb.Run();
+  EXPECT_EQ(0, deletes);
+  own_object_cb.Reset();
+  EXPECT_EQ(1, deletes);
+}
+
+TEST_F(BindTest, OwnedForOnceUniquePtr) {
+  int deletes = 0;
+  auto counter = std::make_unique<DeleteCounter>(&deletes);
+
+  // If we don't capture, delete happens on Callback destruction/reset.
+  // return the same value.
+  OnceCallback<DeleteCounter*()> no_capture_cb =
+      BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
+  EXPECT_EQ(0, deletes);
+  no_capture_cb.Reset();  // This should trigger a delete.
+  EXPECT_EQ(1, deletes);
+
+  deletes = 0;
+  counter = std::make_unique<DeleteCounter>(&deletes);
+  OnceClosure own_object_cb =
+      BindOnce(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
+  EXPECT_EQ(0, deletes);
+  own_object_cb.Reset();
+  EXPECT_EQ(1, deletes);
+}
+
 template <typename T>
 class BindVariantsTest : public ::testing::Test {
 };
@@ -1468,10 +1514,20 @@
 }
 
 TEST_F(BindTest, UnwrapOwned) {
-  int* p = new int;
-  auto owned = Owned(p);
-  EXPECT_EQ(p, internal::Unwrap(owned));
-  EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
+  {
+    int* p = new int;
+    auto owned = Owned(p);
+    EXPECT_EQ(p, internal::Unwrap(owned));
+    EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
+  }
+
+  {
+    auto p = std::make_unique<int>();
+    int* raw_p = p.get();
+    auto owned = Owned(std::move(p));
+    EXPECT_EQ(raw_p, internal::Unwrap(owned));
+    EXPECT_EQ(raw_p, internal::Unwrap(std::move(owned)));
+  }
 }
 
 TEST_F(BindTest, UnwrapPassed) {
diff --git a/base/files/file_util.cc b/base/files/file_util.cc
index 02c7934..c6481c5 100644
--- a/base/files/file_util.cc
+++ b/base/files/file_util.cc
@@ -295,6 +295,16 @@
 
   return -1;
 }
+
+FilePath GetUniquePath(const FilePath& path) {
+  FilePath unique_path = path;
+  int uniquifier = GetUniquePathNumber(path, FilePath::StringType());
+  if (uniquifier > 0) {
+    unique_path = unique_path.InsertBeforeExtensionASCII(
+        StringPrintf(" (%d)", uniquifier));
+  }
+  return unique_path;
+}
 #endif  // !defined(OS_NACL_NONSFI)
 
 }  // namespace base
diff --git a/base/files/file_util.h b/base/files/file_util.h
index 456962a..d87fae1 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -396,6 +396,10 @@
 BASE_EXPORT int GetUniquePathNumber(const FilePath& path,
                                     const FilePath::StringType& suffix);
 
+// If file at |path| already exists, modifies filename portion of |path| to
+// return unique path.
+BASE_EXPORT FilePath GetUniquePath(const FilePath& path);
+
 // Sets the given |fd| to non-blocking mode.
 // Returns true if it was able to set it in the non-blocking mode, otherwise
 // false.
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc
index ce475be..55c51fa 100644
--- a/base/files/file_util_unittest.cc
+++ b/base/files/file_util_unittest.cc
@@ -2438,6 +2438,45 @@
   }
 }
 
+TEST_F(FileUtilTest, GetUniquePathTest) {
+  // Create a unique temp directory and use it to generate a unique file path.
+  base::ScopedTempDir temp_dir;
+  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
+  EXPECT_TRUE(temp_dir.IsValid());
+  FilePath base_name(FILE_PATH_LITERAL("Unique_Base_Name.txt"));
+  FilePath base_path = temp_dir.GetPath().Append(base_name);
+  EXPECT_FALSE(PathExists(base_path));
+
+  // GetUniquePath() should return unchanged path if file does not exist.
+  EXPECT_EQ(base_path, GetUniquePath(base_path));
+
+  // Create the file.
+  File file(base_path, File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
+  EXPECT_TRUE(PathExists(base_path));
+
+  static const FilePath::CharType* const kExpectedNames[] = {
+      FILE_PATH_LITERAL("Unique_Base_Name (1).txt"),
+      FILE_PATH_LITERAL("Unique_Base_Name (2).txt"),
+      FILE_PATH_LITERAL("Unique_Base_Name (3).txt"),
+  };
+
+  // Call GetUniquePath() three times against this existing file name.
+  for (const FilePath::CharType* expected_name : kExpectedNames) {
+    FilePath expected_path = temp_dir.GetPath().Append(expected_name);
+    FilePath path = GetUniquePath(base_path);
+    EXPECT_EQ(expected_path, path);
+
+    // Verify that a file with this path indeed does not exist on the file
+    // system.
+    EXPECT_FALSE(PathExists(path));
+
+    // Create the file so it exists for the next call to GetUniquePath() in the
+    // loop.
+    File file(path, File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE);
+    EXPECT_TRUE(PathExists(path));
+  }
+}
+
 #if defined(OS_FUCHSIA)
 // TODO(crbug.com/851747): Re-enable when the Fuchsia-side fix for fdopen has
 // been rolled into Chromium.
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h
index ebbc4e5..76c0ed2e 100644
--- a/base/message_loop/message_pump.h
+++ b/base/message_loop/message_pump.h
@@ -167,10 +167,13 @@
   virtual void ScheduleWork() = 0;
 
   // Schedule a DoDelayedWork callback to happen at the specified time,
-  // cancelling any pending DoDelayedWork callback.  This method may only be
-  // used on the thread that called Run.
-  // TODO(gab): This method is obsolete in the DoSomeWork() variant, remove it
-  // once the migration is complete.
+  // cancelling any pending DoDelayedWork callback. This method may only be used
+  // on the thread that called Run.
+  //
+  // This is mostly a no-op in the DoSomeWork() world but must still be invoked
+  // when the new |delayed_work_time| is sooner than the last one returned from
+  // DoSomeWork(). TODO(gab): Clarify this API once all pumps have been
+  // migrated.
   virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
 
   // Sets the timer slack to the specified value.
diff --git a/base/message_loop/message_pump_unittest.cc b/base/message_loop/message_pump_unittest.cc
index 2579612..616aa6b 100644
--- a/base/message_loop/message_pump_unittest.cc
+++ b/base/message_loop/message_pump_unittest.cc
@@ -30,18 +30,22 @@
 #else
       return true;
 #endif
+
     case MessageLoopBase::Type::TYPE_UI:
 #if defined(OS_IOS)
       // iOS uses a MessagePumpDefault for UI in unit tests, ref.
       // test_support_ios.mm::CreateMessagePumpForUIForTests().
       return true;
+#elif defined(OS_WIN)
+      return true;
 #else
       // TODO(gab): Complete migration of all UI pumps to DoSomeWork() as part
       // of crbug.com/885371.
       return false;
 #endif
+
     case MessageLoopBase::Type::TYPE_IO:
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
       return true;
 #else
       // TODO(gab): Complete migration of all IO pumps to DoSomeWork() as part
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 9de7721..3e9562c 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -4,19 +4,16 @@
 
 #include "base/message_loop/message_pump_win.h"
 
-#include <math.h>
-#include <stdint.h>
-
-#include <limits>
+#include <algorithm>
+#include <cstdint>
+#include <type_traits>
 
 #include "base/bind.h"
 #include "base/debug/alias.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
+#include "base/numerics/ranges.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/trace_event/trace_event.h"
-#include "base/win/current_module.h"
-#include "base/win/wrapped_window_proc.h"
 
 namespace base {
 
@@ -30,6 +27,27 @@
   MESSAGE_LOOP_PROBLEM_MAX,
 };
 
+// Returns the number of milliseconds before |next_task_time|, clamped between
+// zero and the biggest DWORD value (or INFINITE if |next_task_time.is_max()|).
+// Optionally, a recent value of Now() may be passed in to avoid resampling it.
+DWORD GetSleepTimeoutMs(TimeTicks next_task_time,
+                        TimeTicks recent_now = TimeTicks()) {
+  // Shouldn't need to sleep or install a timer when there's pending immediate
+  // work.
+  DCHECK(!next_task_time.is_null());
+
+  if (next_task_time.is_max())
+    return INFINITE;
+
+  auto now = recent_now.is_null() ? TimeTicks::Now() : recent_now;
+  auto timeout_ms = (next_task_time - now).InMillisecondsRoundedUp();
+
+  // A saturated_cast with an unsigned destination automatically clamps negative
+  // values at zero.
+  static_assert(!std::is_signed<DWORD>::value, "DWORD is unexpectedly signed");
+  return saturated_cast<DWORD>(timeout_ms);
+}
+
 }  // namespace
 
 // Message sent to get an additional time slice for pumping (processing) another
@@ -43,6 +61,8 @@
 MessagePumpWin::~MessagePumpWin() = default;
 
 void MessagePumpWin::Run(Delegate* delegate) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   RunState s;
   s.delegate = delegate;
   s.should_quit = false;
@@ -57,33 +77,13 @@
 }
 
 void MessagePumpWin::Quit() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   DCHECK(state_);
   state_->should_quit = true;
 }
 
 //-----------------------------------------------------------------------------
-// MessagePumpWin protected:
-
-int MessagePumpWin::GetCurrentDelay() const {
-  if (delayed_work_time_.is_null())
-    return -1;
-
-  // Be careful here.  TimeDelta has a precision of microseconds, but we want a
-  // value in milliseconds.  If there are 5.5ms left, should the delay be 5 or
-  // 6?  It should be 6 to avoid executing delayed work too early.
-  double timeout =
-      ceil((delayed_work_time_ - TimeTicks::Now()).InMillisecondsF());
-
-  // Range check the |timeout| while converting to an integer.  If the |timeout|
-  // is negative, then we need to run delayed work soon.  If the |timeout| is
-  // "overflowingly" large, that means a delayed task was posted with a
-  // super-long delay.
-  return timeout < 0 ? 0 :
-      (timeout > std::numeric_limits<int>::max() ?
-       std::numeric_limits<int>::max() : static_cast<int>(timeout));
-}
-
-//-----------------------------------------------------------------------------
 // MessagePumpForUI public:
 
 MessagePumpForUI::MessagePumpForUI() {
@@ -95,6 +95,9 @@
 MessagePumpForUI::~MessagePumpForUI() = default;
 
 void MessagePumpForUI::ScheduleWork() {
+  // This is the only MessagePumpForUI method which can be called outside of
+  // |bound_thread_|.
+
   bool not_scheduled = false;
   if (!work_scheduled_.compare_exchange_strong(not_scheduled, true))
     return;  // Someone else continued the pumping.
@@ -120,19 +123,42 @@
 }
 
 void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
-  delayed_work_time_ = delayed_work_time;
-  RescheduleTimer();
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // Since this is always called from |bound_thread_|, there is almost always
+  // nothing to do as the loop is already running. When the loop becomes idle,
+  // it will typically WaitForWork() in DoRunLoop() with the timeout provided by
+  // DoSomeWork(). The only alternative to this is entering a native nested loop
+  // (e.g. modal dialog) under a ScopedNestableTaskAllower, in which case
+  // HandleWorkMessage() will be invoked when the system picks up kMsgHaveWork
+  // and it will ScheduleNativeTimer() if it's out of immediate work. However,
+  // in that alternate scenario : it's possible for a Windows native task (e.g.
+  // https://docs.microsoft.com/en-us/windows/desktop/winmsg/using-hooks) to
+  // wake the native nested loop and PostDelayedTask() to the current thread
+  // from it. This is the only case where we must install/adjust the native
+  // timer from ScheduleDelayedWork() because if we don't, the native loop will
+  // go back to sleep, unaware of the new |delayed_work_time|.
+  // TODO(gab): This could potentially be replaced by a ForegroundIdleProc hook
+  // if Windows ends up being the only platform requiring ScheduleDelayedWork().
+  if (in_native_loop_ && !work_scheduled_) {
+    // TODO(gab): Consider passing a NextWorkInfo object to ScheduleDelayedWork
+    // to take advantage of |recent_now| here too.
+    ScheduleNativeTimer({delayed_work_time, TimeTicks::Now()});
+  }
 }
 
 void MessagePumpForUI::EnableWmQuit() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   enable_wm_quit_ = true;
 }
 
 void MessagePumpForUI::AddObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   observers_.AddObserver(observer);
 }
 
 void MessagePumpForUI::RemoveObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   observers_.RemoveObserver(observer);
 }
 
@@ -141,18 +167,22 @@
 
 bool MessagePumpForUI::MessageCallback(
     UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
   switch (message) {
     case kMsgHaveWork:
       HandleWorkMessage();
       break;
     case WM_TIMER:
-      HandleTimerMessage();
+      if (wparam == reinterpret_cast<UINT_PTR>(this))
+        HandleTimerMessage();
       break;
   }
   return false;
 }
 
 void MessagePumpForUI::DoRunLoop() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // IF this was just a simple PeekMessage() loop (servicing all possible work
   // queues), then Windows would try to achieve the following order according
   // to MSDN documentation about PeekMessage with no filter):
@@ -175,30 +205,37 @@
     // work, then it is a good time to consider sleeping (waiting) for more
     // work.
 
+    in_native_loop_ = false;
     state_->delegate->BeforeDoInternalWork();
+    DCHECK(!in_native_loop_);
+
     bool more_work_is_plausible = ProcessNextWindowsMessage();
+    in_native_loop_ = false;
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |= state_->delegate->DoWork();
+    Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+    in_native_loop_ = false;
+    more_work_is_plausible |= next_work_info.is_immediate();
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |=
-        state_->delegate->DoDelayedWork(&delayed_work_time_);
-    // If we did not process any delayed work, then we can assume that our
-    // existing WM_TIMER if any will fire when delayed work should run.  We
-    // don't want to disturb that timer if it is already in flight.  However,
-    // if we did do all remaining delayed work, then lets kill the WM_TIMER.
-    if (more_work_is_plausible && delayed_work_time_.is_null())
-      KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
-    if (state_->should_quit)
-      break;
+    if (installed_native_timer_) {
+      // As described in ScheduleNativeTimer(), the native timer is only
+      // installed and needed while in a nested native loop. If it is installed,
+      // it means the above work entered such a loop. Having now resumed, the
+      // native timer is no longer needed.
+      KillNativeTimer();
+    }
 
     if (more_work_is_plausible)
       continue;
 
     more_work_is_plausible = state_->delegate->DoIdleWork();
+    // DoIdleWork() shouldn't end up in native nested loops and thus shouldn't
+    // have any chance of reinstalling a native timer.
+    DCHECK(!in_native_loop_);
+    DCHECK(!installed_native_timer_);
     if (state_->should_quit)
       break;
 
@@ -207,20 +244,19 @@
 
     // WaitForWork() does some work itself, so notify the delegate of it.
     state_->delegate->BeforeDoInternalWork();
-    WaitForWork();  // Wait (sleep) until we have work to do again.
+    WaitForWork(next_work_info);
   }
 }
 
-void MessagePumpForUI::WaitForWork() {
+void MessagePumpForUI::WaitForWork(Delegate::NextWorkInfo next_work_info) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // Wait until a message is available, up to the time needed by the timer
   // manager to fire the next set of timers.
-  int delay;
   DWORD wait_flags = MWMO_INPUTAVAILABLE;
-
-  while ((delay = GetCurrentDelay()) != 0) {
-    if (delay < 0)  // Negative value means no timers waiting.
-      delay = INFINITE;
-
+  for (DWORD delay = GetSleepTimeoutMs(next_work_info.delayed_run_time,
+                                       next_work_info.recent_now);
+       delay != 0; delay = GetSleepTimeoutMs(next_work_info.delayed_run_time)) {
     // Tell the optimizer to retain these values to simplify analyzing hangs.
     base::debug::Alias(&delay);
     base::debug::Alias(&wait_flags);
@@ -260,6 +296,12 @@
 }
 
 void MessagePumpForUI::HandleWorkMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // The kMsgHaveWork message was consumed by a native loop, we must assume
+  // we're in one until DoRunLoop() gets control back.
+  in_native_loop_ = true;
+
   // If we are being called outside of the context of Run, then don't try to do
   // any work.  This could correspond to a MessageBox call or something of that
   // sort.
@@ -274,16 +316,30 @@
   // messages that may be in the Windows message queue.
   ProcessPumpReplacementMessage();
 
-  // Now give the delegate a chance to do some work.  It'll let us know if it
-  // needs to do more work.
-  if (state_->delegate->DoWork())
+  Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+  if (next_work_info.is_immediate()) {
     ScheduleWork();
-  state_->delegate->DoDelayedWork(&delayed_work_time_);
-  RescheduleTimer();
+  } else {
+    ScheduleNativeTimer(next_work_info);
+  }
 }
 
 void MessagePumpForUI::HandleTimerMessage() {
-  KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // ::KillTimer doesn't remove pending WM_TIMER messages from the queue,
+  // explicitly ignore the last WM_TIMER message in that case to avoid handling
+  // work from here when DoRunLoop() is active (which could result in scheduling
+  // work from two places at once). Note: we're still fine in the event that a
+  // second native nested loop is entered before such a dead WM_TIMER message is
+  // discarded because ::SetTimer merely resets the timer if invoked twice with
+  // the same id.
+  if (!installed_native_timer_)
+    return;
+
+  // We only need to fire once per specific delay, another timer may be
+  // scheduled below but we're done with this one.
+  KillNativeTimer();
 
   // If we are being called outside of the context of Run, then don't do
   // anything.  This could correspond to a MessageBox call or something of
@@ -291,46 +347,69 @@
   if (!state_)
     return;
 
-  state_->delegate->DoDelayedWork(&delayed_work_time_);
-  RescheduleTimer();
+  Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+  if (next_work_info.is_immediate()) {
+    ScheduleWork();
+  } else {
+    ScheduleNativeTimer(next_work_info);
+  }
 }
 
-void MessagePumpForUI::RescheduleTimer() {
-  if (delayed_work_time_.is_null())
+void MessagePumpForUI::ScheduleNativeTimer(
+    Delegate::NextWorkInfo next_work_info) {
+  DCHECK(!next_work_info.is_immediate());
+  DCHECK(in_native_loop_);
+
+  // Do not redundantly set the same native timer again if it was already set.
+  // This can happen when a nested native loop goes idle with pending delayed
+  // tasks, then gets woken up by an immediate task, and goes back to idle with
+  // the same pending delay. No need to kill the native timer if there is
+  // already one but the |delayed_run_time| has changed as ::SetTimer reuses the
+  // same id and will replace and reset the existing timer.
+  if (installed_native_timer_ &&
+      *installed_native_timer_ == next_work_info.delayed_run_time) {
     return;
-  //
-  // We would *like* to provide high resolution timers.  Windows timers using
-  // SetTimer() have a 10ms granularity.  We have to use WM_TIMER as a wakeup
-  // mechanism because the application can enter modal windows loops where it
-  // is not running our MessageLoop; the only way to have our timers fire in
-  // these cases is to post messages there.
-  //
-  // To provide sub-10ms timers, we process timers directly from our run loop.
-  // For the common case, timers will be processed there as the run loop does
-  // its normal work.  However, we *also* set the system timer so that WM_TIMER
-  // events fire.  This mops up the case of timers not being able to work in
-  // modal message loops.  It is possible for the SetTimer to pop and have no
-  // pending timers, because they could have already been processed by the
-  // run loop itself.
-  //
-  // We use a single SetTimer corresponding to the timer that will expire
-  // soonest.  As new timers are created and destroyed, we update SetTimer.
-  // Getting a spurious SetTimer event firing is benign, as we'll just be
-  // processing an empty timer queue.
-  //
-  int delay_msec = GetCurrentDelay();
-  DCHECK_GE(delay_msec, 0);
+  }
+
+  if (next_work_info.delayed_run_time.is_max())
+    return;
+
+  // We do not use native Windows timers in general as they have a poor, 10ms,
+  // granularity. Instead we rely on MsgWaitForMultipleObjectsEx's
+  // high-resolution timeout to sleep without timers in WaitForWork(). However,
+  // when entering a nested native ::GetMessage() loop (e.g. native modal
+  // windows) under a ScopedNestableTaskAllower, we have to rely on a native
+  // timer when HandleWorkMessage() runs out of immediate work. Since
+  // ScopedNestableTaskAllower invokes ScheduleWork() : we are guaranteed that
+  // HandleWorkMessage() will be called after entering a nested native loop that
+  // should process application tasks. But once HandleWorkMessage() is out of
+  // immediate work, ::SetTimer() is used to guarantee we are invoked again
+  // should the next delayed task expire before the nested native loop ends. The
+  // native timer being unnecessary once we return to our DoRunLoop(), we
+  // ::KillTimer when it resumes (nested native loops should be rare so we're
+  // not worried about ::SetTimer<=>::KillTimer churn).
+  // TODO(gab): The long-standing legacy dependency on the behavior of
+  // ScopedNestableTaskAllower is unfortunate, would be nice to make this a
+  // MessagePump concept (instead of requiring impls to invoke ScheduleWork()
+  // one-way and no-op DoWork() the other way).
+
+  UINT delay_msec = strict_cast<UINT>(GetSleepTimeoutMs(
+      next_work_info.delayed_run_time, next_work_info.recent_now));
   if (delay_msec == 0) {
     ScheduleWork();
   } else {
-    if (delay_msec < USER_TIMER_MINIMUM)
-      delay_msec = USER_TIMER_MINIMUM;
+    // TODO(gab): ::SetTimer()'s documentation claims it does this for us.
+    // Consider removing this safety net.
+    delay_msec = ClampToRange(delay_msec, UINT(USER_TIMER_MINIMUM),
+                              UINT(USER_TIMER_MAXIMUM));
 
-    // Tell the optimizer to retain these values to simplify analyzing hangs.
+    // Tell the optimizer to retain the delay to simplify analyzing hangs.
     base::debug::Alias(&delay_msec);
-    // Create a WM_TIMER event that will wake us up to check for any pending
-    // timers (in case we are running within a nested, external sub-pump).
-    UINT_PTR ret = SetTimer(message_window_.hwnd(), 0, delay_msec, nullptr);
+    UINT_PTR ret =
+        ::SetTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this),
+                   delay_msec, nullptr);
+    installed_native_timer_ = next_work_info.delayed_run_time;
+
     if (ret)
       return;
     // If we can't set timers, we are in big trouble... but cross our fingers
@@ -341,11 +420,21 @@
   }
 }
 
+void MessagePumpForUI::KillNativeTimer() {
+  DCHECK(installed_native_timer_);
+  const bool success =
+      ::KillTimer(message_window_.hwnd(), reinterpret_cast<UINT_PTR>(this));
+  DPCHECK(success);
+  installed_native_timer_.reset();
+}
+
 bool MessagePumpForUI::ProcessNextWindowsMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // If there are sent messages in the queue then PeekMessage internally
   // dispatches the message and returns false. We return true in this
   // case to ensure that the message loop peeks again instead of calling
-  // MsgWaitForMultipleObjectsEx again.
+  // MsgWaitForMultipleObjectsEx.
   bool sent_messages_in_queue = false;
   DWORD queue_status = ::GetQueueStatus(QS_SENDMESSAGE);
   if (HIWORD(queue_status) & QS_SENDMESSAGE)
@@ -359,6 +448,8 @@
 }
 
 bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   TRACE_EVENT1("base,toplevel", "MessagePumpForUI::ProcessMessageHelper",
                "message", msg.message);
   if (WM_QUIT == msg.message) {
@@ -390,6 +481,8 @@
 }
 
 bool MessagePumpForUI::ProcessPumpReplacementMessage() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // When we encounter a kMsgHaveWork message, this method is called to peek and
   // process a replacement message. The goal is to make the kMsgHaveWork as non-
   // intrusive as possible, even though a continuous stream of such messages are
@@ -452,22 +545,25 @@
 }
 
 MessagePumpForIO::MessagePumpForIO() {
-  port_.Set(CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
-      reinterpret_cast<ULONG_PTR>(nullptr), 1));
+  port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
+                                     reinterpret_cast<ULONG_PTR>(nullptr), 1));
   DCHECK(port_.IsValid());
 }
 
 MessagePumpForIO::~MessagePumpForIO() = default;
 
 void MessagePumpForIO::ScheduleWork() {
+  // This is the only MessagePumpForIO method which can be called outside of
+  // |bound_thread_|.
+
   bool not_scheduled = false;
   if (!work_scheduled_.compare_exchange_strong(not_scheduled, true))
     return;  // Someone else continued the pumping.
 
   // Make sure the MessagePump does some work for us.
-  BOOL ret = PostQueuedCompletionStatus(port_.Get(), 0,
-                                        reinterpret_cast<ULONG_PTR>(this),
-                                        reinterpret_cast<OVERLAPPED*>(this));
+  BOOL ret = ::PostQueuedCompletionStatus(port_.Get(), 0,
+                                          reinterpret_cast<ULONG_PTR>(this),
+                                          reinterpret_cast<OVERLAPPED*>(this));
   if (ret)
     return;  // Post worked perfectly.
 
@@ -479,34 +575,40 @@
 }
 
 void MessagePumpForIO::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
-  // We know that we can't be blocked right now since this method can only be
-  // called on the same thread as Run, so we only need to update our record of
-  // how long to sleep when we do sleep.
-  delayed_work_time_ = delayed_work_time;
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  // Since this is always called from |bound_thread_|, there is nothing to do as
+  // the loop is already running. It will WaitForWork() in
+  // DoRunLoop() with the correct timeout when it's out of immediate tasks.
 }
 
 HRESULT MessagePumpForIO::RegisterIOHandler(HANDLE file_handle,
                                             IOHandler* handler) {
-  HANDLE port = CreateIoCompletionPort(file_handle, port_.Get(),
-                                       reinterpret_cast<ULONG_PTR>(handler), 1);
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
+  HANDLE port = ::CreateIoCompletionPort(
+      file_handle, port_.Get(), reinterpret_cast<ULONG_PTR>(handler), 1);
   return (port != nullptr) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
 }
 
 bool MessagePumpForIO::RegisterJobObject(HANDLE job_handle,
                                          IOHandler* handler) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   JOBOBJECT_ASSOCIATE_COMPLETION_PORT info;
   info.CompletionKey = handler;
   info.CompletionPort = port_.Get();
-  return SetInformationJobObject(job_handle,
-                                 JobObjectAssociateCompletionPortInformation,
-                                 &info,
-                                 sizeof(info)) != FALSE;
+  return ::SetInformationJobObject(job_handle,
+                                   JobObjectAssociateCompletionPortInformation,
+                                   &info, sizeof(info)) != FALSE;
 }
 
 //-----------------------------------------------------------------------------
 // MessagePumpForIO private:
 
 void MessagePumpForIO::DoRunLoop() {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   for (;;) {
     // If we do any work, we may create more messages etc., and more work may
     // possibly be waiting in another task group.  When we (for example)
@@ -517,7 +619,8 @@
     // had no work, then it is a good time to consider sleeping (waiting) for
     // more work.
 
-    bool more_work_is_plausible = state_->delegate->DoWork();
+    Delegate::NextWorkInfo next_work_info = state_->delegate->DoSomeWork();
+    bool more_work_is_plausible = next_work_info.is_immediate();
     if (state_->should_quit)
       break;
 
@@ -525,11 +628,6 @@
     if (state_->should_quit)
       break;
 
-    more_work_is_plausible |=
-        state_->delegate->DoDelayedWork(&delayed_work_time_);
-    if (state_->should_quit)
-      break;
-
     if (more_work_is_plausible)
       continue;
 
@@ -540,20 +638,21 @@
     if (more_work_is_plausible)
       continue;
 
-    WaitForWork();  // Wait (sleep) until we have work to do again.
+    WaitForWork(next_work_info);
   }
 }
 
 // Wait until IO completes, up to the time needed by the timer manager to fire
 // the next set of timers.
-void MessagePumpForIO::WaitForWork() {
+void MessagePumpForIO::WaitForWork(Delegate::NextWorkInfo next_work_info) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   // We do not support nested IO message loops. This is to avoid messy
   // recursion problems.
   DCHECK_EQ(1, state_->run_depth) << "Cannot nest an IO message loop!";
 
-  int timeout = GetCurrentDelay();
-  if (timeout < 0)  // Negative value means no timers waiting.
-    timeout = INFINITE;
+  DWORD timeout = GetSleepTimeoutMs(next_work_info.delayed_run_time,
+                                    next_work_info.recent_now);
 
   // Tell the optimizer to retain these values to simplify analyzing hangs.
   base::debug::Alias(&timeout);
@@ -561,6 +660,8 @@
 }
 
 bool MessagePumpForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   IOItem item;
   if (completed_io_.empty() || !MatchCompletedIOItem(filter, &item)) {
     // We have to ask the system for another IO completion.
@@ -583,11 +684,13 @@
 
 // Asks the OS for another IO completion result.
 bool MessagePumpForIO::GetIOItem(DWORD timeout, IOItem* item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   memset(item, 0, sizeof(*item));
   ULONG_PTR key = reinterpret_cast<ULONG_PTR>(nullptr);
   OVERLAPPED* overlapped = nullptr;
-  if (!GetQueuedCompletionStatus(port_.Get(), &item->bytes_transfered, &key,
-                                 &overlapped, timeout)) {
+  if (!::GetQueuedCompletionStatus(port_.Get(), &item->bytes_transfered, &key,
+                                   &overlapped, timeout)) {
     if (!overlapped)
       return false;  // Nothing in the queue.
     item->error = GetLastError();
@@ -600,6 +703,8 @@
 }
 
 bool MessagePumpForIO::ProcessInternalIOItem(const IOItem& item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   if (reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.context) &&
       reinterpret_cast<void*>(this) == reinterpret_cast<void*>(item.handler)) {
     // This is our internal completion.
@@ -612,6 +717,8 @@
 
 // Returns a completion item that was previously received.
 bool MessagePumpForIO::MatchCompletedIOItem(IOHandler* filter, IOItem* item) {
+  DCHECK_CALLED_ON_VALID_THREAD(bound_thread_);
+
   DCHECK(!completed_io_.empty());
   for (std::list<IOItem>::iterator it = completed_io_.begin();
        it != completed_io_.end(); ++it) {
diff --git a/base/message_loop/message_pump_win.h b/base/message_loop/message_pump_win.h
index e9db712..151c5bf 100644
--- a/base/message_loop/message_pump_win.h
+++ b/base/message_loop/message_pump_win.h
@@ -14,6 +14,8 @@
 #include "base/base_export.h"
 #include "base/message_loop/message_pump.h"
 #include "base/observer_list.h"
+#include "base/optional.h"
+#include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "base/win/message_window.h"
 #include "base/win/scoped_handle.h"
@@ -44,10 +46,6 @@
   };
 
   virtual void DoRunLoop() = 0;
-  int GetCurrentDelay() const;
-
-  // The time at which delayed work should run.
-  TimeTicks delayed_work_time_;
 
   // True iff:
   //   * MessagePumpForUI: there's a kMsgDoWork message pending in the Windows
@@ -74,6 +72,8 @@
 
   // State for the current invocation of Run.
   RunState* state_ = nullptr;
+
+  THREAD_CHECKER(bound_thread_);
 };
 
 //-----------------------------------------------------------------------------
@@ -151,10 +151,11 @@
   bool MessageCallback(
       UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result);
   void DoRunLoop() override;
-  void WaitForWork();
+  void WaitForWork(Delegate::NextWorkInfo next_work_info);
   void HandleWorkMessage();
   void HandleTimerMessage();
-  void RescheduleTimer();
+  void ScheduleNativeTimer(Delegate::NextWorkInfo next_work_info);
+  void KillNativeTimer();
   bool ProcessNextWindowsMessage();
   bool ProcessMessageHelper(const MSG& msg);
   bool ProcessPumpReplacementMessage();
@@ -165,6 +166,16 @@
   // TODO(thestig): Remove when the Cloud Print Service goes away.
   bool enable_wm_quit_ = false;
 
+  // Non-nullopt if there's currently a native timer installed. If so, it
+  // indicates when the timer is set to fire and can be used to avoid setting
+  // redundant timers.
+  Optional<TimeTicks> installed_native_timer_;
+
+  // This will become true when a native loop takes our kMsgHaveWork out of the
+  // system queue. It will be reset to false whenever DoRunLoop regains control.
+  // Used to decide whether ScheduleDelayedWork() should start a native timer.
+  bool in_native_loop_ = false;
+
   ObserverList<Observer>::Unchecked observers_;
 };
 
@@ -266,7 +277,7 @@
   };
 
   void DoRunLoop() override;
-  void WaitForWork();
+  void WaitForWork(Delegate::NextWorkInfo next_work_info);
   bool MatchCompletedIOItem(IOHandler* filter, IOItem* item);
   bool GetIOItem(DWORD timeout, IOItem* item);
   bool ProcessInternalIOItem(const IOItem& item);
diff --git a/base/profiler/native_stack_sampler_mac.cc b/base/profiler/native_stack_sampler_mac.cc
index 07825b1..7d74166e 100644
--- a/base/profiler/native_stack_sampler_mac.cc
+++ b/base/profiler/native_stack_sampler_mac.cc
@@ -442,7 +442,7 @@
     // address in the wrong place. This check should ensure that we bail before
     // trying to deref a bad IP obtained this way in the previous frame.
     const ModuleCache::Module* module = module_cache_->GetModuleForAddress(rip);
-    if (!module->is_valid)
+    if (!module)
       return false;
 
     callback(static_cast<uintptr_t>(rip), module);
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc
index 3c57921..b11350f 100644
--- a/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -562,7 +562,7 @@
   for (const auto& frame : frames) {
     output += StringPrintf(
         "0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer),
-        frame.module->filename.AsUTF8Unsafe().c_str());
+        frame.module->GetFilename().AsUTF8Unsafe().c_str());
   }
   return output;
 }
@@ -770,7 +770,7 @@
 
   // Check that all the modules are valid.
   for (const auto& frame : frames)
-    EXPECT_TRUE(frame.module->is_valid);
+    EXPECT_NE(nullptr, frame.module);
 
   // Check that the stack contains a frame for
   // TargetThread::SignalAndWaitUntilSignaled().
diff --git a/base/sampling_heap_profiler/module_cache.cc b/base/sampling_heap_profiler/module_cache.cc
index d1e03c1..9de7bac 100644
--- a/base/sampling_heap_profiler/module_cache.cc
+++ b/base/sampling_heap_profiler/module_cache.cc
@@ -6,12 +6,8 @@
 
 #include <utility>
 
-#include "base/no_destructor.h"
-
 namespace base {
 
-ModuleCache::Module::Module() : is_valid(false) {}
-
 ModuleCache::Module::Module(uintptr_t base_address,
                             const std::string& id,
                             const FilePath& filename)
@@ -21,32 +17,43 @@
                             const std::string& id,
                             const FilePath& filename,
                             size_t size)
-    : base_address(base_address),
-      id(id),
-      filename(filename),
-      is_valid(true),
-      size(size) {}
+    : base_address_(base_address), id_(id), filename_(filename), size_(size) {}
 
 ModuleCache::Module::~Module() = default;
 
+uintptr_t ModuleCache::Module::GetBaseAddress() const {
+  return base_address_;
+}
+
+std::string ModuleCache::Module::GetId() const {
+  return id_;
+}
+
+FilePath ModuleCache::Module::GetFilename() const {
+  return filename_;
+}
+
+size_t ModuleCache::Module::GetSize() const {
+  return size_;
+}
+
 ModuleCache::ModuleCache() = default;
 ModuleCache::~ModuleCache() = default;
 
 const ModuleCache::Module* ModuleCache::GetModuleForAddress(uintptr_t address) {
-  static NoDestructor<Module> invalid_module;
   auto it = modules_cache_map_.upper_bound(address);
   if (it != modules_cache_map_.begin()) {
     DCHECK(!modules_cache_map_.empty());
     --it;
     const Module* module = it->second.get();
-    if (address < module->base_address + module->size)
+    if (address < module->GetBaseAddress() + module->GetSize())
       return module;
   }
 
   std::unique_ptr<Module> module = CreateModuleForAddress(address);
-  if (!module->is_valid)
-    return invalid_module.get();
-  return modules_cache_map_.emplace(module->base_address, std::move(module))
+  if (!module)
+    return nullptr;
+  return modules_cache_map_.emplace(module->GetBaseAddress(), std::move(module))
       .first->second.get();
 }
 
diff --git a/base/sampling_heap_profiler/module_cache.h b/base/sampling_heap_profiler/module_cache.h
index b7d6d94..39b62f17 100644
--- a/base/sampling_heap_profiler/module_cache.h
+++ b/base/sampling_heap_profiler/module_cache.h
@@ -22,11 +22,10 @@
 
 class BASE_EXPORT ModuleCache {
  public:
-  // Module represents the module (DLL or exe) and its validness state.
-  // This struct is used for sampling data transfer from NativeStackSampler
-  // to ProfileBuilder as well as by SamplingHeapProfiler.
-  struct BASE_EXPORT Module {
-    Module();
+  // Module represents a binary module (executable or library) and its
+  // associated state.
+  class BASE_EXPORT Module {
+   public:
     Module(uintptr_t base_address,
            const std::string& id,
            const FilePath& filename);
@@ -39,34 +38,40 @@
     Module(const Module&) = delete;
     Module& operator=(const Module&) = delete;
 
-    // Points to the base address of the module.
-    uintptr_t base_address;
+    // Gets the base address of the module.
+    uintptr_t GetBaseAddress() const;
 
-    // An opaque binary string that uniquely identifies a particular program
-    // version with high probability. This is parsed from headers of the loaded
-    // module.
+    // Gets the opaque binary string that uniquely identifies a particular
+    // program version with high probability. This is parsed from headers of the
+    // loaded module.
     // For binaries generated by GNU tools:
     //   Contents of the .note.gnu.build-id field.
     // On Windows:
     //   GUID + AGE in the debug image headers of a module.
-    std::string id;
+    std::string GetId() const;
 
-    // The filename of the module.
-    FilePath filename;
+    // Gets the filename of the module.
+    // TODO(wittman): This is really the debug basename of the file, which is
+    // the pdb basename for Windows and the binary basename for other
+    // platforms. Update the method name accordingly.
+    FilePath GetFilename() const;
 
-    // The validness of the module.
-    bool is_valid;
+    // Gets the size of the module.
+    size_t GetSize() const;
 
-    // Size of the module.
-    size_t size;
+   private:
+    uintptr_t base_address_;
+    std::string id_;
+    FilePath filename_;
+    size_t size_;
   };
 
   ModuleCache();
   ~ModuleCache();
 
-  // Gets the module containing |address| or an invalid module if |address| is
-  // not within a module. The returned module remains owned by and has the same
-  // lifetime as the ModuleCache object.
+  // Gets the module containing |address| or nullptr if |address| is not within
+  // a module. The returned module remains owned by and has the same lifetime as
+  // the ModuleCache object.
   const Module* GetModuleForAddress(uintptr_t address);
   std::vector<const Module*> GetModules() const;
 
@@ -74,8 +79,8 @@
   // TODO(alph): Refactor corresponding functions to use public API instead,
   // and drop friends.
 
-  // Creates a Module object for the specified memory address. If the address
-  // does not belong to a module returns an invalid module.
+  // Creates a Module object for the specified memory address. Returns null if
+  // the address does not belong to a module.
   static std::unique_ptr<Module> CreateModuleForAddress(uintptr_t address);
   friend class NativeStackSamplerMac;
 
diff --git a/base/sampling_heap_profiler/module_cache_mac.cc b/base/sampling_heap_profiler/module_cache_mac.cc
index 96b24ab..7571098f 100644
--- a/base/sampling_heap_profiler/module_cache_mac.cc
+++ b/base/sampling_heap_profiler/module_cache_mac.cc
@@ -68,7 +68,7 @@
     uintptr_t address) {
   Dl_info inf;
   if (!dladdr(reinterpret_cast<const void*>(address), &inf))
-    return std::make_unique<Module>();
+    return nullptr;
   auto base_module_address = reinterpret_cast<uintptr_t>(inf.dli_fbase);
   return std::make_unique<Module>(
       base_module_address, GetUniqueId(inf.dli_fbase), FilePath(inf.dli_fname),
diff --git a/base/sampling_heap_profiler/module_cache_posix.cc b/base/sampling_heap_profiler/module_cache_posix.cc
index a82c27e..6950e54 100644
--- a/base/sampling_heap_profiler/module_cache_posix.cc
+++ b/base/sampling_heap_profiler/module_cache_posix.cc
@@ -10,7 +10,7 @@
 std::unique_ptr<ModuleCache::Module> ModuleCache::CreateModuleForAddress(
     uintptr_t address) {
   // TODO(alph): Implement it.
-  return std::make_unique<Module>();
+  return nullptr;
 }
 
 }  // namespace base
diff --git a/base/sampling_heap_profiler/module_cache_unittest.cc b/base/sampling_heap_profiler/module_cache_unittest.cc
index a9e3a62..cb60a10 100644
--- a/base/sampling_heap_profiler/module_cache_unittest.cc
+++ b/base/sampling_heap_profiler/module_cache_unittest.cc
@@ -31,25 +31,24 @@
   const ModuleCache::Module* module1 = cache.GetModuleForAddress(ptr1);
   const ModuleCache::Module* module2 = cache.GetModuleForAddress(ptr2);
   EXPECT_EQ(module1, module2);
-  EXPECT_TRUE(module1->is_valid);
-  EXPECT_GT(module1->size, 0u);
-  EXPECT_LE(module1->base_address, ptr1);
-  EXPECT_GT(module1->base_address + module1->size, ptr2);
+  EXPECT_NE(nullptr, module1);
+  EXPECT_GT(module1->GetSize(), 0u);
+  EXPECT_LE(module1->GetBaseAddress(), ptr1);
+  EXPECT_GT(module1->GetBaseAddress() + module1->GetSize(), ptr2);
 }
 
 TEST_F(ModuleCacheTest, MAYBE_ModulesList) {
   ModuleCache cache;
   uintptr_t ptr = reinterpret_cast<uintptr_t>(&AFunctionForTest);
   const ModuleCache::Module* module = cache.GetModuleForAddress(ptr);
-  EXPECT_TRUE(module->is_valid);
+  EXPECT_NE(nullptr, module);
   EXPECT_EQ(1u, cache.GetModules().size());
   EXPECT_EQ(module, cache.GetModules().front());
 }
 
 TEST_F(ModuleCacheTest, InvalidModule) {
   ModuleCache cache;
-  const ModuleCache::Module* invalid_module = cache.GetModuleForAddress(1);
-  EXPECT_FALSE(invalid_module->is_valid);
+  EXPECT_EQ(nullptr, cache.GetModuleForAddress(1));
 }
 
 }  // namespace
diff --git a/base/sampling_heap_profiler/module_cache_win.cc b/base/sampling_heap_profiler/module_cache_win.cc
index ca79f17b..954cef0 100644
--- a/base/sampling_heap_profiler/module_cache_win.cc
+++ b/base/sampling_heap_profiler/module_cache_win.cc
@@ -7,7 +7,6 @@
 #include <objbase.h>
 #include <psapi.h>
 
-#include "base/no_destructor.h"
 #include "base/process/process_handle.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -74,7 +73,7 @@
                            reinterpret_cast<LPCTSTR>(address),
                            &module_handle)) {
     DCHECK_EQ(ERROR_MOD_NOT_FOUND, static_cast<int>(::GetLastError()));
-    return std::make_unique<Module>();
+    return nullptr;
   }
   std::unique_ptr<Module> module = CreateModuleForHandle(module_handle);
   ::CloseHandle(module_handle);
@@ -83,10 +82,8 @@
 
 const ModuleCache::Module* ModuleCache::GetModuleForHandle(
     HMODULE module_handle) {
-  static NoDestructor<ModuleCache::Module> invalid_module;
-
   if (!module_handle)
-    return invalid_module.get();
+    return nullptr;
 
   auto loc = win_module_cache_.find(module_handle);
   if (loc != win_module_cache_.end())
@@ -94,12 +91,12 @@
 
   std::unique_ptr<ModuleCache::Module> module =
       ModuleCache::CreateModuleForHandle(module_handle);
-  if (module->is_valid) {
-    const auto result = win_module_cache_.insert(
-        std::make_pair(module_handle, std::move(module)));
-    return result.first->second.get();
-  }
-  return invalid_module.get();
+  if (!module)
+    return nullptr;
+
+  const auto result = win_module_cache_.insert(
+      std::make_pair(module_handle, std::move(module)));
+  return result.first->second.get();
 }
 
 // static
@@ -109,12 +106,12 @@
   std::string build_id;
   GetDebugInfoForModule(module_handle, &build_id, &pdb_name);
   if (build_id.empty())
-    return std::make_unique<Module>();
+    return nullptr;
 
   MODULEINFO module_info;
   if (!::GetModuleInformation(GetCurrentProcessHandle(), module_handle,
                               &module_info, sizeof(module_info))) {
-    return std::make_unique<Module>();
+    return nullptr;
   }
 
   return std::make_unique<Module>(
diff --git a/base/task/sequence_manager/task_queue_selector_unittest.cc b/base/task/sequence_manager/task_queue_selector_unittest.cc
index 9893ba2..6981a7f 100644
--- a/base/task/sequence_manager/task_queue_selector_unittest.cc
+++ b/base/task/sequence_manager/task_queue_selector_unittest.cc
@@ -100,7 +100,8 @@
           queue_to_index_map_.find(chosen_work_queue->task_queue())->second;
       order.push_back(chosen_queue_index);
       chosen_work_queue->PopTaskForTesting();
-      chosen_work_queue->work_queue_sets()->OnPopQueue(chosen_work_queue);
+      chosen_work_queue->work_queue_sets()->OnPopMinQueueInSet(
+          chosen_work_queue);
     }
     return order;
   }
@@ -328,7 +329,7 @@
   // Simulate the control queue becoming empty.
   WorkQueue* chosen_work_queue = selector_.SelectWorkQueueToService();
   chosen_work_queue->PopTaskForTesting();
-  chosen_work_queue->work_queue_sets()->OnPopQueue(chosen_work_queue);
+  chosen_work_queue->work_queue_sets()->OnPopMinQueueInSet(chosen_work_queue);
 
   // Simulate posting a normal priority task.
   PushTask(2, 2);
diff --git a/base/task/sequence_manager/work_queue.cc b/base/task/sequence_manager/work_queue.cc
index 3d7a5ad..dfe4f50 100644
--- a/base/task/sequence_manager/work_queue.cc
+++ b/base/task/sequence_manager/work_queue.cc
@@ -111,7 +111,7 @@
   if (was_empty || was_blocked) {
     work_queue_sets_->OnTaskPushedToEmptyQueue(this);
   } else {
-    work_queue_sets_->OnFrontTaskChanged(this);
+    work_queue_sets_->OnQueuesFrontTaskChanged(this);
   }
 }
 
@@ -137,8 +137,8 @@
   if (tasks_.empty()) {
     // NB delayed tasks are inserted via Push, no don't need to reload those.
     if (queue_type_ == QueueType::kImmediate) {
-      // Short-circuit the queue reload so that OnPopQueue does the right
-      // thing.
+      // Short-circuit the queue reload so that OnPopMinQueueInSet does the
+      // right thing.
       task_queue_->TakeImmediateIncomingQueueTasks(&tasks_);
     }
     // Since the queue is empty, now is a good time to consider reducing it's
@@ -146,9 +146,9 @@
     tasks_.MaybeShrinkQueue();
   }
 
-  // OnPopQueue calls GetFrontTaskEnqueueOrder which checks BlockedByFence() so
-  // we don't need to here.
-  work_queue_sets_->OnPopQueue(this);
+  // OnPopMinQueueInSet calls GetFrontTaskEnqueueOrder which checks
+  // BlockedByFence() so we don't need to here.
+  work_queue_sets_->OnPopMinQueueInSet(this);
   task_queue_->TraceQueueSize();
   return pending_task;
 }
@@ -166,15 +166,15 @@
     if (tasks_.empty()) {
       // NB delayed tasks are inserted via Push, no don't need to reload those.
       if (queue_type_ == QueueType::kImmediate) {
-        // Short-circuit the queue reload so that OnPopQueue does the right
-        // thing.
+        // Short-circuit the queue reload so that OnPopMinQueueInSet does the
+        // right thing.
         task_queue_->TakeImmediateIncomingQueueTasks(&tasks_);
       }
       // Since the queue is empty, now is a good time to consider reducing it's
       // capacity if we're wasting memory.
       tasks_.MaybeShrinkQueue();
     }
-    work_queue_sets_->OnPopQueue(this);
+    work_queue_sets_->OnQueuesFrontTaskChanged(this);
     task_queue_->TraceQueueSize();
   }
   return task_removed;
@@ -248,7 +248,7 @@
   tasks_.clear();
 
   if (work_queue_sets_ && heap_handle().IsValid())
-    work_queue_sets_->OnPopQueue(this);
+    work_queue_sets_->OnQueuesFrontTaskChanged(this);
 }
 
 void WorkQueue::PopTaskForTesting() {
diff --git a/base/task/sequence_manager/work_queue_sets.cc b/base/task/sequence_manager/work_queue_sets.cc
index b538233..da72bc4 100644
--- a/base/task/sequence_manager/work_queue_sets.cc
+++ b/base/task/sequence_manager/work_queue_sets.cc
@@ -63,13 +63,21 @@
     observer_->WorkQueueSetBecameNonEmpty(set_index);
 }
 
-void WorkQueueSets::OnFrontTaskChanged(WorkQueue* work_queue) {
+void WorkQueueSets::OnQueuesFrontTaskChanged(WorkQueue* work_queue) {
   EnqueueOrder enqueue_order;
-  bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
-  DCHECK(has_enqueue_order);
-  size_t set = work_queue->work_queue_set_index();
-  work_queue_heaps_[set].ChangeKey(work_queue->heap_handle(),
-                                   {enqueue_order, work_queue});
+  size_t set_index = work_queue->work_queue_set_index();
+  if (work_queue->GetFrontTaskEnqueueOrder(&enqueue_order)) {
+    // O(log n)
+    work_queue_heaps_[set_index].ChangeKey(work_queue->heap_handle(),
+                                           {enqueue_order, work_queue});
+  } else {
+    // O(log n)
+    work_queue_heaps_[set_index].Pop();
+    DCHECK(work_queue_heaps_[set_index].empty() ||
+           work_queue_heaps_[set_index].Min().value != work_queue);
+    if (work_queue_heaps_[set_index].empty())
+      observer_->WorkQueueSetBecameEmpty(set_index);
+  }
 }
 
 void WorkQueueSets::OnTaskPushedToEmptyQueue(WorkQueue* work_queue) {
@@ -90,7 +98,7 @@
     observer_->WorkQueueSetBecameNonEmpty(set_index);
 }
 
-void WorkQueueSets::OnPopQueue(WorkQueue* work_queue) {
+void WorkQueueSets::OnPopMinQueueInSet(WorkQueue* work_queue) {
   // Assume that |work_queue| contains the lowest enqueue_order.
   size_t set_index = work_queue->work_queue_set_index();
   DCHECK_EQ(this, work_queue->work_queue_sets());
diff --git a/base/task/sequence_manager/work_queue_sets.h b/base/task/sequence_manager/work_queue_sets.h
index 8e23c7a0..68f8926 100644
--- a/base/task/sequence_manager/work_queue_sets.h
+++ b/base/task/sequence_manager/work_queue_sets.h
@@ -50,14 +50,15 @@
   void ChangeSetIndex(WorkQueue* queue, size_t set_index);
 
   // O(log num queues)
-  void OnFrontTaskChanged(WorkQueue* queue);
+  void OnQueuesFrontTaskChanged(WorkQueue* queue);
 
   // O(log num queues)
   void OnTaskPushedToEmptyQueue(WorkQueue* work_queue);
 
-  // If empty it's O(1) amortized, otherwise it's O(log num queues)
+  // If empty it's O(1) amortized, otherwise it's O(log num queues). Slightly
+  // faster on average than OnQueuesFrontTaskChanged.
   // Assumes |work_queue| contains the lowest enqueue order in the set.
-  void OnPopQueue(WorkQueue* work_queue);
+  void OnPopMinQueueInSet(WorkQueue* work_queue);
 
   // O(log num queues)
   void OnQueueBlocked(WorkQueue* work_queue);
diff --git a/base/task/sequence_manager/work_queue_sets_unittest.cc b/base/task/sequence_manager/work_queue_sets_unittest.cc
index 8aecaae..9ed00f65 100644
--- a/base/task/sequence_manager/work_queue_sets_unittest.cc
+++ b/base/task/sequence_manager/work_queue_sets_unittest.cc
@@ -128,7 +128,44 @@
   EXPECT_EQ(queue3, work_queue_sets_->GetOldestQueueInSet(set));
 }
 
-TEST_F(WorkQueueSetsTest, OnPopQueue) {
+TEST_F(WorkQueueSetsTest, OnQueuesFrontTaskChanged) {
+  WorkQueue* queue1 = NewTaskQueue("queue1");
+  WorkQueue* queue2 = NewTaskQueue("queue2");
+  WorkQueue* queue3 = NewTaskQueue("queue3");
+  queue1->Push(FakeTaskWithEnqueueOrder(6));
+  queue2->Push(FakeTaskWithEnqueueOrder(5));
+  queue3->Push(FakeTaskWithEnqueueOrder(4));
+  size_t set = 4;
+  work_queue_sets_->ChangeSetIndex(queue1, set);
+  work_queue_sets_->ChangeSetIndex(queue2, set);
+  work_queue_sets_->ChangeSetIndex(queue3, set);
+  EXPECT_EQ(queue3, work_queue_sets_->GetOldestQueueInSet(set));
+
+  // Make |queue1| now have a task with the lowest enqueue order.
+  *const_cast<Task*>(queue1->GetFrontTask()) = FakeTaskWithEnqueueOrder(1);
+  work_queue_sets_->OnQueuesFrontTaskChanged(queue1);
+  EXPECT_EQ(queue1, work_queue_sets_->GetOldestQueueInSet(set));
+}
+
+TEST_F(WorkQueueSetsTest, OnQueuesFrontTaskChanged_QueueBecomesEmpty) {
+  WorkQueue* queue1 = NewTaskQueue("queue1");
+  WorkQueue* queue2 = NewTaskQueue("queue2");
+  WorkQueue* queue3 = NewTaskQueue("queue3");
+  queue1->Push(FakeTaskWithEnqueueOrder(6));
+  queue2->Push(FakeTaskWithEnqueueOrder(5));
+  queue3->Push(FakeTaskWithEnqueueOrder(4));
+  size_t set = 4;
+  work_queue_sets_->ChangeSetIndex(queue1, set);
+  work_queue_sets_->ChangeSetIndex(queue2, set);
+  work_queue_sets_->ChangeSetIndex(queue3, set);
+  EXPECT_EQ(queue3, work_queue_sets_->GetOldestQueueInSet(set));
+
+  queue3->PopTaskForTesting();
+  work_queue_sets_->OnQueuesFrontTaskChanged(queue3);
+  EXPECT_EQ(queue2, work_queue_sets_->GetOldestQueueInSet(set));
+}
+
+TEST_F(WorkQueueSetsTest, OnPopMinQueueInSet) {
   WorkQueue* queue1 = NewTaskQueue("queue1");
   WorkQueue* queue2 = NewTaskQueue("queue2");
   WorkQueue* queue3 = NewTaskQueue("queue3");
@@ -143,11 +180,11 @@
   EXPECT_EQ(queue2, work_queue_sets_->GetOldestQueueInSet(set));
 
   queue2->PopTaskForTesting();
-  work_queue_sets_->OnPopQueue(queue2);
+  work_queue_sets_->OnPopMinQueueInSet(queue2);
   EXPECT_EQ(queue2, work_queue_sets_->GetOldestQueueInSet(set));
 }
 
-TEST_F(WorkQueueSetsTest, OnPopQueue_QueueBecomesEmpty) {
+TEST_F(WorkQueueSetsTest, OnPopMinQueueInSet_QueueBecomesEmpty) {
   WorkQueue* queue1 = NewTaskQueue("queue1");
   WorkQueue* queue2 = NewTaskQueue("queue2");
   WorkQueue* queue3 = NewTaskQueue("queue3");
@@ -161,7 +198,7 @@
   EXPECT_EQ(queue3, work_queue_sets_->GetOldestQueueInSet(set));
 
   queue3->PopTaskForTesting();
-  work_queue_sets_->OnPopQueue(queue3);
+  work_queue_sets_->OnPopMinQueueInSet(queue3);
   EXPECT_EQ(queue2, work_queue_sets_->GetOldestQueueInSet(set));
 }
 
@@ -237,7 +274,7 @@
   EXPECT_FALSE(work_queue_sets_->IsSetEmpty(set));
 
   work_queue->PopTaskForTesting();
-  work_queue_sets_->OnPopQueue(work_queue);
+  work_queue_sets_->OnPopMinQueueInSet(work_queue);
   EXPECT_TRUE(work_queue_sets_->IsSetEmpty(set));
 }
 
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
index 161f2cc..7c203f8 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
@@ -174,7 +174,7 @@
      */
     @CallSuper
     protected List<TestRule> getDefaultTestRules() {
-        return Arrays.asList(new DestroyActivitiesRule(), new LifetimeAssertRule());
+        return Collections.singletonList(new LifetimeAssertRule());
     }
 
     /**
diff --git a/base/test/android/javatests/src/org/chromium/base/test/DestroyActivitiesRule.java b/base/test/android/javatests/src/org/chromium/base/test/DestroyActivitiesRule.java
deleted file mode 100644
index 2af3c6d8..0000000
--- a/base/test/android/javatests/src/org/chromium/base/test/DestroyActivitiesRule.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.test;
-
-import android.app.Activity;
-import android.os.Build;
-
-import org.junit.rules.ExternalResource;
-
-import org.chromium.base.ActivityState;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CallbackHelper;
-
-import java.util.concurrent.TimeoutException;
-
-/**
- * This is to ensure all calls to onDestroy() are performed before starting the next test.
- * We could probably remove this when crbug.com/932130 is fixed.
- */
-public class DestroyActivitiesRule extends ExternalResource {
-    private static final String TAG = "DestroyActivities";
-    @Override
-    public void after() {
-        if (ApplicationStatus.isInitialized()) {
-            CallbackHelper allDestroyedCalledback = new CallbackHelper();
-            ApplicationStatus.ActivityStateListener activityStateListener =
-                    (activity, newState) -> {
-                switch (newState) {
-                    case ActivityState.DESTROYED:
-                        if (ApplicationStatus.isEveryActivityDestroyed()) {
-                            allDestroyedCalledback.notifyCalled();
-                        }
-                        break;
-                    case ActivityState.CREATED:
-                        if (!activity.isFinishing()) {
-                            activity.finish();
-                        }
-                        break;
-                }
-            };
-            ApplicationStatus.registerStateListenerForAllActivities(activityStateListener);
-            ThreadUtils.runOnUiThread(() -> {
-                for (Activity a : ApplicationStatus.getRunningActivities()) {
-                    if (!a.isFinishing()) {
-                        a.finish();
-                    }
-                }
-            });
-            try {
-                if (!ApplicationStatus.isEveryActivityDestroyed()) {
-                    allDestroyedCalledback.waitForCallback();
-                }
-            } catch (InterruptedException | TimeoutException e) {
-                // There appears to be a framework bug on KitKat where onStop and onDestroy are not
-                // called for a handful of tests.
-                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
-                    Log.w(TAG, "Activity failed to be destroyed after a test");
-                    for (Activity a : ApplicationStatus.getRunningActivities()) {
-                        ApplicationStatus.onStateChangeForTesting(a, ActivityState.DESTROYED);
-                    }
-                    throw new RuntimeException(e);
-                }
-            } finally {
-                ApplicationStatus.unregisterActivityStateListener(activityStateListener);
-            }
-        }
-    }
-}
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h
index e035834..6996225b 100644
--- a/base/trace_event/trace_log.h
+++ b/base/trace_event/trace_log.h
@@ -151,6 +151,10 @@
     // TraceLog::IsEnabled() is false at this point.
     virtual void OnTraceLogDisabled() = 0;
   };
+  // TODO(oysteine): This API originally needed to use WeakPtrs as the observer
+  // list was copied under the global trace lock, but iterated over outside of
+  // that lock so that observers could add tracing. The list is now protected by
+  // its own lock, so this can be changed to a raw ptr.
   void AddAsyncEnabledStateObserver(
       WeakPtr<AsyncEnabledStateObserver> listener);
   void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener);
diff --git a/build/android/gyp/apkbuilder.py b/build/android/gyp/apkbuilder.py
index 9ffb137e..310a192 100755
--- a/build/android/gyp/apkbuilder.py
+++ b/build/android/gyp/apkbuilder.py
@@ -208,7 +208,7 @@
     if (uncompress and os.path.splitext(basename)[1] == '.so'
         and 'android_linker' not in basename
         and (not has_crazy_linker or 'clang_rt' not in basename)
-        and 'crashpad_handler' not in basename):
+        and (not has_crazy_linker or 'crashpad_handler' not in basename)):
       compress = False
       # Add prefix to prevent android install from extracting upon install.
       if has_crazy_linker:
diff --git a/build/android/gyp/generate_linker_version_script.py b/build/android/gyp/generate_linker_version_script.py
index 5ffff03..34c72eb8 100755
--- a/build/android/gyp/generate_linker_version_script.py
+++ b/build/android/gyp/generate_linker_version_script.py
@@ -42,7 +42,9 @@
   options = parser.parse_args()
 
   # JNI_OnLoad is always exported.
-  symbol_list = ['JNI_OnLoad']
+  # CrashpadHandlerMain() is the entry point to the Crashpad handler, required
+  # for libcrashpad_handler_trampoline.so.
+  symbol_list = ['CrashpadHandlerMain', 'JNI_OnLoad']
 
   if options.export_java_symbols:
     symbol_list.append('Java_*')
diff --git a/build/android/gyp/util/resource_utils.py b/build/android/gyp/util/resource_utils.py
index f0dc680e..2687d88 100644
--- a/build/android/gyp/util/resource_utils.py
+++ b/build/android/gyp/util/resource_utils.py
@@ -520,8 +520,8 @@
 
   Args:
      dep_zips: A list of zip file paths, each one will be extracted to
-       a subdirectory of |deps_dir|, named after the zip file (e.g.
-       '/some/path/foo.zip' -> '{deps_dir}/foo/').
+       a subdirectory of |deps_dir|, named after the zip file's path (e.g.
+       '/some/path/foo.zip' -> '{deps_dir}/some_path_foo/').
     deps_dir: Top-level extraction directory.
   Returns:
     The list of all sub-directory paths, relative to |deps_dir|.
@@ -531,9 +531,10 @@
   """
   dep_subdirs = []
   for z in dep_zips:
-    subdir = os.path.join(deps_dir, os.path.basename(z))
+    subdirname = z.replace(os.path.sep, '_')
+    subdir = os.path.join(deps_dir, subdirname)
     if os.path.exists(subdir):
-      raise Exception('Resource zip name conflict: ' + os.path.basename(z))
+      raise Exception('Resource zip name conflict: ' + subdirname)
     build_utils.ExtractAll(z, path=subdir)
     dep_subdirs.append(subdir)
   return dep_subdirs
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 03dab6d..402dac4 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1589,8 +1589,10 @@
     ]
 
     # TODO(thakis): Enable this for more platforms, https://crbug.com/926235
+    # Fuchsia: https://crbug.com/935588
+    # iOS: https://crbug.com/936211
     has_dchecks = is_debug || dcheck_always_on
-    if (has_dchecks && (is_android || is_linux || is_mac || is_win)) {
+    if (has_dchecks && !is_fuchsia && !is_ios) {
       cflags += [ "-Wextra-semi" ]
     }
   }
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
index 6dd1a7bb..dded3d9c 100644
--- a/build/whitespace_file.txt
+++ b/build/whitespace_file.txt
@@ -175,4 +175,3 @@
 
 SECRET ENDING: IT WAS _____ ALL ALONG!
 testing trailing line.
-Hacky hacky mitigation now works in CQ.
\ No newline at end of file
diff --git a/cc/animation/README.md b/cc/animation/README.md
index a3eb4c4..9ff42545 100644
--- a/cc/animation/README.md
+++ b/cc/animation/README.md
@@ -16,28 +16,64 @@
 are, what the ownership model is, etc. Later sections document how other parts
 of Chromium interact with cc/animation, most prominently Blink and ui/.
 
-## How cc/animation works
+## cc/animation terminology
 
-The root concept in cc/animation is an
-[keyframe model](https://codesearch.chromium.org/chromium/src/cc/animation/keyframe_model.h).
-Animations contain the state necessary to 'play' (interpolate values from) an
+[Animation](https://cs.chromium.org/chromium/src/cc/animation/animation.h)
+A cc::Animation is responsible for managing animating properties for a set of
+targets. Each target is represented by a [KeyframeEffect][] and can be animating
+multiple properties on that target; see KeyframeEffect below.
+
+A particular Animation may not own all the KeyframeEffects for a given
+target. Animation is only a grouping mechanism for related effects, and the
+grouping relationship is defined by the client. It is also the client's
+responsibility to deal with any conflicts that arise from animating the same
+property of the same target across multiple Animations.
+
+Each Animation has a copy on the impl thread, and will take care of
+synchronizing to/from the impl thread when requested.
+
+[SingleKeyframeEffectAnimation](https://cs.chromium.org/chromium/src/cc/animation/single_keyframe_effect_animation.h)
+It is a sub-class of Animation that serves as a bridge between the cc animation
+clients and cc because currently only a single keyframe effect per animation is
+supported.
+
+There is a 1:1 relationship between SingleKeyframeEffectAnimation and
+the KeyframeEffect.
+
+> NOTE: SingleKeyframeEffectAnimation is being deprecated.
+
+[Keyframe model](https://codesearch.chromium.org/chromium/src/cc/animation/keyframe_model.h)
+KeyframeModels contain the state necessary to 'play' (interpolate values from) an
+
 [animation curve](https://codesearch.chromium.org/chromium/src/cc/animation/animation_curve.h),
 which is a function that returns a value given an input time. Aside from the
-animation curve itself, an animation's state includes the run state (playing,
+animation curve itself, a keyframe model's state includes the run state (playing,
 paused, etc), the start time, the current direction (forwards, reverse), etc.
 An animation does not know or care what property is being animated, and holds
 only an opaque identifier for the property to allow clients to map output values
 to the correct properties.
 
-Targeting only a single property means that cc KeyframeModels are distinct from the
-Blink concept of an animation, which wraps the animation of multiple properties.
-To coordinate the playback of multiple cc/animations (e.g. those that are
-animating multiple properties on the same target), KeyframeModels have the concept
-of a group identifier. Animations that have the same group identifier and the
-same target are started together, and animation-finished notifications are only
-sent when all animations in the group have finished.
+[Keyframe effect][]
+A KeyframeEffect owns a group of KeyframeModels for a single target (identified
+by [PropertyToElementIdMap][]). It is responsible for managing the KeyframeModels'
+running states (starting, running, paused, etc), as well as ticking the
+KeyframeModels when it is requested to produce new outputs for a given time.
 
-Animations are grouped together based on their
+Note that a single KeyframeEffect may not own all the KeyframeModels for a
+given target. KeyframeEffect is only a grouping mechanism for related
+KeyframeModels. The commonality between keyframe models on the same target is
+found via ElementAnimations - there is only one ElementAnimations for a given
+target.
+
+Group:
+KeyframeModels that must be run together are called 'grouped' and have the same
+group id. Grouped KeyframeModels are guaranteed to start at the same time and no
+other KeyframeModels may animate any of the group's target properties until all
+KeyframeModels in the group have finished animating. It's also guaranteed that
+no two keyframe models within a keyframe effect that have both the same group id
+and property id.
+
+In general, KeyframeModels are grouped together based on their
 [animation target](https://codesearch.chromium.org/chromium/src/cc/animation/animation_target.h)
 (the entity whose property is being animated) and each such group is owned by an
 [animation](https://codesearch.chromium.org/chromium/src/cc/animation/animation.h).
@@ -192,6 +228,8 @@
 [cc::Animation::Tick]: https://cs.chromium.org/search?q=cc::Animation::Tick+file:%5C.cc
 [cc::AnimationHost::ActivateAnimations]: https://cs.chromium.org/search?q=cc::AnimationHost::ActivateAnimations+ActivateKeyframeEffects
 [cc::ElementAnimations::ElementRegistered]: https://cs.chromium.org/search?q=cc::ElementAnimations::ElementRegistered+file:%5C.cc
+[KeyframeEffect]: https://cs.chromium.org/chromium/src/cc/animation/keyframe_effect.h
+[PropertyToElementIdMap]: https://cs.chromium.org/chromium/src/cc/trees/target_property.h?type=cs&g=0&l=42
 
 `TODO(flackr): Document finishing / cancel / abort.`
 
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index acb88d06..bf8041f 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -486,8 +486,13 @@
 }
 
 SkColor Layer::SafeOpaqueBackgroundColor() const {
-  if (contents_opaque())
+  if (contents_opaque()) {
+    // TODO(936906): We should uncomment this DCHECK, since the
+    // |safe_opaque_background_color_| could be transparent if it is never set
+    // (the default is 0). But to do that, one test needs to be fixed.
+    // DCHECK_EQ(SkColorGetA(safe_opaque_background_color_), SK_AlphaOPAQUE);
     return safe_opaque_background_color_;
+  }
   SkColor color = background_color();
   if (SkColorGetA(color) == 255)
     color = SK_ColorTRANSPARENT;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 2b76496c..3f86637 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -158,6 +158,10 @@
   // background_color(), but if the background_color() is opaque (and this layer
   // claims to not be), then SK_ColorTRANSPARENT is returned.
   SkColor SafeOpaqueBackgroundColor() const;
+  // For testing, return the actual stored value.
+  SkColor ActualSafeOpaqueBackgroundColorForTesting() const {
+    return safe_opaque_background_color_;
+  }
 
   // Set and get the position of this layer, relative to its parent. This is
   // specified in layer space, which excludes device scale and page scale
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index fcdef58..9004f5b 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -158,13 +158,10 @@
       visible_layer_rect(), layer_to_content_scale_x, layer_to_content_scale_y);
   scaled_visible_layer_rect.Intersect(gfx::Rect(scaled_bounds));
 
-  EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
   state->SetAll(scaled_draw_transform, gfx::Rect(scaled_bounds),
                 scaled_visible_layer_rect, draw_properties().clip_rect,
                 draw_properties().is_clipped, contents_opaque,
-                draw_properties().opacity,
-                effect_node->has_render_surface ? SkBlendMode::kSrcOver
-                                                : effect_node->blend_mode,
+                draw_properties().opacity, SkBlendMode::kSrcOver,
                 GetSortingContextId());
 }
 
@@ -630,8 +627,13 @@
 }
 
 SkColor LayerImpl::SafeOpaqueBackgroundColor() const {
-  if (contents_opaque())
+  if (contents_opaque()) {
+    // TODO(936906): We should uncomment this DCHECK, since the
+    // |safe_opaque_background_color_| could be transparent if it is never set
+    // (the default is 0). But to do that, one test needs to be fixed.
+    // DCHECK_EQ(SkColorGetA(safe_opaque_background_color_), SK_AlphaOPAQUE);
     return safe_opaque_background_color_;
+  }
   SkColor color = background_color();
   if (SkColorGetA(color) == 255)
     color = SK_ColorTRANSPARENT;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index c3bed20..d80af73 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -516,7 +516,7 @@
       if (mask_type_ == Layer::LayerMaskType::NOT_MASK &&
           ShowDebugBorders(DebugBorderType::LAYER)) {
         // Fill the whole tile with the missing tile color.
-        color = DebugColors::OOMTileBorderColor();
+        color = DebugColors::DefaultCheckerboardColor();
       }
       auto* quad =
           render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index 72c00d9..0050c722 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -116,13 +116,6 @@
   RunPixelTest(test_type_, content_root, expected_bitmap);
 }
 
-void LayerTreeHostPixelResourceTest::RunPixelResourceTestWithLayerList(
-    scoped_refptr<Layer> root_layer,
-    base::FilePath file_name,
-    PropertyTrees* property_trees) {
-  RunPixelTestWithLayerList(test_type_, root_layer, file_name, property_trees);
-}
-
 ParameterizedPixelResourceTest::ParameterizedPixelResourceTest()
     : LayerTreeHostPixelResourceTest(::testing::get<0>(GetParam()),
                                      ::testing::get<1>(GetParam())) {}
diff --git a/cc/test/layer_tree_pixel_resource_test.h b/cc/test/layer_tree_pixel_resource_test.h
index 55f8500..29de0644 100644
--- a/cc/test/layer_tree_pixel_resource_test.h
+++ b/cc/test/layer_tree_pixel_resource_test.h
@@ -31,10 +31,6 @@
   void RunPixelResourceTest(scoped_refptr<Layer> content_root,
                             const SkBitmap& expected_bitmap);
 
-  void RunPixelResourceTestWithLayerList(scoped_refptr<Layer> root_layer,
-                                         base::FilePath file_name,
-                                         PropertyTrees* property_trees);
-
  protected:
   PixelResourceTestCase test_case_;
   Layer::LayerMaskType mask_type_;
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 8526bd0..a8a89de 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -17,7 +17,6 @@
 #include "cc/test/pixel_test_output_surface.h"
 #include "cc/test/pixel_test_utils.h"
 #include "cc/test/test_in_process_context_provider.h"
-#include "cc/trees/effect_node.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "components/viz/common/frame_sinks/copy_output_result.h"
@@ -34,7 +33,6 @@
 LayerTreePixelTest::LayerTreePixelTest()
     : pixel_comparator_(new ExactPixelComparator(true)),
       test_type_(PIXEL_TEST_GL),
-      property_trees_(nullptr),
       pending_texture_mailbox_callbacks_(0) {}
 
 LayerTreePixelTest::~LayerTreePixelTest() = default;
@@ -120,16 +118,7 @@
 void LayerTreePixelTest::BeginTest() {
   Layer* target =
       readback_target_ ? readback_target_ : layer_tree_host()->root_layer();
-  if (!property_trees_) {
-    target->RequestCopyOfOutput(CreateCopyOutputRequest());
-  } else {
-    layer_tree_host()->property_trees()->effect_tree.AddCopyRequest(
-        target->effect_tree_index(), CreateCopyOutputRequest());
-    layer_tree_host()
-        ->property_trees()
-        ->effect_tree.Node(target->effect_tree_index())
-        ->has_copy_request = true;
-  }
+  target->RequestCopyOfOutput(CreateCopyOutputRequest());
   PostSetNeedsCommitToMainThread();
 }
 
@@ -161,8 +150,6 @@
   layer->SetIsDrawable(true);
   layer->SetBounds(rect.size());
   layer->SetPosition(gfx::PointF(rect.origin()));
-  layer->SetOffsetToTransformParent(
-      gfx::Vector2dF(rect.origin().x(), rect.origin().y()));
   layer->SetBackgroundColor(color);
   return layer;
 }
@@ -239,48 +226,6 @@
   RunTest(CompositorMode::THREADED);
 }
 
-void LayerTreePixelTest::RunPixelTestWithLayerList(
-    PixelTestType test_type,
-    scoped_refptr<Layer> root_layer,
-    base::FilePath file_name,
-    PropertyTrees* property_trees) {
-  test_type_ = test_type;
-  content_root_ = root_layer;
-  property_trees_ = property_trees;
-  readback_target_ = nullptr;
-  ref_file_ = file_name;
-  RunTest(CompositorMode::THREADED);
-}
-
-void LayerTreePixelTest::InitializeForLayerListMode(
-    scoped_refptr<Layer>* root_layer,
-    PropertyTrees* property_trees) {
-  ClipNode clip_node;
-  property_trees->clip_tree.Insert(clip_node, 0);
-
-  EffectNode root_effect;
-  root_effect.clip_id = 1;
-  root_effect.stable_id = 1;
-  root_effect.transform_id = 1;
-  root_effect.has_render_surface = true;
-  property_trees->effect_tree.Insert(root_effect, 0);
-
-  ScrollNode scroll_node;
-  property_trees->scroll_tree.Insert(scroll_node, 0);
-
-  TransformNode transform_node;
-  property_trees->transform_tree.Insert(transform_node, 0);
-
-  *root_layer = Layer::Create();
-  (*root_layer)->SetBounds(gfx::Size(100, 100));
-  (*root_layer)->SetEffectTreeIndex(1);
-  (*root_layer)->SetClipTreeIndex(1);
-  (*root_layer)->SetScrollTreeIndex(1);
-  (*root_layer)->SetTransformTreeIndex(1);
-  (*root_layer)
-      ->set_property_tree_sequence_number(property_trees->sequence_number);
-}
-
 void LayerTreePixelTest::RunSingleThreadedPixelTest(
     PixelTestType test_type,
     scoped_refptr<Layer> content_root,
@@ -305,15 +250,10 @@
 }
 
 void LayerTreePixelTest::SetupTree() {
-  if (property_trees_) {
-    layer_tree_host()->SetRootLayer(content_root_);
-    layer_tree_host()->SetPropertyTreesForTesting(property_trees_);
-  } else {
-    scoped_refptr<Layer> root = Layer::Create();
-    root->SetBounds(content_root_->bounds());
-    root->AddChild(content_root_);
-    layer_tree_host()->SetRootLayer(root);
-  }
+  scoped_refptr<Layer> root = Layer::Create();
+  root->SetBounds(content_root_->bounds());
+  root->AddChild(content_root_);
+  layer_tree_host()->SetRootLayer(root);
   LayerTreeTest::SetupTree();
 }
 
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h
index 4c37dc66..3c95b739 100644
--- a/cc/test/layer_tree_pixel_test.h
+++ b/cc/test/layer_tree_pixel_test.h
@@ -11,10 +11,6 @@
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
 #include "cc/test/layer_tree_test.h"
-#include "cc/trees/clip_node.h"
-#include "cc/trees/effect_node.h"
-#include "cc/trees/scroll_node.h"
-#include "cc/trees/transform_node.h"
 #include "components/viz/common/resources/single_release_callback.h"
 #include "ui/gl/gl_implementation.h"
 
@@ -75,12 +71,6 @@
       int border_width,
       SkColor border_color);
 
-  // Initializes the root layer and root PropertyTrees for layer list mode.
-  // In this mode, all other layers are direct children of |root_layer| and
-  // any property nodes are descendants of node id 1 in the respective trees.
-  void InitializeForLayerListMode(scoped_refptr<Layer>* root_layer,
-                                  PropertyTrees* property_trees);
-
   void RunPixelTest(PixelTestType type,
                     scoped_refptr<Layer> content_root,
                     base::FilePath file_name);
@@ -88,11 +78,6 @@
                     scoped_refptr<Layer> content_root,
                     const SkBitmap& expected_bitmap);
 
-  void RunPixelTestWithLayerList(PixelTestType type,
-                                 scoped_refptr<Layer> root_layer,
-                                 base::FilePath file_name,
-                                 PropertyTrees* property_trees);
-
   void RunSingleThreadedPixelTest(PixelTestType test_type,
                                   scoped_refptr<Layer> content_root,
                                   base::FilePath file_name);
@@ -126,7 +111,6 @@
   std::unique_ptr<PixelComparator> pixel_comparator_;
   PixelTestType test_type_;
   scoped_refptr<Layer> content_root_;
-  PropertyTrees* property_trees_;
   Layer* readback_target_;
   base::FilePath ref_file_;
   SkBitmap expected_bitmap_;
diff --git a/cc/tiles/paint_worklet_image_cache.cc b/cc/tiles/paint_worklet_image_cache.cc
index f9d9d42..1b9052f 100644
--- a/cc/tiles/paint_worklet_image_cache.cc
+++ b/cc/tiles/paint_worklet_image_cache.cc
@@ -33,7 +33,10 @@
 
 PaintWorkletImageCache::PaintWorkletImageCache() {}
 
-PaintWorkletImageCache::~PaintWorkletImageCache() {}
+PaintWorkletImageCache::~PaintWorkletImageCache() {
+  for (const auto& pair : records_)
+    DCHECK_EQ(pair.second.used_ref_count, 0u);
+}
 
 void PaintWorkletImageCache::SetPaintWorkletLayerPainter(
     std::unique_ptr<PaintWorkletLayerPainter> painter) {
@@ -59,6 +62,7 @@
 std::pair<PaintRecord*, base::OnceCallback<void()>>
 PaintWorkletImageCache::GetPaintRecordAndRef(PaintWorkletInput* input) {
   records_[input].used_ref_count++;
+  records_[input].num_of_frames_not_accessed = 0u;
   // The PaintWorkletImageCache object lives as long as the LayerTreeHostImpl,
   // and that ensures that this pointer and the input will be alive when this
   // callback is executed.
@@ -68,6 +72,11 @@
   return std::make_pair(records_[input].record.get(), std::move(callback));
 }
 
+void PaintWorkletImageCache::SetNumOfFramesToPurgeCacheEntryForTest(
+    size_t num) {
+  num_of_frames_to_purge_cache_entry_ = num;
+}
+
 void PaintWorkletImageCache::DecrementCacheRefCount(PaintWorkletInput* input) {
   auto it = records_.find(input);
   DCHECK(it != records_.end());
@@ -77,6 +86,18 @@
   pair.used_ref_count--;
 }
 
+void PaintWorkletImageCache::NotifyDidPrepareTiles() {
+  base::EraseIf(
+      records_,
+      [this](
+          const std::pair<PaintWorkletInput*, PaintWorkletImageCacheValue>& t) {
+        return t.second.num_of_frames_not_accessed >=
+               num_of_frames_to_purge_cache_entry_;
+      });
+  for (auto& pair : records_)
+    pair.second.num_of_frames_not_accessed++;
+}
+
 PaintWorkletImageCache::PaintWorkletImageCacheValue::
     PaintWorkletImageCacheValue() = default;
 
diff --git a/cc/tiles/paint_worklet_image_cache.h b/cc/tiles/paint_worklet_image_cache.h
index bd83611a..749233a 100644
--- a/cc/tiles/paint_worklet_image_cache.h
+++ b/cc/tiles/paint_worklet_image_cache.h
@@ -30,6 +30,10 @@
 
     sk_sp<PaintRecord> record;
     size_t used_ref_count;
+    // Indicates how many continuous frames that this cache is never accessed or
+    // updated. A cache entry should be purged if this number is larger than
+    // |num_of_frames_to_purge_cache_entry_|.
+    size_t num_of_frames_not_accessed = 0u;
   };
 
   PaintWorkletImageCache();
@@ -43,6 +47,8 @@
 
   void PaintImageInTask(const PaintImage& paint_image);
 
+  void NotifyDidPrepareTiles();
+
   // Returns a callback to decrement the ref count for the corresponding entry.
   std::pair<PaintRecord*, base::OnceCallback<void()>> GetPaintRecordAndRef(
       PaintWorkletInput* input);
@@ -52,6 +58,8 @@
     return records_;
   }
 
+  void SetNumOfFramesToPurgeCacheEntryForTest(size_t);
+
  private:
   void DecrementCacheRefCount(PaintWorkletInput* input);
   // This is a map of paint worklet inputs to a pair of paint record and a
@@ -64,6 +72,8 @@
   // life time as the LayerTreeHostImpl, that guarantees that the painter will
   // live as long as the LayerTreeHostImpl.
   std::unique_ptr<PaintWorkletLayerPainter> painter_;
+
+  size_t num_of_frames_to_purge_cache_entry_ = 5u;
 };
 
 }  // namespace cc
diff --git a/cc/tiles/paint_worklet_image_cache_unittest.cc b/cc/tiles/paint_worklet_image_cache_unittest.cc
index ba906312..e046b03 100644
--- a/cc/tiles/paint_worklet_image_cache_unittest.cc
+++ b/cc/tiles/paint_worklet_image_cache_unittest.cc
@@ -135,15 +135,55 @@
       records = cache.GetRecordsForTest();
   EXPECT_EQ(records.size(), 2u);
 
+  cache.SetNumOfFramesToPurgeCacheEntryForTest(2u);
   PaintRecord* record1 =
       records[paint_image1.paint_worklet_input()].record.get();
   EXPECT_TRUE(record1);
+  // Test the |num_of_frames_not_accessed| for this cache entry.
+  EXPECT_EQ(
+      records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
+      0u);
   TestPaintRecord(record1);
 
   PaintRecord* record2 =
       records[paint_image2.paint_worklet_input()].record.get();
   EXPECT_TRUE(record2);
+  // Test the |num_of_frames_not_accessed| for this cache entry.
+  EXPECT_EQ(
+      records[paint_image2.paint_worklet_input()].num_of_frames_not_accessed,
+      0u);
   TestPaintRecord(record2);
+
+  // NotifyDidPrepareTiles is called by TileManager::PrepareTiles() which is
+  // called at each new impl frame. Here we test that a paint record with
+  // |num_of_frames_not_accessed| >= 2 is purged from the cache.
+  cache.NotifyDidPrepareTiles();
+  records = cache.GetRecordsForTest();
+  EXPECT_EQ(
+      records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
+      1u);
+  EXPECT_EQ(
+      records[paint_image2.paint_worklet_input()].num_of_frames_not_accessed,
+      1u);
+
+  std::pair<PaintRecord*, base::OnceCallback<void()>> pair =
+      cache.GetPaintRecordAndRef(paint_image1.paint_worklet_input());
+  // Run the callback to decrement the ref count.
+  std::move(pair.second).Run();
+  records = cache.GetRecordsForTest();
+  EXPECT_EQ(
+      records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
+      0u);
+
+  cache.NotifyDidPrepareTiles();
+  cache.NotifyDidPrepareTiles();
+  records = cache.GetRecordsForTest();
+  // The cache entry for paint_image2 should have been purged because it was
+  // never accessed/updated in the last 2 frames.
+  EXPECT_EQ(records.size(), 1u);
+  EXPECT_EQ(
+      records[paint_image1.paint_worklet_input()].num_of_frames_not_accessed,
+      2u);
 }
 
 }  // namespace
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index 3bd8215..ae2af26 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -585,6 +585,8 @@
   // Schedule tile tasks.
   ScheduleTasks(std::move(prioritized_work));
 
+  image_controller_.paint_worklet_image_cache()->NotifyDidPrepareTiles();
+
   TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
                        "state", BasicStateAsValue());
   return true;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 9f13fe3..6db0c880 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -1839,11 +1839,6 @@
   return LayerListReverseIterator<Layer>(nullptr);
 }
 
-void LayerTreeHost::SetPropertyTreesForTesting(
-    const PropertyTrees* property_trees) {
-  property_trees_ = *property_trees;
-}
-
 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
   for (auto* layer : *this)
     layer->SetNeedsDisplay();
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 4b67381..7750c671 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -484,8 +484,6 @@
   PropertyTrees* property_trees() { return &property_trees_; }
   const PropertyTrees* property_trees() const { return &property_trees_; }
 
-  void SetPropertyTreesForTesting(const PropertyTrees* property_trees);
-
   void SetNeedsDisplayOnAllLayers();
 
   void RegisterLayer(Layer* layer);
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index 484d2f0..e58aadb 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -93,281 +93,6 @@
                        base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png")));
 }
 
-class LayerTreeHostLayerListPixelTest : public ParameterizedPixelResourceTest {
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->use_layer_lists = true;
-  }
-};
-
-INSTANTIATE_PIXEL_RESOURCE_TEST_SUITE_P(LayerTreeHostLayerListPixelTest);
-
-TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffect) {
-  PropertyTrees property_trees;
-  scoped_refptr<Layer> root_layer;
-  InitializeForLayerListMode(&root_layer, &property_trees);
-
-  EffectNode isolation_effect;
-  isolation_effect.clip_id = 1;
-  isolation_effect.stable_id = 2;
-  isolation_effect.has_render_surface = true;
-  isolation_effect.transform_id = 1;
-  property_trees.effect_tree.Insert(isolation_effect, 1);
-
-  EffectNode mask_effect;
-  mask_effect.clip_id = 1;
-  mask_effect.stable_id = 2;
-  mask_effect.transform_id = 1;
-  mask_effect.blend_mode = SkBlendMode::kDstIn;
-  property_trees.effect_tree.Insert(mask_effect, 2);
-
-  scoped_refptr<SolidColorLayer> background =
-      CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
-  background->set_property_tree_sequence_number(property_trees.sequence_number);
-  background->SetClipTreeIndex(1);
-  background->SetEffectTreeIndex(1);
-  background->SetScrollTreeIndex(1);
-  background->SetTransformTreeIndex(1);
-  root_layer->AddChild(background);
-
-  scoped_refptr<SolidColorLayer> green =
-      CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen);
-  green->set_property_tree_sequence_number(property_trees.sequence_number);
-  green->SetClipTreeIndex(1);
-  green->SetEffectTreeIndex(2);
-  green->SetScrollTreeIndex(1);
-  green->SetTransformTreeIndex(1);
-
-  root_layer->AddChild(green);
-
-  gfx::Size mask_bounds(50, 50);
-  MaskContentLayerClient client(mask_bounds);
-
-  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
-  mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
-  mask->set_property_tree_sequence_number(property_trees.sequence_number);
-  mask->SetBounds(mask_bounds);
-  mask->SetIsDrawable(true);
-  mask->SetClipTreeIndex(1);
-  mask->SetEffectTreeIndex(3);
-  mask->SetScrollTreeIndex(1);
-  mask->SetTransformTreeIndex(1);
-  root_layer->AddChild(mask);
-
-  RunPixelResourceTestWithLayerList(
-      root_layer, base::FilePath(FILE_PATH_LITERAL("mask_with_effect.png")),
-      &property_trees);
-}
-
-TEST_P(LayerTreeHostLayerListPixelTest, ScaledMaskWithEffect) {
-  PropertyTrees property_trees;
-  scoped_refptr<Layer> root_layer;
-  InitializeForLayerListMode(&root_layer, &property_trees);
-
-  EffectNode isolation_effect;
-  isolation_effect.clip_id = 1;
-  isolation_effect.stable_id = 2;
-  isolation_effect.has_render_surface = true;
-  isolation_effect.transform_id = 1;
-  property_trees.effect_tree.Insert(isolation_effect, 1);
-
-  EffectNode mask_effect;
-  mask_effect.clip_id = 1;
-  mask_effect.stable_id = 2;
-  mask_effect.transform_id = 2;
-  mask_effect.blend_mode = SkBlendMode::kDstIn;
-  property_trees.effect_tree.Insert(mask_effect, 2);
-
-  // Scale the mask with a non-integral transform. This will trigger the
-  // AA path in the renderer.
-  TransformNode transform;
-  transform.local = gfx::Transform();
-  transform.local.Scale(1.5, 1.5);
-  property_trees.transform_tree.Insert(transform, 1);
-
-  scoped_refptr<SolidColorLayer> background =
-      CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
-  background->set_property_tree_sequence_number(property_trees.sequence_number);
-  background->SetClipTreeIndex(1);
-  background->SetEffectTreeIndex(1);
-  background->SetScrollTreeIndex(1);
-  background->SetTransformTreeIndex(1);
-  root_layer->AddChild(background);
-
-  scoped_refptr<SolidColorLayer> green =
-      CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen);
-  green->set_property_tree_sequence_number(property_trees.sequence_number);
-  green->SetClipTreeIndex(1);
-  green->SetEffectTreeIndex(2);
-  green->SetScrollTreeIndex(1);
-  green->SetTransformTreeIndex(1);
-
-  root_layer->AddChild(green);
-
-  gfx::Size mask_bounds(50, 50);
-  MaskContentLayerClient client(mask_bounds);
-
-  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
-  mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
-  mask->set_property_tree_sequence_number(property_trees.sequence_number);
-  mask->SetBounds(mask_bounds);
-  mask->SetIsDrawable(true);
-  mask->SetClipTreeIndex(1);
-  mask->SetEffectTreeIndex(3);
-  mask->SetScrollTreeIndex(1);
-  mask->SetTransformTreeIndex(2);
-  root_layer->AddChild(mask);
-
-  float percentage_pixels_large_error = 2.5f;  // 2.5%, ~250px / (100*100)
-  float percentage_pixels_small_error = 0.0f;
-  float average_error_allowed_in_bad_pixels = 100.0f;
-  int large_error_allowed = 256;
-  int small_error_allowed = 0;
-  pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
-      true,  // discard_alpha
-      percentage_pixels_large_error, percentage_pixels_small_error,
-      average_error_allowed_in_bad_pixels, large_error_allowed,
-      small_error_allowed);
-
-  RunPixelResourceTestWithLayerList(
-      root_layer,
-      base::FilePath(FILE_PATH_LITERAL("scaled_mask_with_effect.png")),
-      &property_trees);
-}
-
-TEST_P(LayerTreeHostLayerListPixelTest, MaskWithEffectDifferentSize) {
-  PropertyTrees property_trees;
-  scoped_refptr<Layer> root_layer;
-  InitializeForLayerListMode(&root_layer, &property_trees);
-
-  EffectNode isolation_effect;
-  isolation_effect.clip_id = 1;
-  isolation_effect.stable_id = 2;
-  isolation_effect.has_render_surface = true;
-  isolation_effect.transform_id = 1;
-  property_trees.effect_tree.Insert(isolation_effect, 1);
-
-  EffectNode mask_effect;
-  mask_effect.clip_id = 1;
-  mask_effect.stable_id = 2;
-  mask_effect.transform_id = 1;
-  mask_effect.blend_mode = SkBlendMode::kDstIn;
-  property_trees.effect_tree.Insert(mask_effect, 2);
-
-  scoped_refptr<SolidColorLayer> background =
-      CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
-  background->set_property_tree_sequence_number(property_trees.sequence_number);
-  background->SetClipTreeIndex(1);
-  background->SetEffectTreeIndex(1);
-  background->SetScrollTreeIndex(1);
-  background->SetTransformTreeIndex(1);
-  root_layer->AddChild(background);
-
-  scoped_refptr<SolidColorLayer> green =
-      CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen);
-  green->set_property_tree_sequence_number(property_trees.sequence_number);
-  green->SetClipTreeIndex(1);
-  green->SetEffectTreeIndex(2);
-  green->SetScrollTreeIndex(1);
-  green->SetTransformTreeIndex(1);
-
-  root_layer->AddChild(green);
-
-  gfx::Size mask_bounds(25, 25);
-  MaskContentLayerClient client(mask_bounds);
-
-  scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client);
-  mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
-  mask->set_property_tree_sequence_number(property_trees.sequence_number);
-  mask->SetBounds(mask_bounds);
-  mask->SetIsDrawable(true);
-  mask->SetClipTreeIndex(1);
-  mask->SetEffectTreeIndex(3);
-  mask->SetScrollTreeIndex(1);
-  mask->SetTransformTreeIndex(1);
-  root_layer->AddChild(mask);
-
-  // The mask is half the size of thing it's masking. In layer-list mode,
-  // the mask is not automatically scaled to match the other layer.
-  RunPixelResourceTestWithLayerList(
-      root_layer,
-      base::FilePath(FILE_PATH_LITERAL("mask_with_effect_different_size.png")),
-      &property_trees);
-}
-
-TEST_P(LayerTreeHostLayerListPixelTest, ImageMaskWithEffect) {
-  PropertyTrees property_trees;
-  scoped_refptr<Layer> root_layer;
-  InitializeForLayerListMode(&root_layer, &property_trees);
-
-  EffectNode isolation_effect;
-  isolation_effect.clip_id = 1;
-  isolation_effect.stable_id = 2;
-  isolation_effect.has_render_surface = true;
-  isolation_effect.transform_id = 1;
-  property_trees.effect_tree.Insert(isolation_effect, 1);
-
-  EffectNode mask_effect;
-  mask_effect.clip_id = 1;
-  mask_effect.stable_id = 2;
-  mask_effect.transform_id = 1;
-  mask_effect.blend_mode = SkBlendMode::kDstIn;
-  property_trees.effect_tree.Insert(mask_effect, 2);
-
-  scoped_refptr<SolidColorLayer> background =
-      CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
-  background->set_property_tree_sequence_number(property_trees.sequence_number);
-  background->SetClipTreeIndex(1);
-  background->SetEffectTreeIndex(1);
-  background->SetScrollTreeIndex(1);
-  background->SetTransformTreeIndex(1);
-  root_layer->AddChild(background);
-
-  scoped_refptr<SolidColorLayer> green =
-      CreateSolidColorLayer(gfx::Rect(25, 25, 50, 50), kCSSGreen);
-  green->set_property_tree_sequence_number(property_trees.sequence_number);
-  green->SetClipTreeIndex(1);
-  green->SetEffectTreeIndex(2);
-  green->SetScrollTreeIndex(1);
-  green->SetTransformTreeIndex(1);
-
-  root_layer->AddChild(green);
-
-  gfx::Size mask_bounds(50, 50);
-  MaskContentLayerClient client(mask_bounds);
-
-  scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
-  mask->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
-  mask->set_property_tree_sequence_number(property_trees.sequence_number);
-  mask->SetBounds(mask_bounds);
-  mask->SetIsDrawable(true);
-  mask->SetClipTreeIndex(1);
-  mask->SetEffectTreeIndex(3);
-  mask->SetScrollTreeIndex(1);
-  mask->SetTransformTreeIndex(1);
-
-  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200);
-  SkCanvas* canvas = surface->getCanvas();
-  canvas->scale(SkIntToScalar(4), SkIntToScalar(4));
-  scoped_refptr<DisplayItemList> mask_display_list =
-      client.PaintContentsToDisplayList(
-          ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
-  mask_display_list->Raster(canvas);
-  mask->SetImage(PaintImageBuilder::WithDefault()
-                     .set_id(PaintImage::GetNextId())
-                     .set_image(surface->makeImageSnapshot(),
-                                PaintImage::GetNextContentId())
-                     .TakePaintImage(),
-                 SkMatrix::I(), false);
-  root_layer->AddChild(mask);
-
-  // The mask is half the size of thing it's masking. In layer-list mode,
-  // the mask is not automatically scaled to match the other layer.
-  RunPixelResourceTestWithLayerList(
-      root_layer,
-      base::FilePath(FILE_PATH_LITERAL("image_mask_with_effect.png")),
-      &property_trees);
-}
-
 TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
   scoped_refptr<SolidColorLayer> background =
       CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index d445b8f0..f267476d 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2013,3 +2013,303 @@
     }
   }
 }
+
+generate_jni("jni_headers") {
+  sources = [
+    "features/media_router/java/org/chromium/chrome/browser/media/router/ChromeMediaRouter.java",
+    "features/media_router/java/org/chromium/chrome/browser/media/router/ChromeMediaRouterDialogController.java",
+    "features/media_router/java/org/chromium/chrome/browser/media/router/FlingingControllerBridge.java",
+    "features/media_router/java/org/chromium/chrome/browser/media/router/MediaStatusBridge.java",
+    "java/src/org/chromium/chrome/browser/AfterStartupTaskUtils.java",
+    "java/src/org/chromium/chrome/browser/AppHooks.java",
+    "java/src/org/chromium/chrome/browser/ApplicationLifetime.java",
+    "java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java",
+    "java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java",
+    "java/src/org/chromium/chrome/browser/ChromeBackupAgent.java",
+    "java/src/org/chromium/chrome/browser/ChromeBackupWatcher.java",
+    "java/src/org/chromium/chrome/browser/ChromeFeatureList.java",
+    "java/src/org/chromium/chrome/browser/ChromeHttpAuthHandler.java",
+    "java/src/org/chromium/chrome/browser/ChromeVersionInfo.java",
+    "java/src/org/chromium/chrome/browser/DevToolsServer.java",
+    "java/src/org/chromium/chrome/browser/IntentHeadersRecorder.java",
+    "java/src/org/chromium/chrome/browser/IntentHelper.java",
+    "java/src/org/chromium/chrome/browser/NearOomMonitor.java",
+    "java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java",
+    "java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java",
+    "java/src/org/chromium/chrome/browser/ServiceTabLauncher.java",
+    "java/src/org/chromium/chrome/browser/ShortcutHelper.java",
+    "java/src/org/chromium/chrome/browser/UsbChooserDialog.java",
+    "java/src/org/chromium/chrome/browser/WarmupManager.java",
+    "java/src/org/chromium/chrome/browser/WebContentsFactory.java",
+    "java/src/org/chromium/chrome/browser/accessibility/FontSizePrefs.java",
+    "java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java",
+    "java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/CreditCardScannerBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java",
+    "java/src/org/chromium/chrome/browser/autofill/PhoneNumberUtil.java",
+    "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsModel.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderDelegate.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDelegate.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestDelegate.java",
+    "java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestModel.java",
+    "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java",
+    "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java",
+    "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
+    "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
+    "java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java",
+    "java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java",
+    "java/src/org/chromium/chrome/browser/browserservices/UkmRecorder.java",
+    "java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java",
+    "java/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcherBridge.java",
+    "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java",
+    "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java",
+    "java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java",
+    "java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java",
+    "java/src/org/chromium/chrome/browser/compositor/CompositorView.java",
+    "java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java",
+    "java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java",
+    "java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java",
+    "java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java",
+    "java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java",
+    "java/src/org/chromium/chrome/browser/content/ContentUtils.java",
+    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java",
+    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java",
+    "java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPreferenceHelper.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java",
+    "java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java",
+    "java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java",
+    "java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java",
+    "java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java",
+    "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java",
+    "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java",
+    "java/src/org/chromium/chrome/browser/database/SQLiteCursor.java",
+    "java/src/org/chromium/chrome/browser/document/DocumentWebContentsDelegate.java",
+    "java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerServiceFactory.java",
+    "java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java",
+    "java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadController.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadInfo.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadItem.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadLocationDialogBridge.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadManagerService.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadMediaData.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadMediaParserBridge.java",
+    "java/src/org/chromium/chrome/browser/download/DownloadUtils.java",
+    "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java",
+    "java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java",
+    "java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java",
+    "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java",
+    "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java",
+    "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimental.java",
+    "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategory.java",
+    "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java",
+    "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java",
+    "java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java",
+    "java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java",
+    "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java",
+    "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java",
+    "java/src/org/chromium/chrome/browser/feedback/ProcessIdFeedbackSource.java",
+    "java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java",
+    "java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java",
+    "java/src/org/chromium/chrome/browser/findinpage/FindInPageBridge.java",
+    "java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java",
+    "java/src/org/chromium/chrome/browser/historyreport/HistoryReportJniBridge.java",
+    "java/src/org/chromium/chrome/browser/infobar/AdsBlockedInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java",
+    "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java",
+    "java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/FramebustBlockInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBarDelegate.java",
+    "java/src/org/chromium/chrome/browser/infobar/InfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java",
+    "java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/InstantAppsInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/InstantAppsInfoBarDelegate.java",
+    "java/src/org/chromium/chrome/browser/infobar/NearOomInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/NearOomReductionInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfoBarDelegate.java",
+    "java/src/org/chromium/chrome/browser/infobar/PreviewsInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/PreviewsLitePageInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/SavePasswordInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/SimpleConfirmInfoBarBuilder.java",
+    "java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java",
+    "java/src/org/chromium/chrome/browser/infobar/UpdatePasswordInfoBar.java",
+    "java/src/org/chromium/chrome/browser/instantapps/InstantAppsSettings.java",
+    "java/src/org/chromium/chrome/browser/invalidation/InvalidationServiceFactory.java",
+    "java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java",
+    "java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java",
+    "java/src/org/chromium/chrome/browser/locale/LocaleManager.java",
+    "java/src/org/chromium/chrome/browser/locale/LocaleTemplateUrlLoader.java",
+    "java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java",
+    "java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java",
+    "java/src/org/chromium/chrome/browser/metrics/PageLoadMetrics.java",
+    "java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java",
+    "java/src/org/chromium/chrome/browser/metrics/UmaUtils.java",
+    "java/src/org/chromium/chrome/browser/metrics/VariationsSession.java",
+    "java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java",
+    "java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java",
+    "java/src/org/chromium/chrome/browser/notifications/ActionInfo.java",
+    "java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java",
+    "java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java",
+    "java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java",
+    "java/src/org/chromium/chrome/browser/notifications/scheduler/NotificationSchedulerTask.java",
+    "java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotifier.java",
+    "java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java",
+    "java/src/org/chromium/chrome/browser/ntp/LogoBridge.java",
+    "java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java",
+    "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java",
+    "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java",
+    "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsLauncher.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerBridge.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/CCTRequestStatus.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/CctOfflinePageModelObserver.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/SavePageRequest.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/prefetch/OfflineNotificationBackgroundTask.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskScheduler.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java",
+    "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchedPagesNotifier.java",
+    "java/src/org/chromium/chrome/browser/omnibox/OmniboxPrerender.java",
+    "java/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizer.java",
+    "java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java",
+    "java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java",
+    "java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java",
+    "java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java",
+    "java/src/org/chromium/chrome/browser/page_info/CertificateChainHelper.java",
+    "java/src/org/chromium/chrome/browser/page_info/CertificateViewer.java",
+    "java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java",
+    "java/src/org/chromium/chrome/browser/page_info/PageInfoController.java",
+    "java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java",
+    "java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java",
+    "java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java",
+    "java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java",
+    "java/src/org/chromium/chrome/browser/password_manager/Credential.java",
+    "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java",
+    "java/src/org/chromium/chrome/browser/payments/CanMakePaymentQuery.java",
+    "java/src/org/chromium/chrome/browser/payments/JourneyLogger.java",
+    "java/src/org/chromium/chrome/browser/payments/PaymentManifestWebDataService.java",
+    "java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java",
+    "java/src/org/chromium/chrome/browser/payments/SslValidityChecker.java",
+    "java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java",
+    "java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java",
+    "java/src/org/chromium/chrome/browser/permissions/PermissionUmaUtil.java",
+    "java/src/org/chromium/chrome/browser/photo_picker/DecoderService.java",
+    "java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java",
+    "java/src/org/chromium/chrome/browser/preferences/LocationSettings.java",
+    "java/src/org/chromium/chrome/browser/preferences/PrefChangeRegistrar.java",
+    "java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java",
+    "java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java",
+    "java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java",
+    "java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java",
+    "java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java",
+    "java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataCounterBridge.java",
+    "java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java",
+    "java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java",
+    "java/src/org/chromium/chrome/browser/previews/PreviewsAndroidBridge.java",
+    "java/src/org/chromium/chrome/browser/printing/TabPrinter.java",
+    "java/src/org/chromium/chrome/browser/profiles/Profile.java",
+    "java/src/org/chromium/chrome/browser/profiles/ProfileDownloader.java",
+    "java/src/org/chromium/chrome/browser/profiles/ProfileManagerUtils.java",
+    "java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java",
+    "java/src/org/chromium/chrome/browser/push_messaging/PushMessagingServiceObserver.java",
+    "java/src/org/chromium/chrome/browser/rappor/RapporServiceBridge.java",
+    "java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
+    "java/src/org/chromium/chrome/browser/rlz/RlzPingHandler.java",
+    "java/src/org/chromium/chrome/browser/search_engines/TemplateUrl.java",
+    "java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java",
+    "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfAndroidBridge.java",
+    "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfEntry.java",
+    "java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java",
+    "java/src/org/chromium/chrome/browser/signin/AccountManagementScreenHelper.java",
+    "java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java",
+    "java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
+    "java/src/org/chromium/chrome/browser/signin/SigninManager.java",
+    "java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java",
+    "java/src/org/chromium/chrome/browser/signin/UnifiedConsentServiceBridge.java",
+    "java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java",
+    "java/src/org/chromium/chrome/browser/ssl/CaptivePortalHelper.java",
+    "java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java",
+    "java/src/org/chromium/chrome/browser/subresource_filter/TestSubresourceFilterPublisher.java",
+    "java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java",
+    "java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java",
+    "java/src/org/chromium/chrome/browser/suggestions/SuggestionsEventReporterBridge.java",
+    "java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java",
+    "java/src/org/chromium/chrome/browser/tab/Tab.java",
+    "java/src/org/chromium/chrome/browser/tab/TabState.java",
+    "java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java",
+    "java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java",
+    "java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java",
+    "java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java",
+    "java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java",
+    "java/src/org/chromium/chrome/browser/translate/TranslateBridge.java",
+    "java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java",
+    "java/src/org/chromium/chrome/browser/util/ChromeContextUtil.java",
+    "java/src/org/chromium/chrome/browser/util/FeatureUtilities.java",
+    "java/src/org/chromium/chrome/browser/util/PlatformUtil.java",
+    "java/src/org/chromium/chrome/browser/util/UrlUtilities.java",
+    "java/src/org/chromium/chrome/browser/webapps/AddToHomescreenManager.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java",
+    "java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java",
+    "java/src/org/chromium/chrome/browser/widget/ThumbnailGenerator.java",
+  ]
+
+  # Used for testing only, should not be shipped to end users.
+  if (enable_offline_pages_harness) {
+    sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
+  }
+
+  if (enable_feed_in_chrome) {
+    sources += [
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java",
+      "feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java",
+    ]
+  }
+
+  jni_package = "chrome"
+}
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index ea21af4..e5ae1c0 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -235,6 +235,13 @@
       deps += [ ":$_unwind_asset" ]
     }
 
+    # This is a list of all our base module library dependencies. New features
+    # should be added to this list.
+    deps += [
+      "//chrome/android:chrome_java",
+      "//chrome/android/features/media_router:java",
+    ]
+
     if (enable_vr && (_target_type == "android_apk" || !modularize_vr)) {
       deps += [ "//chrome/browser/android/vr:java" ]
     }
@@ -337,6 +344,30 @@
     if (!defined(deps)) {
       deps = []
     }
+    if (!defined(loadable_modules)) {
+      loadable_modules = []
+    }
+    if (!defined(secondary_abi_loadable_modules)) {
+      secondary_abi_loadable_modules = []
+    }
+
+    if (!use_trichrome_library) {
+      deps += [
+        "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
+      ]
+      loadable_modules += [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
+
+      if (android_64bit_target_cpu && build_apk_secondary_abi &&
+          (!defined(invoker.is_64_bit_browser) || !invoker.is_64_bit_browser ||
+           invoker.include_32_bit_webview)) {
+        _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+        deps += [ _trampoline ]
+        _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
+        secondary_abi_loadable_modules +=
+            [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
+      }
+    }
+
     deps += [
       "//android_webview:monochrome_webview_assets",
       "//android_webview/apk:webview_license_activity_java",
@@ -380,11 +411,11 @@
 
       # We store this as a separate .so in the APK and only load as needed.
       if (android_64bit_target_cpu && build_apk_secondary_abi) {
-        secondary_abi_loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
+        secondary_abi_loadable_modules += [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
       } else if (android_64bit_target_cpu && !build_apk_secondary_abi) {
-        loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
+        loadable_modules += [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
       } else {
-        loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
+        loadable_modules += [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ]
       }
     }
   }
diff --git a/chrome/android/features/OWNERS b/chrome/android/features/OWNERS
index b18865e..c21bfeb 100644
--- a/chrome/android/features/OWNERS
+++ b/chrome/android/features/OWNERS
@@ -1,2 +1,3 @@
 agrieve@chromium.org
 tiborg@chromium.org
+wnwen@chromium.org
diff --git a/chrome/android/features/media_router/BUILD.gn b/chrome/android/features/media_router/BUILD.gn
index 745688c1..d606c2f 100644
--- a/chrome/android/features/media_router/BUILD.gn
+++ b/chrome/android/features/media_router/BUILD.gn
@@ -8,7 +8,7 @@
 
 android_library("java") {
   deps = [
-    ":media_router_resources",
+    ":resources",
     "$google_play_services_package:google_play_services_base_java",
     "$google_play_services_package:google_play_services_basement_java",
     "$google_play_services_package:google_play_services_cast_framework_java",
@@ -116,17 +116,17 @@
 }
 
 # TODO(wnwen): Rename these to be more generic once https://crbug.com/935576 is fixed.
-android_resources("media_router_resources") {
+android_resources("resources") {
   resource_dirs = [ "res" ]
   deps = [
-    ":media_router_strings_grd",
+    ":strings_grd",
     "//chrome/android:chrome_app_java_resources",
     "//third_party/android_media:android_media_resources",
   ]
   custom_package = "org.chromium.chrome.media.router"
 }
 
-java_strings_grd("media_router_strings_grd") {
+java_strings_grd("strings_grd") {
   defines = chrome_grit_defines
   grd_file = "strings/android_chrome_media_router_strings.grd"
   outputs = [
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
index 2c1144327..9cc93ca 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -33,7 +33,8 @@
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.AsyncTask;
-import org.chromium.base.task.BackgroundOnlyAsyncTask;
+import org.chromium.base.task.PostTask;
+import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.download.DownloadMetrics.DownloadOpenSource;
@@ -1144,13 +1145,9 @@
             removeDownloadProgress(downloadGuid);
         });
 
-        new BackgroundOnlyAsyncTask<Void>() {
-            @Override
-            public Void doInBackground() {
-                mDownloadManagerDelegate.removeCompletedDownload(downloadGuid, externallyRemoved);
-                return null;
-            }
-        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+        PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> {
+            mDownloadManagerDelegate.removeCompletedDownload(downloadGuid, externallyRemoved);
+        });
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillContact.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillContact.java
index e9c964b..f4263f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillContact.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillContact.java
@@ -11,6 +11,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
 import org.chromium.chrome.browser.widget.prefeditor.EditableOption;
+import org.chromium.payments.mojom.PayerDetail;
 
 /**
  * The locally stored contact details.
@@ -76,6 +77,18 @@
         return mProfile;
     }
 
+    /** @return The payer detail information for the merchant. */
+    public PayerDetail toPayerDetail() {
+        assert mIsComplete;
+        PayerDetail result = new PayerDetail();
+
+        result.name = getPayerName();
+        result.phone = getPayerPhone();
+        result.email = getPayerEmail();
+
+        return result;
+    }
+
     /** @return Whether the contact is complete and ready to be sent to the merchant as-is. */
     @Override
     public boolean isComplete() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index 6828dc33..8aae1d6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -58,6 +58,7 @@
 import org.chromium.payments.mojom.AddressErrors;
 import org.chromium.payments.mojom.CanMakePaymentQueryResult;
 import org.chromium.payments.mojom.HasEnrolledInstrumentQueryResult;
+import org.chromium.payments.mojom.PayerDetail;
 import org.chromium.payments.mojom.PayerErrors;
 import org.chromium.payments.mojom.PaymentComplete;
 import org.chromium.payments.mojom.PaymentCurrencyAmount;
@@ -232,6 +233,7 @@
     private boolean mIsHasEnrolledInstrumentResponsePending;
     private boolean mHasEnrolledInstrumentUsesPerMethodQuota;
     private boolean mIsCurrentPaymentRequestShowing;
+    private boolean mWasRetryCalled;
     private final Queue<Runnable> mRetryQueue = new LinkedList<>();
 
     /**
@@ -800,13 +802,14 @@
 
         if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return;
 
-        if (mUiShippingOptions.isEmpty() && mShippingAddressesSection.getSelectedItem() != null) {
+        if ((mUiShippingOptions.isEmpty() || !TextUtils.isEmpty(details.error))
+                && mShippingAddressesSection.getSelectedItem() != null) {
             mShippingAddressesSection.getSelectedItem().setInvalid();
             mShippingAddressesSection.setSelectedItemIndex(SectionInformation.INVALID_SELECTION);
             mShippingAddressesSection.setErrorMessage(details.error);
         }
 
-        enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent();
+        enableUserInterfaceAfterPaymentRequestUpdateEvent();
     }
 
     /**
@@ -824,10 +827,10 @@
             return;
         }
 
-        enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent();
+        enableUserInterfaceAfterPaymentRequestUpdateEvent();
     }
 
-    private void enableUserInterfaceAfterShippingAddressOrOptionUpdateEvent() {
+    private void enableUserInterfaceAfterPaymentRequestUpdateEvent() {
         if (mPaymentInformationCallback != null) {
             providePaymentInformation();
         } else {
@@ -856,7 +859,7 @@
             mRawTotal = details.total;
         }
 
-        if (details.displayItems.length != 0) {
+        if (mRawLineItems == null || details.displayItems.length != 0) {
             mRawLineItems = Collections.unmodifiableList(Arrays.asList(details.displayItems));
         }
 
@@ -1130,10 +1133,14 @@
             AutofillContact contact = (AutofillContact) option;
             if (contact.isComplete()) {
                 mContactSection.setSelectedItem(option);
+                if (!mWasRetryCalled) return PaymentRequestUI.SelectionResult.NONE;
+                dispatchPayerDetailChangeEventIfNeeded(contact.toPayerDetail());
             } else {
                 editContact(contact);
-                return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
+                if (!mWasRetryCalled) return PaymentRequestUI.SelectionResult.EDITOR_LAUNCH;
             }
+            mPaymentInformationCallback = callback;
+            return PaymentRequestUI.SelectionResult.ASYNCHRONOUS_VALIDATION;
         } else if (optionType == PaymentRequestUI.DataType.PAYMENT_METHODS) {
             PaymentInstrument paymentInstrument = (PaymentInstrument) option;
             if (paymentInstrument instanceof AutofillPaymentInstrument) {
@@ -1279,6 +1286,8 @@
                         // Contact is complete and we were in the "Add flow": add an item to the
                         // list.
                         mContactSection.addAndSelectItem(editedContact);
+                    } else {
+                        dispatchPayerDetailChangeEventIfNeeded(editedContact.toPayerDetail());
                     }
                     // If contact is complete and (toEdit != null), no action needed: the contact
                     // was already selected in the UI.
@@ -1465,6 +1474,8 @@
             return;
         }
 
+        mWasRetryCalled = true;
+
         // Go back to the payment sheet
         mUI.onPayButtonProcessingCancelled();
 
@@ -2004,6 +2015,11 @@
         mClient = null;
     }
 
+    private void dispatchPayerDetailChangeEventIfNeeded(PayerDetail detail) {
+        if (mClient == null || !mWasRetryCalled) return;
+        mClient.onPayerDetailChange(detail);
+    }
+
     /**
      * @return Whether any instance of PaymentRequest has received a show() call. Don't use this
      *         function to check whether the current instance has received a show() call.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
index 1944fb9..908c09c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -383,7 +383,8 @@
                     updateSection(DataType.CONTACT_DETAILS, result.getContactDetails());
                 }
                 updateSection(DataType.PAYMENT_METHODS, result.getPaymentMethods());
-                if (mShippingAddressSectionInformation.getSelectedItem() == null) {
+                if (mShippingAddressSectionInformation != null
+                        && mShippingAddressSectionInformation.getSelectedItem() == null) {
                     expand(mShippingAddressSection);
                 } else {
                     expand(null);
@@ -699,7 +700,8 @@
                     DataType.SHIPPING_OPTIONS, option, mUpdateSectionsCallback);
         } else if (section == mContactDetailsSection) {
             mContactDetailsSectionInformation.setSelectedItem(option);
-            result = mClient.onSectionOptionSelected(DataType.CONTACT_DETAILS, option, null);
+            result = mClient.onSectionOptionSelected(
+                    DataType.CONTACT_DETAILS, option, mUpdateSectionsCallback);
         } else if (section == mPaymentMethodSection) {
             mPaymentMethodSectionInformation.setSelectedItem(option);
             result = mClient.onSectionOptionSelected(DataType.PAYMENT_METHODS, option, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappCustomTabTimeSpentLogger.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappCustomTabTimeSpentLogger.java
index aba94f38..d096a51 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappCustomTabTimeSpentLogger.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappCustomTabTimeSpentLogger.java
@@ -48,6 +48,9 @@
             case LaunchSourceType.WEBAPK:
                 umaSuffix = ".WebApk";
                 break;
+            case LaunchSourceType.MEDIA_LAUNCHER_ACTIVITY:
+                umaSuffix = ".MediaLauncherActivity";
+                break;
             default:
                 umaSuffix = ".Other";
                 break;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
index bee7305..a14fa98 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
@@ -16,7 +16,8 @@
 import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.task.AsyncTask;
-import org.chromium.base.task.BackgroundOnlyAsyncTask;
+import org.chromium.base.task.PostTask;
+import org.chromium.base.task.TaskTraits;
 import org.chromium.blink_public.platform.WebDisplayMode;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.ShortcutSource;
@@ -547,15 +548,11 @@
         if (pendingUpdateFilePath == null) return;
 
         mPreferences.edit().remove(KEY_PENDING_UPDATE_FILE_PATH).apply();
-        new BackgroundOnlyAsyncTask<Void>() {
-            @Override
-            protected Void doInBackground() {
-                if (!new File(pendingUpdateFilePath).delete()) {
-                    Log.d(TAG, "Failed to delete file " + pendingUpdateFilePath);
-                }
-                return null;
+        PostTask.postTask(TaskTraits.BEST_EFFORT_MAY_BLOCK, () -> {
+            if (!new File(pendingUpdateFilePath).delete()) {
+                Log.d(TAG, "Failed to delete file " + pendingUpdateFilePath);
             }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        });
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java
index 852014e1..e31e2a8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ScrimView.java
@@ -7,8 +7,10 @@
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
@@ -17,6 +19,7 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
 import org.chromium.chrome.browser.util.MathUtils;
 import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener;
 import org.chromium.ui.UiUtils;
@@ -56,11 +59,34 @@
 
         /**
          * The background color for the {@link ScrimView}. If null, a default color will be set as
-         * the background.
+         * the background, unless {@link #backgroundDrawable} is set.
          */
+        @Nullable
         public Integer backgroundColor;
 
         /**
+         * Background of the {@link ScrimView}.
+         *
+         * <p>When this is set, no default background color applies and {@link #backgroundColor} is
+         * ignored.
+         *
+         * <p>The drawable is responsible for filling in the background with the appropriate color.
+         * When the scrim should cover the status bar, the background color drawn by this drawable
+         * must be consistent with the status bar's color.
+         */
+        @Nullable
+        public Drawable backgroundDrawable;
+
+        /**
+         * A filter for touch event that happen on this view.
+         *
+         * <p>The filter intercepts click events, which means that {@link
+         * ScrimObserver#onScrimClick} will not be called when an event filter is set.
+         */
+        @Nullable
+        public EventFilter eventFilter;
+
+        /**
          * Build a new set of params to control the scrim.
          * @param anchorView The view that the scrim is using to place itself in the hierarchy.
          * @param showInFrontOfAnchorView Whether the scrim should show in front of the anchor view.
@@ -137,6 +163,9 @@
     /** The duration for the fading animation. This can be overridden for testing. */
     private int mFadeDurationMs;
 
+    /** If true, {@code mActiveParams.eventFilter} is set, but was never called. */
+    private boolean mIsNewEventFilter;
+
     /**
      * @param context An Android {@link Context} for creating the view.
      * @param scrimDelegate A means of changing the scrim over the status bar.
@@ -201,9 +230,13 @@
     private void onParamsChanged(ScrimParams params) {
         mActiveParams = params;
         UiUtils.removeViewFromParent(this);
-        setBackgroundColor(params != null && params.backgroundColor != null
-                        ? params.backgroundColor
-                        : mDefaultBackgroundColor);
+        if (params != null && params.backgroundDrawable != null) {
+            setBackgroundDrawable(params.backgroundDrawable);
+        } else {
+            setBackgroundColor(params != null && params.backgroundColor != null
+                            ? params.backgroundColor
+                            : mDefaultBackgroundColor);
+        }
         if (params == null || params.anchorView == null) return;
 
         placeScrimInHierarchy(params.anchorView, params.showInFrontOfAnchorView);
@@ -211,6 +244,7 @@
         getLayoutParams().height = LayoutParams.MATCH_PARENT;
         assert getLayoutParams() instanceof MarginLayoutParams;
         ((MarginLayoutParams) getLayoutParams()).topMargin = params.topMargin;
+        mIsNewEventFilter = params.eventFilter != null;
     }
 
     @Override
@@ -296,6 +330,22 @@
     }
 
     @Override
+    public boolean onTouchEvent(MotionEvent e) {
+        EventFilter eventFilter = mActiveParams == null ? null : mActiveParams.eventFilter;
+        if (eventFilter == null) return super.onTouchEvent(e);
+
+        // Make sure the first event that goes through the filter is an ACTION_DOWN, even in the
+        // case where the filter is added while a gesture is already in progress.
+        if (mIsNewEventFilter && e.getActionMasked() != MotionEvent.ACTION_DOWN) {
+            MotionEvent downEvent = MotionEvent.obtain(e);
+            downEvent.setAction(MotionEvent.ACTION_DOWN);
+            if (!eventFilter.onTouchEvent(downEvent)) return false;
+        }
+        mIsNewEventFilter = false;
+        return eventFilter.onTouchEvent(e);
+    }
+
+    @Override
     public void onClick(View view) {
         if (mActiveParams == null || mActiveParams.observer == null) return;
         mActiveParams.observer.onScrimClick();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java
index 573aff3a..432d437 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java
@@ -12,7 +12,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.UiThreadTestRule;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -76,11 +75,6 @@
         setApplicationState(ActivityState.RESUMED);
     }
 
-    @After
-    public void tearDown() {
-        setApplicationState(ActivityState.DESTROYED);
-    }
-
     private void setApplicationState(int newState) {
         ApplicationStatus.onStateChangeForTesting(mPlaceholderActivity, newState);
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
index 66993c3..f9f32897 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestRetryTest.java
@@ -65,7 +65,7 @@
     @Feature({"Payments"})
     public void testRetryWithShippingAddressErrors()
             throws InterruptedException, ExecutionException, TimeoutException {
-        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
+        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
         mPaymentRequestTestRule.clickAndWait(
                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
@@ -97,7 +97,7 @@
     @Feature({"Payments"})
     public void testRetryWithPayerErrors()
             throws InterruptedException, ExecutionException, TimeoutException {
-        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
+        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
         mPaymentRequestTestRule.clickAndWait(
                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
@@ -117,7 +117,7 @@
 
         mPaymentRequestTestRule.setTextInEditorAndWait(
                 new String[] {"Jane Doe", "650-253-0000", "jon.doe@gmail.com"},
-                mPaymentRequestTestRule.getEditorTextUpdate());
+                mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
     }
@@ -130,7 +130,7 @@
     @Feature({"Payments"})
     public void testRetryWithShippingAddressErrorsAndPayerErrors()
             throws InterruptedException, ExecutionException, TimeoutException {
-        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
+        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
         mPaymentRequestTestRule.clickAndWait(
                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
@@ -154,14 +154,54 @@
 
         mPaymentRequestTestRule.setTextInEditorAndWait(
                 new String[] {"Jane Doe", "Edge Corp.", "111 Wall St.", "New York", "NY"},
-                mPaymentRequestTestRule.getEditorTextUpdate());
+                mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getEditorValidationError());
 
         mPaymentRequestTestRule.setTextInEditorAndWait(
                 new String[] {"Jane Doe", "650-253-0000", "jon.doe@gmail.com"},
+                mPaymentRequestTestRule.getReadyToEdit());
+        mPaymentRequestTestRule.clickInEditorAndWait(
+                R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
+    }
+
+    /**
+     * Test for onpayerdetailchange event after retry().
+     */
+    @Test
+    @MediumTest
+    @Feature({"Payments"})
+    public void testRetryAndPayerDetailChangeEvent()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
+        mPaymentRequestTestRule.clickAndWait(
+                R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
+        mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
+                R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
+        mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
+                ModalDialogProperties.ButtonType.POSITIVE,
+                mPaymentRequestTestRule.getPaymentResponseReady());
+
+        mPaymentRequestTestRule.retryPaymentRequest("{}", mPaymentRequestTestRule.getReadyToPay());
+
+        mPaymentRequestTestRule.clickInContactInfoAndWait(
+                R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
+        mPaymentRequestTestRule.clickInContactInfoAndWait(
+                R.id.payments_open_editor_pencil_button, mPaymentRequestTestRule.getReadyToEdit());
+        mPaymentRequestTestRule.setTextInEditorAndWait(
+                new String[] {"Jane Doe", "650-253-0000", "jane.doe@gmail.com"},
                 mPaymentRequestTestRule.getEditorTextUpdate());
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
+
+        mPaymentRequestTestRule.clickAndWait(
+                R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
+        mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
+                R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
+        mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
+                ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
+
+        mPaymentRequestTestRule.expectResultContains(
+                new String[] {"Jane Doe", "6502530000", "jane.doe@gmail.com"});
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java
index b11962b..be3e6cd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestUpdateWithTest.java
@@ -180,4 +180,19 @@
                 ModalDialogProperties.ButtonType.POSITIVE, mRule.getDismissed());
         mRule.expectResultContains(new String[] {"freeShipping"});
     }
+
+    /**
+     * Show the shipping address validation error message even if the merchant provided some
+     * shipping options.
+     */
+    @Test
+    @MediumTest
+    @Feature({"Payments"})
+    public void testUpdateWithError() throws Throwable {
+        mRule.triggerUIAndWait("updateWithError", mRule.getReadyToPay());
+        mRule.clickInShippingAddressAndWait(R.id.payments_section, mRule.getReadyToPay());
+        mRule.clickOnShippingAddressSuggestionOptionAndWait(1, mRule.getReadyForInput());
+        CharSequence actualString = mRule.getShippingAddressOptionRowAtIndex(0).getLabelText();
+        Assert.assertEquals("This is an error for a browsertest", actualString);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerTest.java
index af5e4757..65e78d3a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabWindowManagerTest.java
@@ -9,7 +9,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.UiThreadTestRule;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
@@ -25,16 +24,12 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Test for {@link TabWindowManager} APIs.  Makes sure the class handles multiple {@link Activity}s
  * requesting {@link TabModelSelector}s, {@link Activity}s getting destroyed, etc..
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 public class TabWindowManagerTest {
-    private List<Activity> mActivities = new ArrayList<>();
     private final TabModelSelectorFactory mMockTabModelSelectorFactory =
             new TabModelSelectorFactory() {
                 @Override
@@ -46,30 +41,16 @@
 
     private ChromeActivity buildActivity() {
         ChromeActivity activity = new CustomTabActivity();
-        mActivities.add(activity);
         ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED);
         return activity;
     }
 
-    private void destroyActivity(Activity a) {
-        mActivities.remove(a);
-        ApplicationStatus.onStateChangeForTesting(a, ActivityState.DESTROYED);
-    }
-
     private MockTabModelSelector requestSelector(ChromeActivity activity, int requestedIndex) {
         final TabWindowManager manager = TabWindowManager.getInstance();
         manager.setTabModelSelectorFactory(mMockTabModelSelectorFactory);
         return (MockTabModelSelector) manager.requestSelector(activity, activity, requestedIndex);
     }
 
-    @After
-    public void tearDown() {
-        for (Activity a : mActivities) {
-            ApplicationStatus.onStateChangeForTesting(a, ActivityState.DESTROYED);
-        }
-        mActivities.clear();
-    }
-
     @Rule
     public UiThreadTestRule mRule = new UiThreadTestRule();
 
@@ -122,13 +103,11 @@
     @UiThreadTest
     public void testTooManyActivities() {
         for (int i = 0; i < TabWindowManager.MAX_SIMULTANEOUS_SELECTORS; i++) {
-            ChromeActivity a = buildActivity();
-            Assert.assertNotNull("Could not build selector", requestSelector(a, 0));
+            Assert.assertNotNull("Could not build selector", requestSelector(buildActivity(), 0));
         }
 
-        ChromeActivity activity = buildActivity();
-        Assert.assertNull(
-                "Built selectors past the max number supported", requestSelector(activity, 0));
+        Assert.assertNull("Built selectors past the max number supported",
+                requestSelector(buildActivity(), 0));
     }
 
     /**
@@ -197,7 +176,7 @@
         Assert.assertNotNull("Was not able to build the TabModelSelector", selector0);
         Assert.assertEquals("Unexpected model index", 0, manager.getIndexForWindow(activity0));
 
-        destroyActivity(activity0);
+        ApplicationStatus.onStateChangeForTesting(activity0, ActivityState.DESTROYED);
 
         Assert.assertEquals("Still found model", TabWindowManager.INVALID_WINDOW_INDEX,
                 manager.getIndexForWindow(activity0));
@@ -220,7 +199,7 @@
         Assert.assertNotNull("Was not able to build the TabModelSelector", selector0);
         Assert.assertEquals("Unexpected model index", 0, manager.getIndexForWindow(activity0));
 
-        destroyActivity(activity0);
+        ApplicationStatus.onStateChangeForTesting(activity0, ActivityState.DESTROYED);
 
         Assert.assertEquals("Still found model", TabWindowManager.INVALID_WINDOW_INDEX,
                 manager.getIndexForWindow(activity0));
@@ -256,7 +235,7 @@
         Assert.assertEquals("Unexpected model index", 0, manager.getIndexForWindow(activity0));
         Assert.assertEquals("Unexpected model index", 1, manager.getIndexForWindow(activity1));
 
-        destroyActivity(activity1);
+        ApplicationStatus.onStateChangeForTesting(activity1, ActivityState.DESTROYED);
 
         Assert.assertEquals("Still found model", TabWindowManager.INVALID_WINDOW_INDEX,
                 manager.getIndexForWindow(activity1));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/touchless/NoTouchActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/touchless/NoTouchActivityTest.java
index 5835033..e295704 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/touchless/NoTouchActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/touchless/NoTouchActivityTest.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.touchless;
 
-import android.os.Build;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
@@ -17,7 +16,6 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.MockSafeBrowsingApiHandler;
 import org.chromium.chrome.browser.ntp.NewTabPage;
@@ -35,8 +33,6 @@
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeSwitches.NO_TOUCH_MODE})
-// These tests do not have onDestroy called on KitKat, due to what is likely a Android bug.
-@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
 public class NoTouchActivityTest {
     private static final String TEST_PATH = "/chrome/test/data/android/simple.html";
 
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 5219a39..c69807c 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-74.0.3719.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-74.0.3720.0_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/android/static_initializers.gni b/chrome/android/static_initializers.gni
index c97f976..48ac0f80 100644
--- a/chrome/android/static_initializers.gni
+++ b/chrome/android/static_initializers.gni
@@ -13,8 +13,8 @@
     (!is_debug && !using_sanitizer && proprietary_codecs)) {
   # Define expectations only for target_cpu covered by trybots.
   if (target_cpu == "arm") {
-    expected_static_initializer_count = 4
+    expected_static_initializer_count = 6
   } else if (target_cpu == "arm64") {
-    expected_static_initializer_count = 3
+    expected_static_initializer_count = 5
   }
 }
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni
index 3afc7aa..cf22063a 100644
--- a/chrome/android/trichrome.gni
+++ b/chrome/android/trichrome.gni
@@ -82,9 +82,19 @@
       if (build_apk_secondary_abi) {
         secondary_abi_shared_libraries =
             [ "//chrome/android:monochrome_secondary_abi_lib" ]
+
+        _trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
+        deps += [ _trampoline ]
+        _secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
+        secondary_abi_loadable_modules =
+            [ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
       }
     } else {
       shared_libraries = [ "//chrome/android:monochrome" ]
+      deps += [
+        "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
+      ]
+      loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
     }
 
     if (!is_java_debug) {
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index 2da2a7b4..8e991bd 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -152,7 +152,7 @@
             .RequireCapability("file_util", "zip_file")
             .RequireCapability("heap_profiling", "heap_profiler")
             .RequireCapability("heap_profiling", "profiling")
-            .RequireCapability("identity", "identity_manager")
+            .RequireCapability("identity", "identity_accessor")
             .RequireCapability(image_annotation::mojom::kServiceName,
                                image_annotation::mojom::kAnnotationCapability)
             .RequireCapability("ime", "input_engine")
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index aa2c284..365545f9 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -692,7 +692,7 @@
       <!-- about:browser-switch strings -->
       <if expr="is_win or is_macosx or (is_linux and not is_chromeos)">
         <message name="IDS_ABOUT_BROWSER_SWITCH_DESCRIPTION" desc="Description shown while waiting for an alternative browser to open">
-          Your system administrator has configured Chromium to open an alternate browser.
+          Your system administrator has configured Chromium to open an alternative browser to access <ph name="TARGET_URL_HOSTNAME">$1<ex>example.com</ex></ph>.
         </message>
       </if>
 
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index d3ef9c2..4a98bff 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -703,7 +703,7 @@
       <!-- about:browser-switch strings -->
       <if expr="is_win or is_macosx or (is_linux and not is_chromeos)">
         <message name="IDS_ABOUT_BROWSER_SWITCH_DESCRIPTION" desc="Description shown while waiting for an alternative browser to open">
-          Your system administrator has configured Google Chrome to open an alternate browser to access <ph name="URL">$1<ex>http://example.com/</ex></ph>.
+          Your system administrator has configured Google Chrome to open an alternative browser to access <ph name="TARGET_URL_HOSTNAME">$1<ex>example.com</ex></ph>.
         </message>
       </if>
 
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 267ced5c..4593eac 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2690,8 +2690,8 @@
       ":client_discourse_context_proto",
       ":delta_file_proto",
       ":explore_sites_proto",
-      ":jni_headers",
       ":usage_stats_proto",
+      "//chrome/android:jni_headers",
       "//chrome/browser/android/webapk:proto",
       "//chrome/services/media_gallery_util/public/cpp",
       "//components/autofill_assistant/browser",
@@ -4862,306 +4862,6 @@
 }
 
 if (is_android) {
-  generate_jni("jni_headers") {
-    sources = [
-      "../android/features/media_router/java/org/chromium/chrome/browser/media/router/ChromeMediaRouter.java",
-      "../android/features/media_router/java/org/chromium/chrome/browser/media/router/ChromeMediaRouterDialogController.java",
-      "../android/features/media_router/java/org/chromium/chrome/browser/media/router/FlingingControllerBridge.java",
-      "../android/features/media_router/java/org/chromium/chrome/browser/media/router/MediaStatusBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/AfterStartupTaskUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/AppHooks.java",
-      "../android/java/src/org/chromium/chrome/browser/ApplicationLifetime.java",
-      "../android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java",
-      "../android/java/src/org/chromium/chrome/browser/BluetoothChooserDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java",
-      "../android/java/src/org/chromium/chrome/browser/ChromeBackupWatcher.java",
-      "../android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java",
-      "../android/java/src/org/chromium/chrome/browser/ChromeHttpAuthHandler.java",
-      "../android/java/src/org/chromium/chrome/browser/ChromeVersionInfo.java",
-      "../android/java/src/org/chromium/chrome/browser/DevToolsServer.java",
-      "../android/java/src/org/chromium/chrome/browser/IntentHeadersRecorder.java",
-      "../android/java/src/org/chromium/chrome/browser/IntentHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/NearOomMonitor.java",
-      "../android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java",
-      "../android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java",
-      "../android/java/src/org/chromium/chrome/browser/ShortcutHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/UsbChooserDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/WarmupManager.java",
-      "../android/java/src/org/chromium/chrome/browser/WebContentsFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/accessibility/FontSizePrefs.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/AutofillExpirationDateFixFlowBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/AutofillLogger.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/CreditCardScannerBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/PhoneNumberUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantModel.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetails.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/details/AssistantDetailsModel.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/autofill_assistant/payment/AssistantPaymentRequestModel.java",
-      "../android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java",
-      "../android/java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskScheduler.java",
-      "../android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
-      "../android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java",
-      "../android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java",
-      "../android/java/src/org/chromium/chrome/browser/browserservices/UkmRecorder.java",
-      "../android/java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/cached_image_fetcher/CachedImageFetcherBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java",
-      "../android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java",
-      "../android/java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java",
-      "../android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/LayerTitleCache.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/resources/ResourceFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ContextualSearchSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/EphemeralTabSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/SceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSceneLayer.java",
-      "../android/java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/content/ContentUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java",
-      "../android/java/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchContext.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPreferenceHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java",
-      "../android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java",
-      "../android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java",
-      "../android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java",
-      "../android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java",
-      "../android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java",
-      "../android/java/src/org/chromium/chrome/browser/database/SQLiteCursor.java",
-      "../android/java/src/org/chromium/chrome/browser/document/DocumentWebContentsDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerServiceFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadController.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadInfo.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadItem.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadLocationDialogBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadMediaData.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadMediaParserBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/download/service/DownloadBackgroundTask.java",
-      "../android/java/src/org/chromium/chrome/browser/download/service/DownloadTaskScheduler.java",
-      "../android/java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java",
-      "../android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimental.java",
-      "../android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategory.java",
-      "../android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java",
-      "../android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java",
-      "../android/java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/favicon/LargeIconBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java",
-      "../android/java/src/org/chromium/chrome/browser/feedback/ProcessIdFeedbackSource.java",
-      "../android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java",
-      "../android/java/src/org/chromium/chrome/browser/feedback/SystemInfoFeedbackSource.java",
-      "../android/java/src/org/chromium/chrome/browser/findinpage/FindInPageBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/historyreport/HistoryReportJniBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/AdsBlockedInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/FramebustBlockInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBarDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/InstallableAmbientBadgeInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/InstantAppsInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/InstantAppsInfoBarDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/NearOomInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/NearOomReductionInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/PermissionUpdateInfoBarDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/PreviewsInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/PreviewsLitePageInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/ReaderModeInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/SavePasswordInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/SearchGeolocationDisclosureInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/SimpleConfirmInfoBarBuilder.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/TranslateCompactInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/infobar/UpdatePasswordInfoBar.java",
-      "../android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsSettings.java",
-      "../android/java/src/org/chromium/chrome/browser/invalidation/InvalidationServiceFactory.java",
-      "../android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java",
-      "../android/java/src/org/chromium/chrome/browser/locale/LocaleTemplateUrlLoader.java",
-      "../android/java/src/org/chromium/chrome/browser/media/remote/RecordCastAction.java",
-      "../android/java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java",
-      "../android/java/src/org/chromium/chrome/browser/metrics/PageLoadMetrics.java",
-      "../android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java",
-      "../android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/metrics/VariationsSession.java",
-      "../android/java/src/org/chromium/chrome/browser/mojo/ChromeInterfaceRegistrar.java",
-      "../android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java",
-      "../android/java/src/org/chromium/chrome/browser/notifications/ActionInfo.java",
-      "../android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/notifications/scheduler/NotificationSchedulerTask.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotifier.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/LogoBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPagePrefs.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsLauncher.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/CCTRequestStatus.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/CctOfflinePageModelObserver.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePagesDownloadManagerBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/PublishPageCallback.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/SavePageRequest.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/OfflineNotificationBackgroundTask.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTask.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchBackgroundTaskScheduler.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java",
-      "../android/java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchedPagesNotifier.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPrerender.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizer.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java",
-      "../android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java",
-      "../android/java/src/org/chromium/chrome/browser/page_info/CertificateChainHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/page_info/CertificateViewer.java",
-      "../android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java",
-      "../android/java/src/org/chromium/chrome/browser/page_info/PageInfoController.java",
-      "../android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java",
-      "../android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java",
-      "../android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java",
-      "../android/java/src/org/chromium/chrome/browser/password_manager/Credential.java",
-      "../android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/payments/CanMakePaymentQuery.java",
-      "../android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java",
-      "../android/java/src/org/chromium/chrome/browser/payments/PaymentManifestWebDataService.java",
-      "../android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/payments/SslValidityChecker.java",
-      "../android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java",
-      "../android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java",
-      "../android/java/src/org/chromium/chrome/browser/permissions/PermissionUmaUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/photo_picker/DecoderService.java",
-      "../android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/PrefChangeRegistrar.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataCounterBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java",
-      "../android/java/src/org/chromium/chrome/browser/previews/PreviewsAndroidBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/printing/TabPrinter.java",
-      "../android/java/src/org/chromium/chrome/browser/profiles/Profile.java",
-      "../android/java/src/org/chromium/chrome/browser/profiles/ProfileDownloader.java",
-      "../android/java/src/org/chromium/chrome/browser/profiles/ProfileManagerUtils.java",
-      "../android/java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java",
-      "../android/java/src/org/chromium/chrome/browser/push_messaging/PushMessagingServiceObserver.java",
-      "../android/java/src/org/chromium/chrome/browser/rappor/RapporServiceBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
-      "../android/java/src/org/chromium/chrome/browser/rlz/RlzPingHandler.java",
-      "../android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrl.java",
-      "../android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java",
-      "../android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfAndroidBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfEntry.java",
-      "../android/java/src/org/chromium/chrome/browser/sessions/SessionTabHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/AccountManagementScreenHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/IdentityServicesProvider.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/SigninInvestigator.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/SigninManager.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/signin/UnifiedConsentServiceBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/snackbar/smartlockautosignin/AutoSigninSnackbarController.java",
-      "../android/java/src/org/chromium/chrome/browser/ssl/CaptivePortalHelper.java",
-      "../android/java/src/org/chromium/chrome/browser/ssl/SecurityStateModel.java",
-      "../android/java/src/org/chromium/chrome/browser/subresource_filter/TestSubresourceFilterPublisher.java",
-      "../android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSites.java",
-      "../android/java/src/org/chromium/chrome/browser/suggestions/MostVisitedSitesBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsEventReporterBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java",
-      "../android/java/src/org/chromium/chrome/browser/tab/Tab.java",
-      "../android/java/src/org/chromium/chrome/browser/tab/TabState.java",
-      "../android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java",
-      "../android/java/src/org/chromium/chrome/browser/tabmodel/SingleTabModel.java",
-      "../android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java",
-      "../android/java/src/org/chromium/chrome/browser/translate/TranslateBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsBridge.java",
-      "../android/java/src/org/chromium/chrome/browser/util/ChromeContextUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java",
-      "../android/java/src/org/chromium/chrome/browser/util/PlatformUtil.java",
-      "../android/java/src/org/chromium/chrome/browser/util/UrlUtilities.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenManager.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java",
-      "../android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java",
-      "../android/java/src/org/chromium/chrome/browser/widget/ThumbnailGenerator.java",
-    ]
-
-    # Used for testing only, should not be shipped to end users.
-    if (enable_offline_pages_harness) {
-      sources += [ "../android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
-    }
-
-    if (enable_feed_in_chrome) {
-      sources += [
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedOfflineBridge.java",
-        "../android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java",
-      ]
-    }
-
-    jni_package = "chrome"
-  }
-
   proto_library("client_discourse_context_proto") {
     sources = [
       "android/proto/client_discourse_context.proto",
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index b43ccd2a..ec96d43 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -95,6 +95,7 @@
     "//chromeos/dbus:oobe_config_proto",
     "//chromeos/dbus:plugin_vm_service_proto",
     "//chromeos/dbus/services:services",
+    "//chromeos/dbus/system_clock",
     "//chromeos/disks",
     "//chromeos/geolocation",
     "//chromeos/login/auth",
@@ -293,6 +294,8 @@
     "accessibility/switch_access_panel.h",
     "account_manager/account_manager_migrator.cc",
     "account_manager/account_manager_migrator.h",
+    "account_manager/account_manager_util.cc",
+    "account_manager/account_manager_util.h",
     "account_manager/account_migration_runner.cc",
     "account_manager/account_migration_runner.h",
     "android_sms/android_sms_app_manager.cc",
diff --git a/chrome/browser/chromeos/account_manager/account_manager_migrator.cc b/chrome/browser/chromeos/account_manager/account_manager_migrator.cc
index 9c2d067..3626926 100644
--- a/chrome/browser/chromeos/account_manager/account_manager_migrator.cc
+++ b/chrome/browser/chromeos/account_manager/account_manager_migrator.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/auth/arc_auth_service.h"
@@ -31,7 +32,6 @@
 #include "chrome/common/pref_names.h"
 #include "chromeos/account_manager/account_manager.h"
 #include "chromeos/account_manager/account_manager_factory.h"
-#include "chromeos/constants/chromeos_switches.h"
 #include "components/account_id/account_id.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/prefs/pref_service.h"
@@ -472,7 +472,7 @@
 void AccountManagerMigrator::Start() {
   DVLOG(1) << "AccountManagerMigrator::Start";
 
-  if (!chromeos::switches::IsAccountManagerEnabled())
+  if (!chromeos::IsAccountManagerAvailable(profile_))
     return;
 
   ran_migration_steps_ = false;
diff --git a/chrome/browser/chromeos/account_manager/account_manager_util.cc b/chrome/browser/chromeos/account_manager/account_manager_util.cc
new file mode 100644
index 0000000..daeea30e
--- /dev/null
+++ b/chrome/browser/chromeos/account_manager/account_manager_util.cc
@@ -0,0 +1,37 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
+
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/profiles/profiles_state.h"
+#include "chromeos/constants/chromeos_switches.h"
+
+namespace chromeos {
+
+bool IsAccountManagerAvailable(const Profile* const profile) {
+  if (!switches::IsAccountManagerEnabled())
+    return false;
+
+  // Signin Profile does not have any accounts associated with it.
+  if (chromeos::ProfileHelper::IsSigninProfile(profile))
+    return false;
+
+  // LockScreenAppProfile does not link to the user's cryptohome.
+  if (chromeos::ProfileHelper::IsLockScreenAppProfile(profile))
+    return false;
+
+  // Account Manager is unavailable on Guest (Incognito) Sessions.
+  if (profile->IsGuestSession() || profile->IsOffTheRecord())
+    return false;
+
+  // Account Manager is unavailable on Managed Guest Sessions / Public Sessions.
+  if (profiles::IsPublicSession())
+    return false;
+
+  // Available in all other cases.
+  return true;
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/account_manager/account_manager_util.h b/chrome/browser/chromeos/account_manager/account_manager_util.h
new file mode 100644
index 0000000..985d0b5
--- /dev/null
+++ b/chrome/browser/chromeos/account_manager/account_manager_util.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_UTIL_H_
+#define CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_UTIL_H_
+
+class Profile;
+
+namespace chromeos {
+
+bool IsAccountManagerAvailable(const Profile* const profile);
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_ACCOUNT_MANAGER_ACCOUNT_MANAGER_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc
index 254a2c7..e0e2279 100644
--- a/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_active_directory_enrollment_token_fetcher_browsertest.cc
@@ -257,16 +257,11 @@
     token_fetcher_ = std::make_unique<ArcActiveDirectoryEnrollmentTokenFetcher>(
         support_host_.get());
 
-    test_url_loader_factory_ =
-        std::make_unique<network::TestURLLoaderFactory>();
-    test_shared_loader_factory_ =
-        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-            test_url_loader_factory_.get());
-    token_fetcher_->SetURLLoaderFactoryForTesting(test_shared_loader_factory_);
+    token_fetcher_->SetURLLoaderFactoryForTesting(
+        test_url_loader_factory_.GetSafeWeakWrapper());
   }
 
   void TearDownOnMainThread() override {
-    test_shared_loader_factory_->Detach();
     token_fetcher_.reset();
     fake_arc_support_.reset();
     support_host_->SetErrorDelegate(nullptr);
@@ -365,9 +360,7 @@
 
   std::unique_ptr<FakeArcSupport> fake_arc_support_;
   std::unique_ptr<ArcActiveDirectoryEnrollmentTokenFetcher> token_fetcher_;
-  std::unique_ptr<network::TestURLLoaderFactory> test_url_loader_factory_;
-  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
-      test_shared_loader_factory_;
+  network::TestURLLoaderFactory test_url_loader_factory_;
 
  private:
   ArcSupportHost::AuthDelegate* GetAuthDelegate() {
@@ -391,7 +384,7 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        RequestAccountInfoSuccess) {
   StoreCorrectDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         CheckRequestAndGetEnrollRequest(request);
 
@@ -405,8 +398,7 @@
         std::string response_data;
         EXPECT_TRUE(response.SerializeToString(&response_data));
 
-        test_url_loader_factory_->AddResponse(request.url.spec(),
-                                              response_data);
+        test_url_loader_factory_.AddResponse(request.url.spec(), response_data);
       }));
 
   base::RunLoop run_loop;
@@ -417,7 +409,7 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        DmTokenRetrievalFailed) {
   FailDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         // If this gets called, the test will fail.
         ADD_FAILURE() << "DMServer called when not expected";
@@ -431,10 +423,10 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        RequestAccountInfoError) {
   StoreCorrectDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        test_url_loader_factory_->AddResponse(request.url.spec(), std::string(),
-                                              net::HTTP_BAD_REQUEST);
+        test_url_loader_factory_.AddResponse(request.url.spec(), std::string(),
+                                             net::HTTP_BAD_REQUEST);
       }));
 
   base::RunLoop run_loop;
@@ -446,7 +438,7 @@
                        ArcDisabled) {
   StoreCorrectDmToken();
 
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         network::ResourceResponseHead head;
         std::string status_line("HTTP/1.1 904 ARC Disabled");
@@ -455,8 +447,8 @@
             net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
         network::URLLoaderCompletionStatus status;
 
-        test_url_loader_factory_->AddResponse(request.url, head, std::string(),
-                                              status);
+        test_url_loader_factory_.AddResponse(request.url, head, std::string(),
+                                             status);
       }));
   base::RunLoop run_loop;
   ExpectEnrollmentTokenFetchFails(&run_loop, Status::ARC_DISABLED);
@@ -482,13 +474,13 @@
                        SamlFlowSuccess) {
   StoreCorrectDmToken();
 
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         static int count = 0;
         if (count == 0) {
-          InitiateSamlResponseJob(request, test_url_loader_factory_.get());
+          InitiateSamlResponseJob(request, &test_url_loader_factory_);
         } else if (count == 1) {
-          FinishSamlResponseJob(request, test_url_loader_factory_.get());
+          FinishSamlResponseJob(request, &test_url_loader_factory_);
         } else {
           NOTREACHED();
         }
@@ -506,9 +498,9 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        SamlFlowFailsUserCancelled) {
   StoreCorrectDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        InitiateSamlResponseJob(request, test_url_loader_factory_.get());
+        InitiateSamlResponseJob(request, &test_url_loader_factory_);
       }));
 
   base::RunLoop run_loop;
@@ -526,9 +518,9 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        SamlFlowFailsError) {
   StoreCorrectDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
-        InitiateSamlResponseJob(request, test_url_loader_factory_.get());
+        InitiateSamlResponseJob(request, &test_url_loader_factory_);
       }));
   base::RunLoop run_loop;
   SimulateAuthFailsObserver observer(fake_arc_support_.get(), &run_loop);
@@ -548,16 +540,16 @@
                        SamlFlowSucceedsWithDmRetry) {
   StoreCorrectDmToken();
 
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         static int count = 0;
         if (count == 0) {
-          test_url_loader_factory_->AddResponse(
+          test_url_loader_factory_.AddResponse(
               request.url.spec(), std::string(), net::HTTP_BAD_REQUEST);
         } else if (count == 1) {
-          InitiateSamlResponseJob(request, test_url_loader_factory_.get());
+          InitiateSamlResponseJob(request, &test_url_loader_factory_);
         } else if (count == 2) {
-          FinishSamlResponseJob(request, test_url_loader_factory_.get());
+          FinishSamlResponseJob(request, &test_url_loader_factory_);
         } else {
           NOTREACHED();
         }
@@ -578,13 +570,13 @@
 IN_PROC_BROWSER_TEST_F(ArcActiveDirectoryEnrollmentTokenFetcherBrowserTest,
                        SamlFlowSucceedsWithAuthRetry) {
   StoreCorrectDmToken();
-  test_url_loader_factory_->SetInterceptor(
+  test_url_loader_factory_.SetInterceptor(
       base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
         static int count = 0;
         if (count == 0 || count == 1) {
-          InitiateSamlResponseJob(request, test_url_loader_factory_.get());
+          InitiateSamlResponseJob(request, &test_url_loader_factory_);
         } else if (count == 2) {
-          FinishSamlResponseJob(request, test_url_loader_factory_.get());
+          FinishSamlResponseJob(request, &test_url_loader_factory_);
         } else {
           NOTREACHED();
         }
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
index 8afb3be6..849dc73 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -12,6 +12,7 @@
 #include "base/memory/singleton.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_ui_util.h"
 #include "chrome/browser/ui/app_list/arc/arc_data_removal_dialog.h"
-#include "chromeos/constants/chromeos_switches.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/arc_features.h"
@@ -454,7 +454,7 @@
   // proper Profile independent entity once we have that.
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (!chromeos::switches::IsAccountManagerEnabled())
+  if (!chromeos::IsAccountManagerAvailable(profile_))
     return;
 
   // Ignore the update if ARC has not been provisioned yet.
@@ -482,7 +482,7 @@
     const AccountInfo& account_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (!chromeos::switches::IsAccountManagerEnabled())
+  if (!chromeos::IsAccountManagerAvailable(profile_))
     return;
 
   DCHECK(!IsPrimaryGaiaAccount(account_info.gaia));
@@ -687,7 +687,7 @@
 }
 
 void ArcAuthService::TriggerAccountsPushToArc() {
-  if (!chromeos::switches::IsAccountManagerEnabled())
+  if (!chromeos::IsAccountManagerAvailable(profile_))
     return;
 
   const std::vector<AccountInfo> accounts =
diff --git a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
index 0327de0..83097fc1 100644
--- a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
+++ b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_session.cc
@@ -182,7 +182,7 @@
     std::move(callback).Run();
     return;
   }
-  gpu::gles2::GLES2Interface* gl = aura::Env::GetInstance()
+  gpu::gles2::GLES2Interface* gl = display_root_window_->env()
                                        ->context_factory()
                                        ->SharedMainThreadContextProvider()
                                        ->ContextGL();
@@ -254,7 +254,7 @@
     SetOutputBufferCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   std::move(callback).Run();
-  gpu::gles2::GLES2Interface* gl = aura::Env::GetInstance()
+  gpu::gles2::GLES2Interface* gl = display_root_window_->env()
                                        ->context_factory()
                                        ->SharedMainThreadContextProvider()
                                        ->ContextGL();
@@ -272,7 +272,7 @@
 void ArcScreenCaptureSession::OnDesktopCaptured(
     std::unique_ptr<viz::CopyOutputResult> result) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  gpu::gles2::GLES2Interface* gl = aura::Env::GetInstance()
+  gpu::gles2::GLES2Interface* gl = display_root_window_->env()
                                        ->context_factory()
                                        ->SharedMainThreadContextProvider()
                                        ->ContextGL();
@@ -308,7 +308,7 @@
 void ArcScreenCaptureSession::CopyDesktopTextureToGpuBuffer(
     std::unique_ptr<DesktopTexture> desktop_texture,
     std::unique_ptr<PendingBuffer> pending_buffer) {
-  gpu::gles2::GLES2Interface* gl = aura::Env::GetInstance()
+  gpu::gles2::GLES2Interface* gl = display_root_window_->env()
                                        ->context_factory()
                                        ->SharedMainThreadContextProvider()
                                        ->ContextGL();
@@ -327,7 +327,7 @@
   if (desktop_texture->release_callback_) {
     desktop_texture->release_callback_->Run(gpu::SyncToken(), false);
   }
-  aura::Env::GetInstance()
+  display_root_window_->env()
       ->context_factory()
       ->SharedMainThreadContextProvider()
       ->ContextSupport()
diff --git a/chrome/browser/chromeos/child_accounts/event_based_status_reporting_service_unittest.cc b/chrome/browser/chromeos/child_accounts/event_based_status_reporting_service_unittest.cc
index 28bb4d89..86c432c1 100644
--- a/chrome/browser/chromeos/child_accounts/event_based_status_reporting_service_unittest.cc
+++ b/chrome/browser/chromeos/child_accounts/event_based_status_reporting_service_unittest.cc
@@ -20,7 +20,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
-#include "chromeos/dbus/fake_system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "components/account_id/account_id.h"
 #include "components/arc/common/app.mojom.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -92,8 +92,7 @@
         DBusThreadManager::GetSetterForTesting();
     dbus_setter->SetPowerManagerClient(
         std::make_unique<FakePowerManagerClient>());
-    dbus_setter->SetSystemClockClient(
-        std::make_unique<FakeSystemClockClient>());
+    SystemClockClient::Initialize(nullptr /* bus */);
     profile_ = std::make_unique<TestingProfile>();
     profile_.get()->SetSupervisedUserId(supervised_users::kChildAccountSUID);
     arc_test_.SetUp(profile());
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
index e0d6addb..68165b7 100644
--- a/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
+++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.cc
@@ -68,7 +68,7 @@
     UsageTimeStateNotifier::GetInstance()->AddObserver(this);
 
   system::TimezoneSettings::GetInstance()->AddObserver(this);
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(this);
+  chromeos::SystemClockClient::Get()->AddObserver(this);
   pref_change_registrar_.Init(pref_service_);
   pref_change_registrar_.Add(
       prefs::kUsageTimeLimit,
@@ -95,8 +95,7 @@
     UsageTimeStateNotifier::GetInstance()->RemoveObserver(this);
 
   system::TimezoneSettings::GetInstance()->RemoveObserver(this);
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
-      this);
+  SystemClockClient::Get()->RemoveObserver(this);
 }
 
 void ScreenTimeController::AddObserver(Observer* observer) {
diff --git a/chrome/browser/chromeos/child_accounts/screen_time_controller.h b/chrome/browser/chromeos/child_accounts/screen_time_controller.h
index beeec2a..64cf02c7 100644
--- a/chrome/browser/chromeos/child_accounts/screen_time_controller.h
+++ b/chrome/browser/chromeos/child_accounts/screen_time_controller.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/chromeos/child_accounts/time_limit_notifier.h"
 #include "chrome/browser/chromeos/child_accounts/usage_time_limit_processor.h"
 #include "chrome/browser/chromeos/child_accounts/usage_time_state_notifier.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/session_manager/core/session_manager_observer.h"
diff --git a/chrome/browser/chromeos/dbus/dbus_helper.cc b/chrome/browser/chromeos/dbus/dbus_helper.cc
index c7c9fbd42..7ee3868 100644
--- a/chrome/browser/chromeos/dbus/dbus_helper.cc
+++ b/chrome/browser/chromeos/dbus/dbus_helper.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/tpm/install_attributes.h"
 
 namespace chromeos {
@@ -17,6 +18,10 @@
   // Initialize DBusThreadManager for the browser.
   DBusThreadManager::Initialize(DBusThreadManager::kAll);
 
+  // Initialize Chrome dbus clients.
+  dbus::Bus* bus = DBusThreadManager::Get()->GetSystemBus();
+  SystemClockClient::Initialize(bus);
+
   // Initialize the device settings service so that we'll take actions per
   // signals sent from the session manager. This needs to happen before
   // g_browser_process initializes BrowserPolicyConnector.
@@ -25,7 +30,8 @@
 }
 
 void ShutdownDBus() {
-  // NOTE: This must only be called if Initialize() was called.
+  // NOTE: These must only be called if InitializeDBus() was called.
+  SystemClockClient::Shutdown();
   DBusThreadManager::Shutdown();
   SystemSaltGetter::Shutdown();
 }
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
index 57ff3fb..e7be7c1 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -21,7 +21,7 @@
 #include "chromeos/dbus/cryptohome/rpc.pb.h"
 #include "chromeos/dbus/cryptohome_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/system/factory_ping_embargo_check.h"
 #include "chromeos/system/statistics_provider.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
@@ -158,13 +158,11 @@
     : public chromeos::SystemClockClient::Observer {
  public:
   SystemClockSyncWaiter() : weak_ptr_factory_(this) {
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(
-        this);
+    chromeos::SystemClockClient::Get()->AddObserver(this);
   }
 
   ~SystemClockSyncWaiter() override {
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
-        this);
+    chromeos::SystemClockClient::Get()->RemoveObserver(this);
   }
 
   // Waits for the system clock to be synchronized. If it already is
@@ -188,11 +186,9 @@
                          base::BindRepeating(&SystemClockSyncWaiter::OnTimeout,
                                              weak_ptr_factory_.GetWeakPtr()));
 
-    chromeos::DBusThreadManager::Get()
-        ->GetSystemClockClient()
-        ->WaitForServiceToBeAvailable(base::BindOnce(
-            &SystemClockSyncWaiter::OnGotSystemClockServiceAvailable,
-            weak_ptr_factory_.GetWeakPtr()));
+    chromeos::SystemClockClient::Get()->WaitForServiceToBeAvailable(
+        base::BindOnce(&SystemClockSyncWaiter::OnGotSystemClockServiceAvailable,
+                       weak_ptr_factory_.GetWeakPtr()));
   }
 
  private:
@@ -204,7 +200,7 @@
       return;
     }
 
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->GetLastSyncInfo(
+    chromeos::SystemClockClient::Get()->GetLastSyncInfo(
         base::BindOnce(&SystemClockSyncWaiter::OnGotLastSyncInfo,
                        weak_ptr_factory_.GetWeakPtr()));
   }
@@ -237,7 +233,7 @@
 
   // chromeos::SystemClockClient::Observer:
   void SystemClockUpdated() override {
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->GetLastSyncInfo(
+    chromeos::SystemClockClient::Get()->GetLastSyncInfo(
         base::BindOnce(&SystemClockSyncWaiter::OnGotLastSyncInfo,
                        weak_ptr_factory_.GetWeakPtr()));
   }
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index cef0e09..fc00bed 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "base/scoped_observer.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/test_timeouts.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/screens/gaia_view.h"
@@ -41,6 +42,7 @@
 
 #if defined(GOOGLE_CHROME_BUILD)
 #include "apps/test/app_window_waiter.h"
+#include "ash/public/cpp/ash_pref_names.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -99,6 +101,24 @@
     LoginUtilsTest::SetUp();
   }
 
+  void LoginAndSetContainedShellPref(bool contained_shell_pref_value) {
+    extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
+
+    WaitForSigninScreen();
+
+    Login("username");
+
+    // Take some time to finish login and register user prefs.
+    base::RunLoop().RunUntilIdle();
+
+    // Update the now registered Contained Shell pref.
+    ProfileHelper::Get()
+        ->GetProfileByUser(user_manager::UserManager::Get()->GetActiveUser())
+        ->GetPrefs()
+        ->SetBoolean(ash::prefs::kContainedShellEnabled,
+                     contained_shell_pref_value);
+  }
+
  private:
   base::test::ScopedFeatureList feature_list_;
 };
@@ -138,8 +158,12 @@
   DISALLOW_COPY_AND_ASSIGN(FullscreenWindowEnvObserver);
 };
 
+IN_PROC_BROWSER_TEST_F(LoginUtilsContainedShellTest, PRE_ContainedShellLaunch) {
+  LoginAndSetContainedShellPref(true);
+}
+
 // Checks that the Contained Experience window is launched on sign-in when the
-// feature is enabled.
+// feature is enabled and its pref allows it.
 IN_PROC_BROWSER_TEST_F(LoginUtilsContainedShellTest, ContainedShellLaunch) {
   // Enable all component extensions.
   extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
@@ -150,17 +174,40 @@
 
   Login("username");
 
-  base::RunLoop().RunUntilIdle();
-
   // Wait for the app to launch before verifying it is fullscreen.
   apps::AppWindowWaiter waiter(
       extensions::AppWindowRegistry::Get(ProfileHelper::Get()->GetProfileByUser(
           user_manager::UserManager::Get()->GetActiveUser())),
       extension_misc::kContainedHomeAppId);
-  waiter.WaitForShown();
-
+  EXPECT_NE(nullptr,
+            waiter.WaitForShownWithTimeout(TestTimeouts::action_timeout()));
   EXPECT_TRUE(fullscreen_observer.did_fullscreen_window_launch());
 }
+
+IN_PROC_BROWSER_TEST_F(LoginUtilsContainedShellTest,
+                       PRE_ContainedShellDoesntLaunchWhenPrefIsDisabled) {
+  LoginAndSetContainedShellPref(false);
+}
+
+// Checks that the Contained Experience window does not launch in sign-in when
+// its pref is disabled
+IN_PROC_BROWSER_TEST_F(LoginUtilsContainedShellTest,
+                       ContainedShellDoesntLaunchWhenPrefIsDisabled) {
+  // Enable all component extensions.
+  extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
+
+  WaitForSigninScreen();
+
+  Login("username");
+
+  // Wait for the app to launch before verifying that it didn't.
+  apps::AppWindowWaiter waiter(
+      extensions::AppWindowRegistry::Get(ProfileHelper::Get()->GetProfileByUser(
+          user_manager::UserManager::Get()->GetActiveUser())),
+      extension_misc::kContainedHomeAppId);
+  EXPECT_EQ(nullptr,
+            waiter.WaitForShownWithTimeout(TestTimeouts::action_timeout()));
+}
 #endif  // defined(GOOGLE_CHROME_BUILD)
 
 // Exercises login, like the desktopui_MashLogin Chrome OS autotest.
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index b11a487c..0a0dcad 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -75,7 +75,7 @@
 #include "chromeos/dbus/fake_cryptohome_client.h"
 #include "chromeos/dbus/fake_session_manager_client.h"
 #include "chromeos/dbus/fake_shill_manager_client.h"
-#include "chromeos/dbus/fake_system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/geolocation/simple_geolocation_provider.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -1535,13 +1535,6 @@
                                                   "AABC");
   }
 
-  void SetUpInProcessBrowserTestFixture() override {
-    auto system_clock_client = std::make_unique<FakeSystemClockClient>();
-    system_clock_client_ = system_clock_client.get();
-    DBusThreadManager::GetSetterForTesting()->SetSystemClockClient(
-        std::move(system_clock_client));
-  }
-
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WizardControllerDeviceStateTest::SetUpCommandLine(command_line);
 
@@ -1550,12 +1543,11 @@
         chromeos::AutoEnrollmentController::kInitialEnrollmentAlways);
   }
 
-  FakeSystemClockClient* system_clock_client() { return system_clock_client_; }
+  SystemClockClient::TestInterface* system_clock_client() {
+    return SystemClockClient::Get()->GetTestInterface();
+  }
 
  private:
-  // Unowned pointer - owned by DBusThreadManager.
-  FakeSystemClockClient* system_clock_client_ = nullptr;
-
   DISALLOW_COPY_AND_ASSIGN(
       WizardControllerDeviceStateWithInitialEnrollmentTest);
 };
@@ -1725,7 +1717,7 @@
 
 IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateWithInitialEnrollmentTest,
                        ControlFlowNoInitialEnrollmentDuringEmbargoPeriod) {
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
 
   fake_statistics_provider_.ClearMachineStatistic(system::kActivateDateKey);
@@ -1809,7 +1801,7 @@
   EXPECT_EQ(AutoEnrollmentController::AutoEnrollmentCheckType::kNone,
             auto_enrollment_controller()->auto_enrollment_check_type());
 
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
 
   base::RunLoop().RunUntilIdle();
@@ -1932,7 +1924,7 @@
   g_browser_process->local_state()->Set(prefs::kServerBackedDeviceState,
                                         device_state);
 
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
 
   policy::FakeAutoEnrollmentClient* fake_auto_enrollment_client =
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc
index 25bf6ab..06cac2a 100644
--- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc
+++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.cc
@@ -37,13 +37,13 @@
   if (chromeos::DBusThreadManager::IsInitialized()) {
     chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
         this);
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(
-        this);
-    chromeos::DBusThreadManager::Get()
-        ->GetSystemClockClient()
-        ->WaitForServiceToBeAvailable(
-            base::Bind(&DeviceOffHoursController::SystemClockInitiallyAvailable,
-                       weak_ptr_factory_.GetWeakPtr()));
+    auto* system_clock_client = chromeos::SystemClockClient::Get();
+    if (system_clock_client) {
+      system_clock_client->AddObserver(this);
+      system_clock_client->WaitForServiceToBeAvailable(
+          base::Bind(&DeviceOffHoursController::SystemClockInitiallyAvailable,
+                     weak_ptr_factory_.GetWeakPtr()));
+    }
   }
 }
 
@@ -53,8 +53,8 @@
   if (chromeos::DBusThreadManager::IsInitialized()) {
     chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
         this);
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
-        this);
+    if (chromeos::SystemClockClient::Get())
+      chromeos::SystemClockClient::Get()->RemoveObserver(this);
   }
 }
 
@@ -197,7 +197,7 @@
   // current device time. Ask SystemClockClient to update information about the
   // system time synchronization with the network time asynchronously.
   // Information will be received by NetworkSynchronizationUpdated method.
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->GetLastSyncInfo(
+  chromeos::SystemClockClient::Get()->GetLastSyncInfo(
       base::Bind(&DeviceOffHoursController::NetworkSynchronizationUpdated,
                  weak_ptr_factory_.GetWeakPtr()));
 }
@@ -206,7 +206,7 @@
     bool service_is_available) {
   if (!service_is_available)
     return;
-  chromeos::DBusThreadManager::Get()->GetSystemClockClient()->GetLastSyncInfo(
+  chromeos::SystemClockClient::Get()->GetLastSyncInfo(
       base::Bind(&DeviceOffHoursController::NetworkSynchronizationUpdated,
                  weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h
index e9efd3ef..7b6def2 100644
--- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h
+++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller.h
@@ -14,9 +14,9 @@
 #include "base/time/clock.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chromeos/policy/weekly_time/weekly_time_interval.h"
 #include "chromeos/dbus/power_manager_client.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
+#include "chromeos/policy/weekly_time/weekly_time_interval.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 
 namespace policy {
diff --git a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc
index a53a57f..4ca12b9 100644
--- a/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/off_hours/device_off_hours_controller_unittest.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
-#include "chromeos/dbus/fake_system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 
 namespace em = enterprise_management;
@@ -109,8 +109,7 @@
 
   void SetUp() override {
     chromeos::DeviceSettingsTestBase::SetUp();
-    system_clock_client_ = new chromeos::FakeSystemClockClient();
-    dbus_setter_->SetSystemClockClient(base::WrapUnique(system_clock_client_));
+    chromeos::SystemClockClient::Initialize(nullptr /* bus */);
     power_manager_client_ = new chromeos::FakePowerManagerClient();
     dbus_setter_->SetPowerManagerClient(
         base::WrapUnique(power_manager_client_));
@@ -121,6 +120,8 @@
         device_settings_service_.device_off_hours_controller();
   }
 
+  void TearDown() override { chromeos::SystemClockClient::Shutdown(); }
+
   void UpdateDeviceSettings() {
     device_policy_.Build();
     session_manager_client_.set_device_policy(device_policy_.GetBlob());
@@ -141,8 +142,8 @@
   // = Monday etc.)
   int NextDayOfWeek(int day_of_week) { return day_of_week % 7 + 1; }
 
-  chromeos::FakeSystemClockClient* system_clock_client() {
-    return system_clock_client_;
+  chromeos::SystemClockClient::TestInterface* system_clock_client() {
+    return chromeos::SystemClockClient::Get()->GetTestInterface();
   }
 
   chromeos::FakePowerManagerClient* power_manager() {
@@ -159,9 +160,6 @@
 
  private:
   // The object is owned by DeviceSettingsTestBase class.
-  chromeos::FakeSystemClockClient* system_clock_client_;
-
-  // The object is owned by DeviceSettingsTestBase class.
   chromeos::FakePowerManagerClient* power_manager_client_;
 
   // The object is owned by DeviceSettingsService class.
@@ -174,7 +172,7 @@
 };
 
 TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursUnset) {
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
   em::ChromeDeviceSettingsProto& proto(device_policy_.payload());
   proto.mutable_guest_mode_enabled()->set_guest_mode_enabled(false);
@@ -190,7 +188,7 @@
 }
 
 TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursModeOff) {
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
   em::ChromeDeviceSettingsProto& proto(device_policy_.payload());
   proto.mutable_guest_mode_enabled()->set_guest_mode_enabled(false);
@@ -215,7 +213,7 @@
 }
 
 TEST_F(DeviceOffHoursControllerSimpleTest, CheckOffHoursModeOn) {
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
   em::ChromeDeviceSettingsProto& proto(device_policy_.payload());
   proto.mutable_guest_mode_enabled()->set_guest_mode_enabled(false);
@@ -239,7 +237,7 @@
 }
 
 TEST_F(DeviceOffHoursControllerSimpleTest, NoNetworkSynchronization) {
-  system_clock_client()->set_network_synchronized(false);
+  system_clock_client()->SetNetworkSynchronized(false);
   system_clock_client()->NotifyObserversSystemClockUpdated();
   em::ChromeDeviceSettingsProto& proto(device_policy_.payload());
   proto.mutable_guest_mode_enabled()->set_guest_mode_enabled(false);
@@ -266,7 +264,7 @@
   EXPECT_FALSE(
       device_off_hours_controller()->IsCurrentSessionAllowedOnlyForOffHours());
 
-  system_clock_client()->set_network_synchronized(true);
+  system_clock_client()->SetNetworkSynchronized(true);
   system_clock_client()->NotifyObserversSystemClockUpdated();
 
   EXPECT_FALSE(
@@ -302,7 +300,7 @@
 
   void SetUp() override {
     DeviceOffHoursControllerSimpleTest::SetUp();
-    system_clock_client()->set_network_synchronized(true);
+    system_clock_client()->SetNetworkSynchronized(true);
     system_clock_client()->NotifyObserversSystemClockUpdated();
     // Clocks are set to 1970-01-01 00:00:00 UTC, Thursday.
     test_clock_.SetNow(base::Time::UnixEpoch());
diff --git a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
index 8bb829d..be377e6 100644
--- a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
+++ b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
@@ -110,8 +110,7 @@
   auto interface = UsbInterfaceInfo::New();
   interface->interface_number = 0;
   interface->alternates.push_back(UsbAlternateInterfaceInfo::New(
-      /*alternate_setting=*/0,  // alternate_setting
-      class_code, subclass_code, protocol_code,
+      /*alternate_setting=*/0, class_code, subclass_code, protocol_code,
       /*interface_name=*/base::nullopt, std::move(endpoints)));
 
   auto config = UsbConfigurationInfo::New();
@@ -140,7 +139,7 @@
   device::mojom::UsbDeviceInfoPtr ClonePtr() { return GetDeviceInfo().Clone(); }
 
  private:
-  ~FakeAndroidUsbDeviceInfo() override {}
+  ~FakeAndroidUsbDeviceInfo() override = default;
 
   bool broken_traits_;
 };
@@ -167,8 +166,9 @@
                   const std::string& serial,
                   const std::string& command)
       : callback_(callback),
-        connection_(new MockAndroidConnection(this, serial, command)) {
-  }
+        connection_(
+            std::make_unique<MockAndroidConnection>(this, serial, command)) {}
+  ~MockLocalSocket() override = default;
 
   void Receive(const std::string& data) {
     connection_->Receive(data);
@@ -203,6 +203,8 @@
         base::WrapUnique(device_object), std::move(request));
   }
 
+  ~FakeAndroidUsbDevice() override = default;
+
  protected:
   FakeAndroidUsbDevice(scoped_refptr<FakeUsbDeviceInfo> device,
                        device::mojom::UsbDeviceClientPtr client)
@@ -226,9 +228,10 @@
                           GenericTransferOutCallback callback) override {
     if (remaining_body_length_ == 0) {
       // A new message, parse header first.
+      DCHECK_GE(buffer.size(), 6u);
       const auto* header = reinterpret_cast<const uint32_t*>(buffer.data());
-      current_message_.reset(
-          new AdbMessage(header[0], header[1], header[2], std::string()));
+      current_message_ = std::make_unique<AdbMessage>(header[0], header[1],
+                                                      header[2], std::string());
       remaining_body_length_ = header[3];
       uint32_t magic = header[5];
       if ((current_message_->command ^ 0xffffffff) != magic) {
@@ -403,6 +406,10 @@
 };
 
 class FakeAndroidUsbManager : public FakeUsbDeviceManager {
+ public:
+  FakeAndroidUsbManager() = default;
+  ~FakeAndroidUsbManager() override = default;
+
   void GetDevice(const std::string& guid,
                  device::mojom::UsbDeviceRequest device_request,
                  device::mojom::UsbDeviceClientPtr device_client) override {
@@ -414,7 +421,8 @@
 
 class FakeUsbManagerForCheckingTraits : public FakeAndroidUsbManager {
  public:
-  FakeUsbManagerForCheckingTraits() : step_(0) {}
+  FakeUsbManagerForCheckingTraits() = default;
+  ~FakeUsbManagerForCheckingTraits() override = default;
 
   void GetDevices(device::mojom::UsbEnumerationOptionsPtr options,
                   GetDevicesCallback callback) override {
@@ -448,7 +456,7 @@
   }
 
  private:
-  int step_;
+  int step_ = 0;
 };
 
 class DevToolsAndroidBridgeWarmUp
@@ -457,21 +465,22 @@
   DevToolsAndroidBridgeWarmUp(base::Closure closure,
                               DevToolsAndroidBridge* adb_bridge)
       : closure_(closure), adb_bridge_(adb_bridge) {}
+  ~DevToolsAndroidBridgeWarmUp() override = default;
 
   void DeviceCountChanged(int count) override {
     adb_bridge_->RemoveDeviceCountListener(this);
     closure_.Run();
   }
 
+ private:
   base::Closure closure_;
   DevToolsAndroidBridge* adb_bridge_;
 };
 
 class AndroidUsbDiscoveryTest : public InProcessBrowserTest {
  protected:
-  AndroidUsbDiscoveryTest()
-      : scheduler_invoked_(0) {
-  }
+  AndroidUsbDiscoveryTest() = default;
+  ~AndroidUsbDiscoveryTest() override = default;
 
   void SetUpOnMainThread() override {
     adb_bridge_ =
@@ -481,13 +490,12 @@
         &AndroidUsbDiscoveryTest::ScheduleDeviceCountRequest,
         base::Unretained(this)));
 
-    scoped_refptr<UsbDeviceProvider> provider =
-        new UsbDeviceProvider(browser()->profile());
 
     AndroidDeviceManager::DeviceProviders providers;
-    providers.push_back(provider);
+    providers.push_back(
+        base::MakeRefCounted<UsbDeviceProvider>(browser()->profile()));
     adb_bridge_->set_device_providers_for_test(providers);
-    runner_ = new content::MessageLoopRunner;
+    runner_ = base::MakeRefCounted<content::MessageLoopRunner>();
 
     // Set a fake USB device manager for AndroidUsbDevice.
     usb_manager_ = CreateFakeUsbManager();
@@ -512,22 +520,28 @@
   scoped_refptr<content::MessageLoopRunner> runner_;
   std::unique_ptr<FakeUsbDeviceManager> usb_manager_;
   DevToolsAndroidBridge* adb_bridge_;
-  int scheduler_invoked_;
+  int scheduler_invoked_ = 0;
 };
 
 class AndroidUsbCountTest : public AndroidUsbDiscoveryTest {
  protected:
+  AndroidUsbCountTest() = default;
+  ~AndroidUsbCountTest() override = default;
+
   void SetUpOnMainThread() override {
     AndroidUsbDiscoveryTest::SetUpOnMainThread();
     DevToolsAndroidBridgeWarmUp warmup(runner_->QuitClosure(), adb_bridge_);
     adb_bridge_->AddDeviceCountListener(&warmup);
     runner_->Run();
-    runner_ = new content::MessageLoopRunner;
+    runner_ = base::MakeRefCounted<content::MessageLoopRunner>();
   }
 };
 
 class AndroidUsbTraitsTest : public AndroidUsbDiscoveryTest {
  protected:
+  AndroidUsbTraitsTest() = default;
+  ~AndroidUsbTraitsTest() override = default;
+
   std::unique_ptr<FakeUsbDeviceManager> CreateFakeUsbManager() override {
     return std::make_unique<FakeUsbManagerForCheckingTraits>();
   }
@@ -535,6 +549,9 @@
 
 class AndroidBreakingUsbTest : public AndroidUsbDiscoveryTest {
  protected:
+  AndroidBreakingUsbTest() = default;
+  ~AndroidBreakingUsbTest() override = default;
+
   std::unique_ptr<FakeUsbDeviceManager> CreateFakeUsbManager() override {
     auto manager = std::make_unique<FakeAndroidUsbManager>();
     manager->AddDevice(ConstructFakeUsbDevice<BreakingAndroidTraits>());
@@ -544,6 +561,9 @@
 
 class AndroidNoConfigUsbTest : public AndroidUsbDiscoveryTest {
  protected:
+  AndroidNoConfigUsbTest() = default;
+  ~AndroidNoConfigUsbTest() override = default;
+
   std::unique_ptr<FakeUsbDeviceManager> CreateFakeUsbManager() override {
     auto manager = std::make_unique<FakeAndroidUsbManager>();
     manager->AddDevice(ConstructFakeUsbDevice<AndroidTraits>());
@@ -559,17 +579,18 @@
       : adb_bridge_(adb_bridge),
         callback_(callback) {
   }
+  ~MockListListener() override = default;
 
   void DeviceListChanged(
       const DevToolsAndroidBridge::RemoteDevices& devices) override {
-      for (const auto& device : devices) {
-        if (device->is_connected()) {
-          ASSERT_EQ(kDeviceModel, device->model());
-          ASSERT_EQ(kDeviceSerial, device->serial());
-          adb_bridge_->RemoveDeviceListListener(this);
-          callback_.Run();
-          break;
-        }
+    for (const auto& device : devices) {
+      if (device->is_connected()) {
+        ASSERT_EQ(kDeviceModel, device->model());
+        ASSERT_EQ(kDeviceSerial, device->serial());
+        adb_bridge_->RemoveDeviceListListener(this);
+        callback_.Run();
+        break;
+      }
     }
   }
 
@@ -580,7 +601,8 @@
 class MockCountListener : public DevToolsAndroidBridge::DeviceCountListener {
  public:
   explicit MockCountListener(DevToolsAndroidBridge* adb_bridge)
-      : adb_bridge_(adb_bridge), invoked_(0) {}
+      : adb_bridge_(adb_bridge) {}
+  ~MockCountListener() override = default;
 
   void DeviceCountChanged(int count) override {
     ++invoked_;
@@ -591,16 +613,14 @@
   void Shutdown() { base::RunLoop::QuitCurrentWhenIdleDeprecated(); }
 
   DevToolsAndroidBridge* adb_bridge_;
-  int invoked_;
+  int invoked_ = 0;
 };
 
 class MockCountListenerWithReAdd : public MockCountListener {
  public:
-  explicit MockCountListenerWithReAdd(
-      DevToolsAndroidBridge* adb_bridge)
-      : MockCountListener(adb_bridge),
-        readd_count_(2) {
-  }
+  explicit MockCountListenerWithReAdd(DevToolsAndroidBridge* adb_bridge)
+      : MockCountListener(adb_bridge) {}
+  ~MockCountListenerWithReAdd() override = default;
 
   void DeviceCountChanged(int count) override {
     ++invoked_;
@@ -615,16 +635,15 @@
     }
   }
 
-  int readd_count_;
+  int readd_count_ = 2;
 };
 
 class MockCountListenerWithReAddWhileQueued : public MockCountListener {
  public:
-  MockCountListenerWithReAddWhileQueued(
+  explicit MockCountListenerWithReAddWhileQueued(
       DevToolsAndroidBridge* adb_bridge)
-      : MockCountListener(adb_bridge),
-        readded_(false) {
-  }
+      : MockCountListener(adb_bridge) {}
+  ~MockCountListenerWithReAddWhileQueued() override = default;
 
   void DeviceCountChanged(int count) override {
     ++invoked_;
@@ -645,16 +664,15 @@
     adb_bridge_->AddDeviceCountListener(this);
   }
 
-  bool readded_;
+  bool readded_ = false;
 };
 
 class MockCountListenerForCheckingTraits : public MockCountListener {
  public:
-  MockCountListenerForCheckingTraits(
-      DevToolsAndroidBridge* adb_bridge)
-      : MockCountListener(adb_bridge),
-        step_(0) {
-  }
+  explicit MockCountListenerForCheckingTraits(DevToolsAndroidBridge* adb_bridge)
+      : MockCountListener(adb_bridge) {}
+  ~MockCountListenerForCheckingTraits() override = default;
+
   void DeviceCountChanged(int count) override {
     switch (step_) {
       case 0:
@@ -681,7 +699,7 @@
     step_++;
   }
 
-  int step_;
+  int step_ = 0;
 };
 
 }  // namespace
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 2502666a..4403b6f 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -152,7 +152,7 @@
             weak_ptr_factory_.GetWeakPtr(), gaia_id));
   } else {
     // Get the AccountInfo for the account that the extension wishes to use.
-    GetMojoIdentityManager()->GetAccountInfoFromGaiaId(
+    GetMojoIdentityAccessor()->GetAccountInfoFromGaiaId(
         gaia_id,
         base::BindOnce(
             &IdentityGetAuthTokenFunction::OnReceivedExtensionAccountInfo, this,
@@ -261,7 +261,7 @@
     // If the account is in auth error, it won't be in the identity manager.
     // Save the email now to use as email hint for the login prompt.
     email_for_default_web_account_ = account.email;
-    GetMojoIdentityManager()->GetAccountInfoFromGaiaId(
+    GetMojoIdentityAccessor()->GetAccountInfoFromGaiaId(
         account.gaia_id,
         base::BindOnce(
             &IdentityGetAuthTokenFunction::OnReceivedExtensionAccountInfo, this,
@@ -729,7 +729,7 @@
   gaia_web_auth_flow_.reset();
   device_access_token_request_.reset();
   token_key_account_access_token_fetcher_.reset();
-  mojo_identity_manager_.reset();
+  mojo_identity_accessor_.reset();
   scoped_identity_manager_observer_.RemoveAll();
   extensions::IdentityAPI::GetFactoryInstance()
       ->Get(GetProfile())
@@ -873,14 +873,14 @@
   return client_id;
 }
 
-::identity::mojom::IdentityManager*
-IdentityGetAuthTokenFunction::GetMojoIdentityManager() {
-  if (!mojo_identity_manager_.is_bound()) {
+::identity::mojom::IdentityAccessor*
+IdentityGetAuthTokenFunction::GetMojoIdentityAccessor() {
+  if (!mojo_identity_accessor_.is_bound()) {
     content::BrowserContext::GetConnectorFor(GetProfile())
         ->BindInterface(::identity::mojom::kServiceName,
-                        mojo::MakeRequest(&mojo_identity_manager_));
+                        mojo::MakeRequest(&mojo_identity_accessor_));
   }
-  return mojo_identity_manager_.get();
+  return mojo_identity_accessor_.get();
 }
 
 bool IdentityGetAuthTokenFunction::IsPrimaryAccountOnly() const {
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
index 8c24338..d9dc69a 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -21,7 +21,7 @@
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/cpp/identity_manager.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 
 namespace identity {
 class AccessTokenFetcher;
@@ -194,12 +194,12 @@
 
   std::string GetOAuth2ClientId() const;
 
-  // Gets the Identity Manager, lazily binding it.
+  // Gets the IdentityAccessor mojo interface, lazily binding it.
   // TODO(https://crbug.com/913853): As of Dec 2018, the chrome.identity
   // API is the only client of the Identity Service. It should be migrated to
   // the IdentityManager soon after the IdentityManager is backed by the
   // Identity Service.
-  ::identity::mojom::IdentityManager* GetMojoIdentityManager();
+  ::identity::mojom::IdentityAccessor* GetMojoIdentityAccessor();
 
   // Returns true if extensions are restricted to the primary account.
   bool IsPrimaryAccountOnly() const;
@@ -225,7 +225,7 @@
   std::unique_ptr<base::CallbackList<void()>::Subscription>
       identity_api_shutdown_subscription_;
 
-  identity::mojom::IdentityManagerPtr mojo_identity_manager_;
+  identity::mojom::IdentityAccessorPtr mojo_identity_accessor_;
   ScopedObserver<identity::IdentityManager, identity::IdentityManager::Observer>
       scoped_identity_manager_observer_;
 
diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
index 885dfd9..f03aab6 100644
--- a/chrome/browser/extensions/webstore_installer.cc
+++ b/chrome/browser/extensions/webstore_installer.cc
@@ -129,14 +129,7 @@
   base::FilePath file =
       download_directory.AppendASCII(id + "_" + random_number + ".crx");
 
-  int uniquifier =
-      base::GetUniquePathNumber(file, base::FilePath::StringType());
-  if (uniquifier > 0) {
-    file = file.InsertBeforeExtensionASCII(
-        base::StringPrintf(" (%d)", uniquifier));
-  }
-
-  return file;
+  return base::GetUniquePath(file);
 }
 
 void MaybeAppendAuthUserParameter(const std::string& authuser, GURL* url) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index e7464bc..315e9000 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2814,8 +2814,9 @@
   },
   {
     "name": "show-autofill-type-predictions",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "ftirelo", "mathp" ],
+    // This is used by autofill devs to debug on Android.
+    "expiry_milestone": -1
   },
   {
     "name": "show-managed-ui",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 6a5e274..b5ff356 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2707,9 +2707,9 @@
 
 #if BUILDFLAG(ENABLE_ANDROID_NIGHT_MODE)
 
-const char kAndroidNightModeName[] = "Enable night mode based on user settings";
+const char kAndroidNightModeName[] = "Android Chrome UI dark mode";
 const char kAndroidNightModeDescription[] =
-    "If enabled, user can enable night mode through settings.";
+    "If enabled, user can enable Android Chrome UI dark mode through settings.";
 
 #endif  // BUILDFLAG(ENABLE_ANDROID_NIGHT_MODE)
 
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc
index 4041d91c..3bceb80a 100644
--- a/chrome/browser/net/profile_network_context_service.cc
+++ b/chrome/browser/net/profile_network_context_service.cc
@@ -37,7 +37,6 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/shared_cors_origin_access_list.h"
 #include "content/public/browser/storage_partition.h"
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index bc24283e..5498e6aa 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -40,12 +40,10 @@
 #include "components/policy/policy_constants.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/variations/net/variations_http_headers.h"
 #include "components/variations/variations_associated_data.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
@@ -581,8 +579,6 @@
 SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
   network::mojom::NetworkContextParamsPtr network_context_params =
       network::mojom::NetworkContextParams::New();
-  content::UpdateCorsExemptHeader(network_context_params.get());
-  variations::UpdateCorsExemptHeaderForVariations(network_context_params.get());
 
   network_context_params->enable_brotli =
       base::FeatureList::IsEnabled(features::kBrotliEncoding);
diff --git a/chrome/browser/performance_manager/browser_child_process_watcher.cc b/chrome/browser/performance_manager/browser_child_process_watcher.cc
index 2669784..c0a35bf 100644
--- a/chrome/browser/performance_manager/browser_child_process_watcher.cc
+++ b/chrome/browser/performance_manager/browser_child_process_watcher.cc
@@ -61,10 +61,13 @@
 }
 
 void BrowserChildProcessWatcher::GPUProcessExited(int id, int exit_code) {
-  DCHECK(base::ContainsKey(gpu_process_nodes_, id));
-
-  auto* process_node = gpu_process_nodes_[id].get();
-  process_node->SetProcessExitStatus(exit_code);
+  // It appears the exit code can be delivered either after the host is
+  // disconnected, or perhaps before the HostConnected notification,
+  // specifically on crash.
+  if (base::ContainsKey(gpu_process_nodes_, id)) {
+    auto* process_node = gpu_process_nodes_[id].get();
+    process_node->SetProcessExitStatus(exit_code);
+  }
 }
 
 }  // namespace performance_manager
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 460bb02..4b660619 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -554,6 +554,8 @@
 #endif
     RegisterUserProfilePrefs(pref_registry_.get());
 
+  SimpleDependencyManager::GetInstance()->RegisterProfilePrefsForServices(
+      key_.get(), pref_registry_.get());
   BrowserContextDependencyManager::GetInstance()
       ->RegisterProfilePrefsForServices(this, pref_registry_.get());
 
diff --git a/chrome/browser/resources/browser_switcher/app.js b/chrome/browser/resources/browser_switcher/app.js
index e34196f..4f2d80b 100644
--- a/chrome/browser/resources/browser_switcher/app.js
+++ b/chrome/browser/resources/browser_switcher/app.js
@@ -123,7 +123,7 @@
     if (this.error_) {
       return this.i18n(this.error_, getUrlHostname(this.url_));
     }
-    return this.i18n('description');
+    return this.i18n('description', getUrlHostname(this.url_));
   },
 });
 
diff --git a/chrome/browser/resources/history/shared_vars.html b/chrome/browser/resources/history/shared_vars.html
index 73ce890..d5f0b55 100644
--- a/chrome/browser/resources/history/shared_vars.html
+++ b/chrome/browser/resources/history/shared_vars.html
@@ -33,6 +33,7 @@
   }
 
   html[dark] {
+    --card-border-color: var(--google-grey-refresh-500);
     --history-item-time-color: var(--cr-secondary-text-color);
     --interactive-color: var(--google-blue-refresh-300);
     --separator-color: var(--cr-separator-color);
diff --git a/chrome/browser/safe_browsing/download_protection/two_phase_uploader_unittest.cc b/chrome/browser/safe_browsing/download_protection/two_phase_uploader_unittest.cc
index 161876d..47e9389 100644
--- a/chrome/browser/safe_browsing/download_protection/two_phase_uploader_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/two_phase_uploader_unittest.cc
@@ -76,7 +76,8 @@
         std::make_unique<network::TestNetworkServiceClient>(
             mojo::MakeRequest(&network_service_client_ptr));
     network_service_ = network::NetworkService::CreateForTesting();
-    network_service_->SetClient(std::move(network_service_client_ptr));
+    network_service_->SetClient(std::move(network_service_client_ptr),
+                                network::mojom::NetworkServiceParams::New());
     shared_url_loader_factory_ =
         base::MakeRefCounted<network::TestSharedURLLoaderFactory>(
             network_service_.get());
diff --git a/chrome/browser/search/instant_service_unittest.cc b/chrome/browser/search/instant_service_unittest.cc
index 66345ae..3f5dc50 100644
--- a/chrome/browser/search/instant_service_unittest.cc
+++ b/chrome/browser/search/instant_service_unittest.cc
@@ -20,7 +20,7 @@
 #include "chrome/common/url_constants.h"
 #include "components/ntp_tiles/constants.h"
 #include "components/ntp_tiles/ntp_tile.h"
-#include "components/ntp_tiles/pref_names.cc"
+#include "components/ntp_tiles/pref_names.h"
 #include "components/ntp_tiles/section_type.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler.h b/chrome/browser/send_tab_to_self/receiving_ui_handler.h
index 3790b99..36ba233f 100644
--- a/chrome/browser/send_tab_to_self/receiving_ui_handler.h
+++ b/chrome/browser/send_tab_to_self/receiving_ui_handler.h
@@ -23,13 +23,13 @@
 
   // Display the new entry passed in as an argument. The entry is owned by the
   // model and should not be modified.
-  virtual void DisplayNewEntry(const SendTabToSelfEntry* entry);
+  virtual void DisplayNewEntry(const SendTabToSelfEntry* entry) = 0;
   // Dismiss any UI associated with this entry.
   // Entry object is owned by the the model and should not be
   // modified by any implementors of this class.
   // TODO(crbug.com/935719): Figure out whether we need to pass the entire entry
   // or we can pass a smaller subset of information.
-  virtual void DismissEntry(const SendTabToSelfEntry* entry);
+  virtual void DismissEntry(const SendTabToSelfEntry* entry) = 0;
 };
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc
index c219e22..2945b0b 100644
--- a/chrome/browser/signin/account_consistency_mode_manager.cc
+++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -21,7 +21,7 @@
 #include "google_apis/google_api_keys.h"
 
 #if defined(OS_CHROMEOS)
-#include "chromeos/constants/chromeos_switches.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #endif
 
 using signin::AccountConsistencyMethod;
@@ -210,11 +210,9 @@
       kAccountConsistencyFeature, kAccountConsistencyFeatureMethodParameter);
 
 #if defined(OS_CHROMEOS)
-  if (chromeos::switches::IsAccountManagerEnabled())
+  if (chromeos::IsAccountManagerAvailable(profile))
     return AccountConsistencyMethod::kMirror;
 
-  // TODO(sinhak): Clean this up. When Account Manager is released, Chrome OS
-  // will always have Mirror enabled for regular profiles.
   return (method_value == kAccountConsistencyFeatureMethodMirror ||
           profile->GetPrefs()->GetBoolean(
               prefs::kAccountConsistencyMirrorRequired))
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc
index b1b909d..ac45123 100644
--- a/chrome/browser/signin/dice_response_handler_unittest.cc
+++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -20,19 +20,12 @@
 #include "components/signin/core/browser/about_signin_internals.h"
 #include "components/signin/core/browser/account_consistency_method.h"
 #include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
-#include "components/signin/core/browser/fake_account_fetcher_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
-#include "components/signin/core/browser/mutable_profile_oauth2_token_service_delegate.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/core/browser/signin_header_helper.h"
-#include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "google_apis/gaia/fake_oauth2_token_service_delegate.h"
 #include "services/identity/public/cpp/identity_test_environment.h"
 #include "services/identity/public/cpp/identity_test_utils.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -98,20 +91,10 @@
             base::test::ScopedTaskEnvironment::MainThreadType::
                 IO_MOCK_TIME),  // URLRequestContext requires IO.
         signin_client_(&pref_service_),
-        token_service_(&pref_service_,
-                       std::make_unique<FakeOAuth2TokenServiceDelegate>()),
-        signin_manager_(&signin_client_,
-                        &token_service_,
-                        &account_tracker_service_,
-                        nullptr,
-                        signin::AccountConsistencyMethod::kDisabled),
-        cookie_service_(&token_service_, &signin_client_),
-        identity_test_env_(&pref_service_,
-                           &account_tracker_service_,
-                           &account_fetcher_service_,
-                           &token_service_,
-                           &signin_manager_,
-                           &cookie_service_),
+        identity_test_env_(/*test_url_loader_factory=*/nullptr,
+                           &pref_service_,
+                           signin::AccountConsistencyMethod::kDice,
+                           &signin_client_),
         signin_error_controller_(
             SigninErrorController::AccountMode::PRIMARY_ACCOUNT,
             identity_test_env_.identity_manager()),
@@ -122,15 +105,6 @@
         reconcilor_unblocked_count_(0) {
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     AboutSigninInternals::RegisterPrefs(pref_service_.registry());
-    AccountTrackerService::RegisterPrefs(pref_service_.registry());
-    AccountFetcherService::RegisterPrefs(pref_service_.registry());
-    ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
-    SigninManager::RegisterProfilePrefs(pref_service_.registry());
-    account_tracker_service_.Initialize(&pref_service_, base::FilePath());
-    signin_manager_.Initialize(&pref_service_);
-    account_fetcher_service_.Initialize(&signin_client_, &token_service_,
-                                        &account_tracker_service_,
-                                        std::make_unique<TestImageDecoder>());
     auto account_reconcilor_delegate =
         std::make_unique<signin::DiceAccountReconcilorDelegate>(
             &signin_client_, signin::AccountConsistencyMethod::kDiceMigration);
@@ -145,13 +119,7 @@
     account_reconcilor_->RemoveObserver(this);
     account_reconcilor_->Shutdown();
     about_signin_internals_.Shutdown();
-    cookie_service_.Shutdown();
     signin_error_controller_.Shutdown();
-    signin_manager_.Shutdown();
-    account_fetcher_service_.Shutdown();
-    account_tracker_service_.Shutdown();
-    token_service_.Shutdown();
-    signin_client_.Shutdown();
   }
 
   void InitializeDiceResponseHandler(
@@ -206,11 +174,6 @@
   base::ScopedTempDir temp_dir_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   DiceTestSigninClient signin_client_;
-  FakeProfileOAuth2TokenService token_service_;
-  AccountTrackerService account_tracker_service_;
-  FakeAccountFetcherService account_fetcher_service_;
-  SigninManager signin_manager_;
-  GaiaCookieManagerService cookie_service_;
   identity::IdentityTestEnvironment identity_test_env_;
   SigninErrorController signin_error_controller_;
   AboutSigninInternals about_signin_internals_;
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
index 4351a96a..60b13deb 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -34,10 +34,10 @@
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #include "chrome/browser/chromeos/oauth2_token_service_delegate.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chromeos/account_manager/account_manager_factory.h"
-#include "chromeos/constants/chromeos_switches.h"
 #include "components/user_manager/user_manager.h"
 #endif  // defined(OS_CHROMEOS)
 
@@ -48,17 +48,6 @@
 namespace {
 
 #if defined(OS_CHROMEOS)
-bool ShouldCreateCrOsOAuthDelegate(Profile* profile) {
-  // Chrome OS Account Manager should only be instantiated in "regular"
-  // profiles. Do not try to create |ChromeOSOAuth2TokenServiceDelegate| (which
-  // uses CrOS Account Manager as the source of truth) for Signin Profile,
-  // Lock Screen Profile and Guest Sessions.
-  return chromeos::switches::IsAccountManagerEnabled() &&
-         !chromeos::ProfileHelper::IsSigninProfile(profile) &&
-         !chromeos::ProfileHelper::IsLockScreenAppProfile(profile) &&
-         !profile->IsGuestSession();
-}
-
 std::unique_ptr<chromeos::ChromeOSOAuth2TokenServiceDelegate>
 CreateCrOsOAuthDelegate(Profile* profile) {
   chromeos::AccountManagerFactory* factory =
@@ -130,7 +119,7 @@
 #else  // defined(OS_ANDROID)
 
 #if defined(OS_CHROMEOS)
-  if (ShouldCreateCrOsOAuthDelegate(profile)) {
+  if (chromeos::IsAccountManagerAvailable(profile)) {
     return CreateCrOsOAuthDelegate(profile);
   }
 #endif  // defined(OS_CHROMEOS)
@@ -138,7 +127,7 @@
   // Fall back to |MutableProfileOAuth2TokenServiceDelegate|:
   // 1. On all platforms other than Android and Chrome OS.
   // 2. On Chrome OS, if |ChromeOSOAuth2TokenServiceDelegate| cannot be used
-  // for this |profile|. See |ShouldCreateCrOsOAuthDelegate|.
+  // for this |profile|. See |chromeos::IsAccountManagerAvailable|.
   return CreateMutableProfileOAuthDelegate(profile);
 
 #endif  // defined(OS_ANDROID)
diff --git a/chrome/browser/signin/signin_error_notifier_ash.cc b/chrome/browser/signin/signin_error_notifier_ash.cc
index f0f23fa..03cf1b95 100644
--- a/chrome/browser/signin/signin_error_notifier_ash.cc
+++ b/chrome/browser/signin/signin_error_notifier_ash.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #include "chrome/browser/chromeos/login/user_flow.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -31,7 +32,6 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
-#include "chromeos/constants/chromeos_switches.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "services/identity/public/cpp/identity_manager.h"
@@ -100,7 +100,7 @@
       return;
   }
 
-  if (!chromeos::switches::IsAccountManagerEnabled()) {
+  if (!chromeos::IsAccountManagerAvailable(profile_)) {
     // If this flag is disabled, Chrome OS does not have a concept of Secondary
     // Accounts. Preserve existing behavior.
     HandleDeviceAccountError();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 3069d1a..e2f1fea 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -12,6 +12,7 @@
 import("//chrome/common/features.gni")
 import("//chromeos/assistant/assistant.gni")
 import("//components/feature_engagement/features.gni")
+import("//components/feed/features.gni")
 import("//components/nacl/features.gni")
 import("//components/offline_pages/buildflags/features.gni")
 import("//components/signin/features.gni")
@@ -412,6 +413,7 @@
     "//components/favicon/content",
     "//components/favicon/core",
     "//components/feature_engagement",
+    "//components/feed:buildflags",
     "//components/feed:feature_list",
     "//components/feed/content:feed_content",
     "//components/feed/core:feed_core",
@@ -560,9 +562,11 @@
     deps += [
       "//chrome/browser/ui/webui/eoc_internals:mojo_bindings",
       "//chrome/browser/ui/webui/explore_sites_internals:mojo_bindings",
-      "//chrome/browser/ui/webui/feed_internals:mojo_bindings",
       "//chrome/browser/ui/webui/snippets_internals:mojo_bindings",
     ]
+    if (enable_feed_in_chrome) {
+      deps += [ "//chrome/browser/ui/webui/feed_internals:mojo_bindings" ]
+    }
   }
 
   if (!is_fuchsia) {
@@ -718,10 +722,6 @@
       "webui/explore_sites_internals/explore_sites_internals_page_handler.h",
       "webui/explore_sites_internals/explore_sites_internals_ui.cc",
       "webui/explore_sites_internals/explore_sites_internals_ui.h",
-      "webui/feed_internals/feed_internals_page_handler.cc",
-      "webui/feed_internals/feed_internals_page_handler.h",
-      "webui/feed_internals/feed_internals_ui.cc",
-      "webui/feed_internals/feed_internals_ui.h",
       "webui/offline/offline_internals_ui.cc",
       "webui/offline/offline_internals_ui.h",
       "webui/offline/offline_internals_ui_message_handler.cc",
@@ -735,8 +735,16 @@
       "webui/webapks_ui.cc",
       "webui/webapks_ui.h",
     ]
+    if (enable_feed_in_chrome) {
+      sources += [
+        "webui/feed_internals/feed_internals_page_handler.cc",
+        "webui/feed_internals/feed_internals_page_handler.h",
+        "webui/feed_internals/feed_internals_ui.cc",
+        "webui/feed_internals/feed_internals_ui.h",
+      ]
+    }
     deps += [
-      "//chrome/browser:jni_headers",
+      "//chrome/android:jni_headers",
       "//components/embedder_support/android:web_contents_delegate",
       "//components/navigation_interception",
       "//components/subresource_filter/core/browser:browser",
@@ -1753,6 +1761,7 @@
       "//chromeos/cryptohome",
       "//chromeos/dbus",
       "//chromeos/dbus:cryptohome_proto",
+      "//chromeos/dbus/system_clock",
       "//chromeos/login/auth",
       "//chromeos/login/login_state",
       "//chromeos/network",
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
index 6afcdd8..dc1bb7b 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
@@ -378,6 +378,7 @@
       context, delegate.release(), new ChromeWebContentsHandler);
   views::Widget::InitParams init_params(
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+  init_params.keep_on_top = true;
   views::WebDialogView* web_view = view.release();
   init_params.name = "GCPW";  // Used for debugging only.
   init_params.delegate = web_view;
diff --git a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
index 469f3f9..74509e7 100644
--- a/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
+++ b/chrome/browser/ui/views/drag_and_drop_interactive_uitest.cc
@@ -835,7 +835,7 @@
 // There is no known way to execute test-controlled tasks during
 // a drag-and-drop loop run by Windows OS.
 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
-#elif defined(OS_CHROMEOS)
+#elif defined(OS_CHROMEOS) || defined(OS_LINUX)
 // Flakiness on CrOS tracked by https://crbug.com/835573.
 #define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
 #else
diff --git a/chrome/browser/ui/views/payments/payment_request_update_with_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_update_with_browsertest.cc
index e636197b..d6e152c 100644
--- a/chrome/browser/ui/views/payments/payment_request_update_with_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_update_with_browsertest.cc
@@ -296,4 +296,35 @@
   ExpectBodyContains({"freeShipping"});
 }
 
+// Show the shipping address validation error message even if the merchant
+// provided some shipping options.
+IN_PROC_BROWSER_TEST_F(PaymentRequestUpdateWithTest, UpdateWithError) {
+  NavigateTo("/payment_request_update_with_test.html");
+  autofill::AutofillProfile billing_address = autofill::test::GetFullProfile();
+  AddAutofillProfile(billing_address);
+  AddAutofillProfile(autofill::test::GetFullProfile2());
+  autofill::CreditCard card = autofill::test::GetCreditCard();
+  card.set_billing_address_id(billing_address.guid());
+  AddCreditCard(card);
+
+  RunJavaScriptFunctionToOpenPaymentRequestUI("updateWithError");
+
+  OpenShippingAddressSectionScreen();
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING});
+  ClickOnChildInListViewAndWait(
+      /* child_index=*/1, /*total_num_children=*/2,
+      DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
+      /*wait_for_animation=*/false);
+  // Wait for the animation here explicitly, otherwise
+  // ClickOnChildInListViewAndWait tries to install an AnimationDelegate before
+  // the animation is kicked off (since that's triggered off of the spec being
+  // updated) and this hits a DCHECK.
+  WaitForAnimation();
+
+  EXPECT_EQ(base::ASCIIToUTF16("This is an error for a browsertest"),
+            GetLabelText(DialogViewID::SHIPPING_ADDRESS_SECTION_HEADER_LABEL));
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
index 1cc609d7..6b52e8e6 100644
--- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc
+++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -178,8 +178,10 @@
   // | Warning icon | Warning message            |
   // ---------------------------------------------
   std::unique_ptr<views::View> CreateHeaderView() override {
-    if (!spec()->GetShippingOptions().empty())
+    if (!spec()->GetShippingOptions().empty() &&
+        spec()->selected_shipping_option_error().empty()) {
       return nullptr;
+    }
 
     auto header_view = std::make_unique<views::View>();
     // 8 pixels between the warning icon view (if present) and the text.
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index ee25b11..ea09634 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -118,11 +118,14 @@
 #if defined(OS_ANDROID)
 #include "chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h"
 #include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals_ui.h"
-#include "chrome/browser/ui/webui/feed_internals/feed_internals_ui.h"
 #include "chrome/browser/ui/webui/offline/offline_internals_ui.h"
 #include "chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h"
 #include "chrome/browser/ui/webui/webapks_ui.h"
+#include "components/feed/buildflags.h"
 #include "components/feed/feed_feature_list.h"
+#if BUILDFLAG(ENABLE_FEED_IN_CHROME)
+#include "chrome/browser/ui/webui/feed_internals/feed_internals_ui.h"
+#endif  // BUILDFLAG(ENABLE_FEED_IN_CHROME)
 #else
 #include "chrome/browser/ui/webui/bookmarks/bookmarks_ui.h"
 #include "chrome/browser/ui/webui/devtools_ui.h"
@@ -547,10 +550,15 @@
     return &NewWebUI<OfflineInternalsUI>;
   if (url.host_piece() == chrome::kChromeUISnippetsInternalsHost &&
       !profile->IsOffTheRecord()) {
-    if (base::FeatureList::IsEnabled(feed::kInterestFeedContentSuggestions))
-      return &NewWebUI<FeedInternalsUI>;
-    else
+    if (!base::FeatureList::IsEnabled(feed::kInterestFeedContentSuggestions)) {
       return &NewWebUI<SnippetsInternalsUI>;
+    } else {
+#if BUILDFLAG(ENABLE_FEED_IN_CHROME)
+      return &NewWebUI<FeedInternalsUI>;
+#else
+      return nullptr;
+#endif  // BUILDFLAG(ENABLE_FEED_IN_CHROME)
+    }
   }
   if (url.host_piece() == chrome::kChromeUIWebApksHost)
     return &NewWebUI<WebApksUI>;
diff --git a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc
index 75edf7a9..25d655f 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc
@@ -78,10 +78,6 @@
 
 void BaseWebUIHandler::GetAdditionalParameters(base::DictionaryValue* dict) {}
 
-void BaseWebUIHandler::CallJS(const std::string& method) {
-  web_ui()->CallJavascriptFunctionUnsafe(method);
-}
-
 void BaseWebUIHandler::ShowScreen(OobeScreen screen) {
   ShowScreenWithData(screen, nullptr);
 }
@@ -95,8 +91,7 @@
   if (data) {
     screen_params.SetKey("data", data->Clone());
   }
-  web_ui()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.showScreen",
-                                         screen_params);
+  CallJS("cr.ui.Oobe.showScreen", screen_params);
 }
 
 OobeUI* BaseWebUIHandler::GetOobeUI() const {
diff --git a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
index d5f56e0..9722baa 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
@@ -21,7 +21,7 @@
 namespace base {
 class DictionaryValue;
 class ListValue;
-}
+}  // namespace base
 
 namespace login {
 class LocalizedValuesBuilder;
@@ -120,57 +120,81 @@
   // with Context at some point.
   virtual void GetAdditionalParameters(base::DictionaryValue* parameters);
 
-  // Shortcut for calling JS methods on WebUI side.
-  void CallJS(const std::string& method);
+  void CallJS(const std::string& function_name) {
+    if (js_calls_container_->is_initialized()) {
+      web_ui()->CallJavascriptFunctionUnsafe(function_name);
+    } else {
+      js_calls_container_->deferred_js_calls().push_back(
+          base::Bind(&BaseWebUIHandler::CallJavascriptFunctionImmediate<>,
+                     base::Unretained(this), function_name));
+    }
+  }
 
   template <typename A1>
-  void CallJS(const std::string& method, const A1& arg1) {
-    web_ui()->CallJavascriptFunctionUnsafe(method, ::login::MakeValue(arg1));
+  void CallJS(const std::string& function_name, const A1& arg1) {
+    if (js_calls_container_->is_initialized()) {
+      web_ui()->CallJavascriptFunctionUnsafe(function_name,
+                                             ::login::MakeValue(arg1));
+    } else {
+      js_calls_container_->deferred_js_calls().push_back(base::Bind(
+          &BaseWebUIHandler::CallJavascriptFunctionImmediate<base::Value>,
+          base::Unretained(this), function_name,
+          ::login::MakeValue(arg1).Clone()));
+    }
   }
 
   template <typename A1, typename A2>
-  void CallJS(const std::string& method, const A1& arg1, const A2& arg2) {
-    web_ui()->CallJavascriptFunctionUnsafe(method, ::login::MakeValue(arg1),
-                                           ::login::MakeValue(arg2));
+  void CallJS(const std::string& function_name,
+              const A1& arg1,
+              const A2& arg2) {
+    if (js_calls_container_->is_initialized()) {
+      web_ui()->CallJavascriptFunctionUnsafe(
+          function_name, ::login::MakeValue(arg1), ::login::MakeValue(arg2));
+    } else {
+      js_calls_container_->deferred_js_calls().push_back(base::Bind(
+          &BaseWebUIHandler::CallJavascriptFunctionImmediate<base::Value,
+                                                             base::Value>,
+          base::Unretained(this), function_name,
+          ::login::MakeValue(arg1).Clone(), ::login::MakeValue(arg2).Clone()));
+    }
   }
 
   template <typename A1, typename A2, typename A3>
-  void CallJS(const std::string& method,
+  void CallJS(const std::string& function_name,
               const A1& arg1,
               const A2& arg2,
               const A3& arg3) {
-    web_ui()->CallJavascriptFunctionUnsafe(method, ::login::MakeValue(arg1),
-                                           ::login::MakeValue(arg2),
-                                           ::login::MakeValue(arg3));
+    if (js_calls_container_->is_initialized()) {
+      web_ui()->CallJavascriptFunctionUnsafe(
+          function_name, ::login::MakeValue(arg1), ::login::MakeValue(arg2),
+          ::login::MakeValue(arg3));
+    } else {
+      js_calls_container_->deferred_js_calls().push_back(base::Bind(
+          &BaseWebUIHandler::CallJavascriptFunctionImmediate<
+              base::Value, base::Value, base::Value>,
+          base::Unretained(this), function_name,
+          ::login::MakeValue(arg1).Clone(), ::login::MakeValue(arg2).Clone(),
+          ::login::MakeValue(arg3).Clone()));
+    }
   }
 
   template <typename A1, typename A2, typename A3, typename A4>
-  void CallJS(const std::string& method,
+  void CallJS(const std::string& function_name,
               const A1& arg1,
               const A2& arg2,
               const A3& arg3,
               const A4& arg4) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        method, ::login::MakeValue(arg1), ::login::MakeValue(arg2),
-        ::login::MakeValue(arg3), ::login::MakeValue(arg4));
-  }
-
-  template <typename... Args>
-  void CallJSOrDefer(const std::string& function_name, const Args&... args) {
-    DCHECK(js_calls_container_);
     if (js_calls_container_->is_initialized()) {
-      CallJS(function_name, args...);
+      web_ui()->CallJavascriptFunctionUnsafe(
+          function_name, ::login::MakeValue(arg1), ::login::MakeValue(arg2),
+          ::login::MakeValue(arg3), ::login::MakeValue(arg4));
     } else {
-      // Note that std::conditional is used here in order to obtain a sequence
-      // of base::Value types with the length equal to sizeof...(Args); the C++
-      // template parameter pack expansion rules require that the name of the
-      // parameter pack appears in the pattern, even though the elements of the
-      // Args pack are not actually in this code.
       js_calls_container_->deferred_js_calls().push_back(base::Bind(
-          &BaseWebUIHandler::ExecuteDeferredJSCall<
-              typename std::conditional<true, base::Value, Args>::type...>,
+          &BaseWebUIHandler::CallJavascriptFunctionImmediate<
+              base::Value, base::Value, base::Value, base::Value>,
           base::Unretained(this), function_name,
-          base::Passed(::login::MakeValue(args).CreateDeepCopy())...));
+          ::login::MakeValue(arg1).Clone(), ::login::MakeValue(arg2).Clone(),
+          ::login::MakeValue(arg3).Clone(), ::login::MakeValue(arg4).Clone()));
     }
   }
 
@@ -217,14 +241,13 @@
 
  private:
   friend class OobeUI;
-  // Calls Javascript method.
-  //
-  // Note that the Args template parameter pack should consist of types
-  // convertible to base::Value.
+
+  // This function provides a unique name for every overload of
+  // CallJavascriptFunctionUnsafe, allowing it to be used in base::Bind.
   template <typename... Args>
-  void ExecuteDeferredJSCall(const std::string& function_name,
-                             std::unique_ptr<Args>... args) {
-    CallJS(function_name, *args...);
+  void CallJavascriptFunctionImmediate(const std::string& function_name,
+                                       const Args&... args) {
+    web_ui()->CallJavascriptFunctionUnsafe(function_name, args...);
   }
 
   // Returns full name of JS method based on screen and method names.
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index f2a53d4..85c395c 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -235,12 +235,12 @@
     const std::string& help_link_text,
     HelpAppLauncher::HelpTopic help_topic_id) {
   LOG(ERROR) << "CoreOobeHandler::ShowSignInError: error_text=" << error_text;
-  CallJSOrDefer("cr.ui.Oobe.showSignInError", login_attempts, error_text,
-                help_link_text, static_cast<int>(help_topic_id));
+  CallJS("cr.ui.Oobe.showSignInError", login_attempts, error_text,
+         help_link_text, static_cast<int>(help_topic_id));
 }
 
 void CoreOobeHandler::ShowTpmError() {
-  CallJSOrDefer("cr.ui.Oobe.showTpmError");
+  CallJS("cr.ui.Oobe.showTpmError");
 }
 
 void CoreOobeHandler::ShowDeviceResetScreen() {
@@ -258,62 +258,61 @@
 
 void CoreOobeHandler::ShowActiveDirectoryPasswordChangeScreen(
     const std::string& username) {
-  CallJSOrDefer("cr.ui.Oobe.showActiveDirectoryPasswordChangeScreen", username);
+  CallJS("cr.ui.Oobe.showActiveDirectoryPasswordChangeScreen", username);
 }
 
 void CoreOobeHandler::ShowSignInUI(const std::string& email) {
-  CallJSOrDefer("cr.ui.Oobe.showSigninUI", email);
+  CallJS("cr.ui.Oobe.showSigninUI", email);
 }
 
 void CoreOobeHandler::ResetSignInUI(bool force_online) {
-  CallJSOrDefer("cr.ui.Oobe.resetSigninUI", force_online);
+  CallJS("cr.ui.Oobe.resetSigninUI", force_online);
 }
 
 void CoreOobeHandler::ClearUserPodPassword() {
-  CallJSOrDefer("cr.ui.Oobe.clearUserPodPassword");
+  CallJS("cr.ui.Oobe.clearUserPodPassword");
 }
 
 void CoreOobeHandler::RefocusCurrentPod() {
-  CallJSOrDefer("cr.ui.Oobe.refocusCurrentPod");
+  CallJS("cr.ui.Oobe.refocusCurrentPod");
 }
 
 void CoreOobeHandler::ShowPasswordChangedScreen(bool show_password_error,
                                                 const std::string& email) {
-  CallJSOrDefer("cr.ui.Oobe.showPasswordChangedScreen", show_password_error,
-                email);
+  CallJS("cr.ui.Oobe.showPasswordChangedScreen", show_password_error, email);
 }
 
 void CoreOobeHandler::SetUsageStats(bool checked) {
-  CallJSOrDefer("cr.ui.Oobe.setUsageStats", checked);
+  CallJS("cr.ui.Oobe.setUsageStats", checked);
 }
 
 void CoreOobeHandler::SetTpmPassword(const std::string& tpm_password) {
-  CallJSOrDefer("cr.ui.Oobe.setTpmPassword", tpm_password);
+  CallJS("cr.ui.Oobe.setTpmPassword", tpm_password);
 }
 
 void CoreOobeHandler::ClearErrors() {
-  CallJSOrDefer("cr.ui.Oobe.clearErrors");
+  CallJS("cr.ui.Oobe.clearErrors");
 }
 
 void CoreOobeHandler::ReloadContent(const base::DictionaryValue& dictionary) {
-  CallJSOrDefer("cr.ui.Oobe.reloadContent", dictionary);
+  CallJS("cr.ui.Oobe.reloadContent", dictionary);
 }
 
 void CoreOobeHandler::ReloadEulaContent(
     const base::DictionaryValue& dictionary) {
-  CallJSOrDefer("cr.ui.Oobe.reloadEulaContent", dictionary);
+  CallJS("cr.ui.Oobe.reloadEulaContent", dictionary);
 }
 
 void CoreOobeHandler::ShowControlBar(bool show) {
-  CallJSOrDefer("cr.ui.Oobe.showControlBar", show);
+  CallJS("cr.ui.Oobe.showControlBar", show);
 }
 
 void CoreOobeHandler::SetVirtualKeyboardShown(bool shown) {
-  CallJSOrDefer("cr.ui.Oobe.setVirtualKeyboardShown", shown);
+  CallJS("cr.ui.Oobe.setVirtualKeyboardShown", shown);
 }
 
 void CoreOobeHandler::SetClientAreaSize(int width, int height) {
-  CallJSOrDefer("cr.ui.Oobe.setClientAreaSize", width, height);
+  CallJS("cr.ui.Oobe.setClientAreaSize", width, height);
 }
 
 void CoreOobeHandler::HandleInitialized() {
@@ -482,15 +481,15 @@
 
 void CoreOobeHandler::UpdateShutdownAndRebootVisibility(
     bool reboot_on_shutdown) {
-  CallJSOrDefer("cr.ui.Oobe.showShutdown", !reboot_on_shutdown);
+  CallJS("cr.ui.Oobe.showShutdown", !reboot_on_shutdown);
 }
 
 void CoreOobeHandler::SetLoginUserCount(int user_count) {
-  CallJSOrDefer("cr.ui.Oobe.setLoginUserCount", user_count);
+  CallJS("cr.ui.Oobe.setLoginUserCount", user_count);
 }
 
 void CoreOobeHandler::ForwardAccelerator(std::string accelerator_name) {
-  CallJSOrDefer("cr.ui.Oobe.handleAccelerator", accelerator_name);
+  CallJS("cr.ui.Oobe.handleAccelerator", accelerator_name);
 }
 
 void CoreOobeHandler::UpdateA11yState() {
@@ -521,16 +520,16 @@
   }
   a11y_info.SetBoolean("virtualKeyboardEnabled",
                        AccessibilityManager::Get()->IsVirtualKeyboardEnabled());
-  CallJSOrDefer("cr.ui.Oobe.refreshA11yInfo", a11y_info);
+  CallJS("cr.ui.Oobe.refreshA11yInfo", a11y_info);
 }
 
 void CoreOobeHandler::UpdateOobeUIVisibility() {
   const std::string& display = GetOobeUI()->display_type();
   bool has_api_keys_configured = google_apis::HasAPIKeyConfigured() &&
                                  google_apis::HasOAuthClientConfigured();
-  CallJSOrDefer("cr.ui.Oobe.showAPIKeysNotice",
-                !has_api_keys_configured && (display == OobeUI::kOobeDisplay ||
-                                             display == OobeUI::kLoginDisplay));
+  CallJS("cr.ui.Oobe.showAPIKeysNotice",
+         !has_api_keys_configured && (display == OobeUI::kOobeDisplay ||
+                                      display == OobeUI::kLoginDisplay));
 
   // Don't show version label on the stable channel by default.
   bool should_show_version = true;
@@ -539,10 +538,10 @@
       channel == version_info::Channel::BETA) {
     should_show_version = false;
   }
-  CallJSOrDefer("cr.ui.Oobe.showVersion", should_show_version);
-  CallJSOrDefer("cr.ui.Oobe.showOobeUI", show_oobe_ui_);
+  CallJS("cr.ui.Oobe.showVersion", should_show_version);
+  CallJS("cr.ui.Oobe.showOobeUI", show_oobe_ui_);
   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
-    CallJSOrDefer("cr.ui.Oobe.enableKeyboardFlow", true);
+    CallJS("cr.ui.Oobe.enableKeyboardFlow", true);
 }
 
 void CoreOobeHandler::OnOSVersionLabelTextUpdated(
@@ -552,11 +551,11 @@
 
 void CoreOobeHandler::OnEnterpriseInfoUpdated(const std::string& message_text,
                                               const std::string& asset_id) {
-  CallJSOrDefer("cr.ui.Oobe.setEnterpriseInfo", message_text, asset_id);
+  CallJS("cr.ui.Oobe.setEnterpriseInfo", message_text, asset_id);
 }
 
 void CoreOobeHandler::OnDeviceInfoUpdated(const std::string& bluetooth_name) {
-  CallJSOrDefer("cr.ui.Oobe.setBluetoothDeviceInfo", bluetooth_name);
+  CallJS("cr.ui.Oobe.setBluetoothDeviceInfo", bluetooth_name);
 }
 
 ui::EventSink* CoreOobeHandler::GetEventSink() {
@@ -565,7 +564,7 @@
 
 void CoreOobeHandler::UpdateLabel(const std::string& id,
                                   const std::string& text) {
-  CallJSOrDefer("cr.ui.Oobe.setLabelText", id, text);
+  CallJS("cr.ui.Oobe.setLabelText", id, text);
 }
 
 void CoreOobeHandler::UpdateDeviceRequisition() {
@@ -574,8 +573,8 @@
           ->browser_policy_connector_chromeos()
           ->GetDeviceCloudPolicyManager();
   if (policy_manager) {
-    CallJSOrDefer("cr.ui.Oobe.updateDeviceRequisition",
-                  policy_manager->GetDeviceRequisition());
+    CallJS("cr.ui.Oobe.updateDeviceRequisition",
+           policy_manager->GetDeviceRequisition());
   }
 }
 
@@ -591,7 +590,7 @@
 }
 
 void CoreOobeHandler::OnTabletModeToggled(bool enabled) {
-  CallJSOrDefer("cr.ui.Oobe.setTabletModeState", enabled);
+  CallJS("cr.ui.Oobe.setTabletModeState", enabled);
 }
 
 void CoreOobeHandler::UpdateClientAreaSize() {
@@ -606,7 +605,7 @@
       OobeConfiguration::Get()->GetConfiguration(),
       chromeos::configuration::ConfigurationHandlerSide::HANDLER_JS,
       configuration);
-  CallJSOrDefer("cr.ui.Oobe.updateOobeConfiguration", configuration);
+  CallJS("cr.ui.Oobe.updateOobeConfiguration", configuration);
 }
 
 void CoreOobeHandler::OnAccessibilityStatusChanged(
diff --git a/chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.cc b/chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.cc
index dfa2983..f33be252 100644
--- a/chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.cc
+++ b/chrome/browser/ui/webui/chromeos/login/discover/modules/discover_module_pin_setup.cc
@@ -112,18 +112,15 @@
 
 void DiscoverModulePinSetupHandler::HandleGetUserPassword(
     const std::string& callbackId) {
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "window.discoverReturn", base::Value(callbackId),
-      base::Value(module_->ConsumePrimaryUserPassword()));
+  CallJS("window.discoverReturn", callbackId,
+         module_->ConsumePrimaryUserPassword());
   return;
 }
 
 void DiscoverModulePinSetupHandler::OnPinLoginAvailable(
     const std::string& callbackId,
     bool is_available) {
-  web_ui()->CallJavascriptFunctionUnsafe("window.discoverReturn",
-                                         base::Value(callbackId),
-                                         base::Value(is_available));
+  CallJS("window.discoverReturn", callbackId, is_available);
 }
 
 void DiscoverModulePinSetupHandler::HandleGetHasLoginSupport(
diff --git a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
index 6fcc6f2..ad18395 100644
--- a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
@@ -274,9 +274,7 @@
     prefs->CommitPendingWrite();
   }
 
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "login.EnableDebuggingScreen.updateState",
-      base::Value(static_cast<int>(state)));
+  CallJS("login.EnableDebuggingScreen.updateState", static_cast<int>(state));
 }
 
 void EnableDebuggingScreenHandler::HandleOnLearnMore() {
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc
index 5e723d8..9752ff9 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler_unittest.cc
@@ -147,11 +147,10 @@
     user_context_.SetKey(
         Key(Key::KeyType::KEY_TYPE_SALTED_SHA256, "salt", "secret"));
 
-    JSCallsContainer js_calls_container;
-    js_calls_container.ExecuteDeferredJSCalls();
+    js_calls_container_.ExecuteDeferredJSCalls();
     encryption_migration_screen_handler_ =
         std::make_unique<TestEncryptionMigrationScreenHandler>(
-            &js_calls_container);
+            &js_calls_container_);
     encryption_migration_screen_handler_->set_test_web_ui(&test_web_ui_);
     encryption_migration_screen_handler_->SetContinueLoginCallback(
         base::BindOnce(&EncryptionMigrationScreenHandlerTest::OnContinueLogin,
@@ -179,6 +178,7 @@
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_enabler_;
   FakeCryptohomeClient* fake_cryptohome_client_ = nullptr;
   cryptohome::MockAsyncMethodCaller* mock_async_method_caller_ = nullptr;
+  JSCallsContainer js_calls_container_;
   std::unique_ptr<TestEncryptionMigrationScreenHandler>
       encryption_migration_screen_handler_;
   content::TestWebUI test_web_ui_;
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 334568b6..b470cee 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -887,14 +887,14 @@
       dark_muted_color);
   SkColor scroll_color =
       SkColorSetA(base_color, ash::login_constants::kScrollTranslucentAlpha);
-  CallJSOrDefer("login.AccountPickerScreen.setOverlayColors",
-                color_utils::SkColorToRgbaString(dark_muted_color),
-                color_utils::SkColorToRgbaString(scroll_color));
+  CallJS("login.AccountPickerScreen.setOverlayColors",
+         color_utils::SkColorToRgbaString(dark_muted_color),
+         color_utils::SkColorToRgbaString(scroll_color));
 }
 
 void SigninScreenHandler::OnWallpaperBlurChanged(bool blurred) {
-  CallJSOrDefer("login.AccountPickerScreen.togglePodBackground",
-                !blurred /*show_pod_background=*/);
+  CallJS("login.AccountPickerScreen.togglePodBackground",
+         !blurred /*show_pod_background=*/);
 }
 
 void SigninScreenHandler::ClearAndEnablePassword() {
@@ -935,8 +935,7 @@
 
 void SigninScreenHandler::OnUserImageChanged(const user_manager::User& user) {
   if (page_is_ready()) {
-    CallJSOrDefer("login.AccountPickerScreen.updateUserImage",
-                  user.GetAccountId());
+    CallJS("login.AccountPickerScreen.updateUserImage", user.GetAccountId());
   }
 }
 
@@ -1065,7 +1064,7 @@
 }
 
 void SigninScreenHandler::OnTabletModeToggled(bool enabled) {
-  CallJSOrDefer("login.AccountPickerScreen.setTabletModeState", enabled);
+  CallJS("login.AccountPickerScreen.setTabletModeState", enabled);
 }
 
 bool SigninScreenHandler::ShouldLoadGaia() const {
@@ -1241,8 +1240,8 @@
 
 void SigninScreenHandler::LoadUsers(const user_manager::UserList& users,
                                     const base::ListValue& users_list) {
-  CallJSOrDefer("login.AccountPickerScreen.loadUsers", users_list,
-                delegate_->IsShowGuest());
+  CallJS("login.AccountPickerScreen.loadUsers", users_list,
+         delegate_->IsShowGuest());
 
   // Enable pin for any users who can use it.
   // TODO(jdufault): Cache pin state in BrowserProcess::local_state() so we
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.cc b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
index 810bd948..a40bd56 100644
--- a/chrome/browser/ui/webui/chromeos/set_time_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
@@ -19,8 +19,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "content/public/browser/web_contents.h"
@@ -38,14 +37,12 @@
  public:
   SetTimeMessageHandler() {
     system::TimezoneSettings::GetInstance()->AddObserver(this);
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->AddObserver(
-        this);
+    SystemClockClient::Get()->AddObserver(this);
   }
 
   ~SetTimeMessageHandler() override {
     system::TimezoneSettings::GetInstance()->RemoveObserver(this);
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->RemoveObserver(
-        this);
+    SystemClockClient::Get()->RemoveObserver(this);
   }
 
   // WebUIMessageHandler:
@@ -61,7 +58,7 @@
   }
 
  private:
-  // system::SystemClockClient::Observer:
+  // SystemClockClient::Observer:
   void SystemClockUpdated() override {
     web_ui()->CallJavascriptFunctionUnsafe("settime.TimeSetter.updateTime");
   }
@@ -87,8 +84,7 @@
       return;
     }
 
-    chromeos::DBusThreadManager::Get()->GetSystemClockClient()->SetTime(
-        static_cast<int64_t>(seconds));
+    SystemClockClient::Get()->SetTime(static_cast<int64_t>(seconds));
   }
 
   // Handler for Javascript call to change the system time zone when the user
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
index 2a40f3f3..628f99e 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -124,18 +124,6 @@
     pdf_file_saved_closure.Run();
 }
 
-// Returns a unique path for |path|, just like with downloads.
-base::FilePath GetUniquePath(const base::FilePath& path) {
-  base::FilePath unique_path = path;
-  int uniquifier =
-      base::GetUniquePathNumber(path, base::FilePath::StringType());
-  if (uniquifier > 0) {
-    unique_path = unique_path.InsertBeforeExtensionASCII(
-        base::StringPrintf(" (%d)", uniquifier));
-  }
-  return unique_path;
-}
-
 base::FilePath SelectSaveDirectory(const base::FilePath& path,
                                    const base::FilePath& default_path) {
   if (base::DirectoryExists(path))
@@ -327,7 +315,7 @@
   if (!prompt_user) {
     base::PostTaskWithTraitsAndReplyWithResult(
         FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-        base::Bind(&GetUniquePath, path.Append(default_filename)),
+        base::Bind(&base::GetUniquePath, path.Append(default_filename)),
         base::Bind(&PdfPrinterHandler::OnGotUniqueFileName,
                    weak_ptr_factory_.GetWeakPtr()));
     return;
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
index 779d250..2423ebcd 100644
--- a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -13,8 +13,7 @@
 #include "chrome/browser/chromeos/system/timezone_util.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/constants/chromeos_switches.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/prefs/pref_service.h"
@@ -101,8 +100,7 @@
 }
 
 void DateTimeHandler::OnJavascriptAllowed() {
-  SystemClockClient* system_clock_client =
-      DBusThreadManager::Get()->GetSystemClockClient();
+  SystemClockClient* system_clock_client = SystemClockClient::Get();
   scoped_observer_.Add(system_clock_client);
   SystemClockCanSetTimeChanged(system_clock_client->CanSetTime());
 
@@ -152,7 +150,7 @@
 
 void DateTimeHandler::HandleShowSetDateTimeUI(const base::ListValue* args) {
   // Make sure the clock status hasn't changed since the button was clicked.
-  if (!DBusThreadManager::Get()->GetSystemClockClient()->CanSetTime())
+  if (!SystemClockClient::Get()->CanSetTime())
     return;
   SetTimeDialog::ShowDialog(
       web_ui()->GetWebContents()->GetTopLevelNativeWindow());
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h
index b04142f8..c4f2a32 100644
--- a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h
@@ -12,7 +12,7 @@
 #include "base/scoped_observer.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "components/prefs/pref_change_registrar.h"
 
 namespace base {
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 5669b1d..4e2f605 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -59,6 +59,7 @@
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/interfaces/voice_interaction_controller.mojom.h"
 #include "base/system/sys_info.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/assistant/assistant_util.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
@@ -1949,7 +1950,7 @@
   // Used to control the display of Chrome OS Account Manager submenu in the
   // People section.
   html_source->AddBoolean("isAccountManagerEnabled",
-                          chromeos::switches::IsAccountManagerEnabled());
+                          chromeos::IsAccountManagerAvailable(profile));
 #endif
 
   html_source->AddBoolean(
diff --git a/chrome/services/cups_ipp_parser/ipp_parser.cc b/chrome/services/cups_ipp_parser/ipp_parser.cc
index 0b50e78..95042b6 100644
--- a/chrome/services/cups_ipp_parser/ipp_parser.cc
+++ b/chrome/services/cups_ipp_parser/ipp_parser.cc
@@ -127,7 +127,7 @@
     return nullptr;
   }
 
-  return ipp_converter::ConvertIppToMojo(ipp.release());
+  return ipp_converter::ConvertIppToMojo(ipp.get());
 }
 
 // Parse IPP request's |ipp_data|
diff --git a/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.cpp b/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.cpp
index 594632a..66514ae 100644
--- a/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.cpp
+++ b/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.cpp
@@ -98,9 +98,10 @@
       return ValueType::STRING;
 
     default:
-      NOTREACHED();
+      break;
   }
 
+  // Fail to convert any unrecognized types.
   return base::nullopt;
 }
 
diff --git a/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.h b/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.h
index 9e3a704..7142bb93 100644
--- a/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.h
+++ b/chrome/services/cups_ipp_parser/public/cpp/ipp_converter.h
@@ -85,6 +85,7 @@
     ipp_t* ipp);
 
 // Mojom converter for ipp_t objects, return nullptr on failure.
+// Note: This function does not take ownership of |ipp|.
 chrome::mojom::IppMessagePtr ConvertIppToMojo(ipp_t* ipp);
 
 // Common converters for working with arbitrary byte buffers.
diff --git a/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc
index 73ad053..d0cbc16 100644
--- a/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc
+++ b/chrome/services/cups_ipp_parser/public/cpp/ipp_message_parser_fuzzer.cc
@@ -19,7 +19,7 @@
   static Environment env;
 
   auto ipp = ipp_converter::ParseIppMessage({data, size});
-  ipp_converter::ConvertIppToMojo(ipp.release());
+  ipp_converter::ConvertIppToMojo(ipp.get());
 
   return 0;
 }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
index 7b6429b2..6ae85a7 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -145,6 +145,10 @@
         try {
             ApplicationTestUtils.tearDown(InstrumentationRegistry.getTargetContext());
             Thread.setDefaultUncaughtExceptionHandler(mDefaultUncaughtExceptionHandler);
+            if (mSetActivity != null) {
+                // This is to ensure onDestroy() is performed before starting the next test.
+                ApplicationTestUtils.finishActivity(mSetActivity);
+            }
         } catch (Exception e) {
             throw new RuntimeException("Failed to tearDown", e);
         }
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index aab392c..d58766c 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -252,6 +252,7 @@
       allows_browser_windows_(true),
       last_session_exited_cleanly_(true),
       profile_path_(path),
+      simple_dependency_manager_(SimpleDependencyManager::GetInstance()),
       browser_context_dependency_manager_(
           BrowserContextDependencyManager::GetInstance()),
       resource_context_(nullptr),
@@ -299,6 +300,7 @@
       extension_special_storage_policy_(extension_policy),
 #endif
       profile_path_(path),
+      simple_dependency_manager_(SimpleDependencyManager::GetInstance()),
       browser_context_dependency_manager_(
           BrowserContextDependencyManager::GetInstance()),
       resource_context_(nullptr),
@@ -481,15 +483,19 @@
 
   // Prefs for incognito profiles are set in CreateIncognitoPrefService() by
   // simulating ProfileImpl::GetOffTheRecordPrefs().
+  SimpleFactoryKey* key = Profile::GetSimpleFactoryKey(this);
   if (!IsOffTheRecord()) {
     DCHECK(!original_profile_);
     user_prefs::PrefRegistrySyncable* pref_registry =
         static_cast<user_prefs::PrefRegistrySyncable*>(
             prefs_->DeprecatedGetPrefRegistry());
+    simple_dependency_manager_->RegisterProfilePrefsForServices(key,
+                                                                pref_registry);
     browser_context_dependency_manager_->
         RegisterProfilePrefsForServices(this, pref_registry);
   }
 
+  simple_dependency_manager_->CreateServicesForTest(key);
   browser_context_dependency_manager_->CreateBrowserContextServicesForTest(
       this);
 }
@@ -528,7 +534,7 @@
   browser_context_dependency_manager_->DestroyBrowserContextServices(this);
 
   SimpleFactoryKey* key = Profile::GetSimpleFactoryKey(this);
-  SimpleDependencyManager::GetInstance()->DestroyKeyedServices(key);
+  simple_dependency_manager_->DestroyKeyedServices(key);
 
   if (host_content_settings_map_.get())
     host_content_settings_map_->ShutdownOnUIThread();
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index f31cd0f9..a3c5343a 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -29,6 +29,7 @@
 #endif
 
 class BrowserContextDependencyManager;
+class SimpleDependencyManager;
 class ExtensionSpecialStoragePolicy;
 class HostContentSettingsMap;
 
@@ -436,6 +437,7 @@
   // We keep a weak pointer to the dependency manager we want to notify on our
   // death. Defaults to the Singleton implementation but overridable for
   // testing.
+  SimpleDependencyManager* simple_dependency_manager_;
   BrowserContextDependencyManager* browser_context_dependency_manager_;
 
   // Owned, but must be deleted on the IO thread so not placing in a
diff --git a/chromeos/components/drivefs/drivefs_auth.cc b/chromeos/components/drivefs/drivefs_auth.cc
index 6fb88a14..f570eda 100644
--- a/chromeos/components/drivefs/drivefs_auth.cc
+++ b/chromeos/components/drivefs/drivefs_auth.cc
@@ -47,13 +47,13 @@
   }
 
   get_access_token_callback_ = std::move(callback);
-  GetIdentityManager().GetPrimaryAccountWhenAvailable(
+  GetIdentityAccessor().GetPrimaryAccountWhenAvailable(
       base::BindOnce(&DriveFsAuth::AccountReady, base::Unretained(this)));
 }
 
 void DriveFsAuth::AccountReady(const AccountInfo& info,
                                const identity::AccountState& state) {
-  GetIdentityManager().GetAccessToken(
+  GetIdentityAccessor().GetAccessToken(
       delegate_->GetAccountId().GetUserEmail(),
       {"https://www.googleapis.com/auth/drive"}, kIdentityConsumerId,
       base::BindOnce(&DriveFsAuth::GotChromeAccessToken,
@@ -91,13 +91,13 @@
   last_token_expiry_ = expiry;
 }
 
-identity::mojom::IdentityManager& DriveFsAuth::GetIdentityManager() {
+identity::mojom::IdentityAccessor& DriveFsAuth::GetIdentityAccessor() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!identity_manager_) {
+  if (!identity_accessor_) {
     delegate_->GetConnector()->BindInterface(
-        identity::mojom::kServiceName, mojo::MakeRequest(&identity_manager_));
+        identity::mojom::kServiceName, mojo::MakeRequest(&identity_accessor_));
   }
-  return *identity_manager_;
+  return *identity_accessor_;
 }
 
 }  // namespace drivefs
diff --git a/chromeos/components/drivefs/drivefs_auth.h b/chromeos/components/drivefs/drivefs_auth.h
index 90e9ebc..ec0c138 100644
--- a/chromeos/components/drivefs/drivefs_auth.h
+++ b/chromeos/components/drivefs/drivefs_auth.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "base/time/clock.h"
 #include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 
 class AccountId;
 
@@ -75,15 +75,15 @@
 
   void UpdateCachedToken(const std::string& token, base::Time expiry);
 
-  identity::mojom::IdentityManager& GetIdentityManager();
+  identity::mojom::IdentityAccessor& GetIdentityAccessor();
 
   SEQUENCE_CHECKER(sequence_checker_);
   const base::Clock* const clock_;
   const base::FilePath profile_path_;
   Delegate* const delegate_;
 
-  // The connection to the identity service. Access via |GetIdentityManager()|.
-  identity::mojom::IdentityManagerPtr identity_manager_;
+  // The connection to the identity service. Access via |GetIdentityAccessor()|.
+  identity::mojom::IdentityAccessorPtr identity_accessor_;
 
   // Pending callback for an in-flight GetAccessToken request.
   mojom::DriveFsDelegate::GetAccessTokenCallback get_access_token_callback_;
diff --git a/chromeos/components/drivefs/drivefs_auth_unittest.cc b/chromeos/components/drivefs/drivefs_auth_unittest.cc
index c6186cb..294de0d 100644
--- a/chromeos/components/drivefs/drivefs_auth_unittest.cc
+++ b/chromeos/components/drivefs/drivefs_auth_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/test/simple_test_clock.h"
 #include "services/identity/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom-test-utils.h"
+#include "services/identity/public/mojom/identity_accessor.mojom-test-utils.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -55,7 +55,7 @@
   DISALLOW_COPY_AND_ASSIGN(AuthDelegateImpl);
 };
 
-class MockIdentityManager {
+class MockIdentityAccessor {
  public:
   MOCK_METHOD3(
       GetAccessToken,
@@ -64,19 +64,19 @@
           const ::identity::ScopeSet& scopes,
           const std::string& consumer_id));
 
-  mojo::BindingSet<identity::mojom::IdentityManager>* bindings_ = nullptr;
+  mojo::BindingSet<identity::mojom::IdentityAccessor>* bindings_ = nullptr;
 };
 
 class FakeIdentityService
-    : public identity::mojom::IdentityManagerInterceptorForTesting,
+    : public identity::mojom::IdentityAccessorInterceptorForTesting,
       public service_manager::Service {
  public:
-  explicit FakeIdentityService(MockIdentityManager* mock,
+  explicit FakeIdentityService(MockIdentityAccessor* mock,
                                const base::Clock* clock,
                                service_manager::mojom::ServiceRequest request)
       : mock_(mock), clock_(clock), binding_(this, std::move(request)) {
     binder_registry_.AddInterface(
-        base::BindRepeating(&FakeIdentityService::BindIdentityManagerRequest,
+        base::BindRepeating(&FakeIdentityService::BindIdentityAccessorRequest,
                             base::Unretained(this)));
     mock_->bindings_ = &bindings_;
   }
@@ -90,12 +90,12 @@
     binder_registry_.BindInterface(interface_name, std::move(interface_pipe));
   }
 
-  void BindIdentityManagerRequest(
-      identity::mojom::IdentityManagerRequest request) {
+  void BindIdentityAccessorRequest(
+      identity::mojom::IdentityAccessorRequest request) {
     bindings_.AddBinding(this, std::move(request));
   }
 
-  // identity::mojom::IdentityManagerInterceptorForTesting overrides:
+  // identity::mojom::IdentityAccessorInterceptorForTesting overrides:
   void GetPrimaryAccountWhenAvailable(
       GetPrimaryAccountWhenAvailableCallback callback) override {
     auto account_id = AccountId::FromUserEmailGaiaId("test@example.com", "ID");
@@ -116,16 +116,16 @@
                             GoogleServiceAuthError(result.second));
   }
 
-  IdentityManager* GetForwardingInterface() override {
+  IdentityAccessor* GetForwardingInterface() override {
     NOTREACHED();
     return nullptr;
   }
 
-  MockIdentityManager* const mock_;
+  MockIdentityAccessor* const mock_;
   const base::Clock* const clock_;
   service_manager::ServiceBinding binding_;
   service_manager::BinderRegistry binder_registry_;
-  mojo::BindingSet<identity::mojom::IdentityManager> bindings_;
+  mojo::BindingSet<identity::mojom::IdentityAccessor> bindings_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeIdentityService);
 };
@@ -139,7 +139,7 @@
     account_id_ = AccountId::FromUserEmailGaiaId("test@example.com", "ID");
     clock_.SetNow(base::Time::Now());
     identity_service_ = std::make_unique<FakeIdentityService>(
-        &mock_identity_manager_, &clock_,
+        &mock_identity_accessor_, &clock_,
         connector_factory_.RegisterInstance(identity::mojom::kServiceName));
     delegate_ = std::make_unique<AuthDelegateImpl>(
         connector_factory_.CreateConnector(), account_id_);
@@ -166,7 +166,7 @@
 
   base::test::ScopedTaskEnvironment task_environment_;
   service_manager::TestConnectorFactory connector_factory_;
-  MockIdentityManager mock_identity_manager_;
+  MockIdentityAccessor mock_identity_accessor_;
   base::SimpleTestClock clock_;
   std::unique_ptr<FakeIdentityService> identity_service_;
 
@@ -180,7 +180,7 @@
 };
 
 TEST_F(DriveFsAuthTest, GetAccessToken_Success) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(
           std::make_pair("auth token", GoogleServiceAuthError::NONE)));
@@ -188,7 +188,7 @@
 }
 
 TEST_F(DriveFsAuthTest, GetAccessToken_GetAccessTokenFailure_Permanent) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(std::make_pair(
           base::nullopt, GoogleServiceAuthError::ACCOUNT_DISABLED)));
@@ -196,7 +196,7 @@
 }
 
 TEST_F(DriveFsAuthTest, GetAccessToken_GetAccessTokenFailure_Transient) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(std::make_pair(
           base::nullopt, GoogleServiceAuthError::SERVICE_UNAVAILABLE)));
@@ -223,14 +223,14 @@
 
 TEST_F(DriveFsAuthTest, GetAccessToken_SequentialRequests) {
   for (int i = 0; i < 3; ++i) {
-    EXPECT_CALL(mock_identity_manager_,
+    EXPECT_CALL(mock_identity_accessor_,
                 GetAccessToken("test@example.com", _, "drivefs"))
         .WillOnce(testing::Return(
             std::make_pair("auth token", GoogleServiceAuthError::NONE)));
     ExpectAccessToken(false, mojom::AccessTokenStatus::kSuccess, "auth token");
   }
   for (int i = 0; i < 3; ++i) {
-    EXPECT_CALL(mock_identity_manager_,
+    EXPECT_CALL(mock_identity_accessor_,
                 GetAccessToken("test@example.com", _, "drivefs"))
         .WillOnce(testing::Return(std::make_pair(
             base::nullopt, GoogleServiceAuthError::ACCOUNT_DISABLED)));
@@ -239,7 +239,7 @@
 }
 
 TEST_F(DriveFsAuthTest, Caching) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(
           std::make_pair("auth token", GoogleServiceAuthError::NONE)));
@@ -251,7 +251,7 @@
 }
 
 TEST_F(DriveFsAuthTest, CachedAndNotCached) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(
           std::make_pair("auth token", GoogleServiceAuthError::NONE)))
@@ -268,7 +268,7 @@
 }
 
 TEST_F(DriveFsAuthTest, CacheExpired) {
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(
           std::make_pair("auth token", GoogleServiceAuthError::NONE)))
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc
index 5754435..28c8a4b 100644
--- a/chromeos/components/drivefs/drivefs_host_unittest.cc
+++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -29,7 +29,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/identity/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom-test-utils.h"
+#include "services/identity/public/mojom/identity_accessor.mojom-test-utils.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/test/test_network_connection_tracker.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
@@ -149,9 +149,9 @@
   DISALLOW_COPY_AND_ASSIGN(TestingDriveFsHostDelegate);
 };
 
-class MockIdentityManager {
+class MockIdentityAccessor {
  public:
-  explicit MockIdentityManager(const base::Clock* clock) : clock_(clock) {}
+  explicit MockIdentityAccessor(const base::Clock* clock) : clock_(clock) {}
   MOCK_METHOD3(
       GetAccessToken,
       std::pair<base::Optional<std::string>, GoogleServiceAuthError::State>(
@@ -163,7 +163,7 @@
       const std::string& account_id,
       const ::identity::ScopeSet& scopes,
       const std::string& consumer_id,
-      identity::mojom::IdentityManager::GetAccessTokenCallback callback) {
+      identity::mojom::IdentityAccessor::GetAccessTokenCallback callback) {
     if (pause_requests_) {
       callbacks_.push_back(std::move(callback));
       return;
@@ -174,7 +174,7 @@
                             GoogleServiceAuthError(result.second));
   }
 
-  std::vector<identity::mojom::IdentityManager::GetAccessTokenCallback>&
+  std::vector<identity::mojom::IdentityAccessor::GetAccessTokenCallback>&
   callbacks() {
     return callbacks_;
   }
@@ -183,20 +183,20 @@
 
   const base::Clock* const clock_;
   bool pause_requests_ = false;
-  std::vector<identity::mojom::IdentityManager::GetAccessTokenCallback>
+  std::vector<identity::mojom::IdentityAccessor::GetAccessTokenCallback>
       callbacks_;
-  mojo::BindingSet<identity::mojom::IdentityManager>* bindings_ = nullptr;
+  mojo::BindingSet<identity::mojom::IdentityAccessor>* bindings_ = nullptr;
 };
 
 class FakeIdentityService
-    : public identity::mojom::IdentityManagerInterceptorForTesting,
+    : public identity::mojom::IdentityAccessorInterceptorForTesting,
       public service_manager::Service {
  public:
-  FakeIdentityService(MockIdentityManager* mock,
+  FakeIdentityService(MockIdentityAccessor* mock,
                       service_manager::mojom::ServiceRequest request)
       : service_binding_(this, std::move(request)), mock_(mock) {
     binder_registry_.AddInterface(
-        base::BindRepeating(&FakeIdentityService::BindIdentityManagerRequest,
+        base::BindRepeating(&FakeIdentityService::BindIdentityAccessorRequest,
                             base::Unretained(this)));
     mock_->bindings_ = &bindings_;
   }
@@ -210,12 +210,12 @@
     binder_registry_.BindInterface(interface_name, std::move(interface_pipe));
   }
 
-  void BindIdentityManagerRequest(
-      identity::mojom::IdentityManagerRequest request) {
+  void BindIdentityAccessorRequest(
+      identity::mojom::IdentityAccessorRequest request) {
     bindings_.AddBinding(this, std::move(request));
   }
 
-  // identity::mojom::IdentityManagerInterceptorForTesting overrides:
+  // identity::mojom::IdentityAccessorInterceptorForTesting overrides:
   void GetPrimaryAccountWhenAvailable(
       GetPrimaryAccountWhenAvailableCallback callback) override {
     auto account_id = AccountId::FromUserEmailGaiaId("test@example.com", "ID");
@@ -234,15 +234,15 @@
                             std::move(callback));
   }
 
-  IdentityManager* GetForwardingInterface() override {
+  IdentityAccessor* GetForwardingInterface() override {
     NOTREACHED();
     return nullptr;
   }
 
   service_manager::ServiceBinding service_binding_;
-  MockIdentityManager* const mock_;
+  MockIdentityAccessor* const mock_;
   service_manager::BinderRegistry binder_registry_;
-  mojo::BindingSet<identity::mojom::IdentityManager> bindings_;
+  mojo::BindingSet<identity::mojom::IdentityAccessor> bindings_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeIdentityService);
 };
@@ -265,7 +265,7 @@
   DriveFsHostTest()
       : network_connection_tracker_(
             network::TestNetworkConnectionTracker::CreateInstance()),
-        mock_identity_manager_(&clock_),
+        mock_identity_accessor_(&clock_),
         bootstrap_binding_(this),
         binding_(&mock_drivefs_) {
     clock_.SetNow(base::Time::Now());
@@ -279,7 +279,7 @@
 
     disk_manager_ = std::make_unique<chromeos::disks::MockDiskMountManager>();
     identity_service_ = std::make_unique<FakeIdentityService>(
-        &mock_identity_manager_,
+        &mock_identity_accessor_,
         connector_factory_.RegisterInstance(identity::mojom::kServiceName));
     host_delegate_ = std::make_unique<TestingDriveFsHostDelegate>(
         connector_factory_.CreateConnector(), account_id_);
@@ -413,7 +413,7 @@
   std::unique_ptr<network::TestNetworkConnectionTracker>
       network_connection_tracker_;
   base::SimpleTestClock clock_;
-  MockIdentityManager mock_identity_manager_;
+  MockIdentityAccessor mock_identity_accessor_;
   service_manager::TestConnectorFactory connector_factory_;
   std::unique_ptr<FakeIdentityService> identity_service_;
   std::unique_ptr<TestingDriveFsHostDelegate> host_delegate_;
@@ -533,7 +533,7 @@
 TEST_F(DriveFsHostTest, GetAccessToken_UnmountDuringMojoRequest) {
   ASSERT_NO_FATAL_FAILURE(DoMount());
 
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::DoAll(
           testing::InvokeWithoutArgs([&]() { host_->Unmount(); }),
@@ -550,7 +550,7 @@
   EXPECT_FALSE(host_->IsMounted());
 
   // Wait for the response to reach the InterfacePtr if it's still open.
-  mock_identity_manager_.bindings_->FlushForTesting();
+  mock_identity_accessor_.bindings_->FlushForTesting();
 }
 
 ACTION_P(CloneStruct, output) {
@@ -710,7 +710,7 @@
 TEST_F(DriveFsHostTest, Remount_CachedOnceOnly) {
   ASSERT_NO_FATAL_FAILURE(DoMount());
 
-  EXPECT_CALL(mock_identity_manager_,
+  EXPECT_CALL(mock_identity_accessor_,
               GetAccessToken("test@example.com", _, "drivefs"))
       .WillOnce(testing::Return(
           std::make_pair("auth token", GoogleServiceAuthError::NONE)))
@@ -735,7 +735,7 @@
 
 TEST_F(DriveFsHostTest, Remount_RequestInflight) {
   ASSERT_NO_FATAL_FAILURE(DoMount());
-  mock_identity_manager_.set_pause_requests(true);
+  mock_identity_accessor_.set_pause_requests(true);
 
   delegate_ptr_->GetAccessToken(
       "client ID", "app ID", {"scope1", "scope2"},
@@ -749,11 +749,11 @@
   ASSERT_NO_FATAL_FAILURE(DoUnmount());
 
   // Now the response is ready.
-  ASSERT_EQ(1u, mock_identity_manager_.callbacks().size());
-  std::move(mock_identity_manager_.callbacks().front())
+  ASSERT_EQ(1u, mock_identity_accessor_.callbacks().size());
+  std::move(mock_identity_accessor_.callbacks().front())
       .Run("auth token", clock_.Now() + base::TimeDelta::FromHours(1),
            GoogleServiceAuthError(GoogleServiceAuthError::NONE));
-  mock_identity_manager_.bindings_->FlushForTesting();
+  mock_identity_accessor_.bindings_->FlushForTesting();
 
   // Second mount will reuse previous token.
   ASSERT_NO_FATAL_FAILURE(DoMount());
@@ -762,7 +762,7 @@
 
 TEST_F(DriveFsHostTest, Remount_RequestInflightCompleteAfterMount) {
   ASSERT_NO_FATAL_FAILURE(DoMount());
-  mock_identity_manager_.set_pause_requests(true);
+  mock_identity_accessor_.set_pause_requests(true);
 
   delegate_ptr_->GetAccessToken(
       "client ID", "app ID", {"scope1", "scope2"},
@@ -780,11 +780,11 @@
   EXPECT_FALSE(init_access_token_);
 
   // Now the response is ready.
-  ASSERT_EQ(1u, mock_identity_manager_.callbacks().size());
-  std::move(mock_identity_manager_.callbacks().front())
+  ASSERT_EQ(1u, mock_identity_accessor_.callbacks().size());
+  std::move(mock_identity_accessor_.callbacks().front())
       .Run("auth token", clock_.Now() + base::TimeDelta::FromHours(1),
            GoogleServiceAuthError(GoogleServiceAuthError::NONE));
-  mock_identity_manager_.bindings_->FlushForTesting();
+  mock_identity_accessor_.bindings_->FlushForTesting();
 
   // A new request will reuse the cached token.
   ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token");
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn
index 34a05f7..9809b50b 100644
--- a/chromeos/dbus/BUILD.gn
+++ b/chromeos/dbus/BUILD.gn
@@ -160,8 +160,6 @@
     "fake_smb_provider_client.h",
     "fake_sms_client.cc",
     "fake_sms_client.h",
-    "fake_system_clock_client.cc",
-    "fake_system_clock_client.h",
     "fake_update_engine_client.cc",
     "fake_update_engine_client.h",
     "fake_upstart_client.cc",
@@ -220,8 +218,6 @@
     "smb_provider_client.h",
     "sms_client.cc",
     "sms_client.h",
-    "system_clock_client.cc",
-    "system_clock_client.h",
     "update_engine_client.cc",
     "update_engine_client.h",
     "upstart_client.cc",
diff --git a/chromeos/dbus/dbus_clients_common.cc b/chromeos/dbus/dbus_clients_common.cc
index ed45093..0a142bc 100644
--- a/chromeos/dbus/dbus_clients_common.cc
+++ b/chromeos/dbus/dbus_clients_common.cc
@@ -25,7 +25,6 @@
 #include "chromeos/dbus/fake_shill_service_client.h"
 #include "chromeos/dbus/fake_shill_third_party_vpn_driver_client.h"
 #include "chromeos/dbus/fake_sms_client.h"
-#include "chromeos/dbus/fake_system_clock_client.h"
 #include "chromeos/dbus/fake_upstart_client.h"
 #include "chromeos/dbus/gsm_sms_client.h"
 #include "chromeos/dbus/hammerd_client.h"
@@ -42,7 +41,6 @@
 #include "chromeos/dbus/shill_service_client.h"
 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h"
 #include "chromeos/dbus/sms_client.h"
-#include "chromeos/dbus/system_clock_client.h"
 #include "chromeos/dbus/update_engine_client.h"
 #include "chromeos/dbus/upstart_client.h"
 
@@ -122,11 +120,6 @@
   else
     sms_client_.reset(new FakeSMSClient);
 
-  if (use_real_clients)
-    system_clock_client_.reset(SystemClockClient::Create());
-  else
-    system_clock_client_.reset(new FakeSystemClockClient);
-
   update_engine_client_.reset(UpdateEngineClient::Create(client_impl_type));
 
   if (use_real_clients)
@@ -158,7 +151,6 @@
   shill_profile_client_->Init(system_bus);
   shill_third_party_vpn_driver_client_->Init(system_bus);
   sms_client_->Init(system_bus);
-  system_clock_client_->Init(system_bus);
   update_engine_client_->Init(system_bus);
   upstart_client_->Init(system_bus);
 
diff --git a/chromeos/dbus/dbus_clients_common.h b/chromeos/dbus/dbus_clients_common.h
index 1a129db..c4a1a10 100644
--- a/chromeos/dbus/dbus_clients_common.h
+++ b/chromeos/dbus/dbus_clients_common.h
@@ -34,7 +34,6 @@
 class ShillServiceClient;
 class ShillThirdPartyVpnDriverClient;
 class SMSClient;
-class SystemClockClient;
 class UpdateEngineClient;
 class UpstartClient;
 
@@ -70,7 +69,6 @@
       shill_third_party_vpn_driver_client_;
   std::unique_ptr<PermissionBrokerClient> permission_broker_client_;
   std::unique_ptr<SMSClient> sms_client_;
-  std::unique_ptr<SystemClockClient> system_clock_client_;
   std::unique_ptr<PowerManagerClient> power_manager_client_;
   std::unique_ptr<SessionManagerClient> session_manager_client_;
   std::unique_ptr<UpdateEngineClient> update_engine_client_;
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc
index 89f8f88..7b45a0d7 100644
--- a/chromeos/dbus/dbus_thread_manager.cc
+++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -49,7 +49,6 @@
 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h"
 #include "chromeos/dbus/smb_provider_client.h"
 #include "chromeos/dbus/sms_client.h"
-#include "chromeos/dbus/system_clock_client.h"
 #include "chromeos/dbus/update_engine_client.h"
 #include "chromeos/dbus/upstart_client.h"
 #include "dbus/bus.h"
@@ -283,10 +282,6 @@
   return clients_common_->sms_client_.get();
 }
 
-SystemClockClient* DBusThreadManager::GetSystemClockClient() {
-  return clients_common_->system_clock_client_.get();
-}
-
 UpdateEngineClient* DBusThreadManager::GetUpdateEngineClient() {
   return clients_common_->update_engine_client_.get();
 }
@@ -526,12 +521,6 @@
       std::move(client);
 }
 
-void DBusThreadManagerSetter::SetSystemClockClient(
-    std::unique_ptr<SystemClockClient> client) {
-  DBusThreadManager::Get()->clients_common_->system_clock_client_ =
-      std::move(client);
-}
-
 void DBusThreadManagerSetter::SetUpdateEngineClient(
     std::unique_ptr<UpdateEngineClient> client) {
   DBusThreadManager::Get()->clients_common_->update_engine_client_ =
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h
index 9eccaff9..ce6113a9 100644
--- a/chromeos/dbus/dbus_thread_manager.h
+++ b/chromeos/dbus/dbus_thread_manager.h
@@ -64,7 +64,6 @@
 class ShillThirdPartyVpnDriverClient;
 class SmbProviderClient;
 class SMSClient;
-class SystemClockClient;
 class UpdateEngineClient;
 class UpstartClient;
 class VirtualFileProviderClient;
@@ -173,7 +172,6 @@
   ShillThirdPartyVpnDriverClient* GetShillThirdPartyVpnDriverClient();
   SmbProviderClient* GetSmbProviderClient();
   SMSClient* GetSMSClient();
-  SystemClockClient* GetSystemClockClient();
   UpdateEngineClient* GetUpdateEngineClient();
   UpstartClient* GetUpstartClient();
   VirtualFileProviderClient* GetVirtualFileProviderClient();
@@ -236,7 +234,6 @@
   void SetShillThirdPartyVpnDriverClient(
       std::unique_ptr<ShillThirdPartyVpnDriverClient> client);
   void SetSmbProviderClient(std::unique_ptr<SmbProviderClient> client);
-  void SetSystemClockClient(std::unique_ptr<SystemClockClient> client);
   void SetUpdateEngineClient(std::unique_ptr<UpdateEngineClient> client);
   void SetUpstartClient(std::unique_ptr<UpstartClient> client);
 
diff --git a/chromeos/dbus/dbus_thread_manager_unittest.cc b/chromeos/dbus/dbus_thread_manager_unittest.cc
index 9de77e71..49689d1 100644
--- a/chromeos/dbus/dbus_thread_manager_unittest.cc
+++ b/chromeos/dbus/dbus_thread_manager_unittest.cc
@@ -45,7 +45,6 @@
   EXPECT_TRUE(manager->GetShillProfileClient());
   EXPECT_TRUE(manager->GetShillThirdPartyVpnDriverClient());
   EXPECT_TRUE(manager->GetSMSClient());
-  EXPECT_TRUE(manager->GetSystemClockClient());
   EXPECT_TRUE(manager->GetUpdateEngineClient());
 
   DBusThreadManager::Shutdown();
@@ -73,7 +72,6 @@
   EXPECT_TRUE(manager->GetShillServiceClient());
   EXPECT_TRUE(manager->GetShillThirdPartyVpnDriverClient());
   EXPECT_TRUE(manager->GetSMSClient());
-  EXPECT_TRUE(manager->GetSystemClockClient());
   EXPECT_TRUE(manager->GetUpdateEngineClient());
 
   // Clients for the browser were created.
@@ -113,7 +111,6 @@
   EXPECT_TRUE(manager->GetShillServiceClient());
   EXPECT_TRUE(manager->GetShillThirdPartyVpnDriverClient());
   EXPECT_TRUE(manager->GetSMSClient());
-  EXPECT_TRUE(manager->GetSystemClockClient());
   EXPECT_TRUE(manager->GetUpdateEngineClient());
 
   // Clients for other processes were not created.
diff --git a/chromeos/dbus/system_clock/BUILD.gn b/chromeos/dbus/system_clock/BUILD.gn
new file mode 100644
index 0000000..d5a6a67c
--- /dev/null
+++ b/chromeos/dbus/system_clock/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
+
+component("system_clock") {
+  defines = [ "IS_SYSTEM_CLOCK_IMPL" ]
+
+  deps = [
+    "//base",
+    "//chromeos/dbus",
+    "//dbus",
+  ]
+
+  sources = [
+    "fake_system_clock_client.cc",
+    "fake_system_clock_client.h",
+    "system_clock_client.cc",
+    "system_clock_client.h",
+  ]
+}
diff --git a/chromeos/dbus/fake_system_clock_client.cc b/chromeos/dbus/system_clock/fake_system_clock_client.cc
similarity index 83%
rename from chromeos/dbus/fake_system_clock_client.cc
rename to chromeos/dbus/system_clock/fake_system_clock_client.cc
index baba88ac..14c13ae7 100644
--- a/chromeos/dbus/fake_system_clock_client.cc
+++ b/chromeos/dbus/system_clock/fake_system_clock_client.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/fake_system_clock_client.h"
+#include "chromeos/dbus/system_clock/fake_system_clock_client.h"
 #include "base/bind.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 
@@ -12,14 +12,15 @@
 
 FakeSystemClockClient::~FakeSystemClockClient() = default;
 
+void FakeSystemClockClient::SetNetworkSynchronized(bool network_synchronized) {
+  network_synchronized_ = network_synchronized;
+}
+
 void FakeSystemClockClient::NotifyObserversSystemClockUpdated() {
   for (auto& observer : observers_)
     observer.SystemClockUpdated();
 }
 
-void FakeSystemClockClient::Init(dbus::Bus* bus) {
-}
-
 void FakeSystemClockClient::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
@@ -49,4 +50,8 @@
       FROM_HERE, base::BindOnce(std::move(callback), true));
 }
 
+SystemClockClient::TestInterface* FakeSystemClockClient::GetTestInterface() {
+  return this;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_system_clock_client.h b/chromeos/dbus/system_clock/fake_system_clock_client.h
similarity index 64%
rename from chromeos/dbus/fake_system_clock_client.h
rename to chromeos/dbus/system_clock/fake_system_clock_client.h
index 1c79bac..21362b6 100644
--- a/chromeos/dbus/fake_system_clock_client.h
+++ b/chromeos/dbus/system_clock/fake_system_clock_client.h
@@ -2,34 +2,31 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_FAKE_SYSTEM_CLOCK_CLIENT_H_
-#define CHROMEOS_DBUS_FAKE_SYSTEM_CLOCK_CLIENT_H_
+#ifndef CHROMEOS_DBUS_SYSTEM_CLOCK_FAKE_SYSTEM_CLOCK_CLIENT_H_
+#define CHROMEOS_DBUS_SYSTEM_CLOCK_FAKE_SYSTEM_CLOCK_CLIENT_H_
 
 #include <stdint.h>
 
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 #include "dbus/object_proxy.h"
 
 namespace chromeos {
 
 // A fake implementation of SystemClockClient. This class does nothing.
-class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeSystemClockClient
-    : public SystemClockClient {
+class COMPONENT_EXPORT(SYSTEM_CLOCK) FakeSystemClockClient
+    : public SystemClockClient,
+      public SystemClockClient::TestInterface {
  public:
   FakeSystemClockClient();
   ~FakeSystemClockClient() override;
 
-  void set_network_synchronized(bool network_synchronized) {
-    network_synchronized_ = network_synchronized;
-  }
-
-  // Calls SystemClockUpdated for |observers_|.
-  void NotifyObserversSystemClockUpdated();
+  // TestInterface
+  void SetNetworkSynchronized(bool network_synchronized) override;
+  void NotifyObserversSystemClockUpdated() override;
 
   // SystemClockClient overrides
-  void Init(dbus::Bus* bus) override;
   void AddObserver(Observer* observer) override;
   void RemoveObserver(Observer* observer) override;
   bool HasObserver(const Observer* observer) const override;
@@ -38,6 +35,7 @@
   void GetLastSyncInfo(GetLastSyncInfoCallback callback) override;
   void WaitForServiceToBeAvailable(
       dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) override;
+  SystemClockClient::TestInterface* GetTestInterface() override;
 
  private:
   bool network_synchronized_ = false;
@@ -49,4 +47,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_DBUS_FAKE_SYSTEM_CLOCK_CLIENT_H_
+#endif  // CHROMEOS_DBUS_SYSTEM_CLOCK_FAKE_SYSTEM_CLOCK_CLIENT_H_
diff --git a/chromeos/dbus/system_clock_client.cc b/chromeos/dbus/system_clock/system_clock_client.cc
similarity index 87%
rename from chromeos/dbus/system_clock_client.cc
rename to chromeos/dbus/system_clock/system_clock_client.cc
index 809e23b..0abd5043 100644
--- a/chromeos/dbus/system_clock_client.cc
+++ b/chromeos/dbus/system_clock/system_clock_client.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/dbus/system_clock/system_clock_client.h"
 
 #include <stdint.h>
 
@@ -12,12 +12,14 @@
 #include "base/bind_helpers.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
+#include "chromeos/dbus/system_clock/fake_system_clock_client.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
+
 namespace {
 
 // Handles replies to D-Bus calls made by GetLastSyncInfo.
@@ -39,16 +41,21 @@
   std::move(callback).Run(network_synchronized);
 }
 
+SystemClockClient* g_instance = nullptr;
+
 }  // namespace
 
 // The SystemClockClient implementation used in production.
 class SystemClockClientImpl : public SystemClockClient {
  public:
-  SystemClockClientImpl()
+  explicit SystemClockClientImpl(dbus::Bus* bus)
       : can_set_time_(false),
         can_set_time_initialized_(false),
         system_clock_proxy_(nullptr),
-        weak_ptr_factory_(this) {}
+        weak_ptr_factory_(this) {
+    CHECK(bus);
+    InitDBus(bus);
+  }
 
   ~SystemClockClientImpl() override = default;
 
@@ -91,8 +98,10 @@
     system_clock_proxy_->WaitForServiceToBeAvailable(std::move(callback));
   }
 
- protected:
-  void Init(dbus::Bus* bus) override {
+  TestInterface* GetTestInterface() override { return nullptr; }
+
+ private:
+  void InitDBus(dbus::Bus* bus) {
     system_clock_proxy_ = bus->GetObjectProxy(
         system_clock::kSystemClockServiceName,
         dbus::ObjectPath(system_clock::kSystemClockServicePath));
@@ -107,7 +116,6 @@
                        weak_ptr_factory_.GetWeakPtr()));
   }
 
- private:
   // Called once when the service initially becomes available (or immediately if
   // it's already available).
   void ServiceInitiallyAvailable(bool service_is_available) {
@@ -132,8 +140,7 @@
   void TimeUpdatedConnected(const std::string& interface_name,
                             const std::string& signal_name,
                             bool success) {
-    LOG_IF(ERROR, !success)
-        << "Failed to connect to TimeUpdated signal.";
+    LOG_IF(ERROR, !success) << "Failed to connect to TimeUpdated signal.";
   }
 
   // Callback for CanSetTime method.
@@ -184,11 +191,29 @@
   DISALLOW_COPY_AND_ASSIGN(SystemClockClientImpl);
 };
 
+SystemClockClient::SystemClockClient() = default;
+
+SystemClockClient::~SystemClockClient() = default;
+
 // static
-SystemClockClient* SystemClockClient::Create() {
-  return new SystemClockClientImpl();
+void SystemClockClient::Initialize(dbus::Bus* bus) {
+  CHECK(!g_instance);
+  if (bus)
+    g_instance = new SystemClockClientImpl(bus);
+  else
+    g_instance = new FakeSystemClockClient();
 }
 
-SystemClockClient::SystemClockClient() = default;
+// static
+void SystemClockClient::Shutdown() {
+  CHECK(g_instance);
+  delete g_instance;
+  g_instance = nullptr;
+}
+
+// static
+SystemClockClient* SystemClockClient::Get() {
+  return g_instance;
+}
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/system_clock_client.h b/chromeos/dbus/system_clock/system_clock_client.h
similarity index 62%
rename from chromeos/dbus/system_clock_client.h
rename to chromeos/dbus/system_clock/system_clock_client.h
index 118f7e4bb..3758a1e 100644
--- a/chromeos/dbus/system_clock_client.h
+++ b/chromeos/dbus/system_clock/system_clock_client.h
@@ -2,21 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_DBUS_SYSTEM_CLOCK_CLIENT_H_
-#define CHROMEOS_DBUS_SYSTEM_CLOCK_CLIENT_H_
+#ifndef CHROMEOS_DBUS_SYSTEM_CLOCK_SYSTEM_CLOCK_CLIENT_H_
+#define CHROMEOS_DBUS_SYSTEM_CLOCK_SYSTEM_CLOCK_CLIENT_H_
 
 #include <stdint.h>
 
 #include "base/callback.h"
 #include "base/component_export.h"
 #include "base/macros.h"
-#include "chromeos/dbus/dbus_client.h"
 #include "dbus/object_proxy.h"
 
+namespace dbus {
+class Bus;
+}
+
 namespace chromeos {
 
-// SystemClockClient is used to communicate with the system clock.
-class COMPONENT_EXPORT(CHROMEOS_DBUS) SystemClockClient : public DBusClient {
+// SystemClockClient is used to communicate with the system clock. This class is
+// safe to use from multiple processes (e.g. Chrome + Ash).
+class COMPONENT_EXPORT(SYSTEM_CLOCK) SystemClockClient {
  public:
   using GetLastSyncInfoCallback = base::OnceCallback<void(bool synchronized)>;
 
@@ -34,6 +38,25 @@
     virtual ~Observer() {}
   };
 
+  // Interface for testing. Only implemented in the fake implementation.
+  class TestInterface {
+   public:
+    // Sets the |synchronized| value passed to GetLastSyncInfo().
+    virtual void SetNetworkSynchronized(bool network_synchronized) = 0;
+
+    // Calls SystemClockUpdated for observers.
+    virtual void NotifyObserversSystemClockUpdated() = 0;
+  };
+
+  // Creates the global instance. If |bus| is null, a fake client is created.
+  static void Initialize(dbus::Bus* bus);
+
+  // Destroys the global instance.
+  static void Shutdown();
+
+  // Returns the global instance which may be null if not initialized.
+  static SystemClockClient* Get();
+
   // Adds the given observer.
   virtual void AddObserver(Observer* observer) = 0;
   // Removes the given observer if this object has the observer.
@@ -55,12 +78,12 @@
   virtual void WaitForServiceToBeAvailable(
       dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) = 0;
 
-  // Creates the instance.
-  static SystemClockClient* Create();
+  virtual TestInterface* GetTestInterface() = 0;
 
  protected:
-  // Create() should be used instead.
+  // Initialize/Shutdown should be used instead.
   SystemClockClient();
+  virtual ~SystemClockClient();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(SystemClockClient);
@@ -68,4 +91,4 @@
 
 }  // namespace chromeos
 
-#endif  // CHROMEOS_DBUS_SYSTEM_CLOCK_CLIENT_H_
+#endif  // CHROMEOS_DBUS_SYSTEM_CLOCK_SYSTEM_CLOCK_CLIENT_H_
diff --git a/chromeos/services/assistant/public/cpp/manifest.cc b/chromeos/services/assistant/public/cpp/manifest.cc
index 081d3ec..1b61200ef 100644
--- a/chromeos/services/assistant/public/cpp/manifest.cc
+++ b/chromeos/services/assistant/public/cpp/manifest.cc
@@ -29,7 +29,7 @@
           .RequireCapability("audio", "stream_factory")
           .RequireCapability("device", "device:battery_monitor")
           .RequireCapability("device", "device:wake_lock")
-          .RequireCapability("identity", "identity_manager")
+          .RequireCapability("identity", "identity_accessor")
           .RequireCapability("media_session", "app")
 
           .Build()};
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc
index 5dd2ba5..b7ba8b0b 100644
--- a/chromeos/services/assistant/service.cc
+++ b/chromeos/services/assistant/service.cc
@@ -84,13 +84,13 @@
 
 void Service::RequestAccessToken() {
   VLOG(1) << "Start requesting access token.";
-  GetIdentityManager()->GetPrimaryAccountInfo(base::BindOnce(
+  GetIdentityAccessor()->GetPrimaryAccountInfo(base::BindOnce(
       &Service::GetPrimaryAccountInfoCallback, base::Unretained(this)));
 }
 
-void Service::SetIdentityManagerForTesting(
-    identity::mojom::IdentityManagerPtr identity_manager) {
-  identity_manager_ = std::move(identity_manager);
+void Service::SetIdentityAccessorForTesting(
+    identity::mojom::IdentityAccessorPtr identity_accessor) {
+  identity_accessor_ = std::move(identity_accessor);
 }
 
 void Service::SetAssistantManagerForTesting(
@@ -240,12 +240,12 @@
   RequestAccessToken();
 }
 
-identity::mojom::IdentityManager* Service::GetIdentityManager() {
-  if (!identity_manager_) {
+identity::mojom::IdentityAccessor* Service::GetIdentityAccessor() {
+  if (!identity_accessor_) {
     service_binding_.GetConnector()->BindInterface(
-        identity::mojom::kServiceName, mojo::MakeRequest(&identity_manager_));
+        identity::mojom::kServiceName, mojo::MakeRequest(&identity_accessor_));
   }
-  return identity_manager_.get();
+  return identity_accessor_.get();
 }
 
 void Service::GetPrimaryAccountInfoCallback(
@@ -264,7 +264,7 @@
   scopes.insert(kScopeAuthGcm);
   if (features::IsClearCutLogEnabled())
     scopes.insert(kScopeClearCutLog);
-  identity_manager_->GetAccessToken(
+  identity_accessor_->GetAccessToken(
       account_info.value().account_id, scopes, "cros_assistant",
       base::BindOnce(&Service::GetAccessTokenCallback, base::Unretained(this)));
 }
diff --git a/chromeos/services/assistant/service.h b/chromeos/services/assistant/service.h
index d5e89c9..c69af88e 100644
--- a/chromeos/services/assistant/service.h
+++ b/chromeos/services/assistant/service.h
@@ -27,7 +27,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/service.h"
 #include "services/service_manager/public/cpp/service_binding.h"
@@ -97,8 +97,8 @@
 
   void RequestAccessToken();
 
-  void SetIdentityManagerForTesting(
-      identity::mojom::IdentityManagerPtr identity_manager);
+  void SetIdentityAccessorForTesting(
+      identity::mojom::IdentityAccessorPtr identity_accessor);
 
   void SetAssistantManagerForTesting(
       std::unique_ptr<AssistantManagerService> assistant_manager_service);
@@ -137,7 +137,7 @@
   void Init(mojom::ClientPtr client,
             mojom::DeviceActionsPtr device_actions) override;
 
-  identity::mojom::IdentityManager* GetIdentityManager();
+  identity::mojom::IdentityAccessor* GetIdentityAccessor();
 
   void GetPrimaryAccountInfoCallback(
       const base::Optional<AccountInfo>& account_info,
@@ -170,7 +170,7 @@
   mojom::ClientPtr client_;
   mojom::DeviceActionsPtr device_actions_;
 
-  identity::mojom::IdentityManagerPtr identity_manager_;
+  identity::mojom::IdentityAccessorPtr identity_accessor_;
 
   AccountId account_id_;
   std::unique_ptr<AssistantManagerService> assistant_manager_service_;
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc
index b921468..7959633 100644
--- a/chromeos/services/assistant/service_unittest.cc
+++ b/chromeos/services/assistant/service_unittest.cc
@@ -19,7 +19,7 @@
 #include "chromeos/dbus/fake_power_manager_client.h"
 #include "chromeos/services/assistant/fake_assistant_manager_service_impl.h"
 #include "chromeos/services/assistant/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.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"
@@ -35,14 +35,14 @@
     base::TimeDelta::FromMilliseconds(1000);
 }
 
-class FakeIdentityManager : identity::mojom::IdentityManager {
+class FakeIdentityAccessor : identity::mojom::IdentityAccessor {
  public:
-  FakeIdentityManager()
+  FakeIdentityAccessor()
       : binding_(this),
         access_token_expriation_delay_(kDefaultTokenExpirationDelay) {}
 
-  identity::mojom::IdentityManagerPtr CreateInterfacePtrAndBind() {
-    identity::mojom::IdentityManagerPtr ptr;
+  identity::mojom::IdentityAccessorPtr CreateInterfacePtrAndBind() {
+    identity::mojom::IdentityAccessorPtr ptr;
     binding_.Bind(mojo::MakeRequest(&ptr));
     return ptr;
   }
@@ -56,7 +56,7 @@
   int get_access_token_count() const { return get_access_token_count_; }
 
  private:
-  // identity::mojom::IdentityManager:
+  // identity::mojom::IdentityAccessor:
   void GetPrimaryAccountInfo(GetPrimaryAccountInfoCallback callback) override {
     AccountInfo account_info;
     account_info.account_id = "account_id";
@@ -94,7 +94,7 @@
     ++get_access_token_count_;
   }
 
-  mojo::Binding<identity::mojom::IdentityManager> binding_;
+  mojo::Binding<identity::mojom::IdentityAccessor> binding_;
 
   base::TimeDelta access_token_expriation_delay_;
 
@@ -102,7 +102,7 @@
 
   bool should_fail_ = false;
 
-  DISALLOW_COPY_AND_ASSIGN(FakeIdentityManager);
+  DISALLOW_COPY_AND_ASSIGN(FakeIdentityAccessor);
 };
 
 class FakeAssistantClient : mojom::Client {
@@ -185,8 +185,8 @@
     mock_timer->SetTaskRunner(mock_task_runner_);
     service_->SetTimerForTesting(std::move(mock_timer));
 
-    service_->SetIdentityManagerForTesting(
-        fake_identity_manager_.CreateInterfacePtrAndBind());
+    service_->SetIdentityAccessorForTesting(
+        fake_identity_accessor_.CreateInterfacePtrAndBind());
 
     auto fake_assistant_manager =
         std::make_unique<FakeAssistantManagerServiceImpl>();
@@ -210,7 +210,7 @@
     return platform_.get();
   }
 
-  FakeIdentityManager* identity_manager() { return &fake_identity_manager_; }
+  FakeIdentityAccessor* identity_accessor() { return &fake_identity_accessor_; }
 
   FakeAssistantManagerServiceImpl* assistant_manager_service() {
     return fake_assistant_manager_;
@@ -232,7 +232,7 @@
   std::unique_ptr<chromeos::assistant::Service> service_;
   mojom::AssistantPlatformPtr platform_;
 
-  FakeIdentityManager fake_identity_manager_;
+  FakeIdentityAccessor fake_identity_accessor_;
   FakeAssistantClient fake_assistant_client_;
   FakeDeviceActions fake_device_actions_;
 
@@ -249,47 +249,47 @@
 };
 
 TEST_F(AssistantServiceTest, RefreshTokenAfterExpire) {
-  auto current_count = identity_manager()->get_access_token_count();
+  auto current_count = identity_accessor()->get_access_token_count();
   mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay / 2);
   base::RunLoop().RunUntilIdle();
 
   // Before token expire, should not request new token.
-  EXPECT_EQ(identity_manager()->get_access_token_count(), current_count);
+  EXPECT_EQ(identity_accessor()->get_access_token_count(), current_count);
 
   mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay);
   base::RunLoop().RunUntilIdle();
 
   // After token expire, should request once.
-  EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count);
+  EXPECT_EQ(identity_accessor()->get_access_token_count(), ++current_count);
 }
 
 TEST_F(AssistantServiceTest, RetryRefreshTokenAfterFailure) {
-  auto current_count = identity_manager()->get_access_token_count();
-  identity_manager()->SetShouldFail(true);
+  auto current_count = identity_accessor()->get_access_token_count();
+  identity_accessor()->SetShouldFail(true);
   mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay);
   base::RunLoop().RunUntilIdle();
 
   // Token request failed.
-  EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count);
+  EXPECT_EQ(identity_accessor()->get_access_token_count(), ++current_count);
 
   base::RunLoop().RunUntilIdle();
 
   // Token request automatically retry.
-  identity_manager()->SetShouldFail(false);
+  identity_accessor()->SetShouldFail(false);
   // The failure delay has jitter so fast forward a bit more.
   mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay * 2);
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count);
+  EXPECT_EQ(identity_accessor()->get_access_token_count(), ++current_count);
 }
 
 TEST_F(AssistantServiceTest, RetryRefreshTokenAfterDeviceWakeup) {
-  auto current_count = identity_manager()->get_access_token_count();
+  auto current_count = identity_accessor()->get_access_token_count();
   power_manager_client()->SendSuspendDone();
   base::RunLoop().RunUntilIdle();
 
   // Token requested immediately after suspend done.
-  EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count);
+  EXPECT_EQ(identity_accessor()->get_access_token_count(), ++current_count);
 }
 
 }  // namespace assistant
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 83e461a..8764984 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -646,7 +646,7 @@
   expect_sync_configuration_aborted_ = false;
   engine_initialized_ = false;
   last_snapshot_ = syncer::SyncCycleSnapshot();
-  auth_manager_->Clear();
+  auth_manager_->ConnectionClosed();
 
   NotifyObservers();
 
diff --git a/components/browser_sync/sync_auth_manager.cc b/components/browser_sync/sync_auth_manager.cc
index 4e52e51..17020a7 100644
--- a/components/browser_sync/sync_auth_manager.cc
+++ b/components/browser_sync/sync_auth_manager.cc
@@ -92,6 +92,18 @@
   return sync_account_;
 }
 
+GoogleServiceAuthError SyncAuthManager::GetLastAuthError() const {
+  // TODO(crbug.com/921553): Which error should take precedence?
+  if (partial_token_status_.connection_status ==
+      syncer::CONNECTION_SERVER_ERROR) {
+    // TODO(crbug.com/921553): Verify whether CONNECTION_FAILED is really an
+    // appropriate auth error here; maybe SERVICE_ERROR would be better? Or
+    // maybe we shouldn't expose this case as an auth error at all?
+    return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
+  }
+  return last_auth_error_;
+}
+
 syncer::SyncTokenStatus SyncAuthManager::GetSyncTokenStatus() const {
   DCHECK(partial_token_status_.next_token_request_time.is_null());
 
@@ -174,13 +186,11 @@
       if (!request_access_token_retry_timer_.IsRunning()) {
         request_access_token_backoff_.Reset();
       }
-      last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
       break;
     case syncer::CONNECTION_SERVER_ERROR:
-      // TODO(crbug.com/839834): Verify whether CONNECTION_FAILED is really an
-      // appropriate auth error here; maybe SERVICE_ERROR would be better?
-      last_auth_error_ =
-          GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
+      // Note: This case will be exposed as an auth error, due to the
+      // |connection_status| in |partial_token_error_|.
+      DCHECK(GetLastAuthError().IsTransientError());
       break;
     case syncer::CONNECTION_NOT_ATTEMPTED:
       // The connection status should never change to "not attempted".
@@ -220,11 +230,8 @@
                           weak_ptr_factory_.GetWeakPtr()));
 }
 
-void SyncAuthManager::Clear() {
-  // TODO(crbug.com/839834): Clearing the auth error here isn't quite right.
-  // It makes sense to clear any auth error we got from the Sync server, but we
-  // should probably retain any errors from the identity manager.
-  last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
+void SyncAuthManager::ConnectionClosed() {
+  partial_token_status_ = syncer::SyncTokenStatus();
   ClearAccessTokenAndRequest();
 }
 
@@ -360,7 +367,8 @@
     sync_account_ = syncer::SyncAccountInfo();
     // Also clear any pending request or auth errors we might have, since they
     // aren't meaningful anymore.
-    Clear();
+    ConnectionClosed();
+    last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
     account_state_changed_callback_.Run();
   }
 
@@ -388,9 +396,6 @@
     request_access_token_retry_timer_.Stop();
   }
 
-  const identity::ScopeSet kOAuth2ScopeSet{
-      GaiaConstants::kChromeSyncOAuth2Scope};
-
   // Invalidate any previous token, otherwise the token service will return the
   // same token again.
   InvalidateAccessToken();
@@ -401,7 +406,7 @@
   ongoing_access_token_fetch_ =
       identity_manager_->CreateAccessTokenFetcherForAccount(
           sync_account_.account_info.account_id, kSyncOAuthConsumerName,
-          kOAuth2ScopeSet,
+          {GaiaConstants::kChromeSyncOAuth2Scope},
           base::BindOnce(&SyncAuthManager::AccessTokenFetched,
                          base::Unretained(this)),
           identity::AccessTokenFetcher::Mode::kWaitUntilRefreshTokenAvailable);
diff --git a/components/browser_sync/sync_auth_manager.h b/components/browser_sync/sync_auth_manager.h
index 18c68ad..d88af49 100644
--- a/components/browser_sync/sync_auth_manager.h
+++ b/components/browser_sync/sync_auth_manager.h
@@ -64,7 +64,9 @@
   // server. Note that this account may not be blessed for Sync-the-feature.
   syncer::SyncAccountInfo GetActiveAccountInfo() const;
 
-  GoogleServiceAuthError GetLastAuthError() const { return last_auth_error_; }
+  // Returns the last auth error that was encountered. The error could have come
+  // from the Sync server or from the IdentityManager.
+  GoogleServiceAuthError GetLastAuthError() const;
 
   // Returns the credentials to be passed to the SyncEngine.
   syncer::SyncCredentials GetCredentials() const;
@@ -76,12 +78,14 @@
   syncer::SyncTokenStatus GetSyncTokenStatus() const;
 
   // Called by ProfileSyncService when the status of the connection to the Sync
-  // server changed. Updates auth error state accordingly.
+  // server changed. Updates auth error state accordingly. During Sync startup,
+  // this is what initiates fetching an access token.
   void ConnectionStatusChanged(syncer::ConnectionStatus status);
 
-  // Clears all auth-related state (error, cached access token etc). Called
-  // when Sync is turned off.
-  void Clear();
+  // Called by ProfileSyncService when the connection to the Sync server is
+  // closed (due to Sync being shut down). Clears all related state (such as
+  // cached access token, error from the server, etc).
+  void ConnectionClosed();
 
   // identity::IdentityManager::Observer implementation.
   void OnPrimaryAccountSet(
@@ -142,12 +146,8 @@
   // delayed startup.
   syncer::SyncAccountInfo sync_account_;
 
-  // This is a cache of the last authentication response we received either
-  // from the sync server or from Chrome's identity/token management system.
-  // TODO(crbug.com/839834): Differentiate between these types of auth errors,
-  // since their semantics and lifetimes are quite different: e.g. the former
-  // can only exist while the Sync engine is initialized; the latter exists
-  // independent of Sync state, and probably shouldn't get reset in Clear().
+  // This is a cache of the last authentication response we received from
+  // Chrome's identity/token management system.
   GoogleServiceAuthError last_auth_error_;
 
   // The current access token. This is mutually exclusive with
@@ -167,7 +167,7 @@
 
   // Info about the state of our access token, for display in the internals UI.
   // "Partial" because this instance is not fully populated - in particular,
-  // |have_token| and |next_token_request_time| get computed on demand.
+  // |has_token| and |next_token_request_time| get computed on demand.
   syncer::SyncTokenStatus partial_token_status_;
 
   base::WeakPtrFactory<SyncAuthManager> weak_ptr_factory_;
diff --git a/components/browser_sync/sync_auth_manager_unittest.cc b/components/browser_sync/sync_auth_manager_unittest.cc
index acd3bd64..24f2376 100644
--- a/components/browser_sync/sync_auth_manager_unittest.cc
+++ b/components/browser_sync/sync_auth_manager_unittest.cc
@@ -69,8 +69,8 @@
   EXPECT_TRUE(auth_manager->access_token().empty());
   // Note: Calling RegisterForAuthNotifications is illegal in local Sync mode,
   // so we don't test that.
-  // Calling Clear() does nothing, but shouldn't crash.
-  auth_manager->Clear();
+  // Calling ConnectionClosed() does nothing, but shouldn't crash.
+  auth_manager->ConnectionClosed();
 }
 
 // ChromeOS doesn't support sign-in/sign-out.
@@ -163,6 +163,33 @@
   EXPECT_EQ(auth_manager->GetLastAuthError().state(),
             GoogleServiceAuthError::NONE);
 }
+
+TEST_F(SyncAuthManagerTest, DoesNotClearAuthErrorOnSyncDisable) {
+  // Start out already signed in before the SyncAuthManager is created.
+  std::string account_id =
+      identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
+
+  auto auth_manager = CreateAuthManager();
+
+  auth_manager->RegisterForAuthNotifications();
+
+  ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+            account_id);
+  ASSERT_EQ(auth_manager->GetLastAuthError().state(),
+            GoogleServiceAuthError::NONE);
+
+  // Force an auth error by revoking the refresh token.
+  identity_env()->RemoveRefreshTokenForPrimaryAccount();
+  ASSERT_NE(auth_manager->GetLastAuthError().state(),
+            GoogleServiceAuthError::NONE);
+
+  // Now Sync gets turned off, e.g. because the user disabled it.
+  auth_manager->ConnectionClosed();
+
+  // Since the user is still signed in, the auth error should have remained.
+  EXPECT_NE(auth_manager->GetLastAuthError().state(),
+            GoogleServiceAuthError::NONE);
+}
 #endif  // !OS_CHROMEOS
 
 TEST_F(SyncAuthManagerTest, ForwardsCredentialsEvents) {
@@ -340,6 +367,37 @@
   EXPECT_EQ(auth_manager->GetCredentials().sync_token, "access_token");
 }
 
+TEST_F(SyncAuthManagerTest, ClearsServerErrorOnSyncDisable) {
+  std::string account_id =
+      identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
+  auto auth_manager = CreateAuthManager();
+  auth_manager->RegisterForAuthNotifications();
+  ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+            account_id);
+
+  // During Sync startup, the SyncEngine attempts to connect to the server
+  // without an access token, resulting in a call to ConnectionStatusChanged
+  // with CONNECTION_AUTH_ERROR. This is what kicks off the initial access token
+  // fetch.
+  auth_manager->ConnectionStatusChanged(syncer::CONNECTION_AUTH_ERROR);
+  identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Now() + base::TimeDelta::FromHours(1));
+  ASSERT_EQ(auth_manager->GetCredentials().sync_token, "access_token");
+
+  // A server error happens.
+  auth_manager->ConnectionStatusChanged(syncer::CONNECTION_SERVER_ERROR);
+  ASSERT_NE(auth_manager->GetLastAuthError(),
+            GoogleServiceAuthError::AuthErrorNone());
+
+  // Now Sync gets turned off, e.g. because the user disabled it.
+  auth_manager->ConnectionClosed();
+
+  // This should have cleared the auth error, because it was due to a server
+  // error which is now not meaningful anymore.
+  EXPECT_EQ(auth_manager->GetLastAuthError(),
+            GoogleServiceAuthError::AuthErrorNone());
+}
+
 TEST_F(SyncAuthManagerTest, RequestsNewAccessTokenOnExpiry) {
   std::string account_id =
       identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
diff --git a/components/cloud_devices/common/printer_description.cc b/components/cloud_devices/common/printer_description.cc
index 94be3b2a..514f9a4 100644
--- a/components/cloud_devices/common/printer_description.cc
+++ b/components/cloud_devices/common/printer_description.cc
@@ -672,30 +672,27 @@
 
 VendorCapability::VendorCapability() = default;
 
-VendorCapability::VendorCapability(Type type,
-                                   const std::string& id,
+VendorCapability::VendorCapability(const std::string& id,
                                    const std::string& display_name,
                                    RangeVendorCapability range_capability)
-    : type_(type),
+    : type_(Type::RANGE),
       id_(id),
       display_name_(display_name),
       range_capability_(std::move(range_capability)) {}
 
-VendorCapability::VendorCapability(Type type,
-                                   const std::string& id,
+VendorCapability::VendorCapability(const std::string& id,
                                    const std::string& display_name,
                                    SelectVendorCapability select_capability)
-    : type_(type),
+    : type_(Type::SELECT),
       id_(id),
       display_name_(display_name),
       select_capability_(std::move(select_capability)) {}
 
 VendorCapability::VendorCapability(
-    Type type,
     const std::string& id,
     const std::string& display_name,
     TypedValueVendorCapability typed_value_capability)
-    : type_(type),
+    : type_(Type::TYPED_VALUE),
       id_(id),
       display_name_(display_name),
       typed_value_capability_(std::move(typed_value_capability)) {}
diff --git a/components/cloud_devices/common/printer_description.h b/components/cloud_devices/common/printer_description.h
index 3253758..cf6432e 100644
--- a/components/cloud_devices/common/printer_description.h
+++ b/components/cloud_devices/common/printer_description.h
@@ -148,16 +148,13 @@
   };
 
   VendorCapability();
-  VendorCapability(Type type,
-                   const std::string& id,
+  VendorCapability(const std::string& id,
                    const std::string& display_name,
                    RangeVendorCapability range_capability);
-  VendorCapability(Type type,
-                   const std::string& id,
+  VendorCapability(const std::string& id,
                    const std::string& display_name,
                    SelectVendorCapability select_capability);
-  VendorCapability(Type type,
-                   const std::string& id,
+  VendorCapability(const std::string& id,
                    const std::string& display_name,
                    TypedValueVendorCapability typed_value_capability);
   VendorCapability(VendorCapability&& other);
diff --git a/components/cloud_devices/common/printer_description_unittest.cc b/components/cloud_devices/common/printer_description_unittest.cc
index 30b62ad..73b8c9f 100644
--- a/components/cloud_devices/common/printer_description_unittest.cc
+++ b/components/cloud_devices/common/printer_description_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/cloud_devices/common/printer_description.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
@@ -1033,17 +1034,16 @@
     EXPECT_TRUE(vendor_capabilities.LoadFrom(description));
     EXPECT_EQ(3u, vendor_capabilities.size());
     EXPECT_TRUE(vendor_capabilities.Contains(VendorCapability(
-        VendorCapability::Type::RANGE, "id_1", "name_1",
+        "id_1", "name_1",
         RangeVendorCapability(RangeVendorCapability::ValueType::INTEGER, "1",
                               "10"))));
     SelectVendorCapability select_capability;
     select_capability.AddDefaultOption(
         SelectVendorCapabilityOption("value", "name"), true);
     EXPECT_TRUE(vendor_capabilities.Contains(
-        VendorCapability(VendorCapability::Type::SELECT, "id_2", "name_2",
-                         std::move(select_capability))));
+        VendorCapability("id_2", "name_2", std::move(select_capability))));
     EXPECT_TRUE(vendor_capabilities.Contains(VendorCapability(
-        VendorCapability::Type::TYPED_VALUE, "id_3", "name_3",
+        "id_3", "name_3",
         TypedValueVendorCapability(
             TypedValueVendorCapability::ValueType::INTEGER, "1"))));
   }
@@ -1065,17 +1065,16 @@
 
   VendorCapabilities vendor_capabilities;
   vendor_capabilities.AddOption(VendorCapability(
-      VendorCapability::Type::RANGE, "id_1", "name_1",
+      "id_1", "name_1",
       RangeVendorCapability(RangeVendorCapability::ValueType::INTEGER, "1",
                             "10")));
   SelectVendorCapability select_capability;
   select_capability.AddDefaultOption(
       SelectVendorCapabilityOption("value", "name"), true);
-  vendor_capabilities.AddOption(VendorCapability(VendorCapability::Type::SELECT,
-                                                 "id_2", "name_2",
-                                                 std::move(select_capability)));
+  vendor_capabilities.AddOption(
+      VendorCapability("id_2", "name_2", std::move(select_capability)));
   vendor_capabilities.AddOption(VendorCapability(
-      VendorCapability::Type::TYPED_VALUE, "id_3", "name_3",
+      "id_3", "name_3",
       TypedValueVendorCapability(TypedValueVendorCapability::ValueType::INTEGER,
                                  "1")));
 
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn
index 915c034..f71dd88 100644
--- a/components/crash/content/app/BUILD.gn
+++ b/components/crash/content/app/BUILD.gn
@@ -66,7 +66,10 @@
   }
 
   if (is_android) {
-    deps += [ "//components/crash/android:jni_headers" ]
+    deps += [
+      "//components/crash/android:jni_headers",
+      "//third_party/crashpad/crashpad/handler",
+    ]
   }
 
   if (is_android || is_linux) {
diff --git a/components/crash/content/app/crashpad_linux.cc b/components/crash/content/app/crashpad_linux.cc
index 47472cae..cd865e97 100644
--- a/components/crash/content/app/crashpad_linux.cc
+++ b/components/crash/content/app/crashpad_linux.cc
@@ -4,6 +4,7 @@
 
 #include "components/crash/content/app/crashpad.h"
 
+#include <dlfcn.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/types.h>
@@ -246,6 +247,33 @@
   }
 }
 
+// Constructs paths to a handler trampoline executable and a library exporting
+// the symbol `CrashpadHandlerMain()`. This requires this function to be built
+// into the same object exporting this symbol and the handler trampoline is
+// adjacent to it.
+bool GetHandlerTrampoline(std::string* handler_trampoline,
+                          std::string* handler_library) {
+  Dl_info info;
+  if (dladdr(reinterpret_cast<void*>(&GetHandlerTrampoline), &info) == 0) {
+    return false;
+  }
+
+  std::string local_handler_library(info.dli_fname);
+
+  size_t libdir_end = local_handler_library.rfind('/');
+  if (libdir_end == std::string::npos) {
+    return false;
+  }
+
+  std::string local_handler_trampoline(local_handler_library, 0,
+                                       libdir_end + 1);
+  local_handler_trampoline += "libcrashpad_handler_trampoline.so";
+
+  handler_trampoline->swap(local_handler_trampoline);
+  handler_library->swap(local_handler_library);
+  return true;
+}
+
 #if defined(__arm__) && defined(__ARM_ARCH_7A__)
 #define CURRENT_ABI "armeabi-v7a"
 #elif defined(__arm__)
@@ -281,7 +309,8 @@
 
 // Copies and extends the current environment with CLASSPATH and LD_LIBRARY_PATH
 // set to library paths in the APK.
-bool BuildEnvironmentWithApk(std::vector<std::string>* result) {
+bool BuildEnvironmentWithApk(bool use_64_bit,
+                             std::vector<std::string>* result) {
   DCHECK(result->empty());
 
   std::string classpath;
@@ -299,6 +328,12 @@
   env->GetVar(kLdLibraryPathVar, &current_library_path);
   library_path += ":" + current_library_path;
 
+  static constexpr char kRuntimeRootVar[] = "ANDROID_RUNTIME_ROOT";
+  std::string runtime_root;
+  if (env->GetVar(kRuntimeRootVar, &runtime_root)) {
+    library_path += ":" + runtime_root + (use_64_bit ? "/lib64" : "/lib");
+  }
+
   result->push_back("CLASSPATH=" + classpath);
   result->push_back("LD_LIBRARY_PATH=" + library_path);
   for (char** envp = environ; *envp != nullptr; ++envp) {
@@ -414,6 +449,19 @@
 }
 
 class HandlerStarter {
+#if defined(OS_ANDROID)
+  // TODO(jperaza): Currently only launching a same-bitness handler is
+  // supported. The logic to build package paths, locate a handler executable,
+  // and the crashpad client interface for launching a Java handler need to be
+  // updated to use a specified bitness before a cross-bitness handler can be
+  // used.
+#if defined(ARCH_CPU_64_BITS)
+  static constexpr bool kUse64Bit = true;
+#else
+  static constexpr bool kUse64Bit = false;
+#endif
+#endif  // OS_ANDROID
+
  public:
   static HandlerStarter* Get() {
     static HandlerStarter* instance = new HandlerStarter();
@@ -448,25 +496,35 @@
     }
 
     if (!base::PathExists(handler_path)) {
-      use_java_handler_ = true;
+      // The linker doesn't support loading executables passed on its command
+      // line until Q.
+      if (base::android::BuildInfo::GetInstance()->is_at_least_q()) {
+        bool found_library =
+            GetHandlerTrampoline(&handler_trampoline_, &handler_library_);
+        DCHECK(found_library);
+      } else {
+        use_java_handler_ = true;
+      }
     }
 
     if (!dump_at_crash) {
       return database_path;
     }
 
-    if (use_java_handler_) {
+    if (use_java_handler_ || !handler_trampoline_.empty()) {
       std::vector<std::string> env;
-      if (!BuildEnvironmentWithApk(&env)) {
+      if (!BuildEnvironmentWithApk(kUse64Bit, &env)) {
         return database_path;
       }
 
-      // TODO(jperaza): The logic for constructing an appropriate
-      // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
-      // need to be launched by executing the dynamic linker instead.
-      bool result = GetCrashpadClient().StartJavaHandlerAtCrash(
-          kCrashpadJavaMain, &env, database_path, metrics_path, url,
-          process_annotations, arguments);
+      bool result = use_java_handler_
+                        ? GetCrashpadClient().StartJavaHandlerAtCrash(
+                              kCrashpadJavaMain, &env, database_path,
+                              metrics_path, url, process_annotations, arguments)
+                        : GetCrashpadClient().StartHandlerWithLinkerAtCrash(
+                              handler_trampoline_, handler_library_, kUse64Bit,
+                              &env, database_path, metrics_path, url,
+                              process_annotations, arguments);
       DCHECK(result);
       return database_path;
     }
@@ -499,18 +557,21 @@
     }
 
 #if defined(OS_ANDROID)
-    if (use_java_handler_) {
+    if (use_java_handler_ || !handler_trampoline_.empty()) {
       std::vector<std::string> env;
-      if (!BuildEnvironmentWithApk(&env)) {
+      if (!BuildEnvironmentWithApk(kUse64Bit, &env)) {
         return false;
       }
 
-      // TODO(jperaza): The logic for constructing an appropriate
-      // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
-      // need to be launched by executing the dynamic linker instead.
-      bool result = GetCrashpadClient().StartJavaHandlerForClient(
-          kCrashpadJavaMain, &env, database_path, metrics_path, url,
-          process_annotations, arguments, fd);
+      bool result =
+          use_java_handler_
+              ? GetCrashpadClient().StartJavaHandlerForClient(
+                    kCrashpadJavaMain, &env, database_path, metrics_path, url,
+                    process_annotations, arguments, fd)
+              : GetCrashpadClient().StartHandlerWithLinkerForClient(
+                    handler_trampoline_, handler_library_, kUse64Bit, &env,
+                    database_path, metrics_path, url, process_annotations,
+                    arguments, fd);
       return result;
     }
 #endif
@@ -530,6 +591,8 @@
 
   crashpad::SanitizationInformation browser_sanitization_info_;
 #if defined(OS_ANDROID)
+  std::string handler_trampoline_;
+  std::string handler_library_;
   bool use_java_handler_ = false;
 #endif
 
diff --git a/components/download/internal/common/download_file_impl.cc b/components/download/internal/common/download_file_impl.cc
index 49f97506..e433cb0 100644
--- a/components/download/internal/common/download_file_impl.cc
+++ b/components/download/internal/common/download_file_impl.cc
@@ -380,11 +380,7 @@
   base::FilePath new_path = parameters->new_path;
 
   if ((parameters->option & UNIQUIFY) && new_path != file_.full_path()) {
-    int uniquifier =
-        base::GetUniquePathNumber(new_path, base::FilePath::StringType());
-    if (uniquifier > 0)
-      new_path = new_path.InsertBeforeExtensionASCII(
-          base::StringPrintf(" (%d)", uniquifier));
+    new_path = base::GetUniquePath(new_path);
   }
 
   DownloadInterruptReason reason = file_.Rename(new_path);
diff --git a/components/embedder_support/android/delegate/color_chooser_android.h b/components/embedder_support/android/delegate/color_chooser_android.h
index d05421b..6b38cc1 100644
--- a/components/embedder_support/android/delegate/color_chooser_android.h
+++ b/components/embedder_support/android/delegate/color_chooser_android.h
@@ -12,7 +12,7 @@
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "content/public/browser/color_chooser.h"
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h"
 
 using base::android::AttachCurrentThread;
 using base::android::ScopedJavaLocalRef;
diff --git a/components/keyed_service/core/simple_dependency_manager.cc b/components/keyed_service/core/simple_dependency_manager.cc
index a70d694..385ca3ac 100644
--- a/components/keyed_service/core/simple_dependency_manager.cc
+++ b/components/keyed_service/core/simple_dependency_manager.cc
@@ -5,6 +5,7 @@
 #include "components/keyed_service/core/simple_dependency_manager.h"
 
 #include "base/no_destructor.h"
+#include "base/trace_event/trace_event.h"
 #include "components/keyed_service/core/simple_factory_key.h"
 
 #ifndef NDEBUG
@@ -30,6 +31,19 @@
   return factory.get();
 }
 
+void SimpleDependencyManager::RegisterProfilePrefsForServices(
+    SimpleFactoryKey* key,
+    user_prefs::PrefRegistrySyncable* pref_registry) {
+  TRACE_EVENT0("browser",
+               "SimpleDependencyManager::RegisterProfilePrefsForServices");
+  RegisterPrefsForServices(key, pref_registry);
+}
+
+void SimpleDependencyManager::CreateServicesForTest(SimpleFactoryKey* key) {
+  TRACE_EVENT0("browser", "SimpleDependencyManager::CreateServices");
+  DependencyManager::CreateContextServices(key, true);
+}
+
 SimpleDependencyManager::SimpleDependencyManager() = default;
 
 SimpleDependencyManager::~SimpleDependencyManager() = default;
diff --git a/components/keyed_service/core/simple_dependency_manager.h b/components/keyed_service/core/simple_dependency_manager.h
index 4358b1c2..817a5ed 100644
--- a/components/keyed_service/core/simple_dependency_manager.h
+++ b/components/keyed_service/core/simple_dependency_manager.h
@@ -23,6 +23,18 @@
 
   static SimpleDependencyManager* GetInstance();
 
+  // Registers profile-specific preferences for all services via |registry|.
+  // |key| is used to prevent multiple registrations on the same BrowserContext
+  // in tests.
+  void RegisterProfilePrefsForServices(
+      SimpleFactoryKey* key,
+      user_prefs::PrefRegistrySyncable* pref_registry);
+
+  // Create services for test BrowserContexts - these contexts will not create
+  // services for any SimpleKeyedBaseFactories that return true from
+  // ServiceIsNULLWhileTesting().
+  void CreateServicesForTest(SimpleFactoryKey* key);
+
  private:
   ~SimpleDependencyManager() override;
 
diff --git a/components/metrics/call_stack_profile_builder.cc b/components/metrics/call_stack_profile_builder.cc
index f176a2e..9240d3b 100644
--- a/components/metrics/call_stack_profile_builder.cc
+++ b/components/metrics/call_stack_profile_builder.cc
@@ -91,7 +91,7 @@
     // keep the frame information even if its module is invalid so we have
     // visibility into how often this issue is happening on the server.
     CallStackProfile::Location* location = stack.add_frame();
-    if (!frame.module->is_valid)
+    if (!frame.module)
       continue;
 
     // Dedup modules.
@@ -105,7 +105,7 @@
     // Write CallStackProfile::Location protobuf message.
     ptrdiff_t module_offset =
         reinterpret_cast<const char*>(frame.instruction_pointer) -
-        reinterpret_cast<const char*>(frame.module->base_address);
+        reinterpret_cast<const char*>(frame.module->GetBaseAddress());
     DCHECK_GE(module_offset, 0);
     location->set_address(static_cast<uint64_t>(module_offset));
     location->set_module_id_index(module_loc->second);
@@ -167,8 +167,8 @@
   for (const auto* module : modules_) {
     CallStackProfile::ModuleIdentifier* module_id =
         call_stack_profile->add_module_id();
-    module_id->set_build_id(module->id);
-    module_id->set_name_md5_prefix(HashModuleFilename(module->filename));
+    module_id->set_build_id(module->GetId());
+    module_id->set_name_md5_prefix(HashModuleFilename(module->GetFilename()));
   }
 
   PassProfilesToMetricsProvider(std::move(sampled_profile_));
diff --git a/components/metrics/call_stack_profile_builder_unittest.cc b/components/metrics/call_stack_profile_builder_unittest.cc
index 7481a5c..f956b9dd 100644
--- a/components/metrics/call_stack_profile_builder_unittest.cc
+++ b/components/metrics/call_stack_profile_builder_unittest.cc
@@ -85,15 +85,15 @@
 #endif
 
   const uintptr_t module_base_address1 = 0x1000;
-  Module module1 = {module_base_address1, "1", module_path};
+  Module module1(module_base_address1, "1", module_path);
   Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
-  Module module2 = {module_base_address2, "2", module_path};
+  Module module2(module_base_address2, "2", module_path);
   Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   const uintptr_t module_base_address3 = 0x1010;
-  Module module3 = {module_base_address3, "3", module_path};
+  Module module3(module_base_address3, "3", module_path);
   Frame frame3 = {module_base_address3 + 0x10, &module3};
 
   std::vector<Frame> frames1 = {frame1, frame2};
@@ -165,11 +165,11 @@
 #endif
 
   const uintptr_t module_base_address1 = 0x1000;
-  Module module1 = {module_base_address1, "1", module_path};
+  Module module1(module_base_address1, "1", module_path);
   Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
-  Module module2 = {module_base_address2, "2", module_path};
+  Module module2(module_base_address2, "2", module_path);
   Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames = {frame1, frame2};
@@ -211,11 +211,11 @@
 #endif
 
   const uintptr_t module_base_address1 = 0x1000;
-  Module module1 = {module_base_address1, "1", module_path};
+  Module module1(module_base_address1, "1", module_path);
   Frame frame1 = {module_base_address1 + 0x10, &module1};
 
   const uintptr_t module_base_address2 = 0x1100;
-  Module module2 = {module_base_address2, "2", module_path};
+  Module module2(module_base_address2, "2", module_path);
   Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames1 = {frame1};
@@ -251,8 +251,8 @@
       std::make_unique<TestingCallStackProfileBuilder>(kProfileParams);
 
   const uintptr_t module_base_address1 = 0x1000;
-  Module module1;  // module1 has no information hence invalid.
-  Frame frame1 = {module_base_address1 + 0x10, &module1};
+  // A frame with no module.
+  Frame frame1 = {module_base_address1 + 0x10, nullptr};
 
   const uintptr_t module_base_address2 = 0x1100;
 #if defined(OS_WIN)
@@ -262,7 +262,7 @@
   uint64_t module_md5 = 0x554838A8451AC36CULL;
   base::FilePath module_path("/some/path/to/chrome");
 #endif
-  Module module2 = {module_base_address2, "2", module_path};
+  Module module2(module_base_address2, "2", module_path);
   Frame frame2 = {module_base_address2 + 0x10, &module2};
 
   std::vector<Frame> frames = {frame1, frame2};
@@ -311,7 +311,7 @@
   base::FilePath module_path("/some/path/to/chrome");
 #endif
 
-  Module module = {module_base_address, "1", module_path};
+  Module module(module_base_address, "1", module_path);
   Frame frame1 = {module_base_address + 0x10, &module};
   Frame frame2 = {module_base_address + 0x20, &module};
 
@@ -369,7 +369,7 @@
   base::FilePath module_path("/some/path/to/chrome");
 #endif
 
-  Module module = {0x1000, "1", module_path};
+  Module module(0x1000, "1", module_path);
   Frame frame = {0x1000 + 0x10, &module};
 
   // Id 0 means the message loop hasn't been started yet, so the sample should
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 1e51ff5..7649d926 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -261,6 +261,10 @@
 
 // Feature used to show a generic vector icon for omnibox search instead of the
 // search engine favicon.
+//
+// This feature flag's string has a typo: "Omnibox" => "Ominbox".
+// Do not correct this typo, because this misspelled string is being used
+// as-is in field trials.
 const base::Feature kUIExperimentUseGenericSearchEngineIcon{
     "OminboxUIExperimentUseGenericSearchEngineIcon",
     base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 6122d6e..ac2b9e3 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -256,7 +256,11 @@
           0) {
         changes = password_store_sync_->AddLoginSync(
             PasswordFromEntityChange(entity_change, /*sync_time=*/time_now));
-        DCHECK_LE(1U, changes.size());
+        // TODO(crbug.com/936823): The DCHECK_LE below is legit. However, recent
+        // crashes suggest that 2 changes are returned in the above call
+        // (details are in the bug). It should be uncommentted once the
+        // underlying cause is discovered.
+        // DCHECK_LE(1U, changes.size());
       } else {
         changes = password_store_sync_->UpdateLoginSync(
             PasswordFromEntityChange(entity_change, /*sync_time=*/time_now));
@@ -266,6 +270,25 @@
         return syncer::ModelError(
             FROM_HERE, "Failed to add/update an entry in the password store.");
       }
+
+      // TODO(crbug.com/936823): |changes| should never contain more than one
+      // change. This code path has been added to address the issue explained in
+      // the bug. It should be removed once the underlying cause of the issue is
+      // discovered.
+      if (changes.size() == 2) {
+        // In that case the first change indicates a removal of an existing
+        // password and we aren't interested in it.
+        DCHECK(changes[0].type() == PasswordStoreChange::REMOVE);
+        DCHECK(changes[1].type() == PasswordStoreChange::ADD);
+        change_processor()->UpdateStorageKey(
+            entity_change.data(),
+            /*storage_key=*/
+            base::NumberToString(changes[1].primary_key()),
+            metadata_change_list.get());
+        password_store_changes.push_back(changes[1]);
+        continue;
+      }
+
       change_processor()->UpdateStorageKey(
           entity_change.data(),
           /*storage_key=*/
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc
index c8dee60..d1312bc 100644
--- a/components/payments/content/payment_request_spec.cc
+++ b/components/payments/content/payment_request_spec.cc
@@ -358,7 +358,7 @@
 
   selected_shipping_option_ = nullptr;
   selected_shipping_option_error_.clear();
-  if (details_->shipping_options->empty()) {
+  if (details_->shipping_options->empty() || !details_->error.empty()) {
     // No options are provided by the merchant.
     if (after_update) {
       // This is after an update, which means that the selected address is not
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp
index bb1786b5..581d17f 100644
--- a/components/security_interstitials_strings.grdp
+++ b/components/security_interstitials_strings.grdp
@@ -69,7 +69,7 @@
     Did you mean?
   </message>
   <message name="IDS_LOOKALIKE_URL_HEADING" desc="Large heading. Context: the error page that's shown when the requested URL looks like a more popular URL.">
-    Did you mean to go to &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN">$1<ex>example.com</ex></ph>&lt;/a&gt;?
+    Did you mean &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN">$1<ex>example.com</ex></ph>&lt;/a&gt;?
   </message>
   <message name="IDS_LOOKALIKE_URL_IGNORE" desc="Button text. Context: the error page that's shown when the requested URL looks like a more popular URL. This button continues on to the originally-requested URL.">
     Ignore
diff --git a/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1 b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1
new file mode 100644
index 0000000..981ff93
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1 b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1
new file mode 100644
index 0000000..981ff93
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1 b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1
new file mode 100644
index 0000000..981ff93
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1 b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1
new file mode 100644
index 0000000..981ff93
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d
\ No newline at end of file
diff --git a/components/security_state/core/BUILD.gn b/components/security_state/core/BUILD.gn
index 8ccd5b9d..676f699 100644
--- a/components/security_state/core/BUILD.gn
+++ b/components/security_state/core/BUILD.gn
@@ -16,8 +16,6 @@
     "insecure_input_event_data.h",
     "security_state.cc",
     "security_state.h",
-    "security_state_ui.cc",
-    "security_state_ui.h",
   ]
 
   public_deps = [
diff --git a/components/security_state/core/security_state_ui.cc b/components/security_state/core/security_state_ui.cc
deleted file mode 100644
index e91560ae..0000000
--- a/components/security_state/core/security_state_ui.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/security_state/core/security_state_ui.h"
-
-namespace security_state {
-
-bool ShouldAlwaysShowIcon(SecurityLevel security_level) {
-  // Enumerate all |SecurityLevel| values for compile-time enforcement that all
-  // cases are explicitly handled.
-  switch (security_level) {
-    case NONE:
-      return false;
-    case HTTP_SHOW_WARNING:
-    case EV_SECURE:
-    case SECURE:
-    case SECURE_WITH_POLICY_INSTALLED_CERT:
-    case DANGEROUS:
-      return true;
-    case SECURITY_LEVEL_COUNT:
-      NOTREACHED();
-      return false;
-  }
-  NOTREACHED();
-  return false;
-}
-
-}  // namespace security_state
diff --git a/components/security_state/core/security_state_ui.h b/components/security_state/core/security_state_ui.h
deleted file mode 100644
index 035091f..0000000
--- a/components/security_state/core/security_state_ui.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SECURITY_STATE_SECURITY_STATE_UI_H_
-#define COMPONENTS_SECURITY_STATE_SECURITY_STATE_UI_H_
-
-#include "components/security_state/core/security_state.h"
-
-// Provides helper methods that encapsulate platform-independent security UI
-// logic.
-namespace security_state {
-
-// On some (mobile) form factors, the security indicator icon is hidden to save
-// UI space. This returns whether the icon should always be shown for the given
-// |security_level|, i.e. whether to override the hiding behaviour.
-bool ShouldAlwaysShowIcon(SecurityLevel security_level);
-
-}  // namespace security_state
-
-#endif  // COMPONENTS_SECURITY_STATE_SECURITY_STATE_UI_H_
diff --git a/components/test/data/payments/payment_request_update_with_test.html b/components/test/data/payments/payment_request_update_with_test.html
index c30f3ab0..7ee44c9 100644
--- a/components/test/data/payments/payment_request_update_with_test.html
+++ b/components/test/data/payments/payment_request_update_with_test.html
@@ -17,6 +17,7 @@
 <button class="small" onclick="updateWithDisplayItems()" id="updateWithDisplayItems">updateWithDisplayItems</button>
 <button class="small" onclick="updateWithShippingOptions()" id="updateWithShippingOptions">updateWithShippingOptions</button>
 <button class="small" onclick="updateWithModifiers()" id="updateWithModifiers">updateWithModifiers</button>
+<button class="small" onclick="updateWithError()" id="updateWithError">updateWithError</button>
 <pre id="result"></pre>
 <script src="util.js"></script>
 <script src="update_with.js"></script>
diff --git a/components/test/data/payments/retry.js b/components/test/data/payments/retry.js
index e1926c9..f06a204f 100644
--- a/components/test/data/payments/retry.js
+++ b/components/test/data/payments/retry.js
@@ -5,6 +5,7 @@
  */
 
 var gPaymentResponse = null;
+var gRetryPromise = null;
 
 /**
  * Launches the PaymentRequest UI
@@ -19,7 +20,15 @@
   getPaymentResponse(options)
       .then(function(response) {
         gPaymentResponse = response;
-        print(JSON.stringify(gPaymentResponse, undefined, 2));
+        var eventPromise = new Promise(function(resolve) {
+          gPaymentResponse.addEventListener('payerdetailchange', resolve);
+        });
+        eventPromise.then(function() {
+          gRetryPromise.then(function() {
+            print(JSON.stringify(gPaymentResponse, undefined, 2));
+            gPaymentResponse.complete('success');
+          });
+        });
       });
 }
 
@@ -33,5 +42,5 @@
     return;
   }
 
-  gPaymentResponse.retry(validationErrors);
+  gRetryPromise = gPaymentResponse.retry(validationErrors);
 }
diff --git a/components/test/data/payments/style.css b/components/test/data/payments/style.css
index 9126316b..c38b6b6 100644
--- a/components/test/data/payments/style.css
+++ b/components/test/data/payments/style.css
@@ -11,8 +11,8 @@
 }
 
 button.small {
-  font-size: 2em;
-  height: 3em;
+  font-size: 1em;
+  height: 2em;
   width: 100%;
 }
 
diff --git a/components/test/data/payments/update_with.js b/components/test/data/payments/update_with.js
index 9791173..7feb3c0 100644
--- a/components/test/data/payments/update_with.js
+++ b/components/test/data/payments/update_with.js
@@ -157,3 +157,20 @@
   });
   showPaymentRequest(pr);
 }
+
+/**
+ * Calls updateWith() with an error.
+ */
+function updateWithError() {  // eslint-disable-line no-unused-vars
+  var pr = buildPaymentRequest();
+  var errorDetails = {
+    error: 'This is an error for a browsertest',
+  };
+  pr.addEventListener('shippingaddresschange', function(e) {
+    e.updateWith(errorDetails);
+  });
+  pr.addEventListener('shippingoptionchange', function(e) {
+    e.updateWith(errorDetails);
+  });
+  showPaymentRequest(pr);
+}
diff --git a/components/tracing/common/native_stack_sampler_android.cc b/components/tracing/common/native_stack_sampler_android.cc
index 3b65e8a5..e28ae1f 100644
--- a/components/tracing/common/native_stack_sampler_android.cc
+++ b/components/tracing/common/native_stack_sampler_android.cc
@@ -4,7 +4,6 @@
 
 #include "components/tracing/common/native_stack_sampler_android.h"
 
-#include "base/no_destructor.h"
 #include "base/sampling_heap_profiler/module_cache.h"
 #include "base/trace_event/trace_event.h"
 
@@ -22,7 +21,6 @@
 NativeStackSamplerAndroid::RecordStackFrames(
     StackBuffer* stack_buffer,
     base::StackSamplingProfiler::ProfileBuilder* profile_builder) {
-  static base::NoDestructor<base::ModuleCache::Module> invalid_module;
   if (!unwinder_.is_initialized()) {
     // May block on disk access. This function is executed on the profiler
     // thread, so this will only block profiling execution.
@@ -36,8 +34,7 @@
   frames.reserve(depth);
   for (size_t i = 0; i < depth; ++i) {
     // TODO(ssid): Add support for obtaining modules here.
-    frames.emplace_back(reinterpret_cast<uintptr_t>(pcs[i]),
-                        invalid_module.get());
+    frames.emplace_back(reinterpret_cast<uintptr_t>(pcs[i]), nullptr);
   }
   return frames;
 }
diff --git a/components/tracing/common/tracing_sampler_profiler.cc b/components/tracing/common/tracing_sampler_profiler.cc
index 98aae72..dd043a8 100644
--- a/components/tracing/common/tracing_sampler_profiler.cc
+++ b/components/tracing/common/tracing_sampler_profiler.cc
@@ -38,51 +38,53 @@
   return base::StringPrintf("off:0x%" PRIxPTR, offset_from_module_base);
 }
 
-// This class will receive the sampling profiler stackframes and output them
-// to the chrome trace via an event.
-class TracingProfileBuilder
-    : public base::StackSamplingProfiler::ProfileBuilder {
- public:
-  TracingProfileBuilder(base::PlatformThreadId sampled_thread_id)
-      : sampled_thread_id_(sampled_thread_id) {}
+}  // namespace
 
-  base::ModuleCache* GetModuleCache() override { return &module_cache_; }
+TracingSamplerProfiler::TracingProfileBuilder::TracingProfileBuilder(
+    base::PlatformThreadId sampled_thread_id)
+    : sampled_thread_id_(sampled_thread_id) {}
 
-  void OnSampleCompleted(
-      std::vector<base::StackSamplingProfiler::Frame> frames) override {
-    int process_priority = base::Process::Current().GetPriority();
-    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
-                         "ProcessPriority", TRACE_EVENT_SCOPE_THREAD,
-                         "priority", process_priority);
+base::ModuleCache*
+TracingSamplerProfiler::TracingProfileBuilder::GetModuleCache() {
+  return &module_cache_;
+}
 
-    if (frames.empty()) {
-      TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
-                           "StackCpuSampling", TRACE_EVENT_SCOPE_THREAD,
-                           "frames", "empty", "thread_id", sampled_thread_id_);
+void TracingSamplerProfiler::TracingProfileBuilder::OnSampleCompleted(
+    std::vector<base::StackSamplingProfiler::Frame> frames) {
+  int process_priority = base::Process::Current().GetPriority();
+  TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+                       "ProcessPriority", TRACE_EVENT_SCOPE_THREAD, "priority",
+                       process_priority);
 
-      return;
-    }
-    // Insert an event with the frames rendered as a string with the following
-    // formats:
-    //   offset - module [debugid]
-    //  [OR]
-    //   symbol - module []
-    // The offset is difference between the load module address and the
-    // frame address.
-    //
-    // Example:
-    //
-    //   "malloc             - libc.so    []
-    //    std::string::alloc - stdc++.so  []
-    //    off:7ffb3f991b2d   - USER32.dll [2103C0950C7DEC7F7AAA44348EDC1DDD1]
-    //    off:7ffb3d439164   - win32u.dll [B3E4BE89CA7FB42A2AC1E1C475284CA11]
-    //    off:7ffaf3e26201   - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
-    //    off:7ffaf3e26008   - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
-    //    [...] "
-    std::string result;
-    for (const auto& frame : frames) {
-      std::string frame_name;
-      std::string module_name;
+  if (frames.empty()) {
+    TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+                         "StackCpuSampling", TRACE_EVENT_SCOPE_THREAD, "frames",
+                         "empty", "thread_id", sampled_thread_id_);
+
+    return;
+  }
+  // Insert an event with the frames rendered as a string with the following
+  // formats:
+  //   offset - module [debugid]
+  //  [OR]
+  //   symbol - module []
+  // The offset is difference between the load module address and the
+  // frame address.
+  //
+  // Example:
+  //
+  //   "malloc             - libc.so    []
+  //    std::string::alloc - stdc++.so  []
+  //    off:7ffb3f991b2d   - USER32.dll [2103C0950C7DEC7F7AAA44348EDC1DDD1]
+  //    off:7ffb3d439164   - win32u.dll [B3E4BE89CA7FB42A2AC1E1C475284CA11]
+  //    off:7ffaf3e26201   - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
+  //    off:7ffaf3e26008   - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
+  //    [...] "
+  std::string result;
+  for (const auto& frame : frames) {
+    std::string frame_name;
+    std::string module_name;
+    std::string module_id;
 #if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
     defined(OFFICIAL_BUILD)
       Dl_info info = {};
@@ -110,28 +112,24 @@
       if (frame_name.empty())
         frame_name = "Unknown";
 #else
-      module_name = frame.module->filename.BaseName().MaybeAsASCII();
+    if (frame.module) {
+      module_name = frame.module->GetFilename().BaseName().MaybeAsASCII();
+      module_id = frame.module->GetId();
       frame_name = GetFrameNameFromOffsetAddr(frame.instruction_pointer -
-                                              frame.module->base_address);
+                                              frame.module->GetBaseAddress());
+    } else {
+      module_name = module_id = "";
+      frame_name = "Unknown";
+    }
 #endif
       base::StringAppendF(&result, "%s - %s [%s]\n", frame_name.c_str(),
-                          module_name.c_str(), frame.module->id.c_str());
-    }
+                          module_name.c_str(), module_id.c_str());
+  }
 
     TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
                          "StackCpuSampling", TRACE_EVENT_SCOPE_THREAD, "frames",
                          result, "thread_id", sampled_thread_id_);
-  }
-
-  void OnProfileCompleted(base::TimeDelta profile_duration,
-                          base::TimeDelta sampling_period) override {}
-
- private:
-  base::ModuleCache module_cache_;
-  base::PlatformThreadId sampled_thread_id_;
-};
-
-}  // namespace
+}
 
 // static
 std::unique_ptr<TracingSamplerProfiler>
diff --git a/components/tracing/common/tracing_sampler_profiler.h b/components/tracing/common/tracing_sampler_profiler.h
index 16c0f016..29010717 100644
--- a/components/tracing/common/tracing_sampler_profiler.h
+++ b/components/tracing/common/tracing_sampler_profiler.h
@@ -7,15 +7,12 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/profiler/stack_sampling_profiler.h"
 #include "base/sequence_checker.h"
 #include "base/threading/platform_thread.h"
 #include "base/trace_event/trace_log.h"
 #include "components/tracing/tracing_export.h"
 
-namespace base {
-class StackSamplingProfiler;
-}
-
 namespace tracing {
 
 // This class is a bridge between the base stack sampling profiler and chrome
@@ -30,6 +27,25 @@
 class TRACING_EXPORT TracingSamplerProfiler
     : public base::trace_event::TraceLog::EnabledStateObserver {
  public:
+  // This class will receive the sampling profiler stackframes and output them
+  // to the chrome trace via an event. Exposed for testing.
+  class TRACING_EXPORT TracingProfileBuilder
+      : public base::StackSamplingProfiler::ProfileBuilder {
+   public:
+    TracingProfileBuilder(base::PlatformThreadId sampled_thread_id);
+
+    // base::StackSamplingProfiler::ProfileBuilder
+    base::ModuleCache* GetModuleCache() override;
+    void OnSampleCompleted(
+        std::vector<base::StackSamplingProfiler::Frame> frames) override;
+    void OnProfileCompleted(base::TimeDelta profile_duration,
+                            base::TimeDelta sampling_period) override {}
+
+   private:
+    base::ModuleCache module_cache_;
+    base::PlatformThreadId sampled_thread_id_;
+  };
+
   // Creates sampling profiler on main thread. Since the message loop might not
   // be setup when creating this profiler, the client must call
   // OnMessageLoopStarted() when setup.
diff --git a/components/tracing/common/tracing_sampler_profiler_unittest.cc b/components/tracing/common/tracing_sampler_profiler_unittest.cc
index a4f2554..da4b899 100644
--- a/components/tracing/common/tracing_sampler_profiler_unittest.cc
+++ b/components/tracing/common/tracing_sampler_profiler_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/at_exit.h"
 #include "base/bind.h"
+#include "base/files/file_path.h"
 #include "base/json/json_reader.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/profiler/stack_sampling_profiler.h"
@@ -176,4 +177,25 @@
   ValidateReceivedEvents();
 }
 
+TEST(TracingProfileBuilderTest, ValidModule) {
+#if defined(OS_WIN)
+  base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
+#else
+  base::FilePath module_path("/some/path/to/chrome");
+#endif
+
+  base::ModuleCache::Module module(0x1000, "ID", module_path, 0x2000);
+  TracingSamplerProfiler::TracingProfileBuilder profile_builder(
+      (base::PlatformThreadId()));
+  profile_builder.OnSampleCompleted(
+      {base::StackSamplingProfiler::Frame(0x1010, &module)});
+}
+
+TEST(TracingProfileBuilderTest, InvalidModule) {
+  TracingSamplerProfiler::TracingProfileBuilder profile_builder(
+      (base::PlatformThreadId()));
+  profile_builder.OnSampleCompleted(
+      {base::StackSamplingProfiler::Frame(0x1010, nullptr)});
+}
+
 }  // namespace tracing
diff --git a/components/variations/net/DEPS b/components/variations/net/DEPS
index 4b6ac37..432ab454 100644
--- a/components/variations/net/DEPS
+++ b/components/variations/net/DEPS
@@ -3,5 +3,4 @@
   "+components/metrics",
   "+net",
   "+services/network/public/cpp",
-  "+services/network/public/mojom",
 ]
diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc
index 0a0ca46..c06fd47 100644
--- a/components/variations/net/variations_http_headers.cc
+++ b/components/variations/net/variations_http_headers.cc
@@ -112,10 +112,9 @@
       return false;
 
     if (resource_request_) {
-      // Set the variations header to cors_exempt_headers rather than headers
-      // to be exempted from CORS checks.
-      resource_request_->cors_exempt_headers.SetHeaderIfMissing(
-          kClientDataHeader, variations_header_);
+      // Set the variations header to client_data_header rather than headers to
+      // be exempted from CORS checks.
+      resource_request_->client_data_header = variations_header_;
     } else if (url_request_) {
       url_request_->SetExtraRequestHeaderByName(kClientDataHeader,
                                                 variations_header_, false);
@@ -230,16 +229,11 @@
 }
 
 bool HasVariationsHeader(const network::ResourceRequest& request) {
-  return request.cors_exempt_headers.HasHeader(kClientDataHeader);
+  return !request.client_data_header.empty();
 }
 
 bool ShouldAppendVariationsHeaderForTesting(const GURL& url) {
   return ShouldAppendVariationsHeader(url);
 }
 
-void UpdateCorsExemptHeaderForVariations(
-    network::mojom::NetworkContextParams* params) {
-  params->cors_exempt_header_list.push_back(kClientDataHeader);
-}
-
 }  // namespace variations
diff --git a/components/variations/net/variations_http_headers.h b/components/variations/net/variations_http_headers.h
index a18c6ed..a25f45d 100644
--- a/components/variations/net/variations_http_headers.h
+++ b/components/variations/net/variations_http_headers.h
@@ -10,8 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "services/network/public/mojom/network_context.mojom.h"
-
 namespace net {
 struct NetworkTrafficAnnotationTag;
 struct RedirectInfo;
@@ -114,11 +112,6 @@
 // Calls the internal ShouldAppendVariationsHeader() for testing.
 bool ShouldAppendVariationsHeaderForTesting(const GURL& url);
 
-// Updates |cors_exempt_header_list| field of the given |param| to register the
-// variation headers.
-void UpdateCorsExemptHeaderForVariations(
-    network::mojom::NetworkContextParams* params);
-
 }  // namespace variations
 
 #endif  // COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADERS_H_
diff --git a/components/viz/common/quads/draw_quad.h b/components/viz/common/quads/draw_quad.h
index 01de49e..7104746 100644
--- a/components/viz/common/quads/draw_quad.h
+++ b/components/viz/common/quads/draw_quad.h
@@ -74,8 +74,7 @@
   bool IsDebugQuad() const { return material == DEBUG_BORDER; }
 
   bool ShouldDrawWithBlending() const {
-    return needs_blending || shared_quad_state->opacity < 1.0f ||
-           shared_quad_state->blend_mode != SkBlendMode::kSrcOver;
+    return needs_blending || shared_quad_state->opacity < 1.0f;
   }
 
   // Is the left edge of this tile aligned with the originating layer's
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 758b764..62357eb 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -1966,12 +1966,9 @@
   // Blending is required for antialiasing.
   SetBlendEnabled(true);
   SetShaderOpacity(quad->shared_quad_state->opacity);
-  DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode));
-  ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode);
 
   // Draw the quad with antialiasing.
   DrawQuadGeometryWithAA(quad, &local_quad, tile_rect);
-  RestoreBlendFuncToDefault(quad->shared_quad_state->blend_mode);
 }
 
 void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
@@ -2054,9 +2051,7 @@
                  tex_coord_rect.x(), tex_coord_rect.y(), tex_coord_rect.width(),
                  tex_coord_rect.height());
 
-  DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode));
   SetBlendEnabled(quad->ShouldDrawWithBlending());
-  ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode);
 
   SetShaderOpacity(quad->shared_quad_state->opacity);
 
@@ -2098,7 +2093,6 @@
 
   gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
   num_triangles_drawn_ += 2;
-  RestoreBlendFuncToDefault(quad->shared_quad_state->blend_mode);
 }
 
 void GLRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
diff --git a/components/viz/service/display_embedder/direct_context_provider.cc b/components/viz/service/display_embedder/direct_context_provider.cc
index 4be6dba..a714fd9 100644
--- a/components/viz/service/display_embedder/direct_context_provider.cc
+++ b/components/viz/service/display_embedder/direct_context_provider.cc
@@ -51,6 +51,9 @@
                                        command_buffer->service(), &outputter_,
                                        group.get()));
 
+  if (gpu_preferences.enable_gpu_service_logging)
+    decoder->SetLogCommands(true);
+
   command_buffer->set_handler(decoder.get());
 
   gpu::ContextCreationAttribs attribs;
@@ -100,6 +103,10 @@
 
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
       this, "viz::DirectContextProvider", base::ThreadTaskRunnerHandle::Get());
+
+  // TraceEndCHROMIUM is implicit when the context is destroyed
+  gles2_implementation_->TraceBeginCHROMIUM("VizCompositor",
+                                            "DisplayCompositor");
 }
 
 DirectContextProvider::~DirectContextProvider() {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index f9fb82d..0b99a3f2 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -7,6 +7,7 @@
 #include "base/atomic_sequence_num.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/command_line.h"
 #include "base/optional.h"
 #include "base/synchronization/waitable_event.h"
 #include "components/viz/common/frame_sinks/copy_output_request.h"
@@ -22,6 +23,7 @@
 #include "gpu/command_buffer/service/gr_shader_cache.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/scheduler.h"
+#include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/shared_image_factory.h"
 #include "gpu/command_buffer/service/shared_image_representation.h"
 #include "gpu/command_buffer/service/skia_utils.h"
@@ -535,6 +537,12 @@
                         ->GetSurfaceFactoryOzone()
                         ->CreatePlatformWindowSurface(surface_handle);
 #endif
+  if (gpu_service) {
+    gpu_preferences_ = gpu_service->gpu_channel_manager()->gpu_preferences();
+  } else {
+    auto* command_line = base::CommandLine::ForCurrentProcess();
+    gpu_preferences_ = gpu::gles2::ParseGpuPreferences(command_line);
+  }
 
   if (is_using_vulkan())
     InitializeForVulkan(gpu_service);
diff --git a/components/viz/test/data/image_mask_with_effect.png b/components/viz/test/data/image_mask_with_effect.png
deleted file mode 100644
index 8414527..0000000
--- a/components/viz/test/data/image_mask_with_effect.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_with_effect.png b/components/viz/test/data/mask_with_effect.png
deleted file mode 100644
index 8414527..0000000
--- a/components/viz/test/data/mask_with_effect.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_with_effect_different_size.png b/components/viz/test/data/mask_with_effect_different_size.png
deleted file mode 100644
index 82917eb..0000000
--- a/components/viz/test/data/mask_with_effect_different_size.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/scaled_mask_with_effect.png b/components/viz/test/data/scaled_mask_with_effect.png
deleted file mode 100644
index f02eace8..0000000
--- a/components/viz/test/data/scaled_mask_with_effect.png
+++ /dev/null
Binary files differ
diff --git a/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc b/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
index 54eb30b..20dfce7 100644
--- a/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
 #include "content/browser/background_fetch/background_fetch_test_base.h"
+#include "content/browser/background_fetch/background_fetch_test_service_worker.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h"
@@ -64,6 +64,10 @@
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -90,19 +94,17 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId,
-            embedded_worker_test_helper()->last_registration()->developer_id);
-  EXPECT_EQ(kExampleUniqueId,
-            embedded_worker_test_helper()->last_registration()->unique_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId, worker->last_registration()->developer_id);
+  EXPECT_EQ(kExampleUniqueId, worker->last_registration()->unique_id);
   EXPECT_EQ(blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI,
-            embedded_worker_test_helper()->last_registration()->failure_reason);
+            worker->last_registration()->failure_reason);
 
   histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  embedded_worker_test_helper()->set_fail_abort_event(true);
+  worker->set_fail_abort_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
       service_worker_registration_id, origin(), kExampleDeveloperId2,
@@ -121,11 +123,9 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId2,
-            embedded_worker_test_helper()->last_registration()->developer_id);
-  EXPECT_EQ(kExampleUniqueId2,
-            embedded_worker_test_helper()->last_registration()->unique_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId2, worker->last_registration()->developer_id);
+  EXPECT_EQ(kExampleUniqueId2, worker->last_registration()->unique_id);
 
   histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.AbortEvent",
@@ -139,6 +139,10 @@
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -159,17 +163,16 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId, worker->last_registration()->developer_id);
   EXPECT_EQ(blink::mojom::BackgroundFetchResult::UNSET,
-            embedded_worker_test_helper()->last_registration()->result);
+            worker->last_registration()->result);
 
   histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.ClickEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  embedded_worker_test_helper()->set_fail_click_event(true);
+  worker->set_fail_click_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
       service_worker_registration_id, origin(), kExampleDeveloperId2,
@@ -188,11 +191,10 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId2,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId2, worker->last_registration()->developer_id);
   EXPECT_EQ(blink::mojom::BackgroundFetchResult::FAILURE,
-            embedded_worker_test_helper()->last_registration()->result);
+            worker->last_registration()->result);
 
   histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.ClickEvent",
@@ -206,6 +208,10 @@
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -226,15 +232,14 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId, worker->last_registration()->developer_id);
 
   histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.FailEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  embedded_worker_test_helper()->set_fail_fetch_fail_event(true);
+  worker->set_fail_fetch_fail_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
       service_worker_registration_id, origin(), kExampleDeveloperId2,
@@ -252,9 +257,8 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId2,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId2, worker->last_registration()->developer_id);
 
   histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.FailEvent",
@@ -268,6 +272,10 @@
 }
 
 TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchSuccessEvent) {
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -288,18 +296,16 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId, worker->last_registration()->developer_id);
 
-  EXPECT_EQ(kExampleUniqueId,
-            embedded_worker_test_helper()->last_registration()->unique_id);
+  EXPECT_EQ(kExampleUniqueId, worker->last_registration()->unique_id);
 
   histogram_tester_.ExpectUniqueSample(
       "BackgroundFetch.EventDispatchResult.SuccessEvent",
       BackgroundFetchEventDispatcher::DISPATCH_RESULT_SUCCESS, 1);
 
-  embedded_worker_test_helper()->set_fail_fetched_event(true);
+  worker->set_fail_fetched_event(true);
 
   BackgroundFetchRegistrationId second_registration_id(
       service_worker_registration_id, origin(), kExampleDeveloperId2,
@@ -318,11 +324,9 @@
     run_loop.Run();
   }
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId2,
-            embedded_worker_test_helper()->last_registration()->developer_id);
-  EXPECT_EQ(kExampleUniqueId2,
-            embedded_worker_test_helper()->last_registration()->unique_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId2, worker->last_registration()->developer_id);
+  EXPECT_EQ(kExampleUniqueId2, worker->last_registration()->unique_id);
 
   histogram_tester_.ExpectBucketCount(
       "BackgroundFetch.EventDispatchResult.SuccessEvent",
diff --git a/content/browser/background_fetch/background_fetch_job_controller.cc b/content/browser/background_fetch/background_fetch_job_controller.cc
index ded9e4d..6a3d67a0 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -144,7 +144,6 @@
   DCHECK(request_finished_callback);
   DCHECK(request);
 
-  active_request_downloaded_bytes_ = 0;
   active_request_finished_callbacks_.emplace(
       request->download_guid(), std::move(request_finished_callback));
 
@@ -186,23 +185,24 @@
   DCHECK(active_request_map_.count(guid));
   const auto& request = active_request_map_[guid];
   DCHECK(request);
+  InProgressRequestBytes& in_progress_bytes = active_bytes_map_[guid];
 
   // Don't send download updates so the size is not leaked.
   // Upload updates are fine since that information is already available.
   if (!request->can_populate_body() && bytes_downloaded > 0u)
     return;
 
-  if (active_request_downloaded_bytes_ == bytes_downloaded &&
-      active_request_uploaded_bytes_ == bytes_uploaded) {
+  if (in_progress_bytes.downloaded == bytes_downloaded &&
+      in_progress_bytes.uploaded == bytes_uploaded) {
     return;
   }
 
-  active_request_downloaded_bytes_ = bytes_downloaded;
-  active_request_uploaded_bytes_ = bytes_uploaded;
+  in_progress_bytes.downloaded = bytes_downloaded;
+  in_progress_bytes.uploaded = bytes_uploaded;
 
   auto registration = NewRegistration();
-  registration->downloaded += active_request_downloaded_bytes_;
-  registration->uploaded += active_request_uploaded_bytes_;
+  registration->downloaded += GetInProgressDownloadedBytes();
+  registration->uploaded += GetInProgressUploadedBytes();
   progress_callback_.Run(*registration);
 }
 
@@ -217,15 +217,13 @@
 
   request->SetResult(std::move(result));
 
-  if (request->can_populate_body()) {
+  if (request->can_populate_body())
     complete_requests_downloaded_bytes_cache_ += request->GetResponseSize();
-    active_request_downloaded_bytes_ -= request->GetResponseSize();
-  }
-
   complete_requests_uploaded_bytes_cache_ += request->request_body_size();
-  active_request_uploaded_bytes_ -= request->request_body_size();
 
   NotifyDownloadComplete(request);
+  active_bytes_map_.erase(guid);
+  active_request_map_.erase(guid);
 }
 
 blink::mojom::BackgroundFetchRegistrationPtr
@@ -238,11 +236,21 @@
 }
 
 uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
-  return active_request_downloaded_bytes_;
+  uint64_t bytes = 0u;
+  for (const std::pair<std::string, InProgressRequestBytes>& in_progress_bytes :
+       active_bytes_map_) {
+    bytes += in_progress_bytes.second.downloaded;
+  }
+  return bytes;
 }
 
 uint64_t BackgroundFetchJobController::GetInProgressUploadedBytes() {
-  return active_request_uploaded_bytes_;
+  uint64_t bytes = 0u;
+  for (const std::pair<std::string, InProgressRequestBytes>& in_progress_bytes :
+       active_bytes_map_) {
+    bytes += in_progress_bytes.second.uploaded;
+  }
+  return bytes;
 }
 
 void BackgroundFetchJobController::AbortFromDelegate(
diff --git a/content/browser/background_fetch/background_fetch_job_controller.h b/content/browser/background_fetch/background_fetch_job_controller.h
index 13550d6..201dfea 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/content/browser/background_fetch/background_fetch_job_controller.h
@@ -125,6 +125,11 @@
   int pending_downloads() const { return pending_downloads_; }
 
  private:
+  struct InProgressRequestBytes {
+    uint64_t uploaded = 0u;
+    uint64_t downloaded = 0u;
+  };
+
   // Called after the request is completely processed, and the next one can be
   // started.
   void DidMarkRequestAsComplete(blink::mojom::BackgroundFetchError error);
@@ -155,6 +160,9 @@
   std::map<std::string, scoped_refptr<BackgroundFetchRequestInfo>>
       active_request_map_;
 
+  // A map from the download GUID to the in-progress bytes.
+  std::map<std::string, InProgressRequestBytes> active_bytes_map_;
+
   // The registration ID of the fetch this controller represents.
   BackgroundFetchRegistrationId registration_id_;
 
@@ -164,10 +172,6 @@
   // Icon for the represented background fetch registration.
   SkBitmap icon_;
 
-  // Number of bytes downloaded/uploaded for the active request.
-  uint64_t active_request_downloaded_bytes_ = 0u;
-  uint64_t active_request_uploaded_bytes_ = 0u;
-
   // Finished callback to invoke when the active request has finished mapped by
   // its download GUID.
   std::map<std::string, RequestFinishedCallback>
diff --git a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
index bfc5139..ff54aa7 100644
--- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
@@ -124,6 +124,7 @@
           request_counter++, std::move(request_ptr),
           /* has_request_body= */ false);
       request->InitializeDownloadGuid();
+      request->set_can_populate_body(true);
       request_infos.push_back(request);
     }
 
@@ -377,6 +378,33 @@
   EXPECT_TRUE(requests[1]->IsResultSuccess());
 }
 
+TEST_F(BackgroundFetchJobControllerTest, InProgressBytes) {
+  BackgroundFetchRegistrationId registration_id;
+
+  auto requests = CreateRegistrationForRequests(
+      &registration_id,
+      {{GURL("https://example.com/upload?id=1"), "PUT"},
+       {GURL("https://example.com/upload?id=2"), "PUT"}},
+      /* auto_complete_requests= */ true);
+
+  std::unique_ptr<BackgroundFetchJobController> controller =
+      CreateJobController(registration_id, requests.size());
+
+  controller->StartRequest(requests[0], base::DoNothing());
+  controller->StartRequest(requests[1], base::DoNothing());
+
+  // Send fake update event.
+  controller->DidUpdateRequest(requests[0]->download_guid(),
+                               /* uploaded_bytes= */ 10u,
+                               /* downloaded_bytes= */ 20u);
+  controller->DidUpdateRequest(requests[1]->download_guid(),
+                               /* uploaded_bytes= */ 30u,
+                               /* downloaded_bytes= */ 40u);
+
+  EXPECT_EQ(controller->GetInProgressDownloadedBytes(), 20u + 40u);
+  EXPECT_EQ(controller->GetInProgressUploadedBytes(), 10u + 30u);
+}
+
 TEST_F(BackgroundFetchJobControllerTest, Abort) {
   BackgroundFetchRegistrationId registration_id;
 
diff --git a/content/browser/background_fetch/background_fetch_request_info.cc b/content/browser/background_fetch/background_fetch_request_info.cc
index 767e550..4032f38 100644
--- a/content/browser/background_fetch/background_fetch_request_info.cc
+++ b/content/browser/background_fetch/background_fetch_request_info.cc
@@ -60,6 +60,12 @@
     PopulateWithResponse(std::move(result_->response));
   else
     result_->response.reset();
+
+  // Get the response size.
+  if (result_->blob_handle)
+    response_size_ = result_->blob_handle->size();
+  else
+    response_size_ = result_->file_size;
 }
 
 void BackgroundFetchRequestInfo::SetEmptyResultWithFailureReason(
@@ -127,7 +133,6 @@
     blob_data_handle_ =
         std::make_unique<storage::BlobDataHandle>(*result_->blob_handle);
     result_->blob_handle.reset();
-    response_size_ = blob_data_handle_->size();
     return;
   }
 
@@ -141,8 +146,7 @@
 
   blob_data_handle_ = GetBlobStorageContext(blob_storage_context)
                           ->AddFinishedBlob(std::move(blob_builder));
-  if (blob_data_handle_)
-    response_size_ = blob_data_handle_->size();
+  DCHECK_EQ(response_size_, blob_data_handle_ ? blob_data_handle_->size() : 0);
 }
 
 storage::BlobDataHandle*
@@ -161,7 +165,7 @@
 
 uint64_t BackgroundFetchRequestInfo::GetResponseSize() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
+  DCHECK(result_);
   return response_size_;
 }
 
diff --git a/content/browser/background_fetch/background_fetch_request_info.h b/content/browser/background_fetch/background_fetch_request_info.h
index 052a45d..441f86f 100644
--- a/content/browser/background_fetch/background_fetch_request_info.h
+++ b/content/browser/background_fetch/background_fetch_request_info.h
@@ -112,10 +112,10 @@
   storage::BlobDataHandle* GetResponseBlobDataHandle();
 
   // Hands over ownership of the blob data handle.
+  // `CreateResponseBlobDataHandle` must have been called before this.
   std::unique_ptr<storage::BlobDataHandle> TakeResponseBlobDataHandle();
 
-  // Returns the size of the response. `CreateResponseBlobDataHandle` must have
-  // been called before this.
+  // Returns the size of the response.
   uint64_t GetResponseSize() const;
 
   // Returns the time at which the response was completed.
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc
index 060344b..8e22b1fd 100644
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -17,12 +17,12 @@
 #include "build/build_config.h"
 #include "content/browser/background_fetch/background_fetch_context.h"
 #include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
-#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
 #include "content/browser/background_fetch/background_fetch_job_controller.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
 #include "content/browser/background_fetch/background_fetch_service_impl.h"
 #include "content/browser/background_fetch/background_fetch_test_base.h"
 #include "content/browser/background_fetch/background_fetch_test_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_test_service_worker.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/storage_partition_impl.h"
 #include "content/common/background_fetch/background_fetch_types.h"
@@ -546,6 +546,10 @@
   // `backgroundfetchsuccess` event will be dispatched with the expected
   // contents.
 
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -553,8 +557,7 @@
   // base::RunLoop that we'll run until the event has been dispatched. If this
   // test times out, it means that the event could not be dispatched.
   base::RunLoop event_dispatched_loop;
-  embedded_worker_test_helper()->set_fetched_event_closure(
-      event_dispatched_loop.QuitClosure());
+  worker->set_fetched_event_closure(event_dispatched_loop.QuitClosure());
 
   std::vector<blink::mojom::FetchAPIRequestPtr> requests;
 
@@ -603,7 +606,7 @@
   // Spin the |event_dispatched_loop| to wait for the dispatched event.
   event_dispatched_loop.Run();
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
+  ASSERT_TRUE(worker->last_registration());
   EXPECT_EQ(kExampleDeveloperId, registration.developer_id);
 
   // Get all the settled fetches and test properties.
@@ -665,6 +668,10 @@
   // This test verifies that the fail event will be fired when a response either
   // has a non-OK status code, or the response cannot be accessed due to CORS.
 
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -672,8 +679,7 @@
   // base::RunLoop that we'll run until the event has been dispatched. If this
   // test times out, it means that the event could not be dispatched.
   base::RunLoop event_dispatched_loop;
-  embedded_worker_test_helper()->set_fetch_fail_event_closure(
-      event_dispatched_loop.QuitClosure());
+  worker->set_fetch_fail_event_closure(event_dispatched_loop.QuitClosure());
 
   std::vector<blink::mojom::FetchAPIRequestPtr> requests;
 
@@ -710,7 +716,7 @@
   // Spin the |event_dispatched_loop| to wait for the dispatched event.
   event_dispatched_loop.Run();
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
+  ASSERT_TRUE(worker->last_registration());
   EXPECT_EQ(kExampleDeveloperId, registration.developer_id);
 
   // Get all the settled fetches and test properties.
@@ -885,6 +891,10 @@
   // Tests that the `backgroundfetchabort` event will be fired when a Background
   // Fetch registration has been aborted by either the user or developer.
 
+  auto* worker =
+      embedded_worker_test_helper()
+          ->AddNewPendingServiceWorker<BackgroundFetchTestServiceWorker>(
+              embedded_worker_test_helper());
   int64_t service_worker_registration_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
             service_worker_registration_id);
@@ -892,8 +902,7 @@
   // base::RunLoop that we'll run until the event has been dispatched. If this
   // test times out, it means that the event could not be dispatched.
   base::RunLoop event_dispatched_loop;
-  embedded_worker_test_helper()->set_abort_event_closure(
-      event_dispatched_loop.QuitClosure());
+  worker->set_abort_event_closure(event_dispatched_loop.QuitClosure());
 
   constexpr int kResponseCode = 200;
 
@@ -931,9 +940,8 @@
 
   event_dispatched_loop.Run();
 
-  ASSERT_TRUE(embedded_worker_test_helper()->last_registration());
-  EXPECT_EQ(kExampleDeveloperId,
-            embedded_worker_test_helper()->last_registration()->developer_id);
+  ASSERT_TRUE(worker->last_registration());
+  EXPECT_EQ(kExampleDeveloperId, worker->last_registration()->developer_id);
 }
 
 TEST_F(BackgroundFetchServiceTest, UniqueId) {
diff --git a/content/browser/background_fetch/background_fetch_test_base.cc b/content/browser/background_fetch/background_fetch_test_base.cc
index 7bc6a7e..48293109 100644
--- a/content/browser/background_fetch/background_fetch_test_base.cc
+++ b/content/browser/background_fetch/background_fetch_test_base.cc
@@ -78,6 +78,7 @@
     // at time of writing EmbeddedWorkerTestHelper didn't seem to support that.
     : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
       delegate_(browser_context_.GetBackgroundFetchDelegate()),
+      embedded_worker_test_helper_(base::FilePath()),
       origin_(url::Origin::Create(GURL(kTestOrigin))),
       storage_partition_(
           BrowserContext::GetDefaultStoragePartition(browser_context())) {}
diff --git a/content/browser/background_fetch/background_fetch_test_base.h b/content/browser/background_fetch/background_fetch_test_base.h
index bfa6cd1..d05529e 100644
--- a/content/browser/background_fetch/background_fetch_test_base.h
+++ b/content/browser/background_fetch/background_fetch_test_base.h
@@ -12,8 +12,8 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
 #include "content/browser/background_fetch/background_fetch_test_browser_context.h"
+#include "content/browser/background_fetch/background_fetch_test_service_worker.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -69,7 +69,7 @@
 
   // Returns the embedded worker test helper instance, which can be used to
   // influence the behavior of the Service Worker events.
-  BackgroundFetchEmbeddedWorkerTestHelper* embedded_worker_test_helper() {
+  EmbeddedWorkerTestHelper* embedded_worker_test_helper() {
     return &embedded_worker_test_helper_;
   }
 
@@ -90,7 +90,7 @@
 
   MockBackgroundFetchDelegate* delegate_;
 
-  BackgroundFetchEmbeddedWorkerTestHelper embedded_worker_test_helper_;
+  EmbeddedWorkerTestHelper embedded_worker_test_helper_;
 
   url::Origin origin_;
 
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc b/content/browser/background_fetch/background_fetch_test_service_worker.cc
similarity index 76%
rename from content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
rename to content/browser/background_fetch/background_fetch_test_service_worker.cc
index 1d33d7d06..176a279 100644
--- a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
+++ b/content/browser/background_fetch/background_fetch_test_service_worker.cc
@@ -1,8 +1,11 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
+#include "content/browser/background_fetch/background_fetch_test_service_worker.h"
+
+#include <memory>
+#include <utility>
 
 #include "base/callback.h"
 #include "base/time/time.h"
@@ -11,14 +14,13 @@
 
 namespace content {
 
-BackgroundFetchEmbeddedWorkerTestHelper::
-    BackgroundFetchEmbeddedWorkerTestHelper()
-    : EmbeddedWorkerTestHelper(base::FilePath() /* in memory */) {}
+BackgroundFetchTestServiceWorker::BackgroundFetchTestServiceWorker(
+    EmbeddedWorkerTestHelper* helper)
+    : FakeServiceWorker(helper) {}
 
-BackgroundFetchEmbeddedWorkerTestHelper::
-    ~BackgroundFetchEmbeddedWorkerTestHelper() = default;
+BackgroundFetchTestServiceWorker::~BackgroundFetchTestServiceWorker() = default;
 
-void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
+void BackgroundFetchTestServiceWorker::DispatchBackgroundFetchAbortEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
         callback) {
@@ -34,7 +36,7 @@
     abort_event_closure_.Run();
 }
 
-void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
+void BackgroundFetchTestServiceWorker::DispatchBackgroundFetchClickEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
         callback) {
@@ -50,7 +52,7 @@
     click_event_closure_.Run();
 }
 
-void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
+void BackgroundFetchTestServiceWorker::DispatchBackgroundFetchFailEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
         callback) {
@@ -66,7 +68,7 @@
     fetch_fail_event_closure_.Run();
 }
 
-void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent(
+void BackgroundFetchTestServiceWorker::DispatchBackgroundFetchSuccessEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
         callback) {
diff --git a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h b/content/browser/background_fetch/background_fetch_test_service_worker.h
similarity index 77%
rename from content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
rename to content/browser/background_fetch/background_fetch_test_service_worker.h
index a51e448..b1cc0e3 100644
--- a/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
+++ b/content/browser/background_fetch/background_fetch_test_service_worker.h
@@ -1,10 +1,11 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_EMBEDDED_WORKER_TEST_HELPER_H_
-#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_EMBEDDED_WORKER_TEST_HELPER_H_
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_SERVICE_WORKER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_SERVICE_WORKER_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -15,14 +16,13 @@
 
 namespace content {
 
-// Extension of the EmbeddedWorkerTestHelper that enables instrumentation of the
+// Extension of the FakeServiceWorker that enables instrumentation of the
 // events related to the Background Fetch API. Storage for these tests will
 // always be kept in memory, as data persistence is tested elsewhere.
-class BackgroundFetchEmbeddedWorkerTestHelper
-    : public EmbeddedWorkerTestHelper {
+class BackgroundFetchTestServiceWorker : public FakeServiceWorker {
  public:
-  BackgroundFetchEmbeddedWorkerTestHelper();
-  ~BackgroundFetchEmbeddedWorkerTestHelper() override;
+  explicit BackgroundFetchTestServiceWorker(EmbeddedWorkerTestHelper* helper);
+  ~BackgroundFetchTestServiceWorker() override;
 
   // Toggles whether the named Service Worker event should fail.
   void set_fail_abort_event(bool fail) { fail_abort_event_ = fail; }
@@ -50,20 +50,23 @@
   }
 
  protected:
-  // EmbeddedWorkerTestHelper overrides:
-  void OnBackgroundFetchAbortEvent(
+  // FakeServiceWorker overrides:
+  void DispatchBackgroundFetchAbortEvent(
       blink::mojom::BackgroundFetchRegistrationPtr registration,
       blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
           callback) override;
-  void OnBackgroundFetchClickEvent(
+
+  void DispatchBackgroundFetchClickEvent(
       blink::mojom::BackgroundFetchRegistrationPtr registration,
       blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
           callback) override;
-  void OnBackgroundFetchFailEvent(
+
+  void DispatchBackgroundFetchFailEvent(
       blink::mojom::BackgroundFetchRegistrationPtr registration,
       blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
           callback) override;
-  void OnBackgroundFetchSuccessEvent(
+
+  void DispatchBackgroundFetchSuccessEvent(
       blink::mojom::BackgroundFetchRegistrationPtr registration,
       blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
           callback) override;
@@ -81,7 +84,7 @@
 
   blink::mojom::BackgroundFetchRegistrationPtr last_registration_;
 
-  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchEmbeddedWorkerTestHelper);
+  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchTestServiceWorker);
 };
 
 }  // namespace content
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index 484eaa6..4ae7c9ec 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/location.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task/post_task.h"
@@ -323,7 +322,7 @@
     scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
     : op_scheduler_(CacheStorageSchedulerClient::kBackgroundSync),
       service_worker_context_(service_worker_context),
-      parameters_(new BackgroundSyncParameters()),
+      parameters_(std::make_unique<BackgroundSyncParameters>()),
       disabled_(false),
       num_firing_registrations_(0),
       clock_(base::DefaultClock::GetInstance()),
@@ -333,13 +332,13 @@
   service_worker_context_->AddObserver(this);
 
 #if defined(OS_ANDROID)
-  network_observer_.reset(new BackgroundSyncNetworkObserverAndroid(
+  network_observer_ = std::make_unique<BackgroundSyncNetworkObserverAndroid>(
       base::BindRepeating(&BackgroundSyncManager::OnNetworkChanged,
-                          weak_ptr_factory_.GetWeakPtr())));
+                          weak_ptr_factory_.GetWeakPtr()));
 #else
-  network_observer_.reset(new BackgroundSyncNetworkObserver(
+  network_observer_ = std::make_unique<BackgroundSyncNetworkObserver>(
       base::BindRepeating(&BackgroundSyncManager::OnNetworkChanged,
-                          weak_ptr_factory_.GetWeakPtr())));
+                          weak_ptr_factory_.GetWeakPtr()));
 #endif
 }
 
diff --git a/content/browser/devtools/protocol/memory_handler.cc b/content/browser/devtools/protocol/memory_handler.cc
index 5b02174..50e5a35 100644
--- a/content/browser/devtools/protocol/memory_handler.cc
+++ b/content/browser/devtools/protocol/memory_handler.cc
@@ -59,14 +59,15 @@
   std::unique_ptr<Array<Memory::Module>> modules =
       Array<Memory::Module>::create();
   for (const auto* module : module_cache.GetModules()) {
-    modules->addItem(Memory::Module::Create()
-                         .SetName(base::StringPrintf(
-                             "%" PRFilePath, module->filename.value().c_str()))
-                         .SetUuid(module->id)
-                         .SetBaseAddress(base::StringPrintf(
-                             "0x%" PRIxPTR, module->base_address))
-                         .SetSize(static_cast<double>(module->size))
-                         .Build());
+    modules->addItem(
+        Memory::Module::Create()
+            .SetName(base::StringPrintf("%" PRFilePath,
+                                        module->GetFilename().value().c_str()))
+            .SetUuid(module->GetId())
+            .SetBaseAddress(
+                base::StringPrintf("0x%" PRIxPTR, module->GetBaseAddress()))
+            .SetSize(static_cast<double>(module->GetSize()))
+            .Build());
   }
 
   *out_profile = Memory::SamplingProfile::Create()
diff --git a/content/browser/idle/idle_manager.cc b/content/browser/idle/idle_manager.cc
index fd235e40..e6d47d35 100644
--- a/content/browser/idle/idle_manager.cc
+++ b/content/browser/idle/idle_manager.cc
@@ -43,15 +43,15 @@
                                                int idle_threshold) {
   blink::mojom::UserIdleState user;
   if (idle_time >= idle_threshold)
-    user = blink::mojom::UserIdleState::IDLE;
+    user = blink::mojom::UserIdleState::kIdle;
   else
-    user = blink::mojom::UserIdleState::ACTIVE;
+    user = blink::mojom::UserIdleState::kActive;
 
   blink::mojom::ScreenIdleState screen;
   if (locked)
-    screen = blink::mojom::ScreenIdleState::LOCKED;
+    screen = blink::mojom::ScreenIdleState::kLocked;
   else
-    screen = blink::mojom::ScreenIdleState::UNLOCKED;
+    screen = blink::mojom::ScreenIdleState::kUnlocked;
 
   return blink::mojom::IdleState::New(user, screen);
 }
diff --git a/content/browser/idle/idle_manager_unittest.cc b/content/browser/idle/idle_manager_unittest.cc
index ff4ef95..8c6547c 100644
--- a/content/browser/idle/idle_manager_unittest.cc
+++ b/content/browser/idle/idle_manager_unittest.cc
@@ -99,8 +99,8 @@
       base::BindOnce(
           [](base::OnceClosure callback, blink::mojom::IdleStatePtr state) {
             // The initial state of the status of the user is to be active.
-            EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
-            EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+            EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
+            EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
             std::move(callback).Run();
           },
           loop.QuitClosure()));
@@ -133,7 +133,7 @@
     service_ptr->AddMonitor(
         kTresholdInSecs, std::move(monitor_ptr),
         base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
+          EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
           loop.Quit();
         }));
 
@@ -148,7 +148,7 @@
     // Expects Update to be notified about the change to idle.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::IDLE, state->user);
+          EXPECT_EQ(blink::mojom::UserIdleState::kIdle, state->user);
           loop.Quit();
         }));
     loop.Run();
@@ -163,7 +163,7 @@
     // auto quit = loop.QuitClosure();
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
+          EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
           // Ends the test.
           loop.Quit();
         }));
@@ -198,7 +198,7 @@
     service_ptr->AddMonitor(
         kTresholdInSecs, std::move(monitor_ptr),
         base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::LOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kLocked, state->screen);
           loop.Quit();
         }));
 
@@ -215,7 +215,7 @@
     // Expects Update to be notified about the change to unlocked.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
           loop.Quit();
         }));
 
@@ -250,7 +250,7 @@
     service_ptr->AddMonitor(
         kTresholdInSecs, std::move(monitor_ptr),
         base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
           loop.Quit();
         }));
 
@@ -267,7 +267,7 @@
     // Expects Update to be notified about the change to unlocked.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::LOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kLocked, state->screen);
           loop.Quit();
         }));
 
@@ -302,8 +302,8 @@
     service_ptr->AddMonitor(
         kTresholdInSecs, std::move(monitor_ptr),
         base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
-          EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
           loop.Quit();
         }));
 
@@ -320,8 +320,8 @@
     // Expects Update to be notified about the change to locked.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::LOCKED, state->screen);
-          EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kLocked, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
           loop.Quit();
         }));
 
@@ -339,8 +339,8 @@
     // Expects Update to be notified about the change to active.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::IDLE, state->user);
-          EXPECT_EQ(blink::mojom::ScreenIdleState::LOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kIdle, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kLocked, state->screen);
           // Ends the test.
           loop.Quit();
         }));
@@ -377,8 +377,8 @@
     service_ptr->AddMonitor(
         kTresholdInSecs, std::move(monitor_ptr),
         base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::ACTIVE, state->user);
-          EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kActive, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
           loop.Quit();
         }));
 
@@ -395,8 +395,8 @@
     // Expects Update to be notified about the change to idle.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::UserIdleState::IDLE, state->user);
-          EXPECT_EQ(blink::mojom::ScreenIdleState::UNLOCKED, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kIdle, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kUnlocked, state->screen);
           loop.Quit();
         }));
 
@@ -415,8 +415,8 @@
     // Expects Update to be notified about the change to locked.
     EXPECT_CALL(monitor, Update(_))
         .WillOnce(Invoke([&](blink::mojom::IdleStatePtr state) {
-          EXPECT_EQ(blink::mojom::ScreenIdleState::LOCKED, state->screen);
-          EXPECT_EQ(blink::mojom::UserIdleState::IDLE, state->user);
+          EXPECT_EQ(blink::mojom::ScreenIdleState::kLocked, state->screen);
+          EXPECT_EQ(blink::mojom::UserIdleState::kIdle, state->user);
           // Ends the test.
           loop.Quit();
         }));
@@ -493,7 +493,7 @@
   service_ptr->AddMonitor(
       5, std::move(monitor_ptr),
       base::BindLambdaForTesting([&](blink::mojom::IdleStatePtr state) {
-        EXPECT_EQ(blink::mojom::UserIdleState::IDLE, state->user);
+        EXPECT_EQ(blink::mojom::UserIdleState::kIdle, state->user);
         loop.Quit();
       }));
 
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 6a0b176..f6d8cf0 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -962,10 +962,18 @@
   new_request->SetReferrer(network::ComputeReferrer(request_data.referrer));
   new_request->set_referrer_policy(request_data.referrer_policy);
 
-  // Internal headers must be set here to avoid being blocked by CORS checks.
-  net::HttpRequestHeaders merged_headers = headers;
-  merged_headers.MergeFrom(request_data.cors_exempt_headers);
-  new_request->SetExtraRequestHeaders(merged_headers);
+  new_request->SetExtraRequestHeaders(headers);
+  // X-Requested-With and X-Client-Data header must be set here to avoid
+  // breaking CORS checks. They are non-empty when the values are given by the
+  // UA code, therefore they should be ignored by CORS checks.
+  if (!request_data.requested_with_header.empty()) {
+    new_request->SetExtraRequestHeaderByName(
+        "X-Requested-With", request_data.requested_with_header, true);
+  }
+  if (!request_data.client_data_header.empty()) {
+    new_request->SetExtraRequestHeaderByName(
+        "X-Client-Data", request_data.client_data_header, true);
+  }
 
   std::unique_ptr<network::ScopedThrottlingToken> throttling_token =
       network::ScopedThrottlingToken::MaybeCreate(
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc
index 875f948..952f6243 100644
--- a/content/browser/network_service_client.cc
+++ b/content/browser/network_service_client.cc
@@ -405,15 +405,6 @@
     DCHECK(net::NetworkChangeNotifier::HasNetworkChangeNotifier());
     GetNetworkService()->GetNetworkChangeManager(
         mojo::MakeRequest(&network_change_manager_));
-    // Sync the initial network state.
-    network_change_manager_->OnNetworkChanged(
-        true /* dns_changed */, true /* ip_address_changed */,
-        true /* connection_type_changed */,
-        network::mojom::ConnectionType(
-            net::NetworkChangeNotifier::GetConnectionType()),
-        true /* connection_subtype_changed */,
-        network::mojom::ConnectionSubtype(
-            net::NetworkChangeNotifier::GetConnectionSubtype()));
     net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
     net::NetworkChangeNotifier::AddMaxBandwidthObserver(this);
     net::NetworkChangeNotifier::AddIPAddressObserver(this);
diff --git a/content/browser/network_service_instance.cc b/content/browser/network_service_instance.cc
index a4bfac3..cfda4b4 100644
--- a/content/browser/network_service_instance.cc
+++ b/content/browser/network_service_instance.cc
@@ -42,6 +42,18 @@
 network::NetworkConnectionTracker* g_network_connection_tracker;
 network::NetworkService* g_network_service;
 
+network::mojom::NetworkServiceParamsPtr CreateNetworkServiceParams() {
+  network::mojom::NetworkServiceParamsPtr network_service_params =
+      network::mojom::NetworkServiceParams::New();
+  network_service_params->initial_connection_type =
+      network::mojom::ConnectionType(
+          net::NetworkChangeNotifier::GetConnectionType());
+  network_service_params->initial_connection_subtype =
+      network::mojom::ConnectionSubtype(
+          net::NetworkChangeNotifier::GetConnectionSubtype());
+  return network_service_params;
+}
+
 void CreateNetworkServiceOnIO(network::mojom::NetworkServiceRequest request) {
   if (g_network_service) {
     // GetNetworkServiceImpl() was already called and created the object, so
@@ -114,9 +126,14 @@
     }
 
     network::mojom::NetworkServiceClientPtr client_ptr;
+    auto client_request = mojo::MakeRequest(&client_ptr);
+    // Call SetClient before creating NetworkServiceClient, as the latter might
+    // make requests to NetworkService that depend on initialization.
+    (*g_network_service_ptr)
+        ->SetClient(std::move(client_ptr), CreateNetworkServiceParams());
+
     delete g_client;  // In case we're recreating the network service.
-    g_client = new NetworkServiceClient(mojo::MakeRequest(&client_ptr));
-    (*g_network_service_ptr)->SetClient(std::move(client_ptr));
+    g_client = new NetworkServiceClient(std::move(client_request));
 
       const base::CommandLine* command_line =
           base::CommandLine::ForCurrentProcess();
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index 0ad9d31..1eb5cfc 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -20,7 +20,6 @@
 #include "content/browser/url_loader_factory_getter.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 40307f9..88fd859 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1382,16 +1382,12 @@
     // GSB and GSU events instead of sending them to the renderer and continues
     // to progress the fling. So, the renderer doesn't receive two GSB events
     // without any GSE in between.
-    // TODO(wjmaclean/mcnee): Restore the DCHECK below.
-    // https://crbug.com/897216
-    // DCHECK(!is_in_gesture_scroll_[gesture_event.SourceDevice()] ||
-    //        FlingCancellationIsDeferred());
+    DCHECK(!is_in_gesture_scroll_[gesture_event.SourceDevice()] ||
+           FlingCancellationIsDeferred());
     is_in_gesture_scroll_[gesture_event.SourceDevice()] = true;
   } else if (gesture_event.GetType() ==
              blink::WebInputEvent::kGestureScrollEnd) {
-    // TODO(wjmaclean/mcnee): Restore the DCHECK below.
-    // https://crbug.com/897216
-    // DCHECK(is_in_gesture_scroll_[gesture_event.SourceDevice()]);
+    DCHECK(is_in_gesture_scroll_[gesture_event.SourceDevice()]);
     is_in_gesture_scroll_[gesture_event.SourceDevice()] = false;
     is_in_touchpad_gesture_fling_ = false;
     if (view_)
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 7596224..e9fbacf3 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -232,6 +232,96 @@
   ProcessAckedTouchEvents();
 }
 
+RenderWidgetHostInputEventRouter::TouchscreenPinchState::TouchscreenPinchState()
+    : state_(PinchState::NONE) {}
+
+bool RenderWidgetHostInputEventRouter::TouchscreenPinchState::IsInPinch()
+    const {
+  switch (state_) {
+    case PinchState::NONE:
+    case PinchState::EXISTING_BUBBLING_TO_ROOT:
+      return false;
+    case PinchState::PINCH_WITH_ROOT_GESTURE_TARGET:
+    case PinchState::PINCH_WHILE_BUBBLING_TO_ROOT:
+    case PinchState::PINCH_DURING_CHILD_GESTURE:
+      return true;
+  }
+}
+
+bool RenderWidgetHostInputEventRouter::TouchscreenPinchState::
+    NeedsWrappingScrollSequence() const {
+  switch (state_) {
+    case PinchState::NONE:
+    case PinchState::PINCH_DURING_CHILD_GESTURE:
+      return true;
+    case PinchState::EXISTING_BUBBLING_TO_ROOT:
+    case PinchState::PINCH_WITH_ROOT_GESTURE_TARGET:
+    case PinchState::PINCH_WHILE_BUBBLING_TO_ROOT:
+      return false;
+  }
+}
+
+void RenderWidgetHostInputEventRouter::TouchscreenPinchState::
+    DidStartBubblingToRoot() {
+  switch (state_) {
+    case PinchState::NONE:
+      state_ = PinchState::EXISTING_BUBBLING_TO_ROOT;
+      break;
+    case PinchState::PINCH_DURING_CHILD_GESTURE:
+      state_ = PinchState::PINCH_WHILE_BUBBLING_TO_ROOT;
+      break;
+    case PinchState::EXISTING_BUBBLING_TO_ROOT:
+    case PinchState::PINCH_WITH_ROOT_GESTURE_TARGET:
+    case PinchState::PINCH_WHILE_BUBBLING_TO_ROOT:
+      NOTREACHED();
+  }
+}
+
+void RenderWidgetHostInputEventRouter::TouchscreenPinchState::
+    DidStopBubblingToRoot() {
+  DCHECK_EQ(PinchState::EXISTING_BUBBLING_TO_ROOT, state_);
+  state_ = PinchState::NONE;
+}
+
+void RenderWidgetHostInputEventRouter::TouchscreenPinchState::
+    DidStartPinchInRoot() {
+  DCHECK_EQ(PinchState::NONE, state_);
+  state_ = PinchState::PINCH_WITH_ROOT_GESTURE_TARGET;
+}
+
+void RenderWidgetHostInputEventRouter::TouchscreenPinchState::
+    DidStartPinchInChild() {
+  switch (state_) {
+    case PinchState::NONE:
+      state_ = PinchState::PINCH_DURING_CHILD_GESTURE;
+      break;
+    case PinchState::EXISTING_BUBBLING_TO_ROOT:
+      state_ = PinchState::PINCH_WHILE_BUBBLING_TO_ROOT;
+      break;
+    case PinchState::PINCH_WITH_ROOT_GESTURE_TARGET:
+    case PinchState::PINCH_WHILE_BUBBLING_TO_ROOT:
+    case PinchState::PINCH_DURING_CHILD_GESTURE:
+      NOTREACHED();
+  }
+}
+
+void RenderWidgetHostInputEventRouter::TouchscreenPinchState::DidStopPinch() {
+  switch (state_) {
+    case PinchState::PINCH_WITH_ROOT_GESTURE_TARGET:
+      state_ = PinchState::NONE;
+      break;
+    case PinchState::PINCH_WHILE_BUBBLING_TO_ROOT:
+      state_ = PinchState::EXISTING_BUBBLING_TO_ROOT;
+      break;
+    case PinchState::PINCH_DURING_CHILD_GESTURE:
+      state_ = PinchState::NONE;
+      break;
+    case PinchState::NONE:
+    case PinchState::EXISTING_BUBBLING_TO_ROOT:
+      NOTREACHED();
+  }
+}
+
 bool RenderWidgetHostInputEventRouter::HasEventsPendingDispatch() const {
   return event_targeter_->HasEventsPendingDispatch();
 }
@@ -355,8 +445,6 @@
       last_emulated_event_root_view_(nullptr),
       last_device_scale_factor_(1.f),
       active_touches_(0),
-      in_touchscreen_gesture_pinch_(false),
-      gesture_pinch_did_send_scroll_begin_(false),
       event_targeter_(std::make_unique<RenderWidgetTargeter>(this)),
       use_viz_hit_test_(features::IsVizHitTestingEnabled()),
       touch_event_ack_queue_(new TouchEventAckQueue(this)),
@@ -1082,6 +1170,25 @@
     return false;
   }
 
+  const bool touchscreen_bubble_to_root =
+      event.SourceDevice() == blink::kWebGestureDeviceTouchscreen &&
+      !bubbling_gesture_scroll_target_->IsRenderWidgetHostViewChildFrame();
+  if (touchscreen_bubble_to_root) {
+    if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
+      touchscreen_pinch_state_.DidStartBubblingToRoot();
+
+      // If a pinch's scroll sequence is sent to an OOPIF and the pinch
+      // begin event is dispatched to the root before the scroll begin is
+      // bubbled to the root, a wrapping scroll begin will have already been
+      // sent to the root.
+      if (touchscreen_pinch_state_.IsInPinch()) {
+        return true;
+      }
+    } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
+      touchscreen_pinch_state_.DidStopBubblingToRoot();
+    }
+  }
+
   bubbling_gesture_scroll_target_->ProcessGestureEvent(
       GestureEventInTarget(event, bubbling_gesture_scroll_target_),
       latency_info);
@@ -1174,6 +1281,14 @@
   DCHECK(bubbling_gesture_scroll_target_);
   SendGestureScrollEnd(bubbling_gesture_scroll_target_,
                        bubbling_gesture_scroll_source_device_);
+
+  const bool touchscreen_bubble_to_root =
+      bubbling_gesture_scroll_source_device_ ==
+          blink::kWebGestureDeviceTouchscreen &&
+      !bubbling_gesture_scroll_target_->IsRenderWidgetHostViewChildFrame();
+  if (touchscreen_bubble_to_root)
+    touchscreen_pinch_state_.DidStopBubblingToRoot();
+
   // TODO(mcnee): We should also inform |bubbling_gesture_scroll_origin_| that
   // we are no longer bubbling its events, otherwise it could continue to send
   // them and interfere with a new scroll gesture being bubbled.
@@ -1301,6 +1416,24 @@
   return owner_map_.empty();
 }
 
+namespace {
+
+bool IsPinchCurrentlyAllowedInTarget(RenderWidgetHostViewBase* target) {
+  base::Optional<cc::TouchAction> target_allowed_touch_action(
+      cc::kTouchActionNone);
+  if (target) {
+    target_allowed_touch_action =
+        (static_cast<RenderWidgetHostImpl*>(target->GetRenderWidgetHost()))
+            ->input_router()
+            ->AllowedTouchAction();
+  }
+  DCHECK(target_allowed_touch_action.has_value());
+  return (target_allowed_touch_action.value() &
+          cc::TouchAction::kTouchActionPinchZoom);
+}
+
+}  // namespace
+
 void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
     RenderWidgetHostViewBase* root_view,
     RenderWidgetHostViewBase* target,
@@ -1308,61 +1441,50 @@
     const ui::LatencyInfo& latency,
     const base::Optional<gfx::PointF>& target_location) {
   if (gesture_event.GetType() == blink::WebInputEvent::kGesturePinchBegin) {
-    in_touchscreen_gesture_pinch_ = true;
-    // If the root view wasn't already receiving the gesture stream, then we
-    // need to wrap the diverted pinch events in a GestureScrollBegin/End.
-    // TODO(wjmaclean,kenrb,tdresser): When scroll latching lands, we can
-    // revisit how this code should work.
-    // https://crbug.com/526463
-    auto* rwhi =
-        static_cast<RenderWidgetHostImpl*>(root_view->GetRenderWidgetHost());
-    // If the root view is the current gesture target, then we explicitly don't
-    // send a GestureScrollBegin, as by the time we see GesturePinchBegin there
-    // should have been one.
-    if (root_view != touchscreen_gesture_target_ &&
-        !rwhi->is_in_touchscreen_gesture_scroll()) {
-      base::Optional<cc::TouchAction> target_allowed_touch_action(
-          cc::kTouchActionNone);
-      if (touchscreen_gesture_target_) {
-        target_allowed_touch_action =
-            (static_cast<RenderWidgetHostImpl*>(
-                 touchscreen_gesture_target_->GetRenderWidgetHost()))
-                ->input_router()
-                ->AllowedTouchAction();
-      }
-      DCHECK(target_allowed_touch_action.has_value());
-      if (target_allowed_touch_action.value() &
-          cc::TouchAction::kTouchActionPinchZoom) {
-        gesture_pinch_did_send_scroll_begin_ = true;
-        // The pinch gesture will be sent to the root view and it may not have a
-        // valid touch action yet. In this case, set the touch action to auto.
-        rwhi->input_router()->ForceSetTouchActionAuto();
+    if (root_view == touchscreen_gesture_target_) {
+      // If the root view is the current gesture target, there is no need to
+      // wrap the pinch events ourselves.
+      touchscreen_pinch_state_.DidStartPinchInRoot();
+    } else if (IsPinchCurrentlyAllowedInTarget(touchscreen_gesture_target_)) {
+      // If pinch is not allowed in the child, don't do any diverting of the
+      // pinch events to the root. Have the events go to the child whose
+      // TouchActionFilter will discard them.
+
+      auto* root_rwhi =
+          static_cast<RenderWidgetHostImpl*>(root_view->GetRenderWidgetHost());
+
+      // The pinch gesture will be sent to the root view and it may not have a
+      // valid touch action yet. In this case, set the touch action to auto.
+      root_rwhi->input_router()->ForceSetTouchActionAuto();
+
+      if (touchscreen_pinch_state_.NeedsWrappingScrollSequence()) {
+        // If the root view is not the gesture target, and a scroll gesture has
+        // not already started in the root from scroll bubbling, then we need
+        // to warp the diverted pinch events in a GestureScrollBegin/End.
+        DCHECK(!root_rwhi->is_in_touchscreen_gesture_scroll());
         SendGestureScrollBegin(root_view, gesture_event);
-      } else {
-        // When target does not allow touch-action: pinch, instead of sending
-        // pinch gestures to the root frame, we send all gesture pinch events
-        // to the subframe target so the target can look after disposing of
-        // them.
-        in_touchscreen_gesture_pinch_ = false;
       }
+
+      touchscreen_pinch_state_.DidStartPinchInChild();
     }
   }
 
-  if (in_touchscreen_gesture_pinch_) {
+  if (touchscreen_pinch_state_.IsInPinch()) {
     root_view->ProcessGestureEvent(gesture_event, latency);
+
     if (gesture_event.GetType() == blink::WebInputEvent::kGesturePinchEnd) {
-      in_touchscreen_gesture_pinch_ = false;
-      // If the root view wasn't already receiving the gesture stream, then we
-      // need to wrap the diverted pinch events in a GestureScrollBegin/End.
-      auto* rwhi =
-          static_cast<RenderWidgetHostImpl*>(root_view->GetRenderWidgetHost());
-      if (root_view != touchscreen_gesture_target_ &&
-          gesture_pinch_did_send_scroll_begin_ &&
-          rwhi->is_in_touchscreen_gesture_scroll()) {
+      const bool send_scroll_end =
+          touchscreen_pinch_state_.NeedsWrappingScrollSequence();
+      touchscreen_pinch_state_.DidStopPinch();
+
+      if (send_scroll_end) {
+        auto* root_rwhi = static_cast<RenderWidgetHostImpl*>(
+            root_view->GetRenderWidgetHost());
+        DCHECK(root_rwhi->is_in_touchscreen_gesture_scroll());
         SendGestureScrollEnd(root_view, gesture_event);
       }
-      gesture_pinch_did_send_scroll_begin_ = false;
     }
+
     return;
   }
 
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h
index ec55d04..ca8cd0c 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -360,11 +360,47 @@
   float last_device_scale_factor_;
 
   int active_touches_;
-  // Keep track of when we are between GesturePinchBegin and GesturePinchEnd
-  // inclusive, as we need to route these events (and anything in between) to
-  // the main frame.
-  bool in_touchscreen_gesture_pinch_;
-  bool gesture_pinch_did_send_scroll_begin_;
+
+  // Touchscreen gesture pinch events must be routed to the main frame. This
+  // keeps track of ongoing scroll and pinch gestures so we know when to divert
+  // gesture events to the main frame and whether additional scroll begin/end
+  // events are needed to wrap the pinch.
+  class TouchscreenPinchState {
+   public:
+    TouchscreenPinchState();
+
+    bool IsInPinch() const;
+    bool NeedsWrappingScrollSequence() const;
+
+    void DidStartBubblingToRoot();
+    void DidStopBubblingToRoot();
+    void DidStartPinchInRoot();
+    void DidStartPinchInChild();
+    void DidStopPinch();
+
+   private:
+    enum class PinchState {
+      NONE,
+      // We have touchscreen scroll bubbling to the root before a gesture pinch
+      // starts.
+      EXISTING_BUBBLING_TO_ROOT,
+
+      // We are in a pinch gesture and the root is already the touchscreen
+      // gesture target.
+      PINCH_WITH_ROOT_GESTURE_TARGET,
+
+      // We are in a pinch gesture that is happening while we're also bubbling
+      // scroll to the root.
+      PINCH_WHILE_BUBBLING_TO_ROOT,
+
+      // We are in a pinch gesture that is happening while the child is the
+      // gesture target and it has not bubbled scroll to the root.
+      PINCH_DURING_CHILD_GESTURE
+    };
+    PinchState state_;
+  };
+  TouchscreenPinchState touchscreen_pinch_state_;
+
   std::unordered_map<viz::SurfaceId, HittestData, viz::SurfaceIdHash>
       hittest_data_;
 
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index 3a5ac47..191eef0f 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -22,7 +22,6 @@
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_test_utils.h"
-#include "content/common/background_fetch/background_fetch_types.h"
 #include "content/common/renderer.mojom.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
@@ -329,34 +328,6 @@
     std::move(callback).Run();
 }
 
-void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
-        callback) {
-  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
-        callback) {
-  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
-        callback) {
-  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
-        callback) {
-  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
-}
-
 std::unique_ptr<FakeEmbeddedWorkerInstanceClient>
 EmbeddedWorkerTestHelper::CreateInstanceClient() {
   return std::make_unique<FakeEmbeddedWorkerInstanceClient>(this);
@@ -367,50 +338,6 @@
   return std::make_unique<FakeServiceWorker>(this);
 }
 
-void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
-        callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent,
-                     AsWeakPtr(), std::move(registration),
-                     std::move(callback)));
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEventStub(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
-        callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent,
-                     AsWeakPtr(), std::move(registration),
-                     std::move(callback)));
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEventStub(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
-        callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent,
-                     AsWeakPtr(), std::move(registration),
-                     std::move(callback)));
-}
-
-void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEventStub(
-    blink::mojom::BackgroundFetchRegistrationPtr registration,
-    blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
-        callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent,
-                     AsWeakPtr(), std::move(registration),
-                     std::move(callback)));
-}
-
 EmbeddedWorkerRegistry* EmbeddedWorkerTestHelper::registry() {
   DCHECK(context());
   return context()->embedded_worker_registry();
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h
index f62645e..b2010e8 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -165,24 +165,6 @@
   /////////////////////////////////////////////////////////////////////////////
 
  protected:
-  // TODO(falken): Remove these and use FakeServiceWorker instead.
-  virtual void OnBackgroundFetchAbortEvent(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
-          callback);
-  virtual void OnBackgroundFetchClickEvent(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
-          callback);
-  virtual void OnBackgroundFetchFailEvent(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
-          callback);
-  virtual void OnBackgroundFetchSuccessEvent(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
-          callback);
-
   EmbeddedWorkerRegistry* registry();
 
   blink::mojom::ServiceWorkerHost* GetServiceWorkerHost(
@@ -206,24 +188,6 @@
   class MockNetworkURLLoaderFactory;
   class MockRendererInterface;
 
-  // TODO(falken): Remove these and use FakeServiceWorker instead.
-  void OnBackgroundFetchAbortEventStub(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback
-          callback);
-  void OnBackgroundFetchClickEventStub(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback
-          callback);
-  void OnBackgroundFetchFailEventStub(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback
-          callback);
-  void OnBackgroundFetchSuccessEventStub(
-      blink::mojom::BackgroundFetchRegistrationPtr registration,
-      blink::mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
-          callback);
-
   std::unique_ptr<TestBrowserContext> browser_context_;
   std::unique_ptr<MockRenderProcessHost> render_process_host_;
   std::unique_ptr<MockRenderProcessHost> new_render_process_host_;
diff --git a/content/browser/service_worker/fake_service_worker.cc b/content/browser/service_worker/fake_service_worker.cc
index d9a36d0..a0ccd64 100644
--- a/content/browser/service_worker/fake_service_worker.cc
+++ b/content/browser/service_worker/fake_service_worker.cc
@@ -74,29 +74,25 @@
 void FakeServiceWorker::DispatchBackgroundFetchAbortEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     DispatchBackgroundFetchAbortEventCallback callback) {
-  helper_->OnBackgroundFetchAbortEventStub(std::move(registration),
-                                           std::move(callback));
+  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
 }
 
 void FakeServiceWorker::DispatchBackgroundFetchClickEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     DispatchBackgroundFetchClickEventCallback callback) {
-  helper_->OnBackgroundFetchClickEventStub(std::move(registration),
-                                           std::move(callback));
+  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
 }
 
 void FakeServiceWorker::DispatchBackgroundFetchFailEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     DispatchBackgroundFetchFailEventCallback callback) {
-  helper_->OnBackgroundFetchFailEventStub(std::move(registration),
-                                          std::move(callback));
+  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
 }
 
 void FakeServiceWorker::DispatchBackgroundFetchSuccessEvent(
     blink::mojom::BackgroundFetchRegistrationPtr registration,
     DispatchBackgroundFetchSuccessEventCallback callback) {
-  helper_->OnBackgroundFetchSuccessEventStub(std::move(registration),
-                                             std::move(callback));
+  std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
 }
 
 void FakeServiceWorker::DispatchCookieChangeEvent(
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index cc1e4dc..aa4e763 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -10775,9 +10775,8 @@
 
 // This test verifies that the main-frame's page scale factor propagates to
 // the compositor layertrees in each of the child processes.
-// TODO(crbug.com/923226): Disabled due to flakiness.
 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
-                       DISABLED_PageScaleFactorPropagatesToOOPIFs) {
+                       PageScaleFactorPropagatesToOOPIFs) {
   GURL main_url(embedded_test_server()->GetURL(
       "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index b092ae8..8d85f56 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -58,7 +58,7 @@
 #include "services/device/public/mojom/geolocation_context.mojom.h"
 #include "services/device/public/mojom/wake_lock.mojom.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h"
 #include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
 #include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
 #include "third_party/blink/public/platform/web_drag_operation.h"
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm
index 8b8bc62..0435002 100644
--- a/content/browser/web_contents/web_drag_source_mac.mm
+++ b/content/browser/web_contents/web_drag_source_mac.mm
@@ -364,7 +364,7 @@
           dropData_->GetSafeFilenameForImageFileContents();
       if (suggestedFilename) {
         downloadFileName_ = std::move(*suggestedFilename);
-        net::GetMimeTypeFromExtension(downloadFileName_.Extension(), &mimeType);
+        net::GetMimeTypeFromFile(downloadFileName_, &mimeType);
       }
     } else {
       base::string16 mimeType16;
diff --git a/content/common/content_constants_internal.cc b/content/common/content_constants_internal.cc
index d6e2a4f..be2463a 100644
--- a/content/common/content_constants_internal.cc
+++ b/content/common/content_constants_internal.cc
@@ -37,6 +37,4 @@
 const char kMachBootstrapName[] = "rohitfork";
 #endif
 
-const char kCorsExemptRequestedWithHeaderName[] = "X-Requested-With";
-
 } // namespace content
diff --git a/content/common/content_constants_internal.h b/content/common/content_constants_internal.h
index b520383..9c0767b 100644
--- a/content/common/content_constants_internal.h
+++ b/content/common/content_constants_internal.h
@@ -45,11 +45,6 @@
 CONTENT_EXPORT extern const char kMachBootstrapName[];
 #endif
 
-// Defines a HTTP header name that is set internally, and some code places
-// in content need to know the name to manage the header stored in
-// network::ResourceRequest::cors_exempt_headers.
-extern const char kCorsExemptRequestedWithHeaderName[];
-
 } // namespace content
 
 #endif  // CONTENT_COMMON_CONTENT_CONSTANTS_INTERNAL_H_
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 0afd023d..47b7e21 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -106,8 +106,6 @@
     "content_browser_client.cc",
     "content_browser_client.h",
     "cookie_store_factory.h",
-    "cors_exempt_headers.cc",
-    "cors_exempt_headers.h",
     "cors_origin_pattern_setter.cc",
     "cors_origin_pattern_setter.h",
     "delegate_to_browser_gpu_service_accelerator_factory.h",
diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS
index 805504c5..49fd1ed 100644
--- a/content/public/browser/DEPS
+++ b/content/public/browser/DEPS
@@ -18,7 +18,6 @@
 specific_include_rules = {
   ".*\.cc": [
     "+content/browser",
-    "+content/common/content_constants_internal.h",
     "-content/browser/loader",
 
     # TODO: content/browser/loader is being separated out of content, and this
diff --git a/content/public/browser/cors_exempt_headers.cc b/content/public/browser/cors_exempt_headers.cc
deleted file mode 100644
index c82e8d71..0000000
--- a/content/public/browser/cors_exempt_headers.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/browser/cors_exempt_headers.h"
-
-#include "content/common/content_constants_internal.h"
-
-namespace content {
-
-void UpdateCorsExemptHeader(network::mojom::NetworkContextParams* params) {
-  // Note: This mechanism will be deprecated in the near future. You can find
-  // a recommended alternative approach on URLRequest::cors_exempt_headers at
-  // services/network/public/mojom/url_loader.mojom.
-  params->cors_exempt_header_list.push_back(kCorsExemptRequestedWithHeaderName);
-}
-
-}  // namespace content
diff --git a/content/public/browser/cors_exempt_headers.h b/content/public/browser/cors_exempt_headers.h
deleted file mode 100644
index c9b5cf1..0000000
--- a/content/public/browser/cors_exempt_headers.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
-#define CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
-
-#include "content/common/content_export.h"
-#include "services/network/public/mojom/network_context.mojom.h"
-
-namespace content {
-
-// Updates |cors_exempt_header_list| field of the given |param| to register
-// headers that are used in content for special purpose and should not be
-// blocked by CORS checks.
-CONTENT_EXPORT void UpdateCorsExemptHeader(
-    network::mojom::NetworkContextParams* params);
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_CORS_EXEMPT_HEADERS_H_
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index d1c18704..cb13911 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -25,7 +25,7 @@
 #include "content/public/common/window_container_type.mojom-forward.h"
 #include "third_party/blink/public/common/manifest/web_display_mode.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom-forward.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom-forward.h"
 #include "third_party/blink/public/platform/web_drag_operation.h"
 #include "third_party/blink/public/platform/web_security_style.h"
 #include "third_party/blink/public/web/web_fullscreen_options.h"
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index c68c5a8..4296c21 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -334,7 +334,7 @@
 
 // Whether PaymentRequest exposes hasEnrolledInstrument API.
 const base::Feature kPaymentRequestHasEnrolledInstrument = {
-    "PaymentRequestHasEnrolledInstrument", base::FEATURE_DISABLED_BY_DEFAULT};
+    "PaymentRequestHasEnrolledInstrument", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Whether PDF files should be rendered in diffent processes based on origin.
 const base::Feature kPdfIsolation = {"PdfIsolation",
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 296ba28..52874b8 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -207,6 +207,8 @@
     "manifest/manifest_parser.h",
     "manifest/manifest_uma_util.cc",
     "manifest/manifest_uma_util.h",
+    "media/android/flinging_renderer_client_factory.cc",
+    "media/android/flinging_renderer_client_factory.h",
     "media/android/media_player_renderer_client.cc",
     "media/android/media_player_renderer_client.h",
     "media/android/media_player_renderer_client_factory.cc",
diff --git a/content/renderer/compositor/layer_tree_view.cc b/content/renderer/compositor/layer_tree_view.cc
index ab83f3f..3a18950 100644
--- a/content/renderer/compositor/layer_tree_view.cc
+++ b/content/renderer/compositor/layer_tree_view.cc
@@ -309,10 +309,6 @@
   layer_tree_host_->SetNonBlinkManagedRootLayer(std::move(layer));
 }
 
-void LayerTreeView::SetBackgroundColor(SkColor color) {
-  layer_tree_host_->set_background_color(color);
-}
-
 void LayerTreeView::SetPageScaleFactorAndLimits(float page_scale_factor,
                                                 float minimum,
                                                 float maximum) {
diff --git a/content/renderer/compositor/layer_tree_view.h b/content/renderer/compositor/layer_tree_view.h
index 9b8bd2f2..b03b670 100644
--- a/content/renderer/compositor/layer_tree_view.h
+++ b/content/renderer/compositor/layer_tree_view.h
@@ -133,7 +133,6 @@
   // blink::WebLayerTreeView implementation.
   viz::FrameSinkId GetFrameSinkId() override;
   void SetNonBlinkManagedRootLayer(scoped_refptr<cc::Layer> layer);
-  void SetBackgroundColor(SkColor color) override;
   void SetPageScaleFactorAndLimits(float page_scale_factor,
                                    float minimum,
                                    float maximum) override;
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 80e9372..5cfb1fff 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -27,7 +27,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "content/child/child_thread_impl.h"
-#include "content/common/content_constants_internal.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/navigation_policy.h"
@@ -458,6 +457,7 @@
   DeferState defers_loading_;
   int request_id_;
   bool in_two_phase_read_ = false;
+  bool is_in_on_body_available_ = false;
 
   // Used when ResponseLoadViaDataPipe is enabled and
   // |pass_response_pipe_to_client_| is false.
@@ -726,13 +726,10 @@
     resource_request->headers.SetHeaderIfMissing(network::kAcceptHeader,
                                                  network::kDefaultAcceptHeader);
   }
-  // Set X-Requested-With header to cors_exempt_headers rather than headers to
-  // be exempted from CORS checks.
-  if (!request.GetRequestedWithHeader().IsEmpty()) {
-    resource_request->cors_exempt_headers.SetHeader(
-        kCorsExemptRequestedWithHeaderName,
-        WebString(request.GetRequestedWithHeader()).Utf8());
-  }
+  resource_request->requested_with_header =
+      WebString(request.GetRequestedWithHeader()).Utf8();
+  resource_request->client_data_header =
+      WebString(request.GetClientDataHeader()).Utf8();
 
   if (resource_request->resource_type == RESOURCE_TYPE_PREFETCH ||
       resource_request->resource_type == RESOURCE_TYPE_FAVICON) {
@@ -1037,9 +1034,12 @@
 void WebURLLoaderImpl::Context::OnBodyAvailable(
     MojoResult,
     const mojo::HandleSignalsState&) {
+  DCHECK(!is_in_on_body_available_);
   // Cancel may happen so that we need to protect |this|.
   scoped_refptr<Context> protect(this);
   uint32_t read_bytes = 0;
+  base::AutoReset<bool> auto_reset(&is_in_on_body_available_, true);
+
   // |client_| is nullptr when the request is canceled.
   while (client_ && defers_loading_ == NOT_DEFERRING && !in_two_phase_read_) {
     const void* buffer = nullptr;
@@ -1094,7 +1094,7 @@
     body_handle_.reset();
     body_watcher_.Cancel();
   }
-  if (defers_loading_ == NOT_DEFERRING)
+  if (defers_loading_ == NOT_DEFERRING && !is_in_on_body_available_)
     body_watcher_.ArmOrNotify();
 }
 
diff --git a/content/renderer/media/android/flinging_renderer_client_factory.cc b/content/renderer/media/android/flinging_renderer_client_factory.cc
new file mode 100644
index 0000000..bfe3a29
--- /dev/null
+++ b/content/renderer/media/android/flinging_renderer_client_factory.cc
@@ -0,0 +1,46 @@
+// 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 "content/renderer/media/android/flinging_renderer_client_factory.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/logging.h"
+#include "media/mojo/clients/mojo_renderer.h"
+#include "media/mojo/clients/mojo_renderer_factory.h"
+
+namespace content {
+
+FlingingRendererClientFactory::FlingingRendererClientFactory(
+    std::unique_ptr<media::MojoRendererFactory> mojo_flinging_factory,
+    std::unique_ptr<media::RemotePlaybackClientWrapper> remote_playback_client)
+    : mojo_flinging_factory_(std::move(mojo_flinging_factory)),
+      remote_playback_client_(std::move(remote_playback_client)) {}
+
+FlingingRendererClientFactory::~FlingingRendererClientFactory() = default;
+
+std::unique_ptr<media::Renderer> FlingingRendererClientFactory::CreateRenderer(
+    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    const scoped_refptr<base::TaskRunner>& /* worker_task_runner */,
+    media::AudioRendererSink* /* audio_renderer_sink */,
+    media::VideoRendererSink* video_renderer_sink,
+    const media::RequestOverlayInfoCB& /* request_overlay_info_cb */,
+    const gfx::ColorSpace& /* target_color_space */) {
+  DCHECK(IsFlingingActive());
+
+  return mojo_flinging_factory_->CreateFlingingRenderer(
+      GetActivePresentationId(), media_task_runner, video_renderer_sink);
+}
+
+std::string FlingingRendererClientFactory::GetActivePresentationId() {
+  return remote_playback_client_->GetActivePresentationId();
+}
+
+bool FlingingRendererClientFactory::IsFlingingActive() {
+  return !GetActivePresentationId().empty();
+}
+
+}  // namespace content
diff --git a/content/renderer/media/android/flinging_renderer_client_factory.h b/content/renderer/media/android/flinging_renderer_client_factory.h
new file mode 100644
index 0000000..7a8114e
--- /dev/null
+++ b/content/renderer/media/android/flinging_renderer_client_factory.h
@@ -0,0 +1,62 @@
+// 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 CONTENT_RENDERER_MEDIA_ANDROID_FLINGING_RENDERER_CLIENT_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_ANDROID_FLINGING_RENDERER_CLIENT_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+#include "content/common/content_export.h"
+#include "media/base/renderer_factory.h"
+#include "media/renderers/remote_playback_client_wrapper.h"
+
+namespace media {
+class MojoRendererFactory;
+}
+
+namespace content {
+
+// Creates a renderer for media flinging.
+// The FRCF uses a MojoRendererFactory to create a FlingingRenderer in the
+// browser process. The actual renderer returned by the FRCF is a MojoRenderer
+// directly (as opposed to a dedicated FlingingRendererClient), because all the
+// renderer needs to do is forward calls to the FlingingRenderer in the browser.
+class CONTENT_EXPORT FlingingRendererClientFactory
+    : public media::RendererFactory {
+ public:
+  // |mojo_flinging_factory| should be created using
+  // HostedRendererType::kFlinging, and GetActivePresentationId()
+  // should be given to it through SetGetTypeSpecificIdCB().
+  FlingingRendererClientFactory(
+      std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory,
+      std::unique_ptr<media::RemotePlaybackClientWrapper>
+          remote_playback_client);
+  ~FlingingRendererClientFactory() override;
+
+  std::unique_ptr<media::Renderer> CreateRenderer(
+      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      const scoped_refptr<base::TaskRunner>& worker_task_runner,
+      media::AudioRendererSink* audio_renderer_sink,
+      media::VideoRendererSink* video_renderer_sink,
+      const media::RequestOverlayInfoCB& request_overlay_info_cb,
+      const gfx::ColorSpace& target_color_space) override;
+
+  // Returns whether media flinging has started, based off of whether the
+  // |remote_playback_client_| has a presentation ID or not. Called by
+  // RendererFactorySelector to determine when to create a FlingingRenderer.
+  bool IsFlingingActive();
+
+ private:
+  std::string GetActivePresentationId();
+
+  std::unique_ptr<media::MojoRendererFactory> mojo_flinging_factory_;
+  std::unique_ptr<media::RemotePlaybackClientWrapper> remote_playback_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(FlingingRendererClientFactory);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_MEDIA_ANDROID_FLINGING_RENDERER_CLIENT_FACTORY_H_
diff --git a/content/renderer/media/android/media_player_renderer_client.cc b/content/renderer/media/android/media_player_renderer_client.cc
index 67c5b57..2c1fb90 100644
--- a/content/renderer/media/android/media_player_renderer_client.cc
+++ b/content/renderer/media/android/media_player_renderer_client.cc
@@ -12,10 +12,10 @@
 MediaPlayerRendererClient::MediaPlayerRendererClient(
     scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-    media::MojoRenderer* mojo_renderer,
+    std::unique_ptr<media::MojoRenderer> mojo_renderer,
     media::ScopedStreamTextureWrapper stream_texture_wrapper,
     media::VideoRendererSink* sink)
-    : mojo_renderer_(mojo_renderer),
+    : mojo_renderer_(std::move(mojo_renderer)),
       stream_texture_wrapper_(std::move(stream_texture_wrapper)),
       client_(nullptr),
       sink_(sink),
diff --git a/content/renderer/media/android/media_player_renderer_client.h b/content/renderer/media/android/media_player_renderer_client.h
index f1593b8..3e90a1e 100644
--- a/content/renderer/media/android/media_player_renderer_client.h
+++ b/content/renderer/media/android/media_player_renderer_client.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_H_
 #define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_H_
 
+#include <memory>
+
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -39,7 +41,7 @@
   MediaPlayerRendererClient(
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-      media::MojoRenderer* mojo_renderer,
+      std::unique_ptr<media::MojoRenderer> mojo_renderer,
       media::ScopedStreamTextureWrapper stream_texture_wrapper,
       media::VideoRendererSink* sink);
 
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.cc b/content/renderer/media/android/media_player_renderer_client_factory.cc
index b34fc6b14..3f02921 100644
--- a/content/renderer/media/android/media_player_renderer_client_factory.cc
+++ b/content/renderer/media/android/media_player_renderer_client_factory.cc
@@ -6,12 +6,13 @@
 
 #include "content/renderer/media/android/media_player_renderer_client.h"
 #include "media/mojo/clients/mojo_renderer.h"
+#include "media/mojo/clients/mojo_renderer_factory.h"
 
 namespace content {
 
 MediaPlayerRendererClientFactory::MediaPlayerRendererClientFactory(
     scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-    std::unique_ptr<media::RendererFactory> mojo_renderer_factory,
+    std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory,
     const GetStreamTextureWrapperCB& get_stream_texture_wrapper_cb)
     : get_stream_texture_wrapper_cb_(get_stream_texture_wrapper_cb),
       compositor_task_runner_(std::move(compositor_task_runner)),
@@ -22,24 +23,20 @@
 std::unique_ptr<media::Renderer>
 MediaPlayerRendererClientFactory::CreateRenderer(
     const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
-    const scoped_refptr<base::TaskRunner>& worker_task_runner,
-    media::AudioRendererSink* audio_renderer_sink,
+    const scoped_refptr<base::TaskRunner>& /* worker_task_runner */,
+    media::AudioRendererSink* /* audio_renderer_sink */,
     media::VideoRendererSink* video_renderer_sink,
-    const media::RequestOverlayInfoCB& request_overlay_info_cb,
-    const gfx::ColorSpace& target_color_space) {
-  std::unique_ptr<media::Renderer> renderer =
-      mojo_renderer_factory_->CreateRenderer(
-          media_task_runner, worker_task_runner, audio_renderer_sink,
-          video_renderer_sink, request_overlay_info_cb, target_color_space);
-
-  media::MojoRenderer* mojo_renderer =
-      static_cast<media::MojoRenderer*>(renderer.release());
+    const media::RequestOverlayInfoCB& /* request_overlay_info_cb */,
+    const gfx::ColorSpace& /* target_color_space */) {
+  std::unique_ptr<media::MojoRenderer> mojo_renderer =
+      mojo_renderer_factory_->CreateMediaPlayerRenderer(media_task_runner,
+                                                        video_renderer_sink);
 
   media::ScopedStreamTextureWrapper stream_texture_wrapper =
       get_stream_texture_wrapper_cb_.Run();
 
   return std::make_unique<MediaPlayerRendererClient>(
-      media_task_runner, compositor_task_runner_, mojo_renderer,
+      media_task_runner, compositor_task_runner_, std::move(mojo_renderer),
       std::move(stream_texture_wrapper), video_renderer_sink);
 }
 
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.h b/content/renderer/media/android/media_player_renderer_client_factory.h
index a85f45f..94b4c9a 100644
--- a/content/renderer/media/android/media_player_renderer_client_factory.h
+++ b/content/renderer/media/android/media_player_renderer_client_factory.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_FACTORY_H_
 #define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_FACTORY_H_
 
+#include <memory>
+
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/single_thread_task_runner.h"
@@ -14,6 +16,10 @@
 #include "media/mojo/clients/mojo_renderer_factory.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 
+namespace media {
+class MojoRendererFactory;
+}
+
 namespace content {
 
 // The default class for creating a MediaPlayerRendererClient
@@ -26,7 +32,7 @@
 
   MediaPlayerRendererClientFactory(
       scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
-      std::unique_ptr<media::RendererFactory> mojo_renderer_factory,
+      std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory,
       const GetStreamTextureWrapperCB& get_stream_texture_wrapper_cb);
   ~MediaPlayerRendererClientFactory() override;
 
@@ -46,7 +52,7 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
 
-  std::unique_ptr<media::RendererFactory> mojo_renderer_factory_;
+  std::unique_ptr<media::MojoRendererFactory> mojo_renderer_factory_;
 };
 
 }  // namespace content
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc
index 080ba09..269180b 100644
--- a/content/renderer/media/media_factory.cc
+++ b/content/renderer/media/media_factory.cc
@@ -53,11 +53,11 @@
 #include "url/origin.h"
 
 #if defined(OS_ANDROID)
+#include "content/renderer/media/android/flinging_renderer_client_factory.h"
 #include "content/renderer/media/android/media_player_renderer_client_factory.h"
 #include "content/renderer/media/android/stream_texture_wrapper_impl.h"
 #include "media/base/android/media_codec_util.h"
 #include "media/base/media.h"
-#include "media/renderers/flinging_renderer_client_factory.h"
 #include "url/gurl.h"
 #endif
 
@@ -432,7 +432,6 @@
   // MediaPlayerRendererClientFactory setup.
   auto mojo_media_player_renderer_factory =
       std::make_unique<media::MojoRendererFactory>(
-          media::mojom::HostedRendererType::kMediaPlayer,
           media::MojoRendererFactory::GetGpuFactoriesCB(),
           GetMediaInterfaceFactory());
 
@@ -452,30 +451,16 @@
 
   // FlingingRendererClientFactory (FRCF) setup.
   auto mojo_flinging_factory = std::make_unique<media::MojoRendererFactory>(
-      media::mojom::HostedRendererType::kFlinging,
       media::MojoRendererFactory::GetGpuFactoriesCB(),
       GetMediaInterfaceFactory());
 
-  // Save a temp copy of the pointer, before moving it into the FRCF.
-  // The FRCF cannot be aware of the MojoRendererFactory directly, due to
-  // layering issues.
-  media::MojoRendererFactory* temp_mojo_flinging_factory =
-      mojo_flinging_factory.get();
-
-  auto flinging_factory =
-      std::make_unique<media::FlingingRendererClientFactory>(
-          std::move(mojo_flinging_factory), std::move(client_wrapper));
-
-  // base::Unretained is safe here because the FRCF owns the MojoRendererFactory
-  // and is guaranteed to outlive it.
-  temp_mojo_flinging_factory->SetGetTypeSpecificIdCB(base::BindRepeating(
-      &media::FlingingRendererClientFactory::GetActivePresentationId,
-      base::Unretained(flinging_factory.get())));
+  auto flinging_factory = std::make_unique<FlingingRendererClientFactory>(
+      std::move(mojo_flinging_factory), std::move(client_wrapper));
 
   // base::Unretained is safe here because |factory_selector| owns
   // |flinging_factory|.
   factory_selector->SetQueryIsFlingingActiveCB(
-      base::Bind(&media::FlingingRendererClientFactory::IsFlingingActive,
+      base::Bind(&FlingingRendererClientFactory::IsFlingingActive,
                  base::Unretained(flinging_factory.get())));
 
   factory_selector->AddFactory(
@@ -494,7 +479,6 @@
 #endif  // BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION)
   if (use_mojo_renderer_factory) {
     auto mojo_renderer_factory = std::make_unique<media::MojoRendererFactory>(
-        media::mojom::HostedRendererType::kDefault,
         base::Bind(&RenderThreadImpl::GetGpuFactories,
                    base::Unretained(render_thread)),
         GetMediaInterfaceFactory());
diff --git a/content/renderer/pepper/pepper_video_encoder_host.cc b/content/renderer/pepper/pepper_video_encoder_host.cc
index 1cb22a60..d17fd76 100644
--- a/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -227,6 +227,11 @@
   // No internal state to update on lost context.
 }
 
+void PepperVideoEncoderHost::OnGpuControlReturnData(
+    base::span<const uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
 int32_t PepperVideoEncoderHost::OnHostMsgGetSupportedProfiles(
     ppapi::host::HostMessageContext* context) {
   std::vector<PP_VideoProfileDescription> pp_profiles;
diff --git a/content/renderer/pepper/pepper_video_encoder_host.h b/content/renderer/pepper/pepper_video_encoder_host.h
index cbf01cf..028da68 100644
--- a/content/renderer/pepper/pepper_video_encoder_host.h
+++ b/content/renderer/pepper/pepper_video_encoder_host.h
@@ -85,6 +85,7 @@
       const gpu::SwapBuffersCompleteParams& params) final {}
   void OnSwapBufferPresented(uint64_t swap_id,
                              const gfx::PresentationFeedback& feedback) final {}
+  void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
   int32_t OnHostMsgGetSupportedProfiles(
       ppapi::host::HostMessageContext* context);
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc
index a169202f6..85a1162 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -327,6 +327,11 @@
 void PPB_Graphics3D_Impl::OnGpuControlSwapBuffersCompleted(
     const gpu::SwapBuffersCompleteParams& params) {}
 
+void PPB_Graphics3D_Impl::OnGpuControlReturnData(
+    base::span<const uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
 void PPB_Graphics3D_Impl::OnSwapBuffers() {
   if (HasPendingSwap()) {
     // If we're off-screen, no need to trigger and wait for compositing.
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.h b/content/renderer/pepper/ppb_graphics_3d_impl.h
index 389d291..c71abdf 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -94,6 +94,7 @@
       const gpu::SwapBuffersCompleteParams& params) final;
   void OnSwapBufferPresented(uint64_t swap_id,
                              const gfx::PresentationFeedback& feedback) final {}
+  void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
   // Other notifications from the GPU process.
   void OnSwapBuffers();
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 6fe046cb..0ce1781 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1350,6 +1350,11 @@
   // by RenderViewImpl, so this is surely redundant?
   render_widget->UpdateWebViewWithDeviceScaleFactor();
 
+  // The WebFrame created here was already attached to the Page as its
+  // main frame, and the WebFrameWidget has been initialized, so we can call
+  // WebViewImpl's DidAttachLocalMainFrame().
+  render_view->webview()->DidAttachLocalMainFrame(render_widget);
+
   render_frame->render_widget_ = render_widget;
   render_frame->in_frame_tree_ = true;
   render_frame->Initialize();
@@ -1503,6 +1508,10 @@
     // pulling the device scale factor off the WebView itself.
     render_widget->UpdateWebViewWithDeviceScaleFactor();
 
+    // Note that we do *not* call WebViewImpl's DidAttachLocalMainFrame() here
+    // yet because this frame is provisional and not attached to the Page yet.
+    // We will tell WebViewImpl about it once it is swapped in.
+
     // It may be questionable, since we create un-frozen RenderWidgets at this
     // point for subframes, but we don't un-freeze the main frame's RenderWidget
     // here, instead deferring until the non-provisional frame is swapped in.
@@ -6146,6 +6155,12 @@
       render_view_->GetWidget()->SetIsFrozen(false);
     }
     render_view_->GetWidget()->UpdateWebViewWithDeviceScaleFactor();
+
+    // The WebFrame being swapped in here has now been attached to the Page as
+    // its main frame, and the WebFrameWidget was previously initialized when
+    // the frame was created, so we can call WebViewImpl's
+    // DidAttachLocalMainFrame().
+    render_view_->webview()->DidAttachLocalMainFrame(render_view_->GetWidget());
   }
 
   return true;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index bccdec8..91c52f9d 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -560,7 +560,7 @@
                                        params->devtools_main_frame_token);
     // TODO(danakj): Make WebViewImpl not need a WebWidgetClient when there is a
     // remote main frame (when the RenderWidget is frozen).
-    webview_->SetWebWidgetClient(WidgetClient());
+    webview_->DidAttachRemoteMainFrame(render_widget_);
   }
 
   // TODO(davidben): Move this state from Blink into content.
@@ -1541,10 +1541,6 @@
   DCHECK(frame_widget_);
   frame_widget_->Close();
   frame_widget_ = nullptr;
-
-  // TODO(danakj): Make WebViewImpl not need a WebWidgetClient when there is a
-  // remote main frame (when the RenderWidget is frozen).
-  webview_->SetWebWidgetClient(WidgetClient());
 }
 
 void RenderViewImpl::SetZoomLevel(double zoom_level) {
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 7b64b34..3fb4cda 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1229,6 +1229,10 @@
   host->SetDebugState(debug_state);
 }
 
+void RenderWidget::SetBackgroundColor(SkColor color) {
+  layer_tree_view_->layer_tree_host()->set_background_color(color);
+}
+
 void RenderWidget::UpdateVisualState() {
   if (!GetWebWidget())
     return;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index d2996dee..35e17e7 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -380,6 +380,7 @@
   void SetShowDebugBorders(bool) override;
   void SetShowScrollBottleneckRects(bool) override;
   void SetShowHitTestBorders(bool) override;
+  void SetBackgroundColor(SkColor color) override;
   void IntrinsicSizingInfoChanged(
       const blink::WebIntrinsicSizingInfo&) override;
   void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index c94a37e..b4e40533 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -18,7 +18,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "content/public/browser/client_certificate_delegate.h"
-#include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/login_delegate.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/page_navigator.h"
@@ -560,7 +559,6 @@
   network::mojom::NetworkContextPtr network_context;
   network::mojom::NetworkContextParamsPtr context_params =
       network::mojom::NetworkContextParams::New();
-  UpdateCorsExemptHeader(context_params.get());
   context_params->user_agent = GetUserAgent();
   context_params->accept_language = "en-us,en";
   context_params->enable_data_url_support = true;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 36a1064..eb25626 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -37,14 +37,14 @@
     "../browser/accessibility/accessibility_event_recorder_uia_win.cc",
     "../browser/accessibility/accessibility_event_recorder_uia_win.h",
     "../browser/accessibility/accessibility_event_recorder_win.cc",
-    "../browser/background_fetch/background_fetch_embedded_worker_test_helper.cc",
-    "../browser/background_fetch/background_fetch_embedded_worker_test_helper.h",
     "../browser/background_fetch/background_fetch_test_base.cc",
     "../browser/background_fetch/background_fetch_test_base.h",
     "../browser/background_fetch/background_fetch_test_browser_context.cc",
     "../browser/background_fetch/background_fetch_test_browser_context.h",
     "../browser/background_fetch/background_fetch_test_data_manager.cc",
     "../browser/background_fetch/background_fetch_test_data_manager.h",
+    "../browser/background_fetch/background_fetch_test_service_worker.cc",
+    "../browser/background_fetch/background_fetch_test_service_worker.h",
     "../browser/background_fetch/mock_background_fetch_delegate.cc",
     "../browser/background_fetch/mock_background_fetch_delegate.h",
     "../browser/fileapi/file_system_chooser_test_helpers.cc",
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc
index dcf03d3..b8bc22e6 100644
--- a/content/utility/utility_service_factory.cc
+++ b/content/utility/utility_service_factory.cc
@@ -185,7 +185,7 @@
     scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner) {
   auto service = std::make_unique<network::NetworkService>(
       std::move(network_registry_), nullptr /* request */,
-      nullptr /* net_log */, std::move(service_request));
+      nullptr /* net_log */, std::move(service_request), true);
 
   // Transfer ownership of the service to itself, and have it post to the main
   // thread on self-termination to kill the process.
diff --git a/google_apis/drive/base_requests_server_unittest.cc b/google_apis/drive/base_requests_server_unittest.cc
index 5dcd8b1..17aa745 100644
--- a/google_apis/drive/base_requests_server_unittest.cc
+++ b/google_apis/drive/base_requests_server_unittest.cc
@@ -52,7 +52,8 @@
     network_service_client_ =
         std::make_unique<network::TestNetworkServiceClient>(
             mojo::MakeRequest(&network_service_client_ptr));
-    network_service_ptr->SetClient(std::move(network_service_client_ptr));
+    network_service_ptr->SetClient(std::move(network_service_client_ptr),
+                                   network::mojom::NetworkServiceParams::New());
 
     network::mojom::URLLoaderFactoryParamsPtr params =
         network::mojom::URLLoaderFactoryParams::New();
diff --git a/google_apis/drive/base_requests_unittest.cc b/google_apis/drive/base_requests_unittest.cc
index d594897..e38b5c1 100644
--- a/google_apis/drive/base_requests_unittest.cc
+++ b/google_apis/drive/base_requests_unittest.cc
@@ -128,7 +128,8 @@
     network_service_client_ =
         std::make_unique<network::TestNetworkServiceClient>(
             mojo::MakeRequest(&network_service_client_ptr));
-    network_service_ptr->SetClient(std::move(network_service_client_ptr));
+    network_service_ptr->SetClient(std::move(network_service_client_ptr),
+                                   network::mojom::NetworkServiceParams::New());
 
     network::mojom::URLLoaderFactoryParamsPtr params =
         network::mojom::URLLoaderFactoryParams::New();
diff --git a/google_apis/drive/drive_api_requests_unittest.cc b/google_apis/drive/drive_api_requests_unittest.cc
index 1aa847c59..8c8a01d7 100644
--- a/google_apis/drive/drive_api_requests_unittest.cc
+++ b/google_apis/drive/drive_api_requests_unittest.cc
@@ -138,7 +138,8 @@
     network_service_client_ =
         std::make_unique<network::TestNetworkServiceClient>(
             mojo::MakeRequest(&network_service_client_ptr));
-    network_service_ptr->SetClient(std::move(network_service_client_ptr));
+    network_service_ptr->SetClient(std::move(network_service_client_ptr),
+                                   network::mojom::NetworkServiceParams::New());
 
     network::mojom::URLLoaderFactoryParamsPtr params =
         network::mojom::URLLoaderFactoryParams::New();
diff --git a/google_apis/drive/files_list_request_runner_unittest.cc b/google_apis/drive/files_list_request_runner_unittest.cc
index c349f72..6315653 100644
--- a/google_apis/drive/files_list_request_runner_unittest.cc
+++ b/google_apis/drive/files_list_request_runner_unittest.cc
@@ -85,7 +85,8 @@
     network_service_client_ =
         std::make_unique<network::TestNetworkServiceClient>(
             mojo::MakeRequest(&network_service_client_ptr));
-    network_service_ptr->SetClient(std::move(network_service_client_ptr));
+    network_service_ptr->SetClient(std::move(network_service_client_ptr),
+                                   network::mojom::NetworkServiceParams::New());
 
     network::mojom::URLLoaderFactoryParamsPtr params =
         network::mojom::URLLoaderFactoryParams::New();
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 6a4f779..8e0e79c 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -420,6 +420,11 @@
   pending_presentation_callbacks_.erase(found);
 }
 
+void GLES2Implementation::OnGpuControlReturnData(
+    base::span<const uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
 void GLES2Implementation::FreeSharedMemory(void* mem) {
   mapped_memory_->FreePendingToken(mem, helper_->InsertToken());
 }
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 393b49b..4a5d198 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -390,6 +390,7 @@
       const SwapBuffersCompleteParams& params) final;
   void OnSwapBufferPresented(uint64_t swap_id,
                              const gfx::PresentationFeedback& feedback) final;
+  void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
   void SendErrorMessage(std::string message, int32_t id);
   void CallDeferredErrorCallbacks();
diff --git a/gpu/command_buffer/client/gpu_control_client.h b/gpu/command_buffer/client/gpu_control_client.h
index e9fd10d..27822b7a 100644
--- a/gpu/command_buffer/client/gpu_control_client.h
+++ b/gpu/command_buffer/client/gpu_control_client.h
@@ -7,6 +7,7 @@
 
 #include <cstdint>
 
+#include "base/containers/span.h"
 #include "ui/gfx/presentation_feedback.h"
 
 namespace gpu {
@@ -30,6 +31,8 @@
   virtual void OnSwapBufferPresented(
       uint64_t swap_id,
       const gfx::PresentationFeedback& feedback) = 0;
+  // Sent by the WebGPUDecoder
+  virtual void OnGpuControlReturnData(base::span<const uint8_t> data) = 0;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc
index bae4d80..5053770 100644
--- a/gpu/command_buffer/client/raster_implementation.cc
+++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -384,6 +384,11 @@
   NOTREACHED();
 }
 
+void RasterImplementation::OnGpuControlReturnData(
+    base::span<const uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
 void RasterImplementation::SetAggressivelyFreeResources(
     bool aggressively_free_resources) {
   TRACE_EVENT1("gpu", "RasterImplementation::SetAggressivelyFreeResources",
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h
index 22a403a..acff4ac 100644
--- a/gpu/command_buffer/client/raster_implementation.h
+++ b/gpu/command_buffer/client/raster_implementation.h
@@ -235,6 +235,7 @@
       const SwapBuffersCompleteParams& params) final;
   void OnSwapBufferPresented(uint64_t swap_id,
                              const gfx::PresentationFeedback& feedback) final;
+  void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
   // Gets the GLError through our wrapper.
   GLenum GetGLError();
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc
index f23cec1..f13f326 100644
--- a/gpu/command_buffer/client/webgpu_implementation.cc
+++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -147,6 +147,11 @@
     const gfx::PresentationFeedback& feedback) {
   NOTIMPLEMENTED();
 }
+void WebGPUImplementation::OnGpuControlReturnData(
+    base::span<const uint8_t> data) {
+  // TODO: Handle return commands
+  NOTIMPLEMENTED();
+}
 
 void WebGPUImplementation::Dummy() {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
diff --git a/gpu/command_buffer/client/webgpu_implementation.h b/gpu/command_buffer/client/webgpu_implementation.h
index 2a2e01d..4c3ddaa7 100644
--- a/gpu/command_buffer/client/webgpu_implementation.h
+++ b/gpu/command_buffer/client/webgpu_implementation.h
@@ -84,6 +84,7 @@
       const SwapBuffersCompleteParams& params) final;
   void OnSwapBufferPresented(uint64_t swap_id,
                              const gfx::PresentationFeedback& feedback) final;
+  void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
  private:
   const char* GetLogPrefix() const { return "webgpu"; }
diff --git a/gpu/command_buffer/service/command_buffer_direct.cc b/gpu/command_buffer/service/command_buffer_direct.cc
index f82b529..5b9e2a7c 100644
--- a/gpu/command_buffer/service/command_buffer_direct.cc
+++ b/gpu/command_buffer/service/command_buffer_direct.cc
@@ -103,4 +103,8 @@
   return service_.CreateTransferBufferWithId(size, id);
 }
 
+void CommandBufferDirect::HandleReturnData(base::span<const uint8_t> data) {
+  NOTIMPLEMENTED();
+}
+
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/command_buffer_direct.h b/gpu/command_buffer/service/command_buffer_direct.h
index 3fe8847..52333650 100644
--- a/gpu/command_buffer/service/command_buffer_direct.h
+++ b/gpu/command_buffer/service/command_buffer_direct.h
@@ -51,6 +51,7 @@
   void OnRescheduleAfterFinished() override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override;
 
   scoped_refptr<Buffer> CreateTransferBufferWithId(uint32_t size, int32_t id);
 
diff --git a/gpu/command_buffer/service/decoder_client.h b/gpu/command_buffer/service/decoder_client.h
index 66da71f..d16d8b4 100644
--- a/gpu/command_buffer/service/decoder_client.h
+++ b/gpu/command_buffer/service/decoder_client.h
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "base/containers/span.h"
 #include "gpu/gpu_export.h"
 #include "url/gurl.h"
 
@@ -48,6 +49,9 @@
   virtual void ScheduleGrContextCleanup() = 0;
 
   virtual void SetActiveURL(GURL url) {}
+
+  // Called by the decoder to pass a variable-size block of data to the client.
+  virtual void HandleReturnData(base::span<const uint8_t> data) = 0;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index d70ebf4..d81387c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -65,6 +65,7 @@
   void OnRescheduleAfterFinished() override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   // Template to call glGenXXX functions.
   template <typename T>
@@ -854,6 +855,7 @@
   void OnRescheduleAfterFinished() override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   void SetUp() override;
   void TearDown() override;
diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc
index 0aa22b2..8308addb 100644
--- a/gpu/command_buffer/service/memory_program_cache_unittest.cc
+++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -98,6 +98,7 @@
   void OnRescheduleAfterFinished() override {}
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   int32_t shader_cache_count() { return shader_cache_count_; }
   const std::string& shader_cache_shader() { return shader_cache_shader_; }
diff --git a/gpu/command_buffer/service/passthrough_program_cache_unittest.cc b/gpu/command_buffer/service/passthrough_program_cache_unittest.cc
index 394f47e..3916153 100644
--- a/gpu/command_buffer/service/passthrough_program_cache_unittest.cc
+++ b/gpu/command_buffer/service/passthrough_program_cache_unittest.cc
@@ -48,6 +48,7 @@
   void OnRescheduleAfterFinished() override {}
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   int32_t blob_count() { return blob_count_; }
 
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc
index b9d24a32..adc6541 100644
--- a/gpu/command_buffer/service/program_manager_unittest.cc
+++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -95,6 +95,7 @@
   void OnRescheduleAfterFinished() override {}
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   std::unique_ptr<ProgramManager> manager_;
   GpuPreferences gpu_preferences_;
diff --git a/gpu/command_buffer/service/raster_decoder_unittest.cc b/gpu/command_buffer/service/raster_decoder_unittest.cc
index 005a4db..6837104f 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -302,6 +302,7 @@
   void OnRescheduleAfterFinished() override {}
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   std::unique_ptr<RasterDecoder> CreateDecoder() {
     auto decoder = base::WrapUnique(RasterDecoder::Create(
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.h b/gpu/command_buffer/service/raster_decoder_unittest_base.h
index 6a317c1..9e72426 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.h
@@ -54,6 +54,7 @@
   void OnRescheduleAfterFinished() override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void ScheduleGrContextCleanup() override {}
+  void HandleReturnData(base::span<const uint8_t> data) override {}
 
   // Template to call glGenXXX functions.
   template <typename T>
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
index b2172da..5ab597b 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.cc
+++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -150,6 +150,7 @@
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_BufferPresented, OnBufferPresented);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetGpuFenceHandleComplete,
                         OnGetGpuFenceHandleComplete);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ReturnData, OnReturnData);
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -632,6 +633,12 @@
   std::move(callback).Run(std::move(gpu_fence));
 }
 
+void CommandBufferProxyImpl::OnReturnData(const std::vector<uint8_t>& data) {
+  if (gpu_control_client_) {
+    gpu_control_client_->OnGpuControlReturnData(data);
+  }
+}
+
 void CommandBufferProxyImpl::TakeFrontBuffer(const gpu::Mailbox& mailbox) {
   CheckLock();
   base::AutoLock lock(last_state_lock_);
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h
index 6b0629bf..6464b6b 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.h
+++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -184,6 +184,7 @@
                          const gfx::PresentationFeedback& feedback);
   void OnGetGpuFenceHandleComplete(uint32_t gpu_fence_id,
                                    const gfx::GpuFenceHandle&);
+  void OnReturnData(const std::vector<uint8_t>& data);
 
   // Try to read an updated copy of the state from shared memory, and calls
   // OnGpuStateError() if the new state has an error.
diff --git a/gpu/ipc/common/gpu_messages.h b/gpu/ipc/common/gpu_messages.h
index ce761b73..463001b 100644
--- a/gpu/ipc/common/gpu_messages.h
+++ b/gpu/ipc/common/gpu_messages.h
@@ -312,4 +312,10 @@
                     uint32_t /* gpu_fence_id */,
                     gfx::GpuFenceHandle)
 
+// Returns a block of data from the GPU process to the renderer.
+// This contains server->client messages produced by dawn_wire and is used to
+// remote WebGPU.
+IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ReturnData,
+                    std::vector<uint8_t> /* data */)
+
 #endif  // GPU_IPC_COMMON_GPU_MESSAGES_H_
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 6581b9f..680085f5 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -1195,6 +1195,14 @@
     gr_cache_controller_->ScheduleGrContextCleanup();
 }
 
+void InProcessCommandBuffer::HandleReturnData(base::span<const uint8_t> data) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
+  std::vector<uint8_t> vec(data.data(), data.data() + data.size());
+  PostOrRunClientCallback(base::BindOnce(
+      &InProcessCommandBuffer::HandleReturnDataOnOriginThread,
+      client_thread_weak_ptr_factory_.GetWeakPtr(), std::move(vec)));
+}
+
 void InProcessCommandBuffer::PostOrRunClientCallback(
     base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
@@ -1553,6 +1561,14 @@
   }
 }
 
+void InProcessCommandBuffer::HandleReturnDataOnOriginThread(
+    std::vector<uint8_t> data) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  if (gpu_control_client_) {
+    gpu_control_client_->OnGpuControlReturnData(data);
+  }
+}
+
 void InProcessCommandBuffer::SetUpdateVSyncParametersCallback(
     const UpdateVSyncParametersCallback& callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h
index 02884084..c5729e71 100644
--- a/gpu/ipc/in_process_command_buffer.h
+++ b/gpu/ipc/in_process_command_buffer.h
@@ -156,6 +156,7 @@
   void OnRescheduleAfterFinished() override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void ScheduleGrContextCleanup() override;
+  void HandleReturnData(base::span<const uint8_t> data) override;
 
 // ImageTransportSurfaceDelegate implementation:
 #if defined(OS_WIN)
@@ -308,6 +309,8 @@
                                      uint32_t flags,
                                      const gfx::PresentationFeedback& feedback);
 
+  void HandleReturnDataOnOriginThread(std::vector<uint8_t> data);
+
   const CommandBufferId command_buffer_id_;
 
   // Members accessed on the gpu thread (possibly with the exception of
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc
index 8b059956a..1adfcb0f 100644
--- a/gpu/ipc/service/command_buffer_stub.cc
+++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -643,6 +643,13 @@
   channel_->gpu_channel_manager()->ScheduleGrContextCleanup();
 }
 
+void CommandBufferStub::HandleReturnData(base::span<const uint8_t> data) {
+  std::vector<uint8_t> vec(data.begin(), data.end());
+  IPC::Message* msg =
+      new GpuCommandBufferMsg_ReturnData(route_id_, std::move(vec));
+  Send(msg);
+}
+
 void CommandBufferStub::OnConsoleMessage(int32_t id,
                                          const std::string& message) {
   GPUCommandBufferConsoleMessage console_message;
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h
index 3c21073..983b1f5 100644
--- a/gpu/ipc/service/command_buffer_stub.h
+++ b/gpu/ipc/service/command_buffer_stub.h
@@ -102,6 +102,7 @@
   void OnDescheduleUntilFinished() override;
   void OnRescheduleAfterFinished() override;
   void ScheduleGrContextCleanup() override;
+  void HandleReturnData(base::span<const uint8_t> data) override;
 
   using MemoryTrackerFactory =
       base::RepeatingCallback<std::unique_ptr<MemoryTracker>(
diff --git a/ios/chrome/browser/browser_state/browser_state_services_egtest.mm b/ios/chrome/browser/browser_state/browser_state_services_egtest.mm
index 9a8a10b2..328ba23 100644
--- a/ios/chrome/browser/browser_state/browser_state_services_egtest.mm
+++ b/ios/chrome/browser/browser_state/browser_state_services_egtest.mm
@@ -13,7 +13,7 @@
 #include "ios/web/public/browser_state.h"
 #include "ios/web/public/service_manager_connection.h"
 #include "services/identity/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -22,8 +22,9 @@
 
 namespace {
 
-// Callback passed to identity::mojom::IdentityManager::GetPrimaryAccountInfo().
-// Sets |echo_callback_called_flag| to true to indicate that the callback was
+// Callback passed to
+// identity::mojom::IdentityAccessor::GetPrimaryAccountInfo(). Sets
+// |echo_callback_called_flag| to true to indicate that the callback was
 // invoked.
 void OnGotPrimaryAccountInfo(
     bool* get_primary_account_info_callback_called_flag,
@@ -60,13 +61,13 @@
       chrome_test_util::GetOriginalBrowserState();
 
   // Connect to the Identity Service and bind an IdentityManager instance.
-  identity::mojom::IdentityManagerPtr identityManager;
+  identity::mojom::IdentityAccessorPtr identityAccessor;
   web::BrowserState::GetConnectorFor(browserState)
       ->BindInterface(identity::mojom::kServiceName,
-                      mojo::MakeRequest(&identityManager));
+                      mojo::MakeRequest(&identityAccessor));
 
   bool getPrimaryAccountInfoCallbackCalled = false;
-  identityManager->GetPrimaryAccountInfo(base::BindOnce(
+  identityAccessor->GetPrimaryAccountInfo(base::BindOnce(
       &OnGotPrimaryAccountInfo, &getPrimaryAccountInfoCallbackCalled));
 
   WaitForCallback("GetPrimaryAccountInfo",
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
index 11dc21c6..0b69b68 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -382,13 +382,10 @@
                                           : variations::InIncognito::kNo,
       &resource_request);
   NSMutableDictionary* result = [NSMutableDictionary dictionary];
-  // The variations header appears in cors_exempt_headers rather than in
-  // headers.
-  net::HttpRequestHeaders::Iterator header_iterator(
-      resource_request.cors_exempt_headers);
-  while (header_iterator.GetNext()) {
-    NSString* name = base::SysUTF8ToNSString(header_iterator.name());
-    NSString* value = base::SysUTF8ToNSString(header_iterator.value());
+  if (!resource_request.client_data_header.empty()) {
+    NSString* name = base::SysUTF8ToNSString("X-Client-Data");
+    NSString* value =
+        base::SysUTF8ToNSString(resource_request.client_data_header);
     result[name] = value;
   }
   return [result copy];
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
index fe993ccf..d70b994 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_mediator.mm
@@ -7,7 +7,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/omnibox/browser/location_bar_model.h"
-#include "components/security_state/core/security_state_ui.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h"
 #import "ios/chrome/browser/ui/location_bar/location_bar_consumer.h"
diff --git a/ios/chrome/browser/web/chrome_overlay_manifests.cc b/ios/chrome/browser/web/chrome_overlay_manifests.cc
index 509cffd..bdffefe 100644
--- a/ios/chrome/browser/web/chrome_overlay_manifests.cc
+++ b/ios/chrome/browser/web/chrome_overlay_manifests.cc
@@ -14,7 +14,7 @@
 const service_manager::Manifest& GetChromeWebBrowserOverlayManifest() {
   static base::NoDestructor<service_manager::Manifest> manifest{
       service_manager::ManifestBuilder()
-          .RequireCapability(identity::mojom::kServiceName, "identity_manager")
+          .RequireCapability(identity::mojom::kServiceName, "identity_accessor")
           .RequireCapability(unzip::mojom::kServiceName, "unzip_file")
           .PackageService(identity::GetManifest())
           .Build()};
diff --git a/ios/web/shell/test/BUILD.gn b/ios/web/shell/test/BUILD.gn
index 71a1e425..910da93 100644
--- a/ios/web/shell/test/BUILD.gn
+++ b/ios/web/shell/test/BUILD.gn
@@ -86,6 +86,8 @@
     "earl_grey/shell_earl_grey.mm",
     "earl_grey/shell_matchers.h",
     "earl_grey/shell_matchers.mm",
+    "earl_grey/shell_matchers_shorthand.h",
+    "earl_grey/shell_matchers_shorthand.mm",
     "earl_grey/web_shell_test_case.h",
     "earl_grey/web_shell_test_case.mm",
   ]
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm
index 96d1c43..150098de 100644
--- a/ios/web/shell/test/context_menu_egtest.mm
+++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -18,6 +18,7 @@
 #import "ios/web/shell/test/earl_grey/shell_actions.h"
 #import "ios/web/shell/test/earl_grey/shell_earl_grey.h"
 #import "ios/web/shell/test/earl_grey/shell_matchers.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers_shorthand.h"
 #import "ios/web/shell/test/earl_grey/web_shell_test_case.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/shell/test/earl_grey/shell_matchers.h b/ios/web/shell/test/earl_grey/shell_matchers.h
index bd2a3d67..a81c62a 100644
--- a/ios/web/shell/test/earl_grey/shell_matchers.h
+++ b/ios/web/shell/test/earl_grey/shell_matchers.h
@@ -5,30 +5,34 @@
 #ifndef IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_H_
 #define IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_H_
 
+#import <Foundation/Foundation.h>
+
 #include <string>
 
-#import <EarlGrey/EarlGrey.h>
+// ObjC matcher class for use in EG2 tests (Test and App process).
+// Shell_matchers_shorthand.h/mm is C++ and for use when writing EG1 tests.
+@protocol GREYMatcher;
 
-namespace web {
+@interface ShellMatchers : NSObject
 
 // Matcher for the WKWebView.
-id<GREYMatcher> WebView();
++ (id<GREYMatcher>)webView;
 
 // Matcher for WKWebView's scroll view.
-id<GREYMatcher> WebViewScrollView();
++ (id<GREYMatcher>)webViewScrollView;
 
 // Matcher for web shell address field text property equal to |text|.
-id<GREYMatcher> AddressFieldText(std::string text);
++ (id<GREYMatcher>)addressFieldWithText:(NSString*)text;
 
 // Matcher for back button in web shell.
-id<GREYMatcher> BackButton();
++ (id<GREYMatcher>)backButton;
 
 // Matcher for forward button in web shell.
-id<GREYMatcher> ForwardButton();
++ (id<GREYMatcher>)forwardButton;
 
 // Matcher for address field in web shell.
-id<GREYMatcher> AddressField();
++ (id<GREYMatcher>)addressField;
 
-}  // namespace web
+@end
 
 #endif  // IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_H_
diff --git a/ios/web/shell/test/earl_grey/shell_matchers.mm b/ios/web/shell/test/earl_grey/shell_matchers.mm
index d856a89f..b5bb6a4 100644
--- a/ios/web/shell/test/earl_grey/shell_matchers.mm
+++ b/ios/web/shell/test/earl_grey/shell_matchers.mm
@@ -17,17 +17,17 @@
 #error "This file requires ARC support."
 #endif
 
-namespace web {
+@implementation ShellMatchers
 
-id<GREYMatcher> WebView() {
-  return WebViewInWebState(shell_test_util::GetCurrentWebState());
++ (id<GREYMatcher>)webView {
+  return WebViewInWebState(web::shell_test_util::GetCurrentWebState());
 }
 
-id<GREYMatcher> WebViewScrollView() {
-  return WebViewScrollView(shell_test_util::GetCurrentWebState());
++ (id<GREYMatcher>)webViewScrollView {
+  return WebViewScrollView(web::shell_test_util::GetCurrentWebState());
 }
 
-id<GREYMatcher> AddressFieldText(std::string text) {
++ (id<GREYMatcher>)addressFieldWithText:(NSString*)text {
   MatchesBlock matches = ^BOOL(UIView* view) {
     if (![view isKindOfClass:[UITextField class]]) {
       return NO;
@@ -39,12 +39,12 @@
     UITextField* text_field = base::mac::ObjCCastStrict<UITextField>(view);
     NSString* error_message = [NSString
         stringWithFormat:
-            @"Address field text did not match. expected: %@, actual: %@",
-            base::SysUTF8ToNSString(text), text_field.text];
+            @"Address field text did not match. expected: %@, actual: %@", text,
+            text_field.text];
     GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(
                    base::test::ios::kWaitForUIElementTimeout,
-                   ^{
-                     return base::SysNSStringToUTF8(text_field.text) == text;
+                   ^bool {
+                     return [text_field.text isEqualToString:text];
                    }),
                error_message);
     return YES;
@@ -52,23 +52,23 @@
 
   DescribeToBlock describe = ^(id<GREYDescription> description) {
     [description appendText:@"address field containing "];
-    [description appendText:base::SysUTF8ToNSString(text)];
+    [description appendText:text];
   };
 
   return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
                                               descriptionBlock:describe];
 }
 
-id<GREYMatcher> BackButton() {
++ (id<GREYMatcher>)backButton {
   return grey_accessibilityLabel(kWebShellBackButtonAccessibilityLabel);
 }
 
-id<GREYMatcher> ForwardButton() {
++ (id<GREYMatcher>)forwardButton {
   return grey_accessibilityLabel(kWebShellForwardButtonAccessibilityLabel);
 }
 
-id<GREYMatcher> AddressField() {
++ (id<GREYMatcher>)addressField {
   return grey_accessibilityLabel(kWebShellAddressFieldAccessibilityLabel);
 }
 
-}  // namespace web
+@end
diff --git a/ios/web/shell/test/earl_grey/shell_matchers_shorthand.h b/ios/web/shell/test/earl_grey/shell_matchers_shorthand.h
new file mode 100644
index 0000000..d83a438
--- /dev/null
+++ b/ios/web/shell/test/earl_grey/shell_matchers_shorthand.h
@@ -0,0 +1,37 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_SHORTHAND_H_
+#define IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_SHORTHAND_H_
+
+#import <Foundation/Foundation.h>
+
+#include <string>
+
+// Matchers for use in EG1 tests and in EG2 App Process.
+@protocol GREYMatcher;
+
+namespace web {
+
+// Matcher for the WKWebView.
+id<GREYMatcher> WebView();
+
+// Matcher for WKWebView's scroll view.
+id<GREYMatcher> WebViewScrollView();
+
+// Matcher for web shell address field text property equal to |text|.
+id<GREYMatcher> AddressFieldText(std::string text);
+
+// Matcher for back button in web shell.
+id<GREYMatcher> BackButton();
+
+// Matcher for forward button in web shell.
+id<GREYMatcher> ForwardButton();
+
+// Matcher for address field in web shell.
+id<GREYMatcher> AddressField();
+
+}  // namespace web
+
+#endif  // IOS_WEB_SHELL_TEST_EARL_GREY_SHELL_MATCHERS_SHORTHAND_H_
diff --git a/ios/web/shell/test/earl_grey/shell_matchers_shorthand.mm b/ios/web/shell/test/earl_grey/shell_matchers_shorthand.mm
new file mode 100644
index 0000000..c9b289b
--- /dev/null
+++ b/ios/web/shell/test/earl_grey/shell_matchers_shorthand.mm
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <EarlGrey/EarlGrey.h>
+#import <WebKit/WebKit.h>
+
+#include "base/strings/sys_string_conversions.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers_shorthand.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace web {
+
+id<GREYMatcher> WebView() {
+  return [ShellMatchers webView];
+}
+
+id<GREYMatcher> WebViewScrollView() {
+  return [ShellMatchers webViewScrollView];
+}
+
+id<GREYMatcher> AddressFieldText(std::string text) {
+  return [ShellMatchers addressFieldWithText:base::SysUTF8ToNSString(text)];
+}
+
+id<GREYMatcher> BackButton() {
+  return [ShellMatchers backButton];
+}
+
+id<GREYMatcher> ForwardButton() {
+  return [ShellMatchers forwardButton];
+}
+
+id<GREYMatcher> AddressField() {
+  return [ShellMatchers addressField];
+}
+
+}  // namespace web
diff --git a/ios/web/shell/test/meta_tags_egtest.mm b/ios/web/shell/test/meta_tags_egtest.mm
index 442b1e2b..9933dd1c 100644
--- a/ios/web/shell/test/meta_tags_egtest.mm
+++ b/ios/web/shell/test/meta_tags_egtest.mm
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import <EarlGrey/EarlGrey.h>
+
 #include <map>
 
 #include "base/strings/stringprintf.h"
@@ -10,6 +12,7 @@
 #include "ios/web/public/test/http_server/http_server_util.h"
 #import "ios/web/shell/test/earl_grey/shell_earl_grey.h"
 #import "ios/web/shell/test/earl_grey/shell_matchers.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers_shorthand.h"
 #import "ios/web/shell/test/earl_grey/web_shell_test_case.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/shell/test/page_state_egtest.mm b/ios/web/shell/test/page_state_egtest.mm
index 362960c..c9f303b 100644
--- a/ios/web/shell/test/page_state_egtest.mm
+++ b/ios/web/shell/test/page_state_egtest.mm
@@ -12,6 +12,7 @@
 #include "ios/web/public/test/http_server/http_server_util.h"
 #import "ios/web/shell/test/earl_grey/shell_earl_grey.h"
 #import "ios/web/shell/test/earl_grey/shell_matchers.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers_shorthand.h"
 #import "ios/web/shell/test/earl_grey/web_shell_test_case.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/shell/test/redirect_egtest.mm b/ios/web/shell/test/redirect_egtest.mm
index e694c86..0c32da3 100644
--- a/ios/web/shell/test/redirect_egtest.mm
+++ b/ios/web/shell/test/redirect_egtest.mm
@@ -10,6 +10,7 @@
 #include "ios/web/public/test/http_server/http_server_util.h"
 #import "ios/web/shell/test/earl_grey/shell_earl_grey.h"
 #import "ios/web/shell/test/earl_grey/shell_matchers.h"
+#import "ios/web/shell/test/earl_grey/shell_matchers_shorthand.h"
 #import "ios/web/shell/test/earl_grey/web_shell_test_case.h"
 #include "net/http/http_status_code.h"
 
diff --git a/media/mojo/clients/mojo_renderer_factory.cc b/media/mojo/clients/mojo_renderer_factory.cc
index af8a0eb..d42bb892 100644
--- a/media/mojo/clients/mojo_renderer_factory.cc
+++ b/media/mojo/clients/mojo_renderer_factory.cc
@@ -4,8 +4,7 @@
 
 #include "media/mojo/clients/mojo_renderer_factory.h"
 
-#include <memory>
-#include <string>
+#include <utility>
 
 #include "base/single_thread_task_runner.h"
 #include "build/build_config.h"
@@ -19,22 +18,15 @@
 namespace media {
 
 MojoRendererFactory::MojoRendererFactory(
-    mojom::HostedRendererType type,
     const GetGpuFactoriesCB& get_gpu_factories_cb,
     media::mojom::InterfaceFactory* interface_factory)
     : get_gpu_factories_cb_(get_gpu_factories_cb),
-      interface_factory_(interface_factory),
-      hosted_renderer_type_(type) {
+      interface_factory_(interface_factory) {
   DCHECK(interface_factory_);
 }
 
 MojoRendererFactory::~MojoRendererFactory() = default;
 
-void MojoRendererFactory::SetGetTypeSpecificIdCB(
-    const GetTypeSpecificIdCB& get_type_specific_id) {
-  get_type_specific_id_ = get_type_specific_id;
-}
-
 std::unique_ptr<Renderer> MojoRendererFactory::CreateRenderer(
     const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
     const scoped_refptr<base::TaskRunner>& /* worker_task_runner */,
@@ -42,49 +34,46 @@
     VideoRendererSink* video_renderer_sink,
     const RequestOverlayInfoCB& /* request_overlay_info_cb */,
     const gfx::ColorSpace& /* target_color_space */) {
-  std::unique_ptr<VideoOverlayFactory> overlay_factory;
+  DCHECK(interface_factory_);
 
-  // |get_gpu_factories_cb_| can be null in the HLS/MediaPlayerRenderer case,
-  // when we do not need to create video overlays.
-  if (get_gpu_factories_cb_) {
-    overlay_factory =
-        std::make_unique<VideoOverlayFactory>(get_gpu_factories_cb_.Run());
-  }
+  DCHECK(get_gpu_factories_cb_);
+  auto overlay_factory =
+      std::make_unique<VideoOverlayFactory>(get_gpu_factories_cb_.Run());
 
-  // MediaPlayerRendererClientFactory depends on |this| always returning a MR,
-  // since it uses a static_cast to use some MojoRenderer specific interfaces.
-  // Therefore, |this| should never return anything else than a MojoRenderer.
-  return std::make_unique<MojoRenderer>(media_task_runner,
-                                        std::move(overlay_factory),
-                                        video_renderer_sink, GetRendererPtr());
-}
-
-mojom::RendererPtr MojoRendererFactory::GetRendererPtr() {
   mojom::RendererPtr renderer_ptr;
+  interface_factory_->CreateDefaultRenderer(std::string(),
+                                            mojo::MakeRequest(&renderer_ptr));
 
-  if (interface_factory_) {
-    switch (hosted_renderer_type_) {
-      case mojom::HostedRendererType::kDefault:
-        interface_factory_->CreateDefaultRenderer(
-            std::string(), mojo::MakeRequest(&renderer_ptr));
-        break;
-#if defined(OS_ANDROID)
-      case mojom::HostedRendererType::kMediaPlayer:
-        interface_factory_->CreateMediaPlayerRenderer(
-            mojo::MakeRequest(&renderer_ptr));
-        break;
-      case mojom::HostedRendererType::kFlinging:
-        DCHECK(get_type_specific_id_);
-        interface_factory_->CreateFlingingRenderer(
-            get_type_specific_id_.Run(), mojo::MakeRequest(&renderer_ptr));
-        break;
-#endif  // defined(OS_ANDROID)
-    }
-  } else {
-    NOTREACHED();
-  }
-
-  return renderer_ptr;
+  return std::make_unique<MojoRenderer>(
+      media_task_runner, std::move(overlay_factory), video_renderer_sink,
+      std::move(renderer_ptr));
 }
 
+#if defined(OS_ANDROID)
+std::unique_ptr<MojoRenderer> MojoRendererFactory::CreateFlingingRenderer(
+    const std::string& presentation_id,
+    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    VideoRendererSink* video_renderer_sink) {
+  DCHECK(interface_factory_);
+  mojom::RendererPtr renderer_ptr;
+  interface_factory_->CreateFlingingRenderer(presentation_id,
+                                             mojo::MakeRequest(&renderer_ptr));
+
+  return std::make_unique<MojoRenderer>(
+      media_task_runner, nullptr, video_renderer_sink, std::move(renderer_ptr));
+}
+
+std::unique_ptr<MojoRenderer> MojoRendererFactory::CreateMediaPlayerRenderer(
+    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+    VideoRendererSink* video_renderer_sink) {
+  DCHECK(interface_factory_);
+  mojom::RendererPtr renderer_ptr;
+  interface_factory_->CreateMediaPlayerRenderer(
+      mojo::MakeRequest(&renderer_ptr));
+
+  return std::make_unique<MojoRenderer>(
+      media_task_runner, nullptr, video_renderer_sink, std::move(renderer_ptr));
+}
+#endif  // defined(OS_ANDROID)
+
 }  // namespace media
diff --git a/media/mojo/clients/mojo_renderer_factory.h b/media/mojo/clients/mojo_renderer_factory.h
index 91d3976..88c8b82 100644
--- a/media/mojo/clients/mojo_renderer_factory.h
+++ b/media/mojo/clients/mojo_renderer_factory.h
@@ -6,8 +6,10 @@
 #define MEDIA_MOJO_CLIENTS_MOJO_RENDERER_FACTORY_H_
 
 #include <memory>
+#include <string>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "media/base/renderer_factory.h"
 #include "media/mojo/interfaces/interface_factory.mojom.h"
 #include "media/mojo/interfaces/renderer.mojom.h"
@@ -19,6 +21,7 @@
 namespace media {
 
 class GpuVideoAcceleratorFactories;
+class MojoRenderer;
 
 // The default factory class for creating MojoRenderer.
 //
@@ -29,17 +32,12 @@
 // wrapper factories that use MRF, rather than creating derived MojoRenderer
 // types, or extending MRF. See DecryptingRendererFactory and
 // MediaPlayerRendererClientFactory for examples of small wrappers around MRF.
-//
-// NOTE: MediaPlayerRendererClientFactory uses MojoRenderer specific methods,
-//       and uses a static_cast<MojoRenderer*> internally. |this| should
-//       never return anything but a MojoRenderer. See crbug.com/919494.
 class MojoRendererFactory : public RendererFactory {
  public:
   using GetGpuFactoriesCB = base::Callback<GpuVideoAcceleratorFactories*()>;
   using GetTypeSpecificIdCB = base::Callback<std::string()>;
 
-  MojoRendererFactory(mojom::HostedRendererType type,
-                      const GetGpuFactoriesCB& get_gpu_factories_cb,
+  MojoRendererFactory(const GetGpuFactoriesCB& get_gpu_factories_cb,
                       media::mojom::InterfaceFactory* interface_factory);
 
   ~MojoRendererFactory() final;
@@ -52,27 +50,24 @@
       const RequestOverlayInfoCB& request_overlay_info_cb,
       const gfx::ColorSpace& target_color_space) final;
 
-  // Sets the callback that will fetch the TypeSpecificId when
-  // InterfaceFactory::CreateRenderer() is called. What the string represents
-  // depends on the value of |hosted_renderer_type_|. Currently, we only use it
-  // with mojom::HostedRendererType::kFlinging, in which case
-  // |get_type_specific_id| should return the presentation ID to be given to the
-  // FlingingRenderer in the browser process.
-  void SetGetTypeSpecificIdCB(const GetTypeSpecificIdCB& get_type_specific_id);
+#if defined(OS_ANDROID)
+  std::unique_ptr<MojoRenderer> CreateFlingingRenderer(
+      const std::string& presentation_id,
+      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      VideoRendererSink* video_renderer_sink);
+
+  std::unique_ptr<MojoRenderer> CreateMediaPlayerRenderer(
+      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
+      VideoRendererSink* video_renderer_sink);
+#endif  // defined (OS_ANDROID)
 
  private:
-  mojom::RendererPtr GetRendererPtr();
-
   GetGpuFactoriesCB get_gpu_factories_cb_;
-  GetTypeSpecificIdCB get_type_specific_id_;
 
   // InterfaceFactory or InterfaceProvider used to create or connect to remote
   // renderer.
   media::mojom::InterfaceFactory* interface_factory_ = nullptr;
 
-  // Underlying renderer type that will be hosted by the MojoRenderer.
-  mojom::HostedRendererType hosted_renderer_type_;
-
   DISALLOW_COPY_AND_ASSIGN(MojoRendererFactory);
 };
 
diff --git a/media/renderers/BUILD.gn b/media/renderers/BUILD.gn
index 8c8bd60..99c860a 100644
--- a/media/renderers/BUILD.gn
+++ b/media/renderers/BUILD.gn
@@ -21,8 +21,6 @@
     "default_decoder_factory.h",
     "default_renderer_factory.cc",
     "default_renderer_factory.h",
-    "flinging_renderer_client_factory.cc",
-    "flinging_renderer_client_factory.h",
     "paint_canvas_video_renderer.cc",
     "paint_canvas_video_renderer.h",
     "remote_playback_client_wrapper.h",
diff --git a/media/renderers/flinging_renderer_client_factory.cc b/media/renderers/flinging_renderer_client_factory.cc
deleted file mode 100644
index 0343b95..0000000
--- a/media/renderers/flinging_renderer_client_factory.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 "media/renderers/flinging_renderer_client_factory.h"
-
-#include "base/logging.h"
-#include "media/base/overlay_info.h"
-
-namespace media {
-
-FlingingRendererClientFactory::FlingingRendererClientFactory(
-    std::unique_ptr<RendererFactory> mojo_flinging_factory,
-    std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client)
-    : mojo_flinging_factory_(std::move(mojo_flinging_factory)),
-      remote_playback_client_(std::move(remote_playback_client)) {}
-
-FlingingRendererClientFactory::~FlingingRendererClientFactory() = default;
-
-std::unique_ptr<Renderer> FlingingRendererClientFactory::CreateRenderer(
-    const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
-    const scoped_refptr<base::TaskRunner>& worker_task_runner,
-    AudioRendererSink* audio_renderer_sink,
-    VideoRendererSink* video_renderer_sink,
-    const RequestOverlayInfoCB& request_overlay_info_cb,
-    const gfx::ColorSpace& target_color_space) {
-  DCHECK(IsFlingingActive());
-  return mojo_flinging_factory_->CreateRenderer(
-      media_task_runner, worker_task_runner, audio_renderer_sink,
-      video_renderer_sink, request_overlay_info_cb, target_color_space);
-}
-
-std::string FlingingRendererClientFactory::GetActivePresentationId() {
-  return remote_playback_client_->GetActivePresentationId();
-}
-
-bool FlingingRendererClientFactory::IsFlingingActive() {
-  return !GetActivePresentationId().empty();
-}
-
-}  // namespace media
diff --git a/media/renderers/flinging_renderer_client_factory.h b/media/renderers/flinging_renderer_client_factory.h
deleted file mode 100644
index 73a28a5..0000000
--- a/media/renderers/flinging_renderer_client_factory.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_
-#define MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_
-
-#include "media/base/media_export.h"
-#include "media/base/renderer_factory.h"
-#include "media/renderers/remote_playback_client_wrapper.h"
-
-namespace media {
-
-// Creates a renderer for media flinging.
-// The FRCF uses a MojoRendererFactory to create a FlingingRenderer in the
-// browser process. The actual renderer returned by the FRCF is a MojoRenderer
-// directly (as opposed to a dedicated FlingingRendererClient), because all the
-// renderer needs to do is forward calls to the FlingingRenderer in the browser.
-class MEDIA_EXPORT FlingingRendererClientFactory : public RendererFactory {
- public:
-  // |mojo_flinging_factory| should be created using
-  // HostedRendererType::kFlinging, and GetActivePresentationId()
-  // should be given to it through SetGetTypeSpecificIdCB().
-  FlingingRendererClientFactory(
-      std::unique_ptr<RendererFactory> mojo_flinging_factory,
-      std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client);
-  ~FlingingRendererClientFactory() override;
-
-  std::unique_ptr<Renderer> CreateRenderer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
-      const scoped_refptr<base::TaskRunner>& worker_task_runner,
-      AudioRendererSink* audio_renderer_sink,
-      VideoRendererSink* video_renderer_sink,
-      const RequestOverlayInfoCB& request_overlay_info_cb,
-      const gfx::ColorSpace& target_color_space) override;
-
-  // Returns whether media flinging has started, based off of whether the
-  // |remote_playback_client_| has a presentation ID or not. Called by
-  // RendererFactorySelector to determine when to create a FlingingRenderer.
-  bool IsFlingingActive();
-
-  // Used by the |mojo_flinging_factory_| to retrieve the latest presentation ID
-  // when CreateRenderer() is called.
-  std::string GetActivePresentationId();
-
- private:
-  std::unique_ptr<RendererFactory> mojo_flinging_factory_;
-  std::unique_ptr<RemotePlaybackClientWrapper> remote_playback_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(FlingingRendererClientFactory);
-};
-
-}  // namespace media
-
-#endif  // MEDIA_RENDERERS_FLINGING_RENDERER_CLIENT_FACTORY_H_
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index 92c09f270..112488e 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -303,6 +303,9 @@
     const base::FilePath::StringType& ext,
     bool include_platform_types,
     string* result) const {
+  DCHECK(ext.empty() || ext[0] != '.')
+      << "extension passed in must not include leading dot";
+
   // Avoids crash when unable to handle a long file path. See crbug.com/48733.
   const unsigned kMaxFilePathSize = 65536;
   if (ext.length() > kMaxFilePathSize)
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index a690999a..55772fc 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -213,7 +213,7 @@
   CHECK(false);
   return NULL;
 #elif defined(OS_CHROMEOS)
-  return new NetworkChangeNotifierPosix();
+  return new NetworkChangeNotifierPosix(CONNECTION_UNKNOWN, SUBTYPE_UNKNOWN);
 #elif defined(OS_LINUX)
   return new NetworkChangeNotifierLinux(std::unordered_set<std::string>());
 #elif defined(OS_MACOSX)
diff --git a/net/base/network_change_notifier_posix.cc b/net/base/network_change_notifier_posix.cc
index 0e87a60..89a1ff4 100644
--- a/net/base/network_change_notifier_posix.cc
+++ b/net/base/network_change_notifier_posix.cc
@@ -64,12 +64,14 @@
   dns_config_service_.reset();
 }
 
-NetworkChangeNotifierPosix::NetworkChangeNotifierPosix()
+NetworkChangeNotifierPosix::NetworkChangeNotifierPosix(
+    NetworkChangeNotifier::ConnectionType initial_connection_type,
+    NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype)
     : NetworkChangeNotifier(NetworkChangeCalculatorParamsPosix()),
-      connection_type_(CONNECTION_UNKNOWN),
+      connection_type_(initial_connection_type),
       max_bandwidth_mbps_(
           NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
-              SUBTYPE_UNKNOWN)) {
+              initial_connection_subtype)) {
   notifier_thread_.StartWithOptions(
       base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
 }
diff --git a/net/base/network_change_notifier_posix.h b/net/base/network_change_notifier_posix.h
index 75dc5705..37e6ae40 100644
--- a/net/base/network_change_notifier_posix.h
+++ b/net/base/network_change_notifier_posix.h
@@ -23,7 +23,9 @@
 // for network state changes.
 class NET_EXPORT NetworkChangeNotifierPosix : public NetworkChangeNotifier {
  public:
-  NetworkChangeNotifierPosix();
+  NetworkChangeNotifierPosix(
+      NetworkChangeNotifier::ConnectionType initial_connection_type,
+      NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype);
   ~NetworkChangeNotifierPosix() override;
 
   // These methods are used to notify this object that a network property has
diff --git a/net/base/network_change_notifier_posix_unittest.cc b/net/base/network_change_notifier_posix_unittest.cc
index 99312a09..c540877 100644
--- a/net/base/network_change_notifier_posix_unittest.cc
+++ b/net/base/network_change_notifier_posix_unittest.cc
@@ -15,7 +15,9 @@
   NetworkChangeNotifierPosixTest()
       : scoped_task_environment_(
             base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
-        notifier_(new NetworkChangeNotifierPosix()) {}
+        notifier_(new NetworkChangeNotifierPosix(
+            NetworkChangeNotifier::CONNECTION_UNKNOWN,
+            NetworkChangeNotifier::SUBTYPE_UNKNOWN)) {}
 
   void FastForwardUntilIdle() {
     scoped_task_environment_.FastForwardUntilNoTasksRemain();
diff --git a/services/identity/BUILD.gn b/services/identity/BUILD.gn
index cae93bb..15e7d175 100644
--- a/services/identity/BUILD.gn
+++ b/services/identity/BUILD.gn
@@ -8,8 +8,8 @@
 
 source_set("lib") {
   sources = [
-    "identity_manager_impl.cc",
-    "identity_manager_impl.h",
+    "identity_accessor_impl.cc",
+    "identity_accessor_impl.h",
     "identity_service.cc",
     "identity_service.h",
   ]
@@ -49,7 +49,7 @@
     "//testing/gtest",
   ]
   sources = [
-    "identity_manager_impl_unittest.cc",
+    "identity_accessor_impl_unittest.cc",
     "public/cpp/access_token_fetcher_unittest.cc",
     "public/cpp/identity_manager_unittest.cc",
     "public/cpp/identity_test_environment_unittest.cc",
diff --git a/services/identity/identity_manager_impl.cc b/services/identity/identity_accessor_impl.cc
similarity index 73%
rename from services/identity/identity_manager_impl.cc
rename to services/identity/identity_accessor_impl.cc
index 3e8b8dc..81dbdc1 100644
--- a/services/identity/identity_manager_impl.cc
+++ b/services/identity/identity_accessor_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "services/identity/identity_manager_impl.h"
+#include "services/identity/identity_accessor_impl.h"
 
 #include <utility>
 
@@ -14,13 +14,13 @@
 
 namespace identity {
 
-IdentityManagerImpl::AccessTokenRequest::AccessTokenRequest(
+IdentityAccessorImpl::AccessTokenRequest::AccessTokenRequest(
     const std::string& account_id,
     const ScopeSet& scopes,
     const std::string& consumer_id,
     GetAccessTokenCallback consumer_callback,
     ProfileOAuth2TokenService* token_service,
-    IdentityManagerImpl* manager)
+    IdentityAccessorImpl* manager)
     : OAuth2TokenService::Consumer(consumer_id),
       token_service_(token_service),
       consumer_callback_(std::move(consumer_callback)),
@@ -29,9 +29,9 @@
       token_service_->StartRequest(account_id, scopes, this);
 }
 
-IdentityManagerImpl::AccessTokenRequest::~AccessTokenRequest() = default;
+IdentityAccessorImpl::AccessTokenRequest::~AccessTokenRequest() = default;
 
-void IdentityManagerImpl::AccessTokenRequest::OnGetTokenSuccess(
+void IdentityAccessorImpl::AccessTokenRequest::OnGetTokenSuccess(
     const OAuth2TokenService::Request* request,
     const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
   OnRequestCompleted(request, token_response.access_token,
@@ -39,13 +39,13 @@
                      GoogleServiceAuthError::AuthErrorNone());
 }
 
-void IdentityManagerImpl::AccessTokenRequest::OnGetTokenFailure(
+void IdentityAccessorImpl::AccessTokenRequest::OnGetTokenFailure(
     const OAuth2TokenService::Request* request,
     const GoogleServiceAuthError& error) {
   OnRequestCompleted(request, base::nullopt, base::Time(), error);
 }
 
-void IdentityManagerImpl::AccessTokenRequest::OnRequestCompleted(
+void IdentityAccessorImpl::AccessTokenRequest::OnRequestCompleted(
     const OAuth2TokenService::Request* request,
     const base::Optional<std::string>& access_token,
     base::Time expiration_time,
@@ -57,16 +57,16 @@
 }
 
 // static
-void IdentityManagerImpl::Create(mojom::IdentityManagerRequest request,
-                                 AccountTrackerService* account_tracker,
-                                 SigninManagerBase* signin_manager,
-                                 ProfileOAuth2TokenService* token_service) {
-  new IdentityManagerImpl(std::move(request), account_tracker, signin_manager,
-                          token_service);
+void IdentityAccessorImpl::Create(mojom::IdentityAccessorRequest request,
+                                  AccountTrackerService* account_tracker,
+                                  SigninManagerBase* signin_manager,
+                                  ProfileOAuth2TokenService* token_service) {
+  new IdentityAccessorImpl(std::move(request), account_tracker, signin_manager,
+                           token_service);
 }
 
-IdentityManagerImpl::IdentityManagerImpl(
-    mojom::IdentityManagerRequest request,
+IdentityAccessorImpl::IdentityAccessorImpl(
+    mojom::IdentityAccessorRequest request,
     AccountTrackerService* account_tracker,
     SigninManagerBase* signin_manager,
     ProfileOAuth2TokenService* token_service)
@@ -76,22 +76,22 @@
       token_service_(token_service) {
   signin_manager_shutdown_subscription_ =
       signin_manager_->RegisterOnShutdownCallback(
-          base::BindRepeating(&IdentityManagerImpl::OnSigninManagerShutdown,
+          base::BindRepeating(&IdentityAccessorImpl::OnSigninManagerShutdown,
                               base::Unretained(this)));
   binding_.set_connection_error_handler(base::BindRepeating(
-      &IdentityManagerImpl::OnConnectionError, base::Unretained(this)));
+      &IdentityAccessorImpl::OnConnectionError, base::Unretained(this)));
 
   token_service_->AddObserver(this);
   signin_manager_->AddObserver(this);
 }
 
-IdentityManagerImpl::~IdentityManagerImpl() {
+IdentityAccessorImpl::~IdentityAccessorImpl() {
   token_service_->RemoveObserver(this);
   signin_manager_->RemoveObserver(this);
   binding_.Close();
 }
 
-void IdentityManagerImpl::GetPrimaryAccountInfo(
+void IdentityAccessorImpl::GetPrimaryAccountInfo(
     GetPrimaryAccountInfoCallback callback) {
   // It's annoying that this can't be trivially implemented in terms of
   // GetAccountInfoFromGaiaId(), but there's no SigninManagerBase method that
@@ -103,7 +103,7 @@
   std::move(callback).Run(account_info, account_state);
 }
 
-void IdentityManagerImpl::GetPrimaryAccountWhenAvailable(
+void IdentityAccessorImpl::GetPrimaryAccountWhenAvailable(
     GetPrimaryAccountWhenAvailableCallback callback) {
   AccountInfo account_info = signin_manager_->GetAuthenticatedAccountInfo();
   AccountState account_state = GetStateOfAccount(account_info);
@@ -120,7 +120,7 @@
   std::move(callback).Run(account_info, account_state);
 }
 
-void IdentityManagerImpl::GetAccountInfoFromGaiaId(
+void IdentityAccessorImpl::GetAccountInfoFromGaiaId(
     const std::string& gaia_id,
     GetAccountInfoFromGaiaIdCallback callback) {
   AccountInfo account_info = account_tracker_->FindAccountInfoByGaiaId(gaia_id);
@@ -128,10 +128,10 @@
   std::move(callback).Run(account_info, account_state);
 }
 
-void IdentityManagerImpl::GetAccessToken(const std::string& account_id,
-                                         const ScopeSet& scopes,
-                                         const std::string& consumer_id,
-                                         GetAccessTokenCallback callback) {
+void IdentityAccessorImpl::GetAccessToken(const std::string& account_id,
+                                          const ScopeSet& scopes,
+                                          const std::string& consumer_id,
+                                          GetAccessTokenCallback callback) {
   std::unique_ptr<AccessTokenRequest> access_token_request =
       std::make_unique<AccessTokenRequest>(account_id, scopes, consumer_id,
                                            std::move(callback), token_service_,
@@ -141,17 +141,17 @@
       std::move(access_token_request);
 }
 
-void IdentityManagerImpl::OnRefreshTokenAvailable(
+void IdentityAccessorImpl::OnRefreshTokenAvailable(
     const std::string& account_id) {
   OnAccountStateChange(account_id);
 }
 
-void IdentityManagerImpl::GoogleSigninSucceeded(
+void IdentityAccessorImpl::GoogleSigninSucceeded(
     const AccountInfo& account_info) {
   OnAccountStateChange(account_info.account_id);
 }
 
-void IdentityManagerImpl::OnAccountStateChange(const std::string& account_id) {
+void IdentityAccessorImpl::OnAccountStateChange(const std::string& account_id) {
   AccountInfo account_info = account_tracker_->GetAccountInfo(account_id);
   AccountState account_state = GetStateOfAccount(account_info);
 
@@ -170,12 +170,12 @@
   }
 }
 
-void IdentityManagerImpl::AccessTokenRequestCompleted(
+void IdentityAccessorImpl::AccessTokenRequestCompleted(
     AccessTokenRequest* request) {
   access_token_requests_.erase(request);
 }
 
-AccountState IdentityManagerImpl::GetStateOfAccount(
+AccountState IdentityAccessorImpl::GetStateOfAccount(
     const AccountInfo& account_info) {
   AccountState account_state;
   account_state.has_refresh_token =
@@ -185,11 +185,11 @@
   return account_state;
 }
 
-void IdentityManagerImpl::OnSigninManagerShutdown() {
+void IdentityAccessorImpl::OnSigninManagerShutdown() {
   delete this;
 }
 
-void IdentityManagerImpl::OnConnectionError() {
+void IdentityAccessorImpl::OnConnectionError() {
   delete this;
 }
 
diff --git a/services/identity/identity_manager_impl.h b/services/identity/identity_accessor_impl.h
similarity index 81%
rename from services/identity/identity_manager_impl.h
rename to services/identity/identity_accessor_impl.h
index f7d3bbed..e99f875 100644
--- a/services/identity/identity_manager_impl.h
+++ b/services/identity/identity_accessor_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef SERVICES_IDENTITY_IDENTITY_MANAGER_IMPL_H_
-#define SERVICES_IDENTITY_IDENTITY_MANAGER_IMPL_H_
+#ifndef SERVICES_IDENTITY_IDENTITY_ACCESSOR_IMPL_H_
+#define SERVICES_IDENTITY_IDENTITY_ACCESSOR_IMPL_H_
 
 #include "base/callback_list.h"
 #include "components/signin/core/browser/account_info.h"
@@ -12,26 +12,26 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/identity/public/cpp/account_state.h"
 #include "services/identity/public/cpp/scope_set.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 
 class AccountTrackerService;
 
 namespace identity {
 
-class IdentityManagerImpl : public mojom::IdentityManager,
-                            public OAuth2TokenService::Observer,
-                            public SigninManagerBase::Observer {
+class IdentityAccessorImpl : public mojom::IdentityAccessor,
+                             public OAuth2TokenService::Observer,
+                             public SigninManagerBase::Observer {
  public:
-  static void Create(mojom::IdentityManagerRequest request,
+  static void Create(mojom::IdentityAccessorRequest request,
                      AccountTrackerService* account_tracker,
                      SigninManagerBase* signin_manager,
                      ProfileOAuth2TokenService* token_service);
 
-  IdentityManagerImpl(mojom::IdentityManagerRequest request,
-                      AccountTrackerService* account_tracker,
-                      SigninManagerBase* signin_manager,
-                      ProfileOAuth2TokenService* token_service);
-  ~IdentityManagerImpl() override;
+  IdentityAccessorImpl(mojom::IdentityAccessorRequest request,
+                       AccountTrackerService* account_tracker,
+                       SigninManagerBase* signin_manager,
+                       ProfileOAuth2TokenService* token_service);
+  ~IdentityAccessorImpl() override;
 
  private:
   // Makes an access token request to the OAuth2TokenService on behalf of a
@@ -43,7 +43,7 @@
                        const std::string& consumer_id,
                        GetAccessTokenCallback consumer_callback,
                        ProfileOAuth2TokenService* token_service,
-                       IdentityManagerImpl* manager);
+                       IdentityAccessorImpl* manager);
     ~AccessTokenRequest() override;
 
    private:
@@ -63,12 +63,12 @@
     ProfileOAuth2TokenService* token_service_;
     std::unique_ptr<OAuth2TokenService::Request> token_service_request_;
     GetAccessTokenCallback consumer_callback_;
-    IdentityManagerImpl* manager_;
+    IdentityAccessorImpl* manager_;
   };
   using AccessTokenRequests =
       std::map<AccessTokenRequest*, std::unique_ptr<AccessTokenRequest>>;
 
-  // mojom::IdentityManager:
+  // mojom::IdentityAccessor:
   void GetPrimaryAccountInfo(GetPrimaryAccountInfoCallback callback) override;
   void GetPrimaryAccountWhenAvailable(
       GetPrimaryAccountWhenAvailableCallback callback) override;
@@ -98,7 +98,7 @@
 
   // Called when |signin_manager_| is shutting down. Destroys this instance,
   // since this instance can't outlive the signin classes that it is depending
-  // on. Note that once IdentityManagerImpl manages the lifetime of its
+  // on. Note that once IdentityAccessorImpl manages the lifetime of its
   // dependencies internally, this will no longer be necessary.
   void OnSigninManagerShutdown();
 
@@ -106,7 +106,7 @@
   // since it's no longer needed.
   void OnConnectionError();
 
-  mojo::Binding<mojom::IdentityManager> binding_;
+  mojo::Binding<mojom::IdentityAccessor> binding_;
   AccountTrackerService* account_tracker_;
   SigninManagerBase* signin_manager_;
   ProfileOAuth2TokenService* token_service_;
@@ -125,4 +125,4 @@
 
 }  // namespace identity
 
-#endif  // SERVICES_IDENTITY_IDENTITY_MANAGER_IMPL_H_
+#endif  // SERVICES_IDENTITY_IDENTITY_ACCESSOR_IMPL_H_
diff --git a/services/identity/identity_manager_impl_unittest.cc b/services/identity/identity_accessor_impl_unittest.cc
similarity index 77%
rename from services/identity/identity_manager_impl_unittest.cc
rename to services/identity/identity_accessor_impl_unittest.cc
index fc3b7b1..e76b7af 100644
--- a/services/identity/identity_manager_impl_unittest.cc
+++ b/services/identity/identity_accessor_impl_unittest.cc
@@ -17,7 +17,7 @@
 #include "services/identity/public/cpp/scope_set.h"
 #include "services/identity/public/mojom/account.mojom.h"
 #include "services/identity/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/test/test_connector_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -30,9 +30,9 @@
 const char kTestRefreshToken[] = "dummy-refresh-token";
 const char kTestAccessToken[] = "access_token";
 
-class IdentityManagerImplTest : public testing::Test {
+class IdentityAccessorImplTest : public testing::Test {
  public:
-  IdentityManagerImplTest()
+  IdentityAccessorImplTest()
       : signin_client_(&pref_service_),
         token_service_(&pref_service_),
 #if defined(OS_CHROMEOS)
@@ -58,7 +58,7 @@
   }
 
   void TearDown() override {
-    // Shut down the SigninManager so that the IdentityManagerImpl doesn't end
+    // Shut down the SigninManager so that the IdentityAccessorImpl doesn't end
     // up outliving it.
     signin_manager_.Shutdown();
   }
@@ -108,30 +108,30 @@
   }
 
  protected:
-  mojom::IdentityManager* GetIdentityManagerImpl() {
-    if (!identity_manager_) {
+  mojom::IdentityAccessor* GetIdentityAccessorImpl() {
+    if (!identity_accessor_) {
       test_connector_factory_.GetDefaultConnector()->BindInterface(
-          mojom::kServiceName, &identity_manager_);
+          mojom::kServiceName, &identity_accessor_);
     }
-    return identity_manager_.get();
+    return identity_accessor_.get();
   }
 
-  void ResetIdentityManagerImpl() { identity_manager_.reset(); }
+  void ResetIdentityAccessorImpl() { identity_accessor_.reset(); }
 
-  void FlushIdentityManagerImplForTesting() {
-    GetIdentityManagerImpl();
-    identity_manager_.FlushForTesting();
+  void FlushIdentityAccessorImplForTesting() {
+    GetIdentityAccessorImpl();
+    identity_accessor_.FlushForTesting();
   }
 
-  void SetIdentityManagerImplConnectionErrorHandler(
+  void SetIdentityAccessorImplConnectionErrorHandler(
       base::RepeatingClosure handler) {
-    GetIdentityManagerImpl();
-    identity_manager_.set_connection_error_handler(handler);
+    GetIdentityAccessorImpl();
+    identity_accessor_.set_connection_error_handler(handler);
   }
 
   base::test::ScopedTaskEnvironment task_environemnt_;
 
-  mojom::IdentityManagerPtr identity_manager_;
+  mojom::IdentityAccessorPtr identity_accessor_;
   base::Optional<AccountInfo> primary_account_info_;
   AccountState primary_account_state_;
   base::Optional<AccountInfo> account_info_from_gaia_id_;
@@ -157,32 +157,32 @@
   service_manager::TestConnectorFactory test_connector_factory_;
   IdentityService service_;
 
-  DISALLOW_COPY_AND_ASSIGN(IdentityManagerImplTest);
+  DISALLOW_COPY_AND_ASSIGN(IdentityAccessorImplTest);
 };
 
-// Tests that it is not possible to connect to the Identity Manager if
+// Tests that it is not possible to connect to the IdentityAccessor if
 // initiated after SigninManager shutdown.
-TEST_F(IdentityManagerImplTest, SigninManagerShutdownBeforeConnection) {
+TEST_F(IdentityAccessorImplTest, SigninManagerShutdownBeforeConnection) {
   AccountInfo sentinel;
   sentinel.account_id = "sentinel";
   primary_account_info_ = sentinel;
 
   // Ensure that the Identity Service has actually been created before
   // invoking SigninManagerBase::Shutdown(), since otherwise this test will
-  // spin forever. Then reset the Identity Manager so that the next request
+  // spin forever. Then reset the IdentityAccessor so that the next request
   // makes a fresh connection.
-  FlushIdentityManagerImplForTesting();
-  ResetIdentityManagerImpl();
+  FlushIdentityAccessorImplForTesting();
+  ResetIdentityAccessorImpl();
 
-  // Make a call to connect to the IdentityManagerImpl *after* SigninManager
+  // Make a call to connect to the IdentityAccessorImpl *after* SigninManager
   // shutdown; it should get notified of an error when the Identity Service
   // drops the connection.
   signin_manager()->Shutdown();
   base::RunLoop run_loop;
-  SetIdentityManagerImplConnectionErrorHandler(run_loop.QuitClosure());
+  SetIdentityAccessorImplConnectionErrorHandler(run_loop.QuitClosure());
 
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
 
@@ -191,50 +191,51 @@
   EXPECT_EQ("sentinel", primary_account_info_->account_id);
 }
 
-// Tests that the Identity Manager destroys itself on SigninManager shutdown.
-TEST_F(IdentityManagerImplTest, SigninManagerShutdownAfterConnection) {
+// Tests that the IdentityAccessor destroys itself on SigninManager shutdown.
+TEST_F(IdentityAccessorImplTest, SigninManagerShutdownAfterConnection) {
   base::RunLoop run_loop;
-  SetIdentityManagerImplConnectionErrorHandler(run_loop.QuitClosure());
+  SetIdentityAccessorImplConnectionErrorHandler(run_loop.QuitClosure());
 
-  // Ensure that the IdentityManagerImpl instance has actually been created
+  // Ensure that the IdentityAccessorImpl instance has actually been created
   // before invoking SigninManagerBase::Shutdown(), since otherwise this test
   // will spin forever.
-  FlushIdentityManagerImplForTesting();
+  FlushIdentityAccessorImplForTesting();
   signin_manager()->Shutdown();
   run_loop.Run();
 }
 
-// Tests that the Identity Manager properly handles its own destruction in the
+// Tests that the IdentityAccessor properly handles its own destruction in the
 // case where there is an active consumer request (i.e., a pending callback from
 // a Mojo call). In particular, this flow should not cause a DCHECK to fire in
 // debug mode.
-TEST_F(IdentityManagerImplTest, IdentityManagerImplShutdownWithActiveRequest) {
+TEST_F(IdentityAccessorImplTest,
+       IdentityAccessorImplShutdownWithActiveRequest) {
   base::RunLoop run_loop;
-  SetIdentityManagerImplConnectionErrorHandler(run_loop.QuitClosure());
+  SetIdentityAccessorImplConnectionErrorHandler(run_loop.QuitClosure());
 
-  // Call a method on the IdentityManagerImpl that will cause it to store a
+  // Call a method on the IdentityAccessorImpl that will cause it to store a
   // pending callback. This callback will never be invoked, so just pass dummy
   // arguments to it.
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), base::RepeatingClosure(), nullptr, nullptr));
 
-  // Ensure that the IdentityManagerImpl has received the above call before
+  // Ensure that the IdentityAccessorImpl has received the above call before
   // invoking SigninManagerBase::Shutdown(), as otherwise this test is
   // pointless.
-  FlushIdentityManagerImplForTesting();
+  FlushIdentityAccessorImplForTesting();
 
-  // This flow is what would cause a DCHECK to fire if IdentityManagerImpl is
+  // This flow is what would cause a DCHECK to fire if IdentityAccessorImpl is
   // not properly closing its binding on shutdown.
   signin_manager()->Shutdown();
   run_loop.Run();
 }
 
 // Check that the primary account info is null if not signed in.
-TEST_F(IdentityManagerImplTest, GetPrimaryAccountInfoNotSignedIn) {
+TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoNotSignedIn) {
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_FALSE(primary_account_info_);
@@ -242,11 +243,11 @@
 
 // Check that the primary account info has expected values if signed in without
 // a refresh token available.
-TEST_F(IdentityManagerImplTest, GetPrimaryAccountInfoSignedInNoRefreshToken) {
+TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInNoRefreshToken) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(primary_account_info_);
@@ -260,13 +261,13 @@
 
 // Check that the primary account info has expected values if signed in with a
 // refresh token available.
-TEST_F(IdentityManagerImplTest, GetPrimaryAccountInfoSignedInRefreshToken) {
+TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInRefreshToken) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   token_service()->UpdateCredentials(
       signin_manager()->GetAuthenticatedAccountId(), kTestRefreshToken);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(primary_account_info_);
@@ -280,7 +281,7 @@
 
 // Check that GetPrimaryAccountWhenAvailable() returns immediately in the
 // case where the primary account is available when the call is received.
-TEST_F(IdentityManagerImplTest, GetPrimaryAccountWhenAvailableSignedIn) {
+TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableSignedIn) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   token_service()->UpdateCredentials(
       signin_manager()->GetAuthenticatedAccountId(), kTestRefreshToken);
@@ -288,8 +289,8 @@
   AccountInfo account_info;
   AccountState account_state;
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info), base::Unretained(&account_state)));
   run_loop.Run();
@@ -305,22 +306,22 @@
 // Check that GetPrimaryAccountWhenAvailable() returns the expected account
 // info in the case where the primary account is made available *after* the
 // call is received.
-TEST_F(IdentityManagerImplTest, GetPrimaryAccountWhenAvailableSignInLater) {
+TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableSignInLater) {
   AccountInfo account_info;
   AccountState account_state;
 
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info), base::Unretained(&account_state)));
 
   // Verify that the primary account info is not currently available (this also
-  // serves to ensure that the preceding call has been received by the Identity
-  // Manager before proceeding).
+  // serves to ensure that the preceding call has been received by the
+  // IdentityAccessor before proceeding).
   base::RunLoop run_loop2;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop2.QuitClosure()));
   run_loop2.Run();
   EXPECT_FALSE(primary_account_info_);
@@ -343,7 +344,7 @@
 // Check that GetPrimaryAccountWhenAvailable() returns the expected account
 // info in the case where signin is done before the call is received but the
 // refresh token is made available only *after* the call is received.
-TEST_F(IdentityManagerImplTest,
+TEST_F(IdentityAccessorImplTest,
        GetPrimaryAccountWhenAvailableTokenAvailableLater) {
   AccountInfo account_info;
   AccountState account_state;
@@ -351,18 +352,18 @@
   // Sign in, but don't set the refresh token yet.
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info), base::Unretained(&account_state)));
 
   // Verify that the primary account info is present, but that the primary
   // account is not yet considered available (this also
-  // serves to ensure that the preceding call has been received by the Identity
-  // Manager before proceeding).
+  // serves to ensure that the preceding call has been received by the
+  // IdentityAccessor before proceeding).
   base::RunLoop run_loop2;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop2.QuitClosure()));
   run_loop2.Run();
 
@@ -391,7 +392,7 @@
 // relevant only on non-ChromeOS platforms, as the flow being tested here is not
 // possible on ChromeOS.
 #if !defined(OS_CHROMEOS)
-TEST_F(IdentityManagerImplTest,
+TEST_F(IdentityAccessorImplTest,
        GetPrimaryAccountWhenAvailableAuthenticationAvailableLater) {
   AccountInfo account_info;
   AccountState account_state;
@@ -401,20 +402,20 @@
       account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
   token_service()->UpdateCredentials(account_id_to_use, kTestRefreshToken);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info), base::Unretained(&account_state)));
 
   // Verify that the account is present and has a refresh token, but that the
   // primary account is not yet considered available (this also serves to ensure
-  // that the preceding call has been received by the Identity Manager before
+  // that the preceding call has been received by the IdentityAccessor before
   // proceeding).
   base::RunLoop run_loop2;
-  GetIdentityManagerImpl()->GetAccountInfoFromGaiaId(
+  GetIdentityAccessorImpl()->GetAccountInfoFromGaiaId(
       kTestGaiaId,
       base::BindRepeating(
-          &IdentityManagerImplTest::OnReceivedAccountInfoFromGaiaId,
+          &IdentityAccessorImplTest::OnReceivedAccountInfoFromGaiaId,
           base::Unretained(this), run_loop2.QuitClosure()));
   run_loop2.Run();
 
@@ -448,30 +449,30 @@
 // Check that GetPrimaryAccountWhenAvailable() returns the expected account
 // info to all callers in the case where the primary account is made available
 // after multiple overlapping calls have been received.
-TEST_F(IdentityManagerImplTest,
+TEST_F(IdentityAccessorImplTest,
        GetPrimaryAccountWhenAvailableOverlappingCalls) {
   AccountInfo account_info1;
   AccountState account_state1;
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info1), base::Unretained(&account_state1)));
 
   AccountInfo account_info2;
   AccountState account_state2;
   base::RunLoop run_loop2;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop2.QuitClosure(),
       base::Unretained(&account_info2), base::Unretained(&account_state2)));
 
   // Verify that the primary account info is not currently available (this also
-  // serves to ensure that the preceding call has been received by the Identity
-  // Manager before proceeding).
+  // serves to ensure that the preceding call has been received by the
+  // IdentityAccessor before proceeding).
   base::RunLoop run_loop3;
-  GetIdentityManagerImpl()->GetPrimaryAccountInfo(base::BindRepeating(
-      &IdentityManagerImplTest::OnReceivedPrimaryAccountInfo,
+  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
+      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
       base::Unretained(this), run_loop3.QuitClosure()));
   run_loop3.Run();
   EXPECT_FALSE(primary_account_info_);
@@ -501,7 +502,7 @@
 
 // Check that GetPrimaryAccountWhenAvailable() doesn't return the account as
 // available if the refresh token has an auth error.
-TEST_F(IdentityManagerImplTest,
+TEST_F(IdentityAccessorImplTest,
        GetPrimaryAccountWhenAvailableRefreshTokenHasAuthError) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   token_service()->UpdateCredentials(
@@ -514,13 +515,13 @@
   AccountInfo account_info;
   AccountState account_state;
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
-      &IdentityManagerImplTest::OnPrimaryAccountAvailable,
+  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
+      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
       base::Unretained(this), run_loop.QuitClosure(),
       base::Unretained(&account_info), base::Unretained(&account_state)));
 
-  // Flush the Identity Manager and check that the callback didn't fire.
-  FlushIdentityManagerImplForTesting();
+  // Flush the IdentityAccessor and check that the callback didn't fire.
+  FlushIdentityAccessorImplForTesting();
   EXPECT_TRUE(account_info.account_id.empty());
 
   // Clear the auth error, update credentials, and check that the callback
@@ -541,12 +542,12 @@
 
 // Check that the account info for a given GAIA ID is null if that GAIA ID is
 // unknown.
-TEST_F(IdentityManagerImplTest, GetAccountInfoForUnknownGaiaID) {
+TEST_F(IdentityAccessorImplTest, GetAccountInfoForUnknownGaiaID) {
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetAccountInfoFromGaiaId(
+  GetIdentityAccessorImpl()->GetAccountInfoFromGaiaId(
       kTestGaiaId,
       base::BindRepeating(
-          &IdentityManagerImplTest::OnReceivedAccountInfoFromGaiaId,
+          &IdentityAccessorImplTest::OnReceivedAccountInfoFromGaiaId,
           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_FALSE(account_info_from_gaia_id_);
@@ -554,14 +555,14 @@
 
 // Check that the account info for a given GAIA ID has expected values if that
 // GAIA ID is known and there is no refresh token available for it.
-TEST_F(IdentityManagerImplTest, GetAccountInfoForKnownGaiaIdNoRefreshToken) {
+TEST_F(IdentityAccessorImplTest, GetAccountInfoForKnownGaiaIdNoRefreshToken) {
   std::string account_id =
       account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetAccountInfoFromGaiaId(
+  GetIdentityAccessorImpl()->GetAccountInfoFromGaiaId(
       kTestGaiaId,
       base::BindRepeating(
-          &IdentityManagerImplTest::OnReceivedAccountInfoFromGaiaId,
+          &IdentityAccessorImplTest::OnReceivedAccountInfoFromGaiaId,
           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(account_info_from_gaia_id_);
@@ -574,15 +575,15 @@
 
 // Check that the account info for a given GAIA ID has expected values if that
 // GAIA ID is known and has a refresh token available.
-TEST_F(IdentityManagerImplTest, GetAccountInfoForKnownGaiaIdRefreshToken) {
+TEST_F(IdentityAccessorImplTest, GetAccountInfoForKnownGaiaIdRefreshToken) {
   std::string account_id =
       account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail);
   token_service()->UpdateCredentials(account_id, kTestRefreshToken);
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetAccountInfoFromGaiaId(
+  GetIdentityAccessorImpl()->GetAccountInfoFromGaiaId(
       kTestGaiaId,
       base::BindRepeating(
-          &IdentityManagerImplTest::OnReceivedAccountInfoFromGaiaId,
+          &IdentityAccessorImplTest::OnReceivedAccountInfoFromGaiaId,
           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(account_info_from_gaia_id_);
@@ -595,11 +596,11 @@
 
 // Check that the expected error is received if requesting an access token when
 // not signed in.
-TEST_F(IdentityManagerImplTest, GetAccessTokenNotSignedIn) {
+TEST_F(IdentityAccessorImplTest, GetAccessTokenNotSignedIn) {
   base::RunLoop run_loop;
-  GetIdentityManagerImpl()->GetAccessToken(
+  GetIdentityAccessorImpl()->GetAccessToken(
       kTestGaiaId, ScopeSet(), "dummy_consumer",
-      base::BindRepeating(&IdentityManagerImplTest::OnReceivedAccessToken,
+      base::BindRepeating(&IdentityAccessorImplTest::OnReceivedAccessToken,
                           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_FALSE(access_token_);
@@ -609,16 +610,16 @@
 
 // Check that the expected access token is received if requesting an access
 // token when signed in.
-TEST_F(IdentityManagerImplTest, GetAccessTokenSignedIn) {
+TEST_F(IdentityAccessorImplTest, GetAccessTokenSignedIn) {
   signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
   std::string account_id = signin_manager()->GetAuthenticatedAccountId();
   token_service()->UpdateCredentials(account_id, kTestRefreshToken);
   token_service()->set_auto_post_fetch_response_on_message_loop(true);
   base::RunLoop run_loop;
 
-  GetIdentityManagerImpl()->GetAccessToken(
+  GetIdentityAccessorImpl()->GetAccessToken(
       account_id, ScopeSet(), "dummy_consumer",
-      base::BindRepeating(&IdentityManagerImplTest::OnReceivedAccessToken,
+      base::BindRepeating(&IdentityAccessorImplTest::OnReceivedAccessToken,
                           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
   EXPECT_TRUE(access_token_);
diff --git a/services/identity/identity_service.cc b/services/identity/identity_service.cc
index 7a1cc02..fe55d4a 100644
--- a/services/identity/identity_service.cc
+++ b/services/identity/identity_service.cc
@@ -5,7 +5,7 @@
 #include "services/identity/identity_service.h"
 
 #include "base/bind.h"
-#include "services/identity/identity_manager_impl.h"
+#include "services/identity/identity_accessor_impl.h"
 
 namespace identity {
 
@@ -17,7 +17,7 @@
       account_tracker_(account_tracker),
       signin_manager_(signin_manager),
       token_service_(token_service) {
-  registry_.AddInterface<mojom::IdentityManager>(
+  registry_.AddInterface<mojom::IdentityAccessor>(
       base::Bind(&IdentityService::Create, base::Unretained(this)));
   signin_manager_shutdown_subscription_ =
       signin_manager_->RegisterOnShutdownCallback(
@@ -49,13 +49,13 @@
   return (signin_manager_ == nullptr);
 }
 
-void IdentityService::Create(mojom::IdentityManagerRequest request) {
+void IdentityService::Create(mojom::IdentityAccessorRequest request) {
   // This instance cannot service requests if it has already been shut down.
   if (IsShutDown())
     return;
 
-  IdentityManagerImpl::Create(std::move(request), account_tracker_,
-                              signin_manager_, token_service_);
+  IdentityAccessorImpl::Create(std::move(request), account_tracker_,
+                               signin_manager_, token_service_);
 }
 
 }  // namespace identity
diff --git a/services/identity/identity_service.h b/services/identity/identity_service.h
index 27e2e17..6ece5d1 100644
--- a/services/identity/identity_service.h
+++ b/services/identity/identity_service.h
@@ -6,7 +6,7 @@
 #define SERVICES_IDENTITY_IDENTITY_SERVICE_H_
 
 #include "components/signin/core/browser/signin_manager_base.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/service.h"
 #include "services/service_manager/public/cpp/service_binding.h"
@@ -31,7 +31,7 @@
                        const std::string& interface_name,
                        mojo::ScopedMessagePipeHandle interface_pipe) override;
 
-  void Create(mojom::IdentityManagerRequest request);
+  void Create(mojom::IdentityAccessorRequest request);
 
   // Shuts down this instance, blocking it from serving any pending or future
   // requests. Safe to call multiple times; will be a no-op after the first
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc
index 5417618..9db5e16 100644
--- a/services/identity/public/cpp/identity_test_environment.cc
+++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -209,24 +209,6 @@
     FakeProfileOAuth2TokenService* token_service,
     SigninManagerBase* signin_manager,
     GaiaCookieManagerService* gaia_cookie_manager_service,
-    network::TestURLLoaderFactory* test_url_loader_factory)
-    : IdentityTestEnvironment(pref_service,
-                              account_tracker_service,
-                              account_fetcher_service,
-                              token_service,
-                              signin_manager,
-                              gaia_cookie_manager_service,
-                              test_url_loader_factory,
-                              /*dependency_owner=*/nullptr,
-                              /*identity_manager=*/nullptr) {}
-
-IdentityTestEnvironment::IdentityTestEnvironment(
-    PrefService* pref_service,
-    AccountTrackerService* account_tracker_service,
-    FakeAccountFetcherService* account_fetcher_service,
-    FakeProfileOAuth2TokenService* token_service,
-    SigninManagerBase* signin_manager,
-    GaiaCookieManagerService* gaia_cookie_manager_service,
     IdentityManager* identity_manager,
     network::TestURLLoaderFactory* test_url_loader_factory)
     : IdentityTestEnvironment(pref_service,
diff --git a/services/identity/public/cpp/identity_test_environment.h b/services/identity/public/cpp/identity_test_environment.h
index c4e8338..d63ad3d 100644
--- a/services/identity/public/cpp/identity_test_environment.h
+++ b/services/identity/public/cpp/identity_test_environment.h
@@ -70,22 +70,6 @@
           signin::AccountConsistencyMethod::kDisabled,
       TestSigninClient* test_signin_client = nullptr);
 
-  // Constructor that takes in instances of the dependencies of
-  // IdentityManager and constructs an IdentityManager instance from those
-  // dependencies. For use in contexts where those dependencies are still
-  // being used directly by the creator of this object (i.e., while a test is
-  // being incrementally converted). Prefer the above constructor, and switch to
-  // that constructor once possible (e.g., when an incremental conversion is
-  // completed). NOTE: The passed-in objects must all outlive this object.
-  IdentityTestEnvironment(
-      PrefService* pref_service,
-      AccountTrackerService* account_tracker_service,
-      FakeAccountFetcherService* account_fetcher_service,
-      FakeProfileOAuth2TokenService* token_service,
-      SigninManagerBase* signin_manager,
-      GaiaCookieManagerService* gaia_cookie_manager_service,
-      network::TestURLLoaderFactory* test_url_loader_factory = nullptr);
-
   ~IdentityTestEnvironment() override;
 
   // The IdentityManager instance associated with this instance.
diff --git a/services/identity/public/cpp/manifest.cc b/services/identity/public/cpp/manifest.cc
index ab7926d..40a3aff3 100644
--- a/services/identity/public/cpp/manifest.cc
+++ b/services/identity/public/cpp/manifest.cc
@@ -6,7 +6,7 @@
 
 #include "base/no_destructor.h"
 #include "services/identity/public/mojom/constants.mojom.h"
-#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/identity/public/mojom/identity_accessor.mojom.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
 namespace identity {
@@ -16,9 +16,9 @@
       service_manager::ManifestBuilder()
           .WithServiceName(mojom::kServiceName)
           .WithDisplayName("Identity Service")
-          .ExposeCapability("identity_manager",
+          .ExposeCapability("identity_accessor",
                             service_manager::Manifest::InterfaceList<
-                                mojom::IdentityManager>())
+                                mojom::IdentityAccessor>())
           .Build()};
   return *manifest;
 }
diff --git a/services/identity/public/mojom/BUILD.gn b/services/identity/public/mojom/BUILD.gn
index 1614d49b..ac8812d 100644
--- a/services/identity/public/mojom/BUILD.gn
+++ b/services/identity/public/mojom/BUILD.gn
@@ -10,7 +10,7 @@
     "account_info.mojom",
     "account_state.mojom",
     "google_service_auth_error.mojom",
-    "identity_manager.mojom",
+    "identity_accessor.mojom",
     "scope_set.mojom",
   ]
 
diff --git a/services/identity/public/mojom/identity_manager.mojom b/services/identity/public/mojom/identity_accessor.mojom
similarity index 98%
rename from services/identity/public/mojom/identity_manager.mojom
rename to services/identity/public/mojom/identity_accessor.mojom
index bfc8ccf..4f4f1b9 100644
--- a/services/identity/public/mojom/identity_manager.mojom
+++ b/services/identity/public/mojom/identity_accessor.mojom
@@ -12,7 +12,7 @@
 import "services/identity/public/mojom/scope_set.mojom";
 
 // Gives access to information about the user's Google accounts.
-interface IdentityManager {
+interface IdentityAccessor {
   // Returns the AccountInfo for the Google account that serves as the user's
   // primary account, or null if the user has no primary account (e.g., if they
   // are not signed in). |account_state| gives the current state of the account
diff --git a/services/network/cookie_manager.h b/services/network/cookie_manager.h
index aac75b5..9f19832e 100644
--- a/services/network/cookie_manager.h
+++ b/services/network/cookie_manager.h
@@ -114,6 +114,7 @@
   scoped_refptr<SessionCleanupChannelIDStore> session_cleanup_channel_id_store_;
   mojo::BindingSet<mojom::CookieManager> bindings_;
   std::vector<std::unique_ptr<ListenerRegistration>> listener_registrations_;
+  // Note: RestrictedCookieManager stores pointers to |cookie_settings_|.
   CookieSettings cookie_settings_;
 
   DISALLOW_COPY_AND_ASSIGN(CookieManager);
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index c02b285..9d225be 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -99,7 +99,7 @@
     const ResourceRequest& resource_request,
     mojom::URLLoaderClientPtr client,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
-  if (!IsSane(context_, resource_request)) {
+  if (!IsSane(resource_request)) {
     client->OnComplete(URLLoaderCompletionStatus(net::ERR_INVALID_ARGUMENT));
     return;
   }
@@ -140,8 +140,7 @@
     context_->DestroyURLLoaderFactory(this);
 }
 
-bool CorsURLLoaderFactory::IsSane(const NetworkContext* context,
-                                  const ResourceRequest& request) {
+bool CorsURLLoaderFactory::IsSane(const ResourceRequest& request) {
   // CORS needs a proper origin (including a unique opaque origin). If the
   // request doesn't have one, CORS cannot work.
   if (!request.request_initiator &&
@@ -163,21 +162,6 @@
     return false;
   }
 
-  if (context) {
-    net::HttpRequestHeaders::Iterator header_iterator(
-        request.cors_exempt_headers);
-    const auto& allowed_exempt_headers = context->cors_exempt_header_list();
-    while (header_iterator.GetNext()) {
-      if (allowed_exempt_headers.find(header_iterator.name()) !=
-          allowed_exempt_headers.end()) {
-        continue;
-      }
-      LOG(WARNING) << "|cors_exempt_headers| contains unexpected key: "
-                   << header_iterator.name();
-      return false;
-    }
-  }
-
   // TODO(yhirano): If the request mode is "no-cors", the redirect mode should
   // be "follow".
   return true;
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h
index a072867..490a05db 100644
--- a/services/network/cors/cors_url_loader_factory.h
+++ b/services/network/cors/cors_url_loader_factory.h
@@ -76,8 +76,7 @@
 
   void DeleteIfNeeded();
 
-  static bool IsSane(const NetworkContext* context,
-                     const ResourceRequest& request);
+  static bool IsSane(const ResourceRequest& request);
 
   mojo::BindingSet<mojom::URLLoaderFactory> bindings_;
 
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc
index 5693e1c4..3baaf03 100644
--- a/services/network/cors/preflight_controller.cc
+++ b/services/network/cors/preflight_controller.cc
@@ -85,6 +85,7 @@
   preflight_request->load_flags |= net::LOAD_DO_NOT_SEND_COOKIES;
   preflight_request->load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA;
   preflight_request->fetch_window_id = request.fetch_window_id;
+  preflight_request->render_frame_id = request.render_frame_id;
 
   preflight_request->headers.SetHeader(
       header_names::kAccessControlRequestMethod, request.method);
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc
index d6fcdfc..26fb40d2 100644
--- a/services/network/cors/preflight_controller_unittest.cc
+++ b/services/network/cors/preflight_controller_unittest.cc
@@ -192,6 +192,21 @@
   EXPECT_EQ(request.fetch_window_id, preflight->fetch_window_id);
 }
 
+TEST(PreflightControllerCreatePreflightRequestTest, RenderFrameId) {
+  ResourceRequest request;
+  request.fetch_request_mode = mojom::FetchRequestMode::kCors;
+  request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit;
+  request.request_initiator = url::Origin();
+  request.headers.SetHeader(net::HttpRequestHeaders::kContentType,
+                            "application/octet-stream");
+  request.render_frame_id = 99;
+
+  std::unique_ptr<ResourceRequest> preflight =
+      PreflightController::CreatePreflightRequestForTesting(request);
+
+  EXPECT_EQ(request.render_frame_id, preflight->render_frame_id);
+}
+
 class PreflightControllerTest : public testing::Test {
  public:
   PreflightControllerTest()
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 6de66bf..7d75e33a 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -549,7 +549,7 @@
   resource_scheduler_ =
       std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
 
-  InitializeCorsParams();
+  InitializeCorsOriginAccessList();
 }
 
 // TODO(mmenke): Share URLRequestContextBulder configuration between two
@@ -578,7 +578,7 @@
   resource_scheduler_ =
       std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
 
-  InitializeCorsParams();
+  InitializeCorsOriginAccessList();
 }
 
 NetworkContext::NetworkContext(NetworkService* network_service,
@@ -724,7 +724,8 @@
     const url::Origin& origin) {
   restricted_cookie_manager_bindings_.AddBinding(
       std::make_unique<RestrictedCookieManager>(
-          url_request_context_->cookie_store(), origin),
+          url_request_context_->cookie_store(),
+          &cookie_manager_->cookie_settings(), origin),
       std::move(request));
 }
 
@@ -2315,7 +2316,7 @@
 }
 #endif
 
-void NetworkContext::InitializeCorsParams() {
+void NetworkContext::InitializeCorsOriginAccessList() {
   for (const auto& pattern : params_->cors_origin_access_list) {
     url::Origin origin = url::Origin::Create(GURL(pattern->source_origin));
     cors_origin_access_list_.SetAllowListForOrigin(origin,
@@ -2323,8 +2324,6 @@
     cors_origin_access_list_.SetBlockListForOrigin(origin,
                                                    pattern->block_patterns);
   }
-  for (const auto& key : params_->cors_exempt_header_list)
-    cors_exempt_header_list_.insert(key);
 }
 
 }  // namespace network
diff --git a/services/network/network_context.h b/services/network/network_context.h
index a93ab1d4..ad9e10f 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <set>
 #include <string>
-#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -152,10 +151,6 @@
 
   CookieManager* cookie_manager() { return cookie_manager_.get(); }
 
-  const std::unordered_set<std::string>& cors_exempt_header_list() const {
-    return cors_exempt_header_list_;
-  }
-
 #if defined(OS_ANDROID)
   base::android::ApplicationStatusListener* app_status_listener() const {
     return app_status_listener_.get();
@@ -444,7 +439,7 @@
   void OnSetExpectCTTestReportFailure();
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
 
-  void InitializeCorsParams();
+  void InitializeCorsOriginAccessList();
 
   NetworkService* const network_service_;
 
@@ -513,6 +508,8 @@
 
   mojo::StrongBindingSet<mojom::NetLogExporter> net_log_exporter_bindings_;
 
+  // Ordering: this must be after |cookie_manager_| since it points to its
+  // CookieSettings object.
   mojo::StrongBindingSet<mojom::RestrictedCookieManager>
       restricted_cookie_manager_bindings_;
 
@@ -579,10 +576,6 @@
   // Manages allowed origin access lists.
   cors::OriginAccessList cors_origin_access_list_;
 
-  // Manages header keys that are allowed to be used in
-  // ResourceRequest::cors_exempt_headers.
-  std::unordered_set<std::string> cors_exempt_header_list_;
-
   // Manages CORS preflight requests and its cache.
   cors::PreflightController cors_preflight_controller_;
 
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index bd4b62f..df730291 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -84,14 +84,17 @@
 constexpr auto kUpdateLoadStatesInterval =
     base::TimeDelta::FromMilliseconds(250);
 
-std::unique_ptr<net::NetworkChangeNotifier>
-CreateNetworkChangeNotifierIfNeeded() {
+std::unique_ptr<net::NetworkChangeNotifier> CreateNetworkChangeNotifierIfNeeded(
+    net::NetworkChangeNotifier::ConnectionType initial_connection_type,
+    net::NetworkChangeNotifier::ConnectionSubtype initial_connection_subtype) {
   // There is a global singleton net::NetworkChangeNotifier if NetworkService
   // is running inside of the browser process.
   if (!net::NetworkChangeNotifier::HasNetworkChangeNotifier()) {
-#if defined(OS_ANDROID)
-    // On Android, network change events are synced from the browser process.
-    return std::make_unique<net::NetworkChangeNotifierPosix>();
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+    // On Android and ChromeOS, network change events are synced from the
+    // browser process.
+    return std::make_unique<net::NetworkChangeNotifierPosix>(
+        initial_connection_type, initial_connection_subtype);
 #elif defined(OS_IOS) || defined(OS_FUCHSIA)
     // iOS doesn't embed //content. Fuchsia doesn't have an implementation yet.
     // TODO(xunjieli): Figure out what to do for these 2 platforms.
@@ -218,7 +221,8 @@
     std::unique_ptr<service_manager::BinderRegistry> registry,
     mojom::NetworkServiceRequest request,
     net::NetLog* net_log,
-    service_manager::mojom::ServiceRequest service_request)
+    service_manager::mojom::ServiceRequest service_request,
+    bool delay_initialization_until_set_client)
     : registry_(std::move(registry)), binding_(this) {
   DCHECK(!g_network_service);
   g_network_service = this;
@@ -239,6 +243,22 @@
     Bind(std::move(request));
   }
 
+  if (net_log) {
+    net_log_ = net_log;
+  } else {
+    net_log_ = GetNetLog();
+  }
+
+  if (!delay_initialization_until_set_client)
+    Initialize(mojom::NetworkServiceParams::New());
+}
+
+void NetworkService::Initialize(mojom::NetworkServiceParamsPtr params) {
+  if (initialized_)
+    return;
+
+  initialized_ = true;
+
 #if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
   // Make sure OpenSSL is initialized before using it to histogram data.
   crypto::EnsureOpenSSLInit();
@@ -267,13 +287,11 @@
       command_line->HasSwitch(switches::kIgnoreCertificateErrorsSPKIList));
 
   network_change_manager_ = std::make_unique<NetworkChangeManager>(
-      CreateNetworkChangeNotifierIfNeeded());
-
-  if (net_log) {
-    net_log_ = net_log;
-  } else {
-    net_log_ = GetNetLog();
-  }
+      CreateNetworkChangeNotifierIfNeeded(
+          net::NetworkChangeNotifier::ConnectionType(
+              params->initial_connection_type),
+          net::NetworkChangeNotifier::ConnectionSubtype(
+              params->initial_connection_subtype)));
 
   trace_net_log_observer_.WatchForTraceStart(net_log_);
 
@@ -390,8 +408,10 @@
   return net::CreateNetLogEntriesForActiveObjects(contexts, observer);
 }
 
-void NetworkService::SetClient(mojom::NetworkServiceClientPtr client) {
+void NetworkService::SetClient(mojom::NetworkServiceClientPtr client,
+                               mojom::NetworkServiceParamsPtr params) {
   client_ = std::move(client);
+  Initialize(std::move(params));
 }
 
 void NetworkService::StartNetLog(base::File file,
diff --git a/services/network/network_service.h b/services/network/network_service.h
index 847e836f..7060773 100644
--- a/services/network/network_service.h
+++ b/services/network/network_service.h
@@ -77,7 +77,8 @@
       std::unique_ptr<service_manager::BinderRegistry> registry,
       mojom::NetworkServiceRequest request = nullptr,
       net::NetLog* net_log = nullptr,
-      service_manager::mojom::ServiceRequest service_request = nullptr);
+      service_manager::mojom::ServiceRequest service_request = nullptr,
+      bool delay_initialization_until_set_client = false);
 
   ~NetworkService() override;
 
@@ -112,6 +113,10 @@
   // constructor.
   void Bind(mojom::NetworkServiceRequest request);
 
+  // Allows the browser process to synchronously initialize the NetworkService.
+  // TODO(jam): remove this once the old path is gone.
+  void Initialize(mojom::NetworkServiceParamsPtr params);
+
   // Creates a NetworkService instance on the current thread, optionally using
   // the passed-in NetLog. Does not take ownership of |net_log|. Must be
   // destroyed before |net_log|.
@@ -147,7 +152,8 @@
       net::NetLog::ThreadSafeObserver* observer);
 
   // mojom::NetworkService implementation:
-  void SetClient(mojom::NetworkServiceClientPtr client) override;
+  void SetClient(mojom::NetworkServiceClientPtr client,
+                 mojom::NetworkServiceParamsPtr params) override;
   void StartNetLog(base::File file,
                    mojom::NetLogCaptureMode capture_mode,
                    base::Value constants) override;
@@ -260,6 +266,8 @@
 
   service_manager::ServiceBinding service_binding_{this};
 
+  bool initialized_ = false;
+
   net::NetLog* net_log_ = nullptr;
 
   std::unique_ptr<net::FileNetLogObserver> file_net_log_observer_;
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc
index 8ca4571..4d643e8 100644
--- a/services/network/network_service_unittest.cc
+++ b/services/network/network_service_unittest.cc
@@ -1514,7 +1514,8 @@
   mojom::NetworkServiceClientPtr client_ptr;
   auto client_impl = std::make_unique<ClearSiteDataNetworkServiceClient>(
       mojo::MakeRequest(&client_ptr));
-  service()->SetClient(std::move(client_ptr));
+  service()->SetClient(std::move(client_ptr),
+                       network::mojom::NetworkServiceParams::New());
   url = https_server()->GetURL("/bar");
   url = AddQuery(url, "header", kClearCookiesHeader);
   EXPECT_EQ(0, client_impl->on_clear_site_data_counter());
@@ -1532,7 +1533,8 @@
   mojom::NetworkServiceClientPtr client_ptr;
   auto client_impl = std::make_unique<ClearSiteDataNetworkServiceClient>(
       mojo::MakeRequest(&client_ptr));
-  service()->SetClient(std::move(client_ptr));
+  service()->SetClient(std::move(client_ptr),
+                       network::mojom::NetworkServiceParams::New());
 
   // |passed_header_value| are only checked if |should_call_client| is true.
   const struct TestCase {
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index 454d425..5ac1cf9 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -22,8 +22,8 @@
          referrer_policy == request.referrer_policy &&
          is_prerendering == request.is_prerendering &&
          headers.ToString() == request.headers.ToString() &&
-         cors_exempt_headers.ToString() ==
-             request.cors_exempt_headers.ToString() &&
+         requested_with_header == request.requested_with_header &&
+         client_data_header == request.client_data_header &&
          load_flags == request.load_flags &&
          allow_credentials == request.allow_credentials &&
          plugin_child_id == request.plugin_child_id &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index 11df12af..346344d0 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -47,7 +47,8 @@
       net::URLRequest::NEVER_CLEAR_REFERRER;
   bool is_prerendering = false;
   net::HttpRequestHeaders headers;
-  net::HttpRequestHeaders cors_exempt_headers;
+  std::string requested_with_header;
+  std::string client_data_header;
   int load_flags = 0;
   bool allow_credentials = true;
   int plugin_child_id = -1;
diff --git a/services/network/public/cpp/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc
index f5a4b17..dff4fea 100644
--- a/services/network/public/cpp/simple_url_loader_unittest.cc
+++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -584,7 +584,8 @@
     network::mojom::NetworkServiceClientPtr network_service_client_ptr;
     network_service_client_ = std::make_unique<TestNetworkServiceClient>(
         mojo::MakeRequest(&network_service_client_ptr));
-    network_service_ptr->SetClient(std::move(network_service_client_ptr));
+    network_service_ptr->SetClient(std::move(network_service_client_ptr),
+                                   network::mojom::NetworkServiceParams::New());
 
     mojom::URLLoaderFactoryParamsPtr params =
         mojom::URLLoaderFactoryParams::New();
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index be488ca..f67fb04 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -162,7 +162,8 @@
       !data.ReadReferrer(&out->referrer) ||
       !data.ReadReferrerPolicy(&out->referrer_policy) ||
       !data.ReadHeaders(&out->headers) ||
-      !data.ReadCorsExemptHeaders(&out->cors_exempt_headers) ||
+      !data.ReadRequestedWithHeader(&out->requested_with_header) ||
+      !data.ReadClientDataHeader(&out->client_data_header) ||
       !data.ReadPriority(&out->priority) ||
       !data.ReadCorsPreflightPolicy(&out->cors_preflight_policy) ||
       !data.ReadFetchRequestMode(&out->fetch_request_mode) ||
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index 276e03b4..20dd802 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -85,9 +85,13 @@
       const network::ResourceRequest& request) {
     return request.headers;
   }
-  static const net::HttpRequestHeaders& cors_exempt_headers(
+  static const std::string& requested_with_header(
       const network::ResourceRequest& request) {
-    return request.cors_exempt_headers;
+    return request.requested_with_header;
+  }
+  static const std::string& client_data_header(
+      const network::ResourceRequest& request) {
+    return request.client_data_header;
   }
   static int32_t load_flags(const network::ResourceRequest& request) {
     return request.load_flags;
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
index bd41643..246a2c3 100644
--- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -57,7 +57,8 @@
       net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN;
   original.is_prerendering = false;
   original.headers.SetHeader("Accept", "text/xml");
-  original.cors_exempt_headers.SetHeader("X-Requested-With", "ForTesting");
+  original.requested_with_header = "dummy_requested_with_header";
+  original.client_data_header = "dummy_client_data_header";
   original.load_flags = 3;
   original.allow_credentials = true;
   original.plugin_child_id = 5;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 541496e..b994ea5b 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -347,10 +347,6 @@
   // Specifies the initial set of allowed and blocked origins for the
   // URLLoaderFactory consumers to access beyond the same-origin-policy.
   array<CorsOriginAccessPatterns> cors_origin_access_list;
-
-  // Specifies header keys that are allowed to be used in
-  // network::url_request.cors_exempt_headers.
-  array<string> cors_exempt_header_list;
 };
 
 struct NetworkConditions {
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
index e991c54..a025436 100644
--- a/services/network/public/mojom/network_service.mojom
+++ b/services/network/public/mojom/network_service.mojom
@@ -235,12 +235,18 @@
   mojo_base.mojom.FilePath user_data_path;
 };
 
+// Parameters needed to initialize the network service.
+struct NetworkServiceParams {
+  ConnectionType initial_connection_type = CONNECTION_UNKNOWN;
+  ConnectionSubtype initial_connection_subtype = SUBTYPE_UNKNOWN;
+};
+
 // Browser interface to the network service.
 interface NetworkService {
   // Sets client used by all |NetworkContext|s creating by |NetworkService|.
   // Pending requests may hang if the |client| pipe is closed before they
   // complete.
-  SetClient(NetworkServiceClient client);
+  SetClient(NetworkServiceClient client, NetworkServiceParams params);
 
   // Starts observing the NetLog event stream and writing entries to |file|.
   // |constants| is a legend used for decoding constant values in the log; it
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom
index a269edda..049da805 100644
--- a/services/network/public/mojom/url_loader.mojom
+++ b/services/network/public/mojom/url_loader.mojom
@@ -118,21 +118,19 @@
   // Additional HTTP request headers.
   HttpRequestHeaders headers;
 
-  // HTTP request headers that has been internally added. Some consumers want to
-  // set additional HTTP headers, but such internal headers must be ignored by
-  // CORS check (which run inside Network Service), so the values are stored
-  // here (rather than in |headers|) and later merged into the |headers| after
-  // CORS check.
-  //
-  // *Warning*: Adding new headers to this list is strongly discouraged. What
-  // usually you need is to update the fetch spec, and add your custom headers
-  // to the CORS-safelisted header so to pass proper CORS checks. 'Proxy-' or
-  // 'Sec-' prefixes are also available. See cors::IsCORSSafelistedHeader and
-  // cors::IsForbiddenHeader for details.
-  //
-  // You should ask Loading and CORS OWNERS when you need to add your own
-  // headers to the list.
-  HttpRequestHeaders cors_exempt_headers;  // See Note above before using.
+  // 'X-Requested-With' header value. Some consumers want to set this header,
+  // but such internal headers must be ignored by CORS checks (which run inside
+  // Network Service), so the value is stored here (rather than in |headers|)
+  // and later populated in the headers after CORS check.
+  // TODO(toyoshim): Remove it once PPAPI is deprecated.
+  string requested_with_header;
+
+  // 'X-Client-Data' header value. See comments for |requested_with_header|
+  // above, too.
+  // TODO(toyoshim): Consider to rename this to have a chrome specific prefix
+  // such as 'Chrome-' instead of 'X-', and to add 'Chrome-' prefixed header
+  // names into the forbidden header name list.
+  string client_data_header;
 
   // net::URLRequest load flags.
   int32 load_flags;
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc
index 75acb6e..ffcef5a 100644
--- a/services/network/restricted_cookie_manager.cc
+++ b/services/network/restricted_cookie_manager.cc
@@ -19,6 +19,7 @@
 #include "net/cookies/cookie_options.h"
 #include "net/cookies/cookie_store.h"
 #include "services/network/cookie_managers_shared.h"
+#include "services/network/cookie_settings.h"
 
 namespace network {
 
@@ -75,9 +76,14 @@
   DISALLOW_COPY_AND_ASSIGN(Listener);
 };
 
-RestrictedCookieManager::RestrictedCookieManager(net::CookieStore* cookie_store,
-                                                 const url::Origin& origin)
-    : cookie_store_(cookie_store), origin_(origin), weak_ptr_factory_(this) {
+RestrictedCookieManager::RestrictedCookieManager(
+    net::CookieStore* cookie_store,
+    const CookieSettings* cookie_settings,
+    const url::Origin& origin)
+    : cookie_store_(cookie_store),
+      cookie_settings_(cookie_settings),
+      origin_(origin),
+      weak_ptr_factory_(this) {
   DCHECK(cookie_store);
 }
 
@@ -105,6 +111,13 @@
     return;
   }
 
+  // TODO(morlovich): Try to validate site_for_cookies as well.
+
+  if (!cookie_settings_->IsCookieAccessAllowed(url, site_for_cookies)) {
+    std::move(callback).Run({});
+    return;
+  }
+
   net::CookieOptions net_options;
   if (net::registry_controlled_domains::SameDomainOrHost(
           url, site_for_cookies,
@@ -134,9 +147,6 @@
     const net::CookieStatusList& excluded_cookies) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  // TODO(pwnall): Call NetworkDelegate::CanGetCookies() on a NetworkDelegate
-  //               associated with the NetworkContext.
-
   std::vector<net::CanonicalCookie> result;
   result.reserve(cookie_list.size());
   mojom::CookieMatchType match_type = options->match_type;
@@ -172,10 +182,14 @@
     return;
   }
 
+  // TODO(morlovich): Try to validate site_for_cookies as well.
+  if (!cookie_settings_->IsCookieAccessAllowed(url, site_for_cookies)) {
+    std::move(callback).Run(false);
+    return;
+  }
+
   // TODO(pwnall): Validate the CanonicalCookie fields.
 
-  // TODO(pwnall): Call NetworkDelegate::CanSetCookie() on a NetworkDelegate
-  //               associated with the NetworkContext.
   base::Time now = base::Time::NowFromSystemTime();
   auto sanitized_cookie = std::make_unique<net::CanonicalCookie>(
       cookie.Name(), cookie.Value(), cookie.Domain(), cookie.Path(), now,
diff --git a/services/network/restricted_cookie_manager.h b/services/network/restricted_cookie_manager.h
index 679cd38..f0ec3f6 100644
--- a/services/network/restricted_cookie_manager.h
+++ b/services/network/restricted_cookie_manager.h
@@ -27,6 +27,8 @@
 
 namespace network {
 
+class CookieSettings;
+
 // RestrictedCookieManager implementation.
 //
 // Instances of this class must be created and used on the sequence that hosts
@@ -34,7 +36,9 @@
 class COMPONENT_EXPORT(NETWORK_SERVICE) RestrictedCookieManager
     : public mojom::RestrictedCookieManager {
  public:
+  // |*cookie_store|, |*cookie_settings| must outlive this.
   RestrictedCookieManager(net::CookieStore* cookie_store,
+                          const CookieSettings* cookie_settings,
                           const url::Origin& origin);
   ~RestrictedCookieManager() override;
 
@@ -79,6 +83,7 @@
   bool ValidateAccessToCookiesAt(const GURL& url);
 
   net::CookieStore* const cookie_store_;
+  const CookieSettings* const cookie_settings_;
   const url::Origin origin_;
 
   base::LinkedList<Listener> listeners_;
diff --git a/services/network/restricted_cookie_manager_unittest.cc b/services/network/restricted_cookie_manager_unittest.cc
index 293b14a..5a204d3 100644
--- a/services/network/restricted_cookie_manager_unittest.cc
+++ b/services/network/restricted_cookie_manager_unittest.cc
@@ -16,6 +16,7 @@
 #include "net/cookies/cookie_monster.h"
 #include "net/cookies/cookie_store.h"
 #include "net/cookies/cookie_store_test_callbacks.h"
+#include "services/network/cookie_settings.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -86,6 +87,7 @@
       : cookie_monster_(nullptr, nullptr, nullptr /* netlog */),
         service_(std::make_unique<RestrictedCookieManager>(
             &cookie_monster_,
+            &cookie_settings_,
             url::Origin::Create(GURL("http://example.com")))),
         binding_(service_.get(), mojo::MakeRequest(&service_ptr_)) {
     sync_service_ =
@@ -149,6 +151,7 @@
 
   base::MessageLoopForIO message_loop_;
   net::CookieMonster cookie_monster_;
+  CookieSettings cookie_settings_;
   std::unique_ptr<RestrictedCookieManager> service_;
   mojom::RestrictedCookieManagerPtr service_ptr_;
   mojo::Binding<mojom::RestrictedCookieManager> binding_;
@@ -260,6 +263,37 @@
   ASSERT_THAT(cookies, testing::SizeIs(0));
 }
 
+TEST_F(RestrictedCookieManagerTest, GetAllForUrlPolicy) {
+  SetSessionCookie("cookie-name", "cookie-value", "example.com", "/");
+
+  // With default policy, should be able to get all cookies, even third-party.
+  {
+    auto options = mojom::CookieManagerGetOptions::New();
+    options->name = "cookie-name";
+    options->match_type = mojom::CookieMatchType::STARTS_WITH;
+
+    std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+        GURL("http://example.com/test/"), GURL("http://notexample.com"),
+        std::move(options));
+    ASSERT_THAT(cookies, testing::SizeIs(1));
+    EXPECT_EQ("cookie-name", cookies[0].Name());
+    EXPECT_EQ("cookie-value", cookies[0].Value());
+  }
+
+  // Disabing getting third-party cookies works correctly.
+  cookie_settings_.set_block_third_party_cookies(true);
+  {
+    auto options = mojom::CookieManagerGetOptions::New();
+    options->name = "cookie-name";
+    options->match_type = mojom::CookieMatchType::STARTS_WITH;
+
+    std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+        GURL("http://example.com/test/"), GURL("http://notexample.com"),
+        std::move(options));
+    ASSERT_THAT(cookies, testing::SizeIs(0));
+  }
+}
+
 TEST_F(RestrictedCookieManagerTest, SetCanonicalCookie) {
   EXPECT_TRUE(sync_service_->SetCanonicalCookie(
       net::CanonicalCookie(
@@ -294,6 +328,39 @@
   ASSERT_TRUE(received_bad_message());
 }
 
+TEST_F(RestrictedCookieManagerTest, SetCanonicalCookiePolicy) {
+  {
+    // With default settings object, setting a third-party cookie is OK.
+    auto cookie =
+        net::CanonicalCookie::Create(GURL("http://example.com"), "A=B",
+                                     base::Time::Now(), net::CookieOptions());
+    EXPECT_TRUE(sync_service_->SetCanonicalCookie(
+        *cookie, GURL("http://example.com"), GURL("http://notexample.com")));
+  }
+
+  {
+    // Not if third-party cookies are disabled, though.
+    cookie_settings_.set_block_third_party_cookies(true);
+    auto cookie =
+        net::CanonicalCookie::Create(GURL("http://example.com"), "A2=B2",
+                                     base::Time::Now(), net::CookieOptions());
+    EXPECT_FALSE(sync_service_->SetCanonicalCookie(
+        *cookie, GURL("http://example.com"), GURL("http://notexample.com")));
+  }
+
+  // Read back, in first-part context
+  auto options = mojom::CookieManagerGetOptions::New();
+  options->name = "A";
+  options->match_type = mojom::CookieMatchType::STARTS_WITH;
+
+  std::vector<net::CanonicalCookie> cookies = sync_service_->GetAllForUrl(
+      GURL("http://example.com/test/"), GURL("http://example.com/"),
+      std::move(options));
+  ASSERT_THAT(cookies, testing::SizeIs(1));
+  EXPECT_EQ("A", cookies[0].Name());
+  EXPECT_EQ("B", cookies[0].Value());
+}
+
 namespace {
 
 // Stashes the cookie changes it receives, for testing.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index aac0f313..7d2455b6 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -376,15 +376,20 @@
   url_request_->set_attach_same_site_cookies(request.attach_same_site_cookies);
   url_request_->SetReferrer(ComputeReferrer(request.referrer));
   url_request_->set_referrer_policy(request.referrer_policy);
+  url_request_->SetExtraRequestHeaders(request.headers);
+  // X-Requested-With and X-Client-Data header must be set here to avoid
+  // breaking CORS checks. They are non-empty when the values are given by the
+  // UA code, therefore they should be ignored by CORS checks.
+  if (!request.requested_with_header.empty()) {
+    url_request_->SetExtraRequestHeaderByName(
+        "X-Requested-With", request.requested_with_header, true);
+  }
+  if (!request.client_data_header.empty()) {
+    url_request_->SetExtraRequestHeaderByName("X-Client-Data",
+                                              request.client_data_header, true);
+  }
   url_request_->set_upgrade_if_insecure(request.upgrade_if_insecure);
 
-  // |cors_excempt_headers| must be merged here to avoid breaking CORS checks.
-  // They are non-empty when the values are given by the UA code, therefore
-  // they should be ignored by CORS checks.
-  net::HttpRequestHeaders merged_headers = request.headers;
-  merged_headers.MergeFrom(request.cors_exempt_headers);
-  url_request_->SetExtraRequestHeaders(merged_headers);
-
   url_request_->SetUserData(kUserDataKey,
                             std::make_unique<UnownedPointer>(this));
 
diff --git a/services/tracing/perfetto/perfetto_tracing_coordinator.cc b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
index 27d64c5d..e10fd5d 100644
--- a/services/tracing/perfetto/perfetto_tracing_coordinator.cc
+++ b/services/tracing/perfetto/perfetto_tracing_coordinator.cc
@@ -256,15 +256,15 @@
   // system as a fallback when using Perfetto, rather than
   // the browser directly using a Consumer interface, we have to
   // attempt to linearize with newly connected agents so we only
-  // call the BeginTracing callback when we can be fairly sure
+  // call the BeginTracing callback when we can be sure
   // that all current agents have registered with Perfetto and
   // started tracing if requested. We do this linearization
-  // by calling RequestBufferStatus but just throwing away the
-  // result.
+  // explicitly using WaitForTracingEnabled() which will wait
+  // for the TraceLog to be enabled before calling its provided
+  // callback.
   auto closure = base::BindRepeating(
       [](base::WeakPtr<PerfettoTracingCoordinator> coordinator,
-         AgentRegistry::AgentEntry* agent_entry, uint32_t capacity,
-         uint32_t count) {
+         AgentRegistry::AgentEntry* agent_entry) {
         bool removed =
             agent_entry->RemoveDisconnectClosure(GetStartTracingClosureName());
         DCHECK(removed);
@@ -275,10 +275,9 @@
       },
       weak_factory_.GetWeakPtr(), base::Unretained(agent_entry));
 
-  agent_entry->AddDisconnectClosure(GetStartTracingClosureName(),
-                                    base::BindOnce(closure, 0, 0));
+  agent_entry->AddDisconnectClosure(GetStartTracingClosureName(), closure);
 
-  agent_entry->agent()->RequestBufferStatus(closure);
+  agent_entry->agent()->WaitForTracingEnabled(closure);
   RemoveExpectedPID(agent_entry->pid());
 }
 
diff --git a/services/tracing/public/cpp/base_agent.cc b/services/tracing/public/cpp/base_agent.cc
index d31c1a9b2..f10dd41 100644
--- a/services/tracing/public/cpp/base_agent.cc
+++ b/services/tracing/public/cpp/base_agent.cc
@@ -51,4 +51,9 @@
   std::move(callback).Run(0 /* capacity */, 0 /* count */);
 }
 
+void BaseAgent::WaitForTracingEnabled(
+    Agent::WaitForTracingEnabledCallback callback) {
+  std::move(callback).Run();
+}
+
 }  // namespace tracing
diff --git a/services/tracing/public/cpp/base_agent.h b/services/tracing/public/cpp/base_agent.h
index 8be2cf54..0c34895 100644
--- a/services/tracing/public/cpp/base_agent.h
+++ b/services/tracing/public/cpp/base_agent.h
@@ -40,6 +40,8 @@
   void StopAndFlush(tracing::mojom::RecorderPtr recorder) override;
   void RequestBufferStatus(
       Agent::RequestBufferStatusCallback callback) override;
+  void WaitForTracingEnabled(
+      Agent::WaitForTracingEnabledCallback callback) override;
 
   mojo::Binding<tracing::mojom::Agent> binding_;
 
diff --git a/services/tracing/public/cpp/trace_event_agent.cc b/services/tracing/public/cpp/trace_event_agent.cc
index 94cc70a..3625b09c 100644
--- a/services/tracing/public/cpp/trace_event_agent.cc
+++ b/services/tracing/public/cpp/trace_event_agent.cc
@@ -40,13 +40,19 @@
     : BaseAgent(kTraceEventLabel,
                 mojom::TraceDataType::ARRAY,
                 base::trace_event::TraceLog::GetInstance()->process_id()),
-      enabled_tracing_modes_(0) {
+      enabled_tracing_modes_(0),
+      weak_ptr_factory_(this) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
+  base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
+      weak_ptr_factory_.GetWeakPtr());
+
   ProducerClient::Get()->AddDataSource(TraceEventDataSource::GetInstance());
 }
 
-TraceEventAgent::~TraceEventAgent() = default;
+TraceEventAgent::~TraceEventAgent() {
+  DCHECK(!tracing_enabled_callback_);
+}
 
 void TraceEventAgent::GetCategories(std::set<std::string>* category_set) {
   for (size_t i = base::trace_event::BuiltinCategories::kVisibleCategoryStart;
@@ -74,7 +80,9 @@
 void TraceEventAgent::StartTracing(const std::string& config,
                                    base::TimeTicks coordinator_time,
                                    StartTracingCallback callback) {
+  DCHECK(!TracingUsesPerfettoBackend());
   DCHECK(!recorder_);
+  DCHECK(!tracing_enabled_callback_);
 #if defined(__native_client__)
   // NaCl and system times are offset by a bit, so subtract some time from
   // the captured timestamps. The value might be off by a bit due to messaging
@@ -92,6 +100,7 @@
 }
 
 void TraceEventAgent::StopAndFlush(mojom::RecorderPtr recorder) {
+  DCHECK(!TracingUsesPerfettoBackend());
   DCHECK(!recorder_);
 
   recorder_ = std::move(recorder);
@@ -110,11 +119,36 @@
 
 void TraceEventAgent::RequestBufferStatus(
     RequestBufferStatusCallback callback) {
+  DCHECK(!TracingUsesPerfettoBackend());
   base::trace_event::TraceLogStatus status =
       base::trace_event::TraceLog::GetInstance()->GetStatus();
   std::move(callback).Run(status.event_capacity, status.event_count);
 }
 
+void TraceEventAgent::WaitForTracingEnabled(
+    Agent::WaitForTracingEnabledCallback callback) {
+  DCHECK(TracingUsesPerfettoBackend());
+  DCHECK(!tracing_enabled_callback_);
+  if (base::trace_event::TraceLog::GetInstance()->IsEnabled()) {
+    std::move(callback).Run();
+    return;
+  }
+
+  tracing_enabled_callback_ = std::move(callback);
+}
+
+// This callback will always come on the same sequence
+// that TraceLog::AddAsyncEnabledStateObserver was called
+// on to begin with, i.e. the same as any WaitForTracingEnabled()
+// calls are run on.
+void TraceEventAgent::OnTraceLogEnabled() {
+  if (tracing_enabled_callback_) {
+    std::move(tracing_enabled_callback_).Run();
+  }
+}
+
+void TraceEventAgent::OnTraceLogDisabled() {}
+
 void TraceEventAgent::OnTraceLogFlush(
     const scoped_refptr<base::RefCountedString>& events_str,
     bool has_more_events) {
diff --git a/services/tracing/public/cpp/trace_event_agent.h b/services/tracing/public/cpp/trace_event_agent.h
index 70063d2..3f62b45 100644
--- a/services/tracing/public/cpp/trace_event_agent.h
+++ b/services/tracing/public/cpp/trace_event_agent.h
@@ -13,7 +13,9 @@
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
+#include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
+#include "base/trace_event/trace_log.h"
 #include "base/values.h"
 #include "services/tracing/public/cpp/base_agent.h"
 #include "services/tracing/public/mojom/tracing.mojom.h"
@@ -29,7 +31,9 @@
 // most of the mojom::Agent functions will never be used
 // as the control signals will go through the Perfetto
 // interface instead.
-class COMPONENT_EXPORT(TRACING_CPP) TraceEventAgent : public BaseAgent {
+class COMPONENT_EXPORT(TRACING_CPP) TraceEventAgent
+    : public BaseAgent,
+      public base::trace_event::TraceLog::AsyncEnabledStateObserver {
  public:
   static TraceEventAgent* GetInstance();
 
@@ -57,13 +61,20 @@
 
   void OnTraceLogFlush(const scoped_refptr<base::RefCountedString>& events_str,
                        bool has_more_events);
+  void WaitForTracingEnabled(
+      Agent::WaitForTracingEnabledCallback callback) override;
+
+  // base::trace_event::TraceLog::AsyncEnabledStateObserver
+  void OnTraceLogEnabled() override;
+  void OnTraceLogDisabled() override;
 
   uint8_t enabled_tracing_modes_;
   mojom::RecorderPtr recorder_;
   std::vector<MetadataGeneratorFunction> metadata_generator_functions_;
+  Agent::WaitForTracingEnabledCallback tracing_enabled_callback_;
 
   THREAD_CHECKER(thread_checker_);
-
+  base::WeakPtrFactory<TraceEventAgent> weak_ptr_factory_;
   DISALLOW_COPY_AND_ASSIGN(TraceEventAgent);
 };
 
diff --git a/services/tracing/public/mojom/tracing.mojom b/services/tracing/public/mojom/tracing.mojom
index 3c282c4..1e9014e4 100644
--- a/services/tracing/public/mojom/tracing.mojom
+++ b/services/tracing/public/mojom/tracing.mojom
@@ -43,6 +43,16 @@
       => (bool success);
   StopAndFlush(Recorder recorder);
   RequestBufferStatus() => (uint32 capacity, uint32 count);
+  // This is only ever needed when the legacy Coordinator uses Perfetto to
+  // start tracing, rather than calling StartTracing on each agent through
+  // this interface. In that case, the Coordinator still needs a way of
+  // deferring the success callback until we know that tracing has started
+  // in each relevant process. This is a temporary thing until all clients
+  // of the TracingController in the browser (which uses the
+  // Coordinator interface) have been migrated to use the Perfetto
+  // Consumer interface directly instead, and the Coordinator/Agent
+  // interfaces can be removed.
+  WaitForTracingEnabled() => ();
 };
 
 // An agent can make several calls to |AddChunk|. Chunks will be concatenated
diff --git a/services/tracing/test_util.cc b/services/tracing/test_util.cc
index 1bce1291..b6674a8 100644
--- a/services/tracing/test_util.cc
+++ b/services/tracing/test_util.cc
@@ -5,6 +5,7 @@
 #include "services/tracing/test_util.h"
 
 #include <string>
+#include <utility>
 
 #include "services/tracing/public/mojom/tracing.mojom.h"
 
@@ -42,4 +43,9 @@
                     trace_log_status_.event_count);
 }
 
+void MockAgent::WaitForTracingEnabled(
+    Agent::WaitForTracingEnabledCallback callback) {
+  std::move(callback).Run();
+}
+
 }  // namespace tracing
diff --git a/services/tracing/test_util.h b/services/tracing/test_util.h
index 821a7eb0..fa72baf 100644
--- a/services/tracing/test_util.h
+++ b/services/tracing/test_util.h
@@ -41,6 +41,8 @@
                     StartTracingCallback cb) override;
   void StopAndFlush(mojom::RecorderPtr recorder) override;
   void RequestBufferStatus(RequestBufferStatusCallback cb) override;
+  void WaitForTracingEnabled(
+      Agent::WaitForTracingEnabledCallback callback) override;
 
   mojo::Binding<mojom::Agent> binding_;
   std::vector<std::string> call_stat_;
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc
index ad13d60..84b81d7 100644
--- a/services/ws/client_root.cc
+++ b/services/ws/client_root.cc
@@ -393,15 +393,6 @@
   }
 }
 
-void ClientRoot::OnWindowTransformed(aura::Window* window,
-                                     ui::PropertyChangeReason reason) {
-  // Transform can affect the window bounds in screen. See
-  // https://crbug.com/931161.
-  DCHECK_EQ(window, window_);
-  if (window->GetBoundsInScreen().origin() != last_bounds_.origin())
-    NotifyClientOfNewBounds();
-}
-
 void ClientRoot::OnHostResized(aura::WindowTreeHost* host) {
   // This function is also called when the device-scale-factor changes too.
   CheckForScaleFactorChange();
diff --git a/services/ws/client_root.h b/services/ws/client_root.h
index 998ae80..21028822 100644
--- a/services/ws/client_root.h
+++ b/services/ws/client_root.h
@@ -134,8 +134,6 @@
                                  int64_t new_display_id) override;
   void OnDidMoveWindowToDisplay(aura::Window* window) override;
   void OnWindowVisibilityChanged(aura::Window* window, bool visible) override;
-  void OnWindowTransformed(aura::Window* window,
-                           ui::PropertyChangeReason reason) override;
 
   // aura::WindowTreeHostObserver:
   void OnHostResized(aura::WindowTreeHost* host) override;
diff --git a/services/ws/client_root_unittest.cc b/services/ws/client_root_unittest.cc
index a512aae..0973fc3 100644
--- a/services/ws/client_root_unittest.cc
+++ b/services/ws/client_root_unittest.cc
@@ -7,7 +7,6 @@
 #include <string>
 #include <vector>
 
-#include "base/run_loop.h"
 #include "services/ws/public/cpp/property_type_converters.h"
 #include "services/ws/public/mojom/window_manager.mojom.h"
 #include "services/ws/window_service.h"
@@ -19,7 +18,6 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
 #include "ui/aura/window_tracker.h"
-#include "ui/gfx/transform.h"
 
 namespace ws {
 namespace {
@@ -53,36 +51,6 @@
   DISALLOW_COPY_AND_ASSIGN(CascadingPropertyTestHelper);
 };
 
-class TransformWaiter : public aura::WindowObserver {
- public:
-  explicit TransformWaiter(aura::Window* window)
-      : run_loop_(base::RunLoop::Type::kNestableTasksAllowed), window_(window) {
-    window_->AddObserver(this);
-  }
-  ~TransformWaiter() override { window_->RemoveObserver(this); }
-
-  void Wait() { run_loop_.Run(); }
-
- private:
-  // aura::WindowObserver:
-  void OnWindowTransformed(aura::Window* window,
-                           ui::PropertyChangeReason reason) override {
-    run_loop_.QuitWhenIdle();
-  }
-
-  base::RunLoop run_loop_;
-  aura::Window* window_;
-
-  DISALLOW_COPY_AND_ASSIGN(TransformWaiter);
-};
-
-void SetTransformAndWait(aura::Window* window,
-                         const gfx::Transform& transform) {
-  TransformWaiter waiter(window);
-  window->SetTransform(transform);
-  waiter.Wait();
-}
-
 // Verifies a property change that occurs while servicing a property change from
 // the client results in notifying the client of the new property.
 TEST(ClientRoot, CascadingPropertyChange) {
@@ -279,33 +247,5 @@
   EXPECT_TRUE(embedding_changes->empty());
 }
 
-TEST(ClientRoot, ClientNotifiedOfPositionChangefromTransform) {
-  WindowServiceTestSetup setup;
-  aura::Window* window = setup.window_tree_test_helper()->NewTopLevelWindow();
-  window->SetBounds(gfx::Rect(0, 5, 100, 200));
-  setup.changes()->clear();
-
-  window->SetBounds(gfx::Rect(10, 15, 100, 200));
-  auto iter =
-      FirstChangeOfType(*setup.changes(), CHANGE_TYPE_NODE_BOUNDS_CHANGED);
-  ASSERT_NE(iter, setup.changes()->end());
-  EXPECT_EQ(gfx::Rect(10, 15, 100, 200), iter->bounds);
-  setup.changes()->clear();
-
-  gfx::Transform transform;
-  transform.Translate(gfx::Vector2dF(10.0, 20.0));
-  SetTransformAndWait(window, transform);
-  iter = FirstChangeOfType(*setup.changes(), CHANGE_TYPE_NODE_BOUNDS_CHANGED);
-  ASSERT_NE(iter, setup.changes()->end());
-  EXPECT_EQ(gfx::Rect(20, 35, 100, 200), iter->bounds);
-  setup.changes()->clear();
-
-  SetTransformAndWait(window, gfx::Transform());
-  iter = FirstChangeOfType(*setup.changes(), CHANGE_TYPE_NODE_BOUNDS_CHANGED);
-  ASSERT_NE(iter, setup.changes()->end());
-  EXPECT_EQ(gfx::Rect(10, 15, 100, 200), iter->bounds);
-  setup.changes()->clear();
-}
-
 }  // namespace
 }  // namespace ws
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 682a3ae..b4eebe3 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -22,9 +22,9 @@
     "blob/data_element.mojom",
     "blob/serialized_blob.mojom",
     "cache_storage/cache_storage.mojom",
+    "choosers/color_chooser.mojom",
     "choosers/file_chooser.mojom",
     "clipboard/clipboard.mojom",
-    "color_chooser/color_chooser.mojom",
     "contacts/contacts_manager.mojom",
     "cookie_store/cookie_store.mojom",
     "crash/crash_memory_metrics_reporter.mojom",
diff --git a/third_party/blink/public/mojom/color_chooser/color_chooser.mojom b/third_party/blink/public/mojom/choosers/color_chooser.mojom
similarity index 100%
rename from third_party/blink/public/mojom/color_chooser/color_chooser.mojom
rename to third_party/blink/public/mojom/choosers/color_chooser.mojom
diff --git a/third_party/blink/public/mojom/color_chooser/OWNERS b/third_party/blink/public/mojom/color_chooser/OWNERS
deleted file mode 100644
index 08850f4..0000000
--- a/third_party/blink/public/mojom/color_chooser/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/platform/modules/idle/idle_manager.mojom b/third_party/blink/public/platform/modules/idle/idle_manager.mojom
index 1309900..e5ee660 100644
--- a/third_party/blink/public/platform/modules/idle/idle_manager.mojom
+++ b/third_party/blink/public/platform/modules/idle/idle_manager.mojom
@@ -9,13 +9,13 @@
 // Proposal: https://github.com/inexorabletash/idle-detection
 
 enum UserIdleState {
-  ACTIVE,
-  IDLE
+  kActive,
+  kIdle
 };
 
 enum ScreenIdleState {
-  LOCKED,
-  UNLOCKED
+  kLocked,
+  kUnlocked
 };
 
 struct IdleState {
diff --git a/third_party/blink/public/platform/web_layer_tree_view.h b/third_party/blink/public/platform/web_layer_tree_view.h
index 6fabefd0..ae8f20a0 100644
--- a/third_party/blink/public/platform/web_layer_tree_view.h
+++ b/third_party/blink/public/platform/web_layer_tree_view.h
@@ -75,9 +75,6 @@
 
   // View properties ---------------------------------------------------
 
-  // Sets the background color for the viewport.
-  virtual void SetBackgroundColor(SkColor) {}
-
   // Sets the current page scale factor and minimum / maximum limits. Both
   // limits are initially 1 (no page scale allowed).
   virtual void SetPageScaleFactorAndLimits(float page_scale_factor,
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h
index 1820058..3aba024 100644
--- a/third_party/blink/public/platform/web_url_request.h
+++ b/third_party/blink/public/platform/web_url_request.h
@@ -318,6 +318,12 @@
   BLINK_PLATFORM_EXPORT const WebString GetRequestedWithHeader() const;
   BLINK_PLATFORM_EXPORT void SetRequestedWithHeader(const WebString&);
 
+  // Remembers 'X-Client-Data' header value. Blink should not set this header
+  // value until CORS checks are done to avoid running checks even against
+  // headers that are internally set.
+  BLINK_PLATFORM_EXPORT const WebString GetClientDataHeader() const;
+  BLINK_PLATFORM_EXPORT void SetClientDataHeader(const WebString&);
+
   // https://fetch.spec.whatwg.org/#concept-request-window
   // See network::ResourceRequest::fetch_window_id for details.
   BLINK_PLATFORM_EXPORT const base::UnguessableToken& GetFetchWindowId() const;
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h
index 79f633d..9a7645b 100644
--- a/third_party/blink/public/web/web_view.h
+++ b/third_party/blink/public/web/web_view.h
@@ -94,12 +94,26 @@
                                       bool compositing_enabled,
                                       WebView* opener);
 
-  // Called on WebView when a WebFrameWidget is created for a local main frame,
-  // and can be set back to null when the WebWidgetClient is removed due to the
-  // main frame being detached.
-  // TODO(danakj): Move this to WebWidget and merge with SetLayerTreeView, have
-  // it be null/not set when the main frame is remote.
-  virtual void SetWebWidgetClient(WebWidgetClient*) = 0;
+  // Called to inform WebViewImpl that a local main frame has been attached.
+  // After this call MainFrameImpl() will return a valid frame until it is
+  // detached. It receives the WebWidgetClient* that provides input/compositing
+  // services for the attached main frame.
+  // This is only called for composited WebViews. Non-composited WebViews do not
+  // have a WebWidgetClient.
+  virtual void DidAttachLocalMainFrame(WebWidgetClient*) = 0;
+
+  // Called to inform WebViewImpl that it has an initial remote main frame. This
+  // is a hack to just get a WebWidgetClient to WebViewImpl since it expects to
+  // always have one at this time.
+  // This does *NOT* need to be called every time a remote main frame exists,
+  // but is meant to be called when WebViewImpl is initialized with a remote
+  // main frame, since it will not receive a WebWidgetClient otherwise.
+  // TODO(danakj): Remove this method when WebViewImpl does not need a
+  // WebWidgetClient without a local main frame. At that point it should
+  // also drop the WebWidgetClient when a local main frame is detached.
+  // This is only called for composited WebViews. Non-composited WebViews do not
+  // have a WebWidgetClient.
+  virtual void DidAttachRemoteMainFrame(WebWidgetClient*) = 0;
 
   // Initializes the various client interfaces.
   virtual void SetPrerendererClient(WebPrerendererClient*) = 0;
@@ -379,6 +393,8 @@
   // Overrides the page's background and base background color. You
   // can use this to enforce a transparent background, which is useful if you
   // want to have some custom background rendered behind the widget.
+  //
+  // These may are only called for composited WebViews.
   virtual void SetBackgroundColorOverride(SkColor) {}
   virtual void ClearBackgroundColorOverride() {}
   virtual void SetBaseBackgroundColorOverride(SkColor) {}
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h
index 0b74d0a..e2a9eb4 100644
--- a/third_party/blink/public/web/web_widget_client.h
+++ b/third_party/blink/public/web/web_widget_client.h
@@ -85,6 +85,11 @@
   virtual void SetShowScrollBottleneckRects(bool) {}
   virtual void SetShowHitTestBorders(bool) {}
 
+  // Sets the background color to be filled in as gutter behind/around the
+  // painted content. Non-composited WebViews need not implement this, as they
+  // paint into another widget which has a background color of its own.
+  virtual void SetBackgroundColor(SkColor color) {}
+
   // A notification callback for when the intrinsic sizing of the
   // widget changed. This is only called for SVG within a remote frame.
   virtual void IntrinsicSizingInfoChanged(const WebIntrinsicSizingInfo&) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
index 3aeda2e..5a3e20af 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
@@ -166,7 +166,8 @@
       GCInfoTable::Get()
           .GCInfoFromIndex(
               HeapObjectHeader::FromPayload(traceable)->GcInfoIndex())
-          ->name_(traceable);
+          ->name(traceable)
+          .value;
   EmbedderNode* graph_node =
       GraphNode(traceable, name, nullptr, current_parent_->GetDomTreeState());
   graph_->AddEdge(current_parent_, graph_node);
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index b531636..02f4f86 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -142,10 +142,10 @@
   // Static helper functions.
   static bool IsInsideFocusableElementOrARIAWidget(const Node&);
 
- protected:
+ private:
+  friend class AXObjectCacheBase;
   AXObjectCache(Document&);
 
- private:
   static AXObjectCacheCreateFunction create_function_;
   DISALLOW_COPY_AND_ASSIGN(AXObjectCache);
 };
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h b/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
index 253a14b..c8534be8 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -33,8 +34,12 @@
   DISALLOW_COPY_AND_ASSIGN(AXObjectCacheBase);
 };
 
-// This is the only subclass of AXObjectCache.
-DEFINE_TYPE_CASTS(AXObjectCacheBase, AXObjectCache, cache, true, true);
+template <>
+struct DowncastTraits<AXObjectCacheBase> {
+  // All concrete implementations of AXObjectCache are derived from
+  // AXObjectCacheBase.
+  static bool AllowFrom(const AXObjectCache& cache) { return true; }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css.dict b/third_party/blink/renderer/core/css/css.dict
index 6572728..4c054b4c 100644
--- a/third_party/blink/renderer/core/css/css.dict
+++ b/third_party/blink/renderer/core/css/css.dict
@@ -507,14 +507,6 @@
 "media-controls-fullscreen-background"
 "media-current-time-display"
 "media-time-remaining-display"
-"-internal-media-cast-off-button"
-"-internal-media-overlay-cast-off-button"
-"-internal-media-track-selection-checkmark"
-"-internal-media-closed-captions-icon"
-"-internal-media-subtitles-icon"
-"-internal-media-overflow-button"
-"-internal-media-download-button"
-"-internal-media-remoting-cast-icon"
 "-internal-media-control"
 "menulist"
 "menulist-button"
@@ -532,7 +524,6 @@
 "searchfield-cancel-button"
 "textfield"
 "textarea"
-"caps-lock-indicator"
 "round"
 "border"
 "border-box"
diff --git a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
index 37338a64..71c2660 100644
--- a/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
+++ b/third_party/blink/renderer/core/css/css_primitive_value_mappings.h
@@ -272,12 +272,6 @@
     case kMediaToggleClosedCaptionsButtonPart:
       value_id_ = CSSValueMediaToggleClosedCaptionsButton;
       break;
-    case kMediaCastOffButtonPart:
-      value_id_ = CSSValueInternalMediaCastOffButton;
-      break;
-    case kMediaOverlayCastOffButtonPart:
-      value_id_ = CSSValueInternalMediaOverlayCastOffButton;
-      break;
     case kMediaSliderPart:
       value_id_ = CSSValueMediaSlider;
       break;
@@ -305,21 +299,6 @@
     case kMediaTimeRemainingPart:
       value_id_ = CSSValueMediaTimeRemainingDisplay;
       break;
-    case kMediaTrackSelectionCheckmarkPart:
-      value_id_ = CSSValueInternalMediaTrackSelectionCheckmark;
-      break;
-    case kMediaClosedCaptionsIconPart:
-      value_id_ = CSSValueInternalMediaClosedCaptionsIcon;
-      break;
-    case kMediaSubtitlesIconPart:
-      value_id_ = CSSValueInternalMediaSubtitlesIcon;
-      break;
-    case kMediaOverflowMenuButtonPart:
-      value_id_ = CSSValueInternalMediaOverflowButton;
-      break;
-    case kMediaDownloadIconPart:
-      value_id_ = CSSValueInternalMediaDownloadButton;
-      break;
     case kMediaControlPart:
       value_id_ = CSSValueInternalMediaControl;
       break;
@@ -371,12 +350,6 @@
     case kTextAreaPart:
       value_id_ = CSSValueTextarea;
       break;
-    case kCapsLockIndicatorPart:
-      value_id_ = CSSValueCapsLockIndicator;
-      break;
-    case kMediaRemotingCastIconPart:
-      value_id_ = CSSValueInternalMediaRemotingCastIcon;
-      break;
   }
 }
 
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index d896714..fbb19cd 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -645,8 +645,10 @@
     "manual",
 
     // -webkit-appearance
-    // The order here must match the order in the ControlPart enum in ThemeTypes.h.
-    // All appearance values that should be accepted by the parser should be listed between 'checkbox' and 'textarea':
+    // The order here must match the order in the ControlPart enum in
+    // theme_types.h.
+    // All appearance values that should be accepted by the parser should be
+    // listed between 'checkbox' and 'textarea'.
     "checkbox",
     "radio",
     "push-button",
@@ -671,14 +673,6 @@
     "media-controls-fullscreen-background",
     "media-current-time-display",
     "media-time-remaining-display",
-    "-internal-media-cast-off-button",
-    "-internal-media-overlay-cast-off-button",
-    "-internal-media-track-selection-checkmark",
-    "-internal-media-closed-captions-icon",
-    "-internal-media-subtitles-icon",
-    "-internal-media-overflow-button",
-    "-internal-media-download-button",
-    "-internal-media-remoting-cast-icon",
     "-internal-media-control",
     "menulist",
     "menulist-button",
@@ -696,8 +690,6 @@
     "searchfield-cancel-button",
     "textfield",
     "textarea",
-    // An appearance value that should not be accepted by the parser:
-    "caps-lock-indicator",
 
     //
     // border-image
diff --git a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
index 5c8a506..6879bfa 100644
--- a/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
+++ b/third_party/blink/renderer/core/css/parser/css_proto_converter.cc
@@ -247,7 +247,6 @@
     "small",
     "media-sliderthumb",
     "round",
-    "-internal-media-subtitles-icon",
     "media-play-button",
     "smaller",
     "jis04",
@@ -345,7 +344,6 @@
     "slider-vertical",
     "-webkit-box",
     "plum",
-    "-internal-media-overlay-cast-off-button",
     "inactivecaptiontext",
     "dodgerblue",
     "threedshadow",
@@ -435,7 +433,6 @@
     "accumulate",
     "flex-end",
     "transparent",
-    "-internal-media-remoting-cast-icon",
     "goldenrod",
     "historical-ligatures",
     "darkviolet",
@@ -463,7 +460,6 @@
     "darkkhaki",
     "keep-all",
     "content",
-    "-internal-media-download-button",
     "upper-roman",
     "cornsilk",
     "red",
@@ -492,7 +488,6 @@
     "sideways-right",
     "jis83",
     "mediumspringgreen",
-    "caps-lock-indicator",
     "sliderthumb-horizontal",
     "forwards",
     "upper-alpha",
@@ -668,7 +663,6 @@
     "read-write-plaintext-only",
     "padding-box",
     "col-resize",
-    "-internal-media-track-selection-checkmark",
     "lower-latin",
     "-webkit-nowrap",
     "table",
@@ -737,7 +731,6 @@
     "center",
     "lightyellow",
     "lavenderblush",
-    "-internal-media-closed-captions-icon",
     "inherit",
     "media-controls-background",
     "justify",
@@ -825,7 +818,6 @@
     "cursive",
     "on",
     "central",
-    "-internal-media-overflow-button",
     "standalone",
     "column",
     "coral",
@@ -858,7 +850,6 @@
     "blanchedalmond",
     "caret",
     "start",
-    "-internal-media-cast-off-button",
     "italic",
     "ivory",
     "buttontext",
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc
index 3e143fd..dcff8f9 100644
--- a/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -680,8 +680,16 @@
   // sibling position. If not, we can't get the next paragraph in
   // InsertListCommand::doApply's while loop. See http://crbug.com/571420
   if (non_editable_node &&
-      non_editable_node->IsDescendantOf(editable_position.AnchorNode()))
-    editable_position = NextVisuallyDistinctCandidate(editable_position);
+      non_editable_node->IsDescendantOf(editable_position.AnchorNode())) {
+    // Make sure not to move out of |highest_root|
+    const PositionTemplate<Strategy> boundary =
+        PositionTemplate<Strategy>::LastPositionInNode(highest_root);
+    const PositionTemplate<Strategy> next_candidate =
+        NextVisuallyDistinctCandidate(editable_position);
+    editable_position = next_candidate.IsNotNull()
+                            ? std::min(boundary, next_candidate)
+                            : boundary;
+  }
   return editable_position;
 }
 
diff --git a/third_party/blink/renderer/core/editing/element_inner_text.cc b/third_party/blink/renderer/core/editing/element_inner_text.cc
index 3374096..a15aa12 100644
--- a/third_party/blink/renderer/core/editing/element_inner_text.cc
+++ b/third_party/blink/renderer/core/editing/element_inner_text.cc
@@ -85,12 +85,6 @@
   // Result character buffer.
   Result result_;
 
-  // Remember last |NGOffsetMapping| to avoid repeated offset mapping
-  // computation.
-  const LayoutBlockFlow* last_offset_mapping_block_flow_ = nullptr;
-  const NGOffsetMapping* last_offset_mapping_ = nullptr;
-  std::unique_ptr<NGOffsetMapping> offset_mapping_storage_;
-
   DISALLOW_COPY_AND_ASSIGN(ElementInnerTextCollector);
 };
 
@@ -220,14 +214,7 @@
   LayoutBlockFlow* const block_flow =
       NGOffsetMapping::GetInlineFormattingContextOf(layout_text);
   DCHECK(block_flow) << layout_text;
-  if (block_flow == last_offset_mapping_block_flow_)
-    return last_offset_mapping_;
-  const NGOffsetMapping* const mapping =
-      NGInlineNode::GetOffsetMapping(block_flow, &offset_mapping_storage_);
-  DCHECK(mapping) << layout_text;
-  last_offset_mapping_block_flow_ = block_flow;
-  last_offset_mapping_ = mapping;
-  return mapping;
+  return NGInlineNode::GetOffsetMapping(block_flow);
 }
 
 void ElementInnerTextCollector::ProcessChildren(const Node& container) {
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index 3e965bb..306582cb 100644
--- a/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -360,7 +360,6 @@
       mapping_needs_recalc_ = true;
       node = first_traversed_node;
       last_block_flow = nullptr;
-      offset_mapping_storage_ = nullptr;
       buffer_.clear();
       invisible_layout_scope_.EnsureRecalc(block_ancestor);
       continue;
@@ -398,7 +397,6 @@
         break;
       }
       if (!last_block_flow) {
-        DCHECK(!offset_mapping_storage_);
         last_block_flow = &block_flow;
       }
       AddTextToBuffer(text_node, block_flow, range);
@@ -458,8 +456,7 @@
                                  LayoutBlockFlow& block_flow,
                                  const EphemeralRangeInFlatTree& range) {
   if (!offset_mapping_ || mapping_needs_recalc_) {
-    offset_mapping_ =
-        NGInlineNode::GetOffsetMapping(&block_flow, &offset_mapping_storage_);
+    offset_mapping_ = NGInlineNode::GetOffsetMapping(&block_flow);
     mapping_needs_recalc_ = false;
   }
 
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 4463625..4119afbd 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -322,8 +322,8 @@
   if (!active_match_)
     return;
 
-  AXObjectCacheBase* ax_object_cache = ToAXObjectCacheBase(
-      OwnerFrame().GetFrame()->GetDocument()->ExistingAXObjectCache());
+  auto* ax_object_cache =
+      OwnerFrame().GetFrame()->GetDocument()->ExistingAXObjectCache();
   if (!ax_object_cache)
     return;
 
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_character.cc b/third_party/blink/renderer/core/editing/selection_modifier_character.cc
index 30430617..648ffd3 100644
--- a/third_party/blink/renderer/core/editing/selection_modifier_character.cc
+++ b/third_party/blink/renderer/core/editing/selection_modifier_character.cc
@@ -528,8 +528,7 @@
   }
 
   DCHECK(context->IsLayoutNGMixin());
-  const NGOffsetMapping* mapping =
-      NGInlineNode::GetOffsetMapping(context, nullptr);
+  const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(context);
   DCHECK(mapping);
 
   const base::Optional<unsigned> start_offset =
diff --git a/third_party/blink/renderer/core/editing/visible_position.cc b/third_party/blink/renderer/core/editing/visible_position.cc
index 4d065d9..1ac80559 100644
--- a/third_party/blink/renderer/core/editing/visible_position.cc
+++ b/third_party/blink/renderer/core/editing/visible_position.cc
@@ -121,8 +121,7 @@
     DCHECK(context);
     DCHECK(context->IsLayoutNGMixin());
 
-    const NGOffsetMapping* mapping =
-        NGInlineNode::GetOffsetMapping(context, nullptr);
+    const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(context);
     DCHECK(mapping);
 
     const base::Optional<unsigned> offset =
diff --git a/third_party/blink/renderer/core/exported/web_layer_test.cc b/third_party/blink/renderer/core/exported/web_layer_test.cc
index fdadf04..4efef7e 100644
--- a/third_party/blink/renderer/core/exported/web_layer_test.cc
+++ b/third_party/blink/renderer/core/exported/web_layer_test.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "build/build_config.h"
+#include "cc/layers/picture_layer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
 #include "third_party/blink/public/web/web_script_source.h"
@@ -11,6 +12,8 @@
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
+#include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -662,4 +665,80 @@
   EXPECT_FALSE(inner_element_layer->subtree_property_changed());
 }
 
+TEST_P(WebLayerListSimTest, SafeOpaqueBackgroundColorGetsSet) {
+  // TODO(crbug.com/765003): CAP may make different layerization decisions and
+  // we cannot guarantee that both divs will be composited in this test. When
+  // CAP gets closer to launch, this test should be updated to pass.
+  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+    return;
+
+  InitializeWithHTML(R"HTML(
+      <!DOCTYPE html>
+      <style>
+      div {
+        position: absolute;
+        z-index: 1;
+        width: 20px;
+        height: 20px;
+      }
+      #behind {
+        top: 12px;
+        left: 12px;
+        background: blue;
+        will-change: transform; /* Composited */
+      }
+      #topleft {
+        top: 0px;
+        left: 0px;
+        background: lime;
+      }
+      #bottomright {
+        top: 24px;
+        left: 24px;
+        background: cyan;
+      }
+      </style>
+      <div id="behind"></div>
+      <div id="topleft"></div>
+      <div id="bottomright"></div>
+  )HTML");
+
+  Compositor().BeginFrame();
+
+  auto* behind_element = GetElementById("behind");
+  auto* behind_layer = ContentLayerAt(ContentLayerCount() - 2);
+  EXPECT_EQ(behind_layer->element_id(),
+            CompositorElementIdFromUniqueObjectId(
+                behind_element->GetLayoutObject()->UniqueId(),
+                CompositorElementIdNamespace::kPrimary));
+  EXPECT_EQ(behind_layer->SafeOpaqueBackgroundColor(), SK_ColorBLUE);
+
+  auto* grouped_mapping =
+      GetElementById("topleft")->GetLayoutBox()->Layer()->GroupedMapping();
+  auto* squashed_layer = grouped_mapping->SquashingLayer()->CcLayer();
+  ASSERT_NE(nullptr, squashed_layer);
+
+  // Top left and bottom right are squashed.
+  // This squashed layer should not be opaque, as it is squashing two squares
+  // with some gaps between them.
+  EXPECT_FALSE(squashed_layer->contents_opaque());
+  // This shouldn't DCHECK.
+  squashed_layer->SafeOpaqueBackgroundColor();
+  // Because contents_opaque is false, the SafeOpaqueBackgroundColor() getter
+  // will return SK_ColorTRANSPARENT. So we need to grab the actual color,
+  // to make sure it's right.
+  SkColor squashed_bg_color =
+      squashed_layer->ActualSafeOpaqueBackgroundColorForTesting();
+  // The squashed layer should have a non-transparent safe opaque background
+  // color, that isn't blue. Exactly which color it is depends on heuristics,
+  // but it should be one of the two colors of the elements that created it.
+  EXPECT_NE(squashed_bg_color, SK_ColorBLUE);
+  EXPECT_EQ(SkColorGetA(squashed_bg_color), SK_AlphaOPAQUE);
+  // #behind is blue, which is SK_ColorBLUE
+  // #topleft is lime, which is SK_ColorGREEN
+  // #bottomright is cyan, which is SK_ColorCYAN
+  EXPECT_TRUE((squashed_bg_color == SK_ColorGREEN) ||
+              (squashed_bg_color == SK_ColorCYAN));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 3ad3354..a324ea3 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -352,7 +352,7 @@
   // and the AXObjectCache doesn't already exist. It's called when trying
   // to attach the accessibility tree of the pop-up to the host page.
   DCHECK(cache);
-  return ToAXObjectCacheBase(cache)->GetOrCreate(document->GetLayoutView());
+  return To<AXObjectCacheBase>(cache)->GetOrCreate(document->GetLayoutView());
 }
 
 void WebPagePopupImpl::SetWindowRect(const IntRect& rect_in_screen) {
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 8a60158..559c3e7d 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -330,23 +330,11 @@
   DCHECK(!AsView().page);
 }
 
-void WebViewImpl::SetWebWidgetClient(WebWidgetClient* client) {
-  AsWidget().client = client;
-}
-
 WebDevToolsAgentImpl* WebViewImpl::MainFrameDevToolsAgentImpl() {
   WebLocalFrameImpl* main_frame = MainFrameImpl();
   return main_frame ? main_frame->DevToolsAgentImpl() : nullptr;
 }
 
-WebLocalFrameImpl* WebViewImpl::MainFrameImpl() const {
-  Page* page = AsView().page.Get();
-  if (!page || !IsA<LocalFrame>(page->MainFrame()))
-    return nullptr;
-
-  return WebLocalFrameImpl::FromFrame(page->DeprecatedLocalMainFrame());
-}
-
 bool WebViewImpl::TabKeyCyclesThroughElements() const {
   DCHECK(AsView().page);
   return AsView().page->TabKeyCyclesThroughElements();
@@ -1566,7 +1554,9 @@
   if (requested_update == LifecycleUpdate::kLayout)
     return;
 
-  UpdateLayerTreeBackgroundColor();
+  // There is no background color for non-composited WebViews (eg printing).
+  if (does_composite_)
+    AsWidget().client->SetBackgroundColor(BackgroundColor());
 
   if (requested_update == LifecycleUpdate::kPrePaint)
     return;
@@ -1976,6 +1966,28 @@
   return WebFrame::FromFrame(page ? page->MainFrame() : nullptr);
 }
 
+WebLocalFrameImpl* WebViewImpl::MainFrameImpl() const {
+  Page* page = AsView().page.Get();
+  if (!page)
+    return nullptr;
+  return WebLocalFrameImpl::FromFrame(DynamicTo<LocalFrame>(page->MainFrame()));
+}
+
+void WebViewImpl::DidAttachLocalMainFrame(WebWidgetClient* client) {
+  DCHECK(does_composite_);
+  DCHECK(MainFrameImpl());
+
+  AsWidget().client = client;
+  // When attaching a local main frame, set up any state on the compositor.
+  AsWidget().client->SetBackgroundColor(BackgroundColor());
+}
+
+void WebViewImpl::DidAttachRemoteMainFrame(WebWidgetClient* client) {
+  DCHECK(does_composite_);
+  DCHECK(!MainFrameImpl());
+  AsWidget().client = client;
+}
+
 WebLocalFrame* WebViewImpl::FocusedFrame() {
   Frame* frame = FocusedCoreFrame();
   // TODO(yabinh): focusedCoreFrame() should always return a local frame, and
@@ -3048,14 +3060,20 @@
 }
 
 void WebViewImpl::SetBackgroundColorOverride(SkColor color) {
+  DCHECK(does_composite_);
+
   background_color_override_enabled_ = true;
   background_color_override_ = color;
-  UpdateLayerTreeBackgroundColor();
+  if (MainFrameImpl())
+    AsWidget().client->SetBackgroundColor(BackgroundColor());
 }
 
 void WebViewImpl::ClearBackgroundColorOverride() {
+  DCHECK(does_composite_);
+
   background_color_override_enabled_ = false;
-  UpdateLayerTreeBackgroundColor();
+  if (MainFrameImpl())
+    AsWidget().client->SetBackgroundColor(BackgroundColor());
 }
 
 void WebViewImpl::SetZoomFactorOverride(float zoom_factor) {
@@ -3365,12 +3383,6 @@
       PageScaleFactor(), MinimumPageScaleFactor(), MaximumPageScaleFactor());
 }
 
-void WebViewImpl::UpdateLayerTreeBackgroundColor() {
-  if (!layer_tree_view_)
-    return;
-  layer_tree_view_->SetBackgroundColor(BackgroundColor());
-}
-
 void WebViewImpl::UpdateDeviceEmulationTransform() {
   if (!visual_viewport_container_layer_)
     return;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index ae1cacdb..4412e83 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -109,7 +109,8 @@
   static bool UseExternalPopupMenus();
 
   // WebView methods:
-  void SetWebWidgetClient(WebWidgetClient*) override;
+  void DidAttachLocalMainFrame(WebWidgetClient*) override;
+  void DidAttachRemoteMainFrame(WebWidgetClient*) override;
   void SetPrerendererClient(WebPrerendererClient*) override;
   WebSettings* GetSettings() override;
   WebString PageEncoding() const override;
@@ -238,8 +239,11 @@
     return dev_tools_emulator_.Get();
   }
 
-  // Returns the main frame associated with this view. This may be null when
-  // the page is shutting down, but will be valid at all other times.
+  // Returns the main frame associated with this view. This will be null when
+  // the main frame is remote.
+  // Internally during startup/shutdown this can be null when no main frame
+  // (local or remote) is attached, but this should not generally matter to code
+  // outside this class.
   WebLocalFrameImpl* MainFrameImpl() const;
 
   // Event related methods:
@@ -501,7 +505,6 @@
   void DoComposite();
   void ReallocateRenderer();
   void UpdateLayerTreeViewPageScale();
-  void UpdateLayerTreeBackgroundColor();
   void UpdateDeviceEmulationTransform();
 
   // Helper function: Widens the width of |source| by the specified margins
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index 5c23ae1..79d27b07 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -496,20 +496,28 @@
                       /*is_hidden=*/false,
                       /*compositing_enabled=*/true, nullptr));
   EXPECT_NE(SK_ColorBLUE, web_view->BackgroundColor());
-  // webView does not have a frame yet, but we should still be able to set the
+  // WebView does not have a frame yet, but we should still be able to set the
   // background color.
   web_view->SetBaseBackgroundColor(SK_ColorBLUE);
   EXPECT_EQ(SK_ColorBLUE, web_view->BackgroundColor());
 
-  // TODO(danakj): Make this part of attaching the main frame's WebFrameWidget.
-  web_view->SetWebWidgetClient(&web_widget_client);
-
   frame_test_helpers::TestWebFrameClient web_frame_client;
   mojom::blink::DocumentInterfaceBrokerPtrInfo document_interface_broker;
   WebLocalFrame* frame = WebLocalFrame::CreateMainFrame(
       web_view, &web_frame_client, nullptr,
       mojo::MakeRequest(&document_interface_broker).PassMessagePipe(), nullptr);
   web_frame_client.Bind(frame);
+
+  // We inform the WebView when it has a local main frame attached once the
+  // WebFrame it fully set up and the WebWidgetClient is initialized (which is
+  // the case by this point).
+  web_view->DidAttachLocalMainFrame(&web_widget_client);
+
+  // The color should be passed to the compositor.
+  cc::LayerTreeHost* host = web_widget_client.layer_tree_host();
+  EXPECT_EQ(SK_ColorBLUE, web_view->BackgroundColor());
+  EXPECT_EQ(SK_ColorBLUE, host->background_color());
+
   // This closes the WebView also.
   web_view->MainFrameWidget()->Close();
 }
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index cc15dd0..de81b2a 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -298,21 +298,21 @@
     }
 
     if (const auto* image = ToHTMLImageElementOrNull(element)) {
-      KURL url =
+      KURL image_url =
           document.CompleteURL(image->getAttribute(html_names::kSrcAttr));
       ImageResourceContent* cached_image = image->CachedImage();
-      AddImageToResources(cached_image, url);
+      AddImageToResources(cached_image, image_url);
     } else if (const auto* input = ToHTMLInputElementOrNull(element)) {
       if (input->type() == input_type_names::kImage && input->ImageLoader()) {
-        KURL url = input->Src();
+        KURL image_url = input->Src();
         ImageResourceContent* cached_image = input->ImageLoader()->GetContent();
-        AddImageToResources(cached_image, url);
+        AddImageToResources(cached_image, image_url);
       }
     } else if (const auto* link = ToHTMLLinkElementOrNull(element)) {
       if (CSSStyleSheet* sheet = link->sheet()) {
-        KURL url =
+        KURL sheet_url =
             document.CompleteURL(link->getAttribute(html_names::kHrefAttr));
-        SerializeCSSStyleSheet(*sheet, url);
+        SerializeCSSStyleSheet(*sheet, sheet_url);
       }
     } else if (const auto* style = ToHTMLStyleElementOrNull(element)) {
       if (CSSStyleSheet* sheet = style->sheet())
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
index 2c14b18..58eb54f 100644
--- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc
+++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -349,6 +349,10 @@
   // TODO(dcheng): The main frame widget currently has a special case.
   // Eliminate this once WebView is no longer a WebWidget.
   blink::WebFrameWidget::CreateForMainFrame(test_web_widget_client_, frame);
+  // We inform the WebView when it has a local main frame attached once the
+  // WebFrame it fully set up and the WebWidgetClient is initialized (which is
+  // the case by this point).
+  web_view_->DidAttachLocalMainFrame(test_web_widget_client_);
 
   // Set an initial size for subframes.
   if (frame->Parent())
@@ -409,13 +413,12 @@
 
   test_web_widget_client_ = CreateDefaultClientIfNeeded(
       web_widget_client, owned_test_web_widget_client_);
-  // TODO(danakj): Remove this! Make WebViewImpl not need a WebWidgetClient when
-  // the main frame is remote.
-  web_view_->SetWebWidgetClient(test_web_widget_client_);
-  // TODO(danakj): Make this part of attaching the main frame's WebFrameWidget.
   web_view_->MainFrameWidget()->SetLayerTreeView(
       test_web_widget_client_->layer_tree_view(),
       test_web_widget_client_->animation_host());
+  // TODO(danakj): Remove this! Make WebViewImpl not need a WebWidgetClient when
+  // the main frame is remote.
+  web_view_->DidAttachRemoteMainFrame(test_web_widget_client_);
 
   return web_view_;
 }
@@ -628,17 +631,21 @@
 }
 
 void TestWebWidgetClient::SetRootLayer(scoped_refptr<cc::Layer> layer) {
-  layer_tree_view_->layer_tree_host()->SetRootLayer(std::move(layer));
+  layer_tree_host()->SetRootLayer(std::move(layer));
+}
+
+void TestWebWidgetClient::SetBackgroundColor(SkColor color) {
+  layer_tree_host()->set_background_color(color);
 }
 
 void TestWebWidgetClient::RegisterViewportLayers(
     const cc::ViewportLayers& layers) {
-  layer_tree_view_->layer_tree_host()->RegisterViewportLayers(layers);
+  layer_tree_host()->RegisterViewportLayers(layers);
 }
 
 void TestWebWidgetClient::RegisterSelection(
     const cc::LayerSelection& selection) {
-  layer_tree_view_->layer_tree_host()->RegisterSelection(selection);
+  layer_tree_host()->RegisterSelection(selection);
 }
 
 void TestWebWidgetClient::DidMeaningfulLayout(
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h
index f2c29d6f..d457bca 100644
--- a/third_party/blink/renderer/core/frame/frame_test_helpers.h
+++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -203,8 +203,12 @@
   void SetRootLayer(scoped_refptr<cc::Layer> layer) override;
   void RegisterViewportLayers(const cc::ViewportLayers& layOAers) override;
   void RegisterSelection(const cc::LayerSelection& selection) override;
+  void SetBackgroundColor(SkColor color) override;
 
   content::LayerTreeView* layer_tree_view() { return layer_tree_view_; }
+  cc::LayerTreeHost* layer_tree_host() {
+    return layer_tree_view_->layer_tree_host();
+  }
   cc::AnimationHost* animation_host() { return animation_host_; }
 
   bool AnimationScheduled() { return animation_scheduled_; }
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 319225d..28c58bca 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -218,9 +218,10 @@
       client, page, owner,
       interface_registry ? interface_registry
                          : InterfaceRegistry::GetEmptyInterfaceRegistry());
-  PageScheduler* page_scheduler = page.GetPageScheduler();
-  if (frame->IsMainFrame() && page_scheduler)
-    page_scheduler->SetIsMainFrameLocal(true);
+  if (frame->IsMainFrame()) {
+    if (PageScheduler* page_scheduler = page.GetPageScheduler())
+      page_scheduler->SetIsMainFrameLocal(true);
+  }
   probe::frameAttachedToParent(frame);
   return frame;
 }
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
index 152ba1b4..feee735 100644
--- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -91,7 +91,7 @@
     absolute_record.average_metric_name = metric_name;
     absolute_record.average_metric_name.append(".Average");
     absolute_record.reset();
-    auto uma_name = uma_preamble;
+    String uma_name = uma_preamble;
     uma_name.append(metric_name);
     uma_name.append(uma_postscript);
     absolute_record.uma_counter.reset(
@@ -107,13 +107,13 @@
     percentage_record.average_metric_name.append(".AverageRatio");
     percentage_record.reset();
     for (auto bucket_substring : threshold_substrings) {
-      String uma_name = uma_percentage_preamble;
-      uma_name.append(metric_name);
-      uma_name.append(uma_percentage_postscript);
-      uma_name.append(bucket_substring);
+      String uma_percentage_name = uma_percentage_preamble;
+      uma_percentage_name.append(metric_name);
+      uma_percentage_name.append(uma_percentage_postscript);
+      uma_percentage_name.append(bucket_substring);
       percentage_record.uma_counters_per_bucket.push_back(
-          std::make_unique<CustomCountHistogram>(uma_name.Utf8().data(), 0,
-                                                 10000000, 50));
+          std::make_unique<CustomCountHistogram>(
+              uma_percentage_name.Utf8().data(), 0, 10000000, 50));
     }
   }
 }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 5b45216..f7dd1a5 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2519,6 +2519,18 @@
 static void RecordGraphicsLayerAsForeignLayer(
     GraphicsContext& context,
     const GraphicsLayer* graphics_layer) {
+  // Copy the first chunk's safe opaque background color over to the cc::Layer
+  // in the foreign layer wrapper.
+  if (graphics_layer->DrawsContent()) {
+    auto& chunks =
+        graphics_layer->GetPaintController().GetPaintArtifact().PaintChunks();
+    SkColor safe_background_color = SK_ColorWHITE;
+    if (chunks.size()) {
+      safe_background_color = chunks[0].safe_opaque_background_color;
+    }
+    graphics_layer->CcLayer()->SetSafeOpaqueBackgroundColor(
+        safe_background_color);
+  }
   // TODO(trchen): Currently the GraphicsLayer hierarchy is still built during
   // CompositingUpdate, and we have to clear them here to ensure no extraneous
   // layers are still attached. In future we will disable all those layer
diff --git a/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc b/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
index c87d81d..fa7863d 100644
--- a/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
+++ b/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
@@ -49,10 +49,11 @@
   if (node_size.Width() * node_size.Height() > max_node_area) {
     IntSize point_offset = view_rect.Size();
     point_offset.Scale(kViewportAnchorRelativeEpsilon);
-    HitTestLocation location(point + point_offset);
+    HitTestLocation alternative_location(point + point_offset);
     node = event_handler
-               .HitTestResultAtLocation(location, HitTestRequest::kReadOnly |
-                                                      HitTestRequest::kActive)
+               .HitTestResultAtLocation(
+                   alternative_location,
+                   HitTestRequest::kReadOnly | HitTestRequest::kActive)
                .InnerNode();
   }
 
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index e737f0ed..9ef2f75 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -978,10 +978,6 @@
   // be moved from WebViewImpl into WebFrameWidget and used for all local
   // frame roots. https://crbug.com/712794
   layer_tree_view_->HeuristicsForGpuRasterizationUpdated(true);
-
-  // WebFrameWidgetImpl is used for child frames, which always have a
-  // transparent background color.
-  layer_tree_view_->SetBackgroundColor(SK_ColorTRANSPARENT);
 }
 
 void WebFrameWidgetImpl::SetIsAcceleratedCompositingActive(bool active) {
@@ -1016,6 +1012,10 @@
   if (!layer_tree_view_)
     return;
 
+  // WebFrameWidgetImpl is used for child frames, which always have a
+  // transparent background color.
+  Client()->SetBackgroundColor(SK_ColorTRANSPARENT);
+
   // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer
   // if it's not null..
   Client()->SetRootLayer(root_layer_);
@@ -1030,6 +1030,10 @@
   if (!layer_tree_view_)
     return;
 
+  // WebFrameWidgetImpl is used for child frames, which always have a
+  // transparent background color.
+  Client()->SetBackgroundColor(SK_ColorTRANSPARENT);
+
   // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer
   // if it's not null..
   Client()->SetRootLayer(root_layer_);
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
index 60ee232..e7be575b 100644
--- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
+++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -12,22 +12,18 @@
 WebViewFrameWidget::WebViewFrameWidget(WebWidgetClient& client,
                                        WebViewImpl& web_view)
     : WebFrameWidgetBase(client), web_view_(&web_view), self_keep_alive_(this) {
-  // TODO(danakj): SetLayerTreeView() here as well, then we can Close() the
-  // WebViewImpl's widget bits in Close().
-  web_view_->SetWebWidgetClient(&client);
 }
 
 WebViewFrameWidget::~WebViewFrameWidget() = default;
 
 void WebViewFrameWidget::Close() {
-  // TODO(danakj): Close() the WebViewImpl here, when we reset the LayerTreeView
-  // in the constructor.
-  web_view_->SetWebWidgetClient(nullptr);
+  // Closing the WebViewFrameWidget happens in response to the local main frame
+  // being detached from the Page/WebViewImpl.
+  // TODO(danakj): Close the WebWidget parts of WebViewImpl here. This should
+  // drop the WebWidgetClient from it as well. For now, WebViewImpl requires a
+  // WebWidgetClient to always be present so this does nothing.
   web_view_ = nullptr;
   WebFrameWidgetBase::Close();
-
-  // Note: this intentionally does not forward to WebView::close(), to make it
-  // easier to untangle the cleanup logic later.
   self_keep_alive_.Clear();
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/color_chooser_client.h b/third_party/blink/renderer/core/html/forms/color_chooser_client.h
index f87e47e..afaa77a 100644
--- a/third_party/blink/renderer/core/html/forms/color_chooser_client.h
+++ b/third_party/blink/renderer/core/html/forms/color_chooser_client.h
@@ -31,7 +31,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_COLOR_CHOOSER_CLIENT_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_COLOR_CHOOSER_CLIENT_H_
 
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom-blink.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
diff --git a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
index 4da2d67a..c683b298 100644
--- a/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
+++ b/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h
@@ -28,7 +28,7 @@
 
 #include <memory>
 #include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom-blink.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/html/forms/color_chooser.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
index 157d644..c601ed51 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
@@ -300,8 +300,12 @@
   EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(0);
   platform_->RunForPeriodSeconds(1);
 
-  // Seek to some time in the past. A completed seek should trigger a *single*
-  // timeupdate.
+  EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
+  Video()->pause();
+  platform_->RunUntilIdle();
+
+  // Seek to some time in the past. A completed seek while paused should trigger
+  // a *single* timeupdate.
   EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
   ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
   Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
@@ -354,10 +358,14 @@
   ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
   Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
   WebMediaPlayer()->FinishSeek();
+
+  // Expect another timeupdate after FinishSeek due to
+  // seeking -> begin scrubbing -> pause -> timeupdate.
+  EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
   platform_->RunUntilIdle();
 
   // Advancing the remainder of the last periodic timeupdate interval should be
-  // insufficient to triggger a new timeupdate event because the seek's
+  // insufficient to trigger a new timeupdate event because the seek's
   // timeupdate occurred only 125ms ago. We desire to fire periodic timeupdates
   // exactly every 250ms from the last timeupdate, and the seek's timeupdate
   // should reset that 250ms ms countdown.
diff --git a/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc b/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
index 7ad0143..45056c7e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_memory_agent.cc
@@ -171,13 +171,13 @@
   std::unique_ptr<protocol::Array<protocol::Memory::Module>> modules =
       protocol::Array<protocol::Memory::Module>::create();
   for (const auto* module : module_cache.GetModules()) {
-    modules->addItem(
-        protocol::Memory::Module::create()
-            .setName(module->filename.value().c_str())
-            .setUuid(module->id.c_str())
-            .setBaseAddress(String::Format("0x%" PRIxPTR, module->base_address))
-            .setSize(static_cast<double>(module->size))
-            .build());
+    modules->addItem(protocol::Memory::Module::create()
+                         .setName(module->GetFilename().value().c_str())
+                         .setUuid(module->GetId().c_str())
+                         .setBaseAddress(String::Format(
+                             "0x%" PRIxPTR, module->GetBaseAddress()))
+                         .setSize(static_cast<double>(module->GetSize()))
+                         .build());
   }
 
   return protocol::Memory::SamplingProfile::create()
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
index 7db1ec6..b9b4836 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc
@@ -315,8 +315,7 @@
   if (!context)
     return NGCaretPosition();
 
-  const NGOffsetMapping* mapping =
-      NGInlineNode::GetOffsetMapping(context, nullptr);
+  const NGOffsetMapping* mapping = NGInlineNode::GetOffsetMapping(context);
   DCHECK(mapping);
   const base::Optional<unsigned> maybe_offset =
       mapping->GetTextContentOffset(position.GetPosition());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index 7965b83..1712ef8 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -459,8 +459,7 @@
 }
 
 const NGOffsetMapping* NGInlineNode::GetOffsetMapping(
-    LayoutBlockFlow* layout_block_flow,
-    std::unique_ptr<NGOffsetMapping>* storage) {
+    LayoutBlockFlow* layout_block_flow) {
   DCHECK(!layout_block_flow->GetDocument().NeedsLayoutTreeUpdate());
 
   // If |layout_block_flow| is LayoutNG, compute from |NGInlineNode|.
@@ -474,7 +473,6 @@
   // |LayoutBlockFlowRateData|.
   if (const NGOffsetMapping* mapping = layout_block_flow->GetOffsetMapping())
     return mapping;
-  DCHECK(storage);
   NGInlineNodeData data;
   ComputeOffsetMapping(layout_block_flow, &data);
   NGOffsetMapping* const mapping = data.offset_mapping.get();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
index 540b4b9..7aa10959 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -76,19 +76,10 @@
   // This funciton must be called with clean layout.
   const NGOffsetMapping* ComputeOffsetMappingIfNeeded();
 
-  // Get |NGOffsetMapping| for the |layout_block_flow|. If |layout_block_flow|
-  // is LayoutNG and it is already laid out, this function is the same as
-  // |ComputeOffsetMappingIfNeeded|. |storage| is not used in this case, and can
-  // be null.
-  //
-  // Otherwise, this function computes |NGOffsetMapping| and store in |storage|
-  // as well as returning the pointer. The caller is responsible for keeping
-  // |storage| for the life cycle of the returned |NGOffsetMapping|.
-  // TODO(yosin): We should get rid of |storage| parameter, since it is no
-  // longer used.
+  // Get |NGOffsetMapping| for the |layout_block_flow|. |layout_block_flow|
+  // should be laid out. This function works for both new and legacy layout.
   static const NGOffsetMapping* GetOffsetMapping(
-      LayoutBlockFlow* layout_block_flow,
-      std::unique_ptr<NGOffsetMapping>* storage);
+      LayoutBlockFlow* layout_block_flow);
 
   bool IsBidiEnabled() const { return Data().is_bidi_enabled_; }
   TextDirection BaseDirection() const { return Data().BaseDirection(); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
index 91494106..330fe32 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -201,7 +201,7 @@
   LayoutBlockFlow* context = NGInlineFormattingContextOf(position);
   if (!context)
     return nullptr;
-  return NGInlineNode::GetOffsetMapping(context, nullptr);
+  return NGInlineNode::GetOffsetMapping(context);
 }
 
 // static
@@ -214,7 +214,7 @@
   LayoutBlockFlow* context = layout_object->ContainingNGBlockFlow();
   if (!context)
     return nullptr;
-  return NGInlineNode::GetOffsetMapping(context, nullptr);
+  return NGInlineNode::GetOffsetMapping(context);
 }
 
 // static
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
index 58aaabf..00eebffc 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -1181,9 +1181,8 @@
   // engine.
   DCHECK_EQ(layout_block_flow->IsLayoutNGMixin(), GetParam());
 
-  std::unique_ptr<NGOffsetMapping> storage;
   const NGOffsetMapping* mapping =
-      NGInlineNode::GetOffsetMapping(layout_block_flow, &storage);
+      NGInlineNode::GetOffsetMapping(layout_block_flow);
   EXPECT_TRUE(mapping);
 
   const String& text_content = mapping->GetText();
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 4d8f8eb..974d4af 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -276,7 +276,7 @@
   // FIXME: Unfortunately we can't assert on this at the moment, because this
   // is called in the base constructor for both LocalFrame and RemoteFrame,
   // when the vtables for the derived classes have not yet been setup. Once this
-  // is fixed, also call  page_scheduler_->SetIsMainFrameLocal() from here
+  // is fixed, also call page_scheduler_->SetIsMainFrameLocal(true) from here
   // instead of from the callers of this method.
   main_frame_ = main_frame;
 }
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index f3415166..7a61f26 100644
--- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -320,7 +320,8 @@
 
 Node* SpatialNavigationController::StartingNode() {
   if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled()) {
-    if (interest_element_ && interest_element_->GetDocument().GetFrame()) {
+    if (interest_element_ && interest_element_->isConnected() &&
+        interest_element_->GetDocument().GetFrame()) {
       // If an iframe is interested, start the search from its document node.
       // This matches the behavior in the focus case below where focusing a
       // frame means the focused document doesn't have a focused element and so
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index 8494a62..9dec43f4 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -339,8 +339,18 @@
     return;
   }
 
-  PaintLineBoxChildren(box_fragment_.Children(), paint_info.ForDescendants(),
-                       paint_offset);
+  DCHECK(layout_object->IsLayoutBlockFlow());
+  const LayoutBlock& layout_block = ToLayoutBlock(*layout_object);
+  if (layout_block.IsLayoutView() ||
+      !paint_info.SuppressPaintingDescendants()) {
+    DCHECK(layout_block.ChildrenInline());
+    if (ShouldPaintDescendantOutlines(paint_info.phase)) {
+      ObjectPainter(layout_block).PaintInlineChildrenOutlines(paint_info);
+    } else {
+      PaintLineBoxChildren(box_fragment_.Children(),
+                           paint_info.ForDescendants(), paint_offset);
+    }
+  }
 }
 
 void NGBoxFragmentPainter::PaintInlineChild(const NGPaintFragment& child,
diff --git a/third_party/blink/renderer/core/paint/theme_painter.cc b/third_party/blink/renderer/core/paint/theme_painter.cc
index d406c6e..d7faae6f 100644
--- a/third_party/blink/renderer/core/paint/theme_painter.cc
+++ b/third_party/blink/renderer/core/paint/theme_painter.cc
@@ -193,14 +193,6 @@
     case kMediaTimeRemainingPart:
     case kMediaCurrentTimePart:
     case kMediaControlsBackgroundPart:
-    case kMediaCastOffButtonPart:
-    case kMediaOverlayCastOffButtonPart:
-    case kMediaTrackSelectionCheckmarkPart:
-    case kMediaClosedCaptionsIconPart:
-    case kMediaSubtitlesIconPart:
-    case kMediaOverflowMenuButtonPart:
-    case kMediaRemotingCastIconPart:
-    case kMediaDownloadIconPart:
       return true;
     case kMenulistButtonPart:
     case kTextFieldPart:
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
index ec460ab..0d6a1dd 100644
--- a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
+++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
@@ -36,11 +36,8 @@
     frame_test_helpers::TestWebWidgetClient& widget_client) {
   web_view_ = &web_view;
   layer_tree_view_ = &layer_tree_view;
-  DCHECK_EQ(&layer_tree_view, web_view_->LayerTreeView());
   test_web_view_client_ = &view_client;
-  DCHECK_EQ(test_web_view_client_, web_view_->Client());
   test_web_widget_client_ = &widget_client;
-  DCHECK_EQ(test_web_widget_client_, web_view_->WidgetClient());
 
   // SimCompositor starts with defer commits enabled, but uses synchronous
   // compositing which does not use defer commits anyhow, it only uses it for
diff --git a/third_party/blink/renderer/modules/idle/idle_state.cc b/third_party/blink/renderer/modules/idle/idle_state.cc
index 9b041bd..36b68a5 100644
--- a/third_party/blink/renderer/modules/idle/idle_state.cc
+++ b/third_party/blink/renderer/modules/idle/idle_state.cc
@@ -24,18 +24,18 @@
 
 String IdleState::user() const {
   switch (state_->user) {
-    case mojom::blink::UserIdleState::ACTIVE:
+    case mojom::blink::UserIdleState::kActive:
       return "active";
-    case mojom::blink::UserIdleState::IDLE:
+    case mojom::blink::UserIdleState::kIdle:
       return "idle";
   }
 }
 
 String IdleState::screen() const {
   switch (state_->screen) {
-    case mojom::blink::ScreenIdleState::LOCKED:
+    case mojom::blink::ScreenIdleState::kLocked:
       return "locked";
-    case mojom::blink::ScreenIdleState::UNLOCKED:
+    case mojom::blink::ScreenIdleState::kUnlocked:
       return "unlocked";
   }
 }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index 45bf4c0..14ed7d3 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -938,9 +938,7 @@
 
   UpdatePlayState();
 
-  UpdateCurrentTimeDisplay();
-
-  timeline_->SetPosition(MediaElement().currentTime());
+  UpdateTimeIndicators();
 
   OnVolumeChange();
   OnTextTracksAddedOrRemoved();
@@ -955,6 +953,11 @@
   OnControlsListUpdated();
 }
 
+void MediaControlsImpl::UpdateTimeIndicators() {
+  timeline_->SetPosition(MediaElement().currentTime());
+  UpdateCurrentTimeDisplay();
+}
+
 void MediaControlsImpl::OnControlsListUpdated() {
   BatchedControlUpdate batch(this);
 
@@ -1125,6 +1128,9 @@
   if (panel_->KeepDisplayedForAccessibility())
     return false;
 
+  if (MediaElement().seeking())
+    return false;
+
   return true;
 }
 
@@ -1620,8 +1626,7 @@
       is_mouse_over_controls_ = true;
       if (!MediaElement().paused()) {
         MakeOpaqueFromPointerEvent();
-        if (ShouldHideMediaControls())
-          StartHideMediaControlsTimer();
+        StartHideMediaControlsIfNecessary();
       }
     }
   } else if (event->type() == event_type_names::kPointerout) {
@@ -1804,6 +1809,11 @@
   overlay_cast_button_->SetIsWanted(false);
 }
 
+void MediaControlsImpl::StartHideMediaControlsIfNecessary() {
+  if (ShouldHideMediaControls())
+    StartHideMediaControlsTimer();
+}
+
 void MediaControlsImpl::StartHideMediaControlsTimer() {
   hide_media_controls_timer_.StartOneShot(
       GetTimeWithoutMouseMovementBeforeHidingMediaControls(), FROM_HERE);
@@ -1877,8 +1887,7 @@
 }
 
 void MediaControlsImpl::OnTimeUpdate() {
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
 
   // 'timeupdate' might be called in a paused state. The controls should not
   // become transparent in that case.
@@ -1920,8 +1929,7 @@
 
 void MediaControlsImpl::OnPlay() {
   UpdatePlayState();
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
   UpdateCSSClassFromState();
 }
 
@@ -1934,8 +1942,7 @@
 
 void MediaControlsImpl::OnPause() {
   UpdatePlayState();
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
   MakeOpaque();
 
   StopHideMediaControlsTimer();
@@ -1943,6 +1950,32 @@
   UpdateCSSClassFromState();
 }
 
+void MediaControlsImpl::OnSeeking() {
+  UpdateTimeIndicators();
+  if (!is_scrubbing_) {
+    is_scrubbing_ = true;
+    UpdateCSSClassFromState();
+  }
+
+  // Don't try to show the controls if the seek was caused by the video being
+  // looped.
+  if (MediaElement().Loop() && MediaElement().currentTime() == 0)
+    return;
+
+  if (!MediaElement().ShouldShowControls())
+    return;
+
+  MaybeShow();
+  StopHideMediaControlsTimer();
+}
+
+void MediaControlsImpl::OnSeeked() {
+  StartHideMediaControlsIfNecessary();
+
+  is_scrubbing_ = false;
+  UpdateCSSClassFromState();
+}
+
 void MediaControlsImpl::OnTextTracksAddedOrRemoved() {
   toggle_closed_captions_button_->UpdateDisplayType();
   toggle_closed_captions_button_->SetIsWanted(
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
index d3017292..6766552 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -282,6 +282,9 @@
 
   void ElementSizeChangedTimerFired(TimerBase*);
 
+  // Update any visible indicators of the current time.
+  void UpdateTimeIndicators();
+
   // Hide elements that don't fit, and show those things that we want which
   // do fit.  This requires that m_effectiveWidth and m_effectiveHeight are
   // current.
@@ -338,6 +341,8 @@
   void OnPlay();
   void OnPlaying();
   void OnPause();
+  void OnSeeking();
+  void OnSeeked();
   void OnTextTracksAddedOrRemoved();
   void OnTextTracksChanged();
   void OnError();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 0b92a45..3b97ac8 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -222,6 +222,9 @@
 
   void SimulateLoadedMetadata() { media_controls_->OnLoadedMetadata(); }
 
+  void SimulateOnSeeking() { media_controls_->OnSeeking(); }
+  void SimulateOnSeeked() { media_controls_->OnSeeked(); }
+
   MediaControlsImpl& MediaControls() { return *media_controls_; }
   MediaControlVolumeSliderElement* VolumeSliderElement() const {
     return media_controls_->volume_slider_;
@@ -624,6 +627,32 @@
   EXPECT_EQ(duration / 2, current_time_display->CurrentValue());
 }
 
+TEST_F(MediaControlsImplTest, TimeIndicatorsUpdatedOnSeeking) {
+  EnsureSizing();
+
+  MediaControlCurrentTimeDisplayElement* current_time_display =
+      GetCurrentTimeDisplayElement();
+  MediaControlTimelineElement* timeline = TimelineElement();
+  double duration = 1000;
+  LoadMediaWithDuration(duration);
+
+  EXPECT_EQ(0, current_time_display->CurrentValue());
+  EXPECT_EQ(0, timeline->valueAsNumber());
+
+  MediaControls().MediaElement().setCurrentTime(duration / 4);
+
+  // Time indicators are not yet updated.
+  EXPECT_EQ(0, current_time_display->CurrentValue());
+  EXPECT_EQ(0, timeline->valueAsNumber());
+
+  SimulateOnSeeking();
+
+  // The time indicators should be updated immediately when the 'seeking' event
+  // is fired.
+  EXPECT_EQ(duration / 4, current_time_display->CurrentValue());
+  EXPECT_EQ(duration / 4, timeline->valueAsNumber());
+}
+
 TEST_F(MediaControlsImplTest, TimelineMetricsWidth) {
   MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
   test::RunPendingTasks();
@@ -863,6 +892,45 @@
 
 }  // namespace
 
+TEST_F(MediaControlsImplTestWithMockScheduler, SeekingShowsControls) {
+  Element* panel = GetElementByShadowPseudoId(MediaControls(),
+                                              "-webkit-media-controls-panel");
+  ASSERT_NE(nullptr, panel);
+
+  MediaControls().MediaElement().SetSrc("http://example.com");
+  MediaControls().MediaElement().Play();
+
+  // Hide the controls to start.
+  MediaControls().Hide();
+  EXPECT_FALSE(IsElementVisible(*panel));
+
+  // Seeking should cause the controls to become visible.
+  SimulateOnSeeking();
+  EXPECT_TRUE(IsElementVisible(*panel));
+}
+
+TEST_F(MediaControlsImplTestWithMockScheduler,
+       SeekingDoesNotShowControlsWhenNoControlsAttr) {
+  Element* panel = GetElementByShadowPseudoId(MediaControls(),
+                                              "-webkit-media-controls-panel");
+  ASSERT_NE(nullptr, panel);
+
+  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
+                                                     false);
+
+  MediaControls().MediaElement().SetSrc("http://example.com");
+  MediaControls().MediaElement().Play();
+
+  // Hide the controls to start.
+  MediaControls().Hide();
+  EXPECT_FALSE(IsElementVisible(*panel));
+
+  // Seeking should not cause the controls to become visible because the
+  // controls attribute is not set.
+  SimulateOnSeeking();
+  EXPECT_FALSE(IsElementVisible(*panel));
+}
+
 TEST_F(MediaControlsImplTestWithMockScheduler,
        ControlsRemainVisibleDuringKeyboardInteraction) {
   EnsureSizing();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
index 3581220..0fe65f1f 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -36,6 +36,8 @@
   GetMediaElement().addEventListener(event_type_names::kPause, this, false);
   GetMediaElement().addEventListener(event_type_names::kDurationchange, this,
                                      false);
+  GetMediaElement().addEventListener(event_type_names::kSeeking, this, false);
+  GetMediaElement().addEventListener(event_type_names::kSeeked, this, false);
   GetMediaElement().addEventListener(event_type_names::kError, this, false);
   GetMediaElement().addEventListener(event_type_names::kLoadedmetadata, this,
                                      false);
@@ -177,6 +179,14 @@
     media_controls_->OnPause();
     return;
   }
+  if (event->type() == event_type_names::kSeeking) {
+    media_controls_->OnSeeking();
+    return;
+  }
+  if (event->type() == event_type_names::kSeeked) {
+    media_controls_->OnSeeked();
+    return;
+  }
   if (event->type() == event_type_names::kError) {
     media_controls_->OnError();
     return;
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index 5059f7e5..402a6e9 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -56,6 +56,7 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/uuid.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -1216,6 +1217,7 @@
 
 void PaymentRequest::OnPayerDetailChange(
     payments::mojom::blink::PayerDetailPtr detail) {
+  CHECK(RuntimeEnabledFeatures::PaymentRetryEnabled());
   DCHECK(payment_response_);
   DCHECK(GetPendingAcceptPromiseResolver());
   DCHECK(!complete_resolver_);
@@ -1226,6 +1228,8 @@
   event->SetPaymentDetailsUpdater(this);
   payment_response_->UpdatePayerDetail(std::move(detail));
   payment_response_->DispatchEvent(*event);
+  if (!event->is_waiting_for_update())
+    payment_provider_->NoUpdatedPaymentDetails();
 }
 
 void PaymentRequest::OnPaymentResponse(PaymentResponsePtr response) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc
index 659df9f..62e5c22 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -503,6 +503,12 @@
   Uninitialize();
 }
 
+bool AudioContext::HasPendingActivity() const {
+  // There's activity only if the context is running.  Suspended contexts are
+  // basically idle with nothing going on.
+  return (ContextState() == kRunning) && BaseAudioContext::HasPendingActivity();
+}
+
 bool AudioContext::HandlePreRenderTasks(const AudioIOPosition* output_position,
                                         const AudioIOCallbackMetric* metric) {
   DCHECK(IsAudioThread());
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.h b/third_party/blink/renderer/modules/webaudio/audio_context.h
index 8618ea5..a99e57bb 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -43,6 +43,7 @@
 
   // For ContextLifeCycleObserver
   void ContextDestroyed(ExecutionContext*) final;
+  bool HasPendingActivity() const override;
 
   ScriptPromise closeContext(ScriptState*);
   bool IsContextClosed() const final;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
index 15a015f..57c8825 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc
@@ -308,8 +308,9 @@
 bool AudioScheduledSourceNode::HasPendingActivity() const {
   // To avoid the leak, a node should be collected regardless of its
   // playback state if the context is closed.
-  if (context()->IsContextClosed())
+  if (context()->ContextState() == BaseAudioContext::kClosed) {
     return false;
+  }
 
   // If a node is scheduled or playing, do not collect the node prematurely
   // even its reference is out of scope. Then fire onended event if assigned.
diff --git a/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc b/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
index b34636ac..b9c56991 100644
--- a/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
+++ b/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
@@ -21,6 +21,12 @@
     return;
 
   for (const auto& active_wrappable : *active_script_wrappables) {
+    // Ignore objects that are currently under construction. They are kept alive
+    // via conservative stack scan.
+    if (active_wrappable->GetHeapObjectHeader() ==
+        BlinkGC::kNotFullyConstructedObject)
+      continue;
+
     if (!active_wrappable->DispatchHasPendingActivity())
       continue;
 
diff --git a/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h b/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
index 18039e55..1dac8ec3 100644
--- a/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
+++ b/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h
@@ -26,7 +26,8 @@
         HeapObjectHeader::FromPayload(descriptor.base_object_payload);
     const char* name = GCInfoTable::Get()
                            .GCInfoFromIndex(header->GcInfoIndex())
-                           ->name_(descriptor.base_object_payload);
+                           ->name(descriptor.base_object_payload)
+                           .value;
     // If this FATAL is hit, it means that a white (not discovered by
     // Trace) object was assigned as a member to a black object (already
     // processed by Trace). The black object will not be processed anymore
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc
index 99ed366..40bfd45 100644
--- a/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -426,6 +426,14 @@
   resource_request_->SetRequestedWithHeader(value);
 }
 
+const WebString WebURLRequest::GetClientDataHeader() const {
+  return resource_request_->GetClientDataHeader();
+}
+
+void WebURLRequest::SetClientDataHeader(const WebString& value) {
+  resource_request_->SetClientDataHeader(value);
+}
+
 const base::UnguessableToken& WebURLRequest::GetFetchWindowId() const {
   return resource_request_->GetFetchWindowId();
 }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index 211cdeb..ab9ad57 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -159,29 +159,6 @@
   return traced_value;
 }
 
-static SkColor DisplayItemBackgroundColor(const DisplayItem& item) {
-  if (item.GetType() != DisplayItem::kBoxDecorationBackground &&
-      item.GetType() != DisplayItem::kDocumentBackground)
-    return SK_ColorTRANSPARENT;
-
-  const auto& drawing_item = static_cast<const DrawingDisplayItem&>(item);
-  const auto record = drawing_item.GetPaintRecord();
-  if (!record)
-    return SK_ColorTRANSPARENT;
-
-  for (cc::PaintOpBuffer::Iterator it(record.get()); it; ++it) {
-    const auto* op = *it;
-    if (op->GetType() == cc::PaintOpType::DrawRect ||
-        op->GetType() == cc::PaintOpType::DrawRRect) {
-      const auto& flags = static_cast<const cc::PaintOpWithFlags*>(op)->flags;
-      // Skip op with looper which may modify the color.
-      if (!flags.getLooper() && flags.getStyle() == cc::PaintFlags::kFill_Style)
-        return flags.getColor();
-    }
-  }
-  return SK_ColorTRANSPARENT;
-}
-
 scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
     scoped_refptr<const PaintArtifact> paint_artifact,
     const PaintChunkSubset& paint_chunks,
@@ -234,11 +211,14 @@
       display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList,
       base::OptionalOrNullptr(params));
 
-  if (paint_chunks[0].size()) {
-    cc_picture_layer_->SetBackgroundColor(DisplayItemBackgroundColor(
-        display_item_list[paint_chunks[0].begin_index]));
-  }
-
+  cc_picture_layer_->SetSafeOpaqueBackgroundColor(
+      paint_chunks[0].safe_opaque_background_color);
+  // TODO(masonfreed): We don't need to set the background color here; only the
+  // safe opaque background color matters. But making that change would require
+  // rebaselining 787 tests to remove the "background_color" property from the
+  // layer dumps.
+  cc_picture_layer_->SetBackgroundColor(
+      paint_chunks[0].safe_opaque_background_color);
   return cc_picture_layer_;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index b27c991..333488c 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -440,6 +440,7 @@
       GetEffectTree().Insert(cc::EffectNode(), current_.effect_id));
   mask_effect.stable_id = mask_effect_id.GetInternalValue();
   mask_effect.clip_id = clip_id;
+  mask_effect.has_render_surface = true;
   mask_effect.blend_mode = SkBlendMode::kDstIn;
 
   const auto& clip_space = current_.clip->LocalTransformSpace();
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc b/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
index e00fa0a..6d488e2 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
@@ -18,6 +18,29 @@
 
 namespace {
 
+static SkColor DisplayItemBackgroundColor(const DisplayItem& item) {
+  if (item.GetType() != DisplayItem::kBoxDecorationBackground &&
+      item.GetType() != DisplayItem::kDocumentBackground)
+    return SK_ColorTRANSPARENT;
+
+  const auto& drawing_item = static_cast<const DrawingDisplayItem&>(item);
+  const auto record = drawing_item.GetPaintRecord();
+  if (!record)
+    return SK_ColorTRANSPARENT;
+
+  for (cc::PaintOpBuffer::Iterator it(record.get()); it; ++it) {
+    const auto* op = *it;
+    if (op->GetType() == cc::PaintOpType::DrawRect ||
+        op->GetType() == cc::PaintOpType::DrawRRect) {
+      const auto& flags = static_cast<const cc::PaintOpWithFlags*>(op)->flags;
+      // Skip op with looper which may modify the color.
+      if (!flags.getLooper() && flags.getStyle() == cc::PaintFlags::kFill_Style)
+        return flags.getColor();
+    }
+  }
+  return SK_ColorTRANSPARENT;
+}
+
 void ComputeChunkDerivedData(const DisplayItemList& display_items,
                              PaintChunk& chunk) {
   // This happens in tests testing paint chunks without display items.
@@ -25,7 +48,8 @@
     return;
 
   SkRegion known_to_be_opaque_region;
-  for (const DisplayItem& item : display_items.ItemsInPaintChunk(chunk)) {
+  auto items = display_items.ItemsInPaintChunk(chunk);
+  for (const DisplayItem& item : items) {
     chunk.bounds.Unite(item.VisualRect());
     chunk.outset_for_raster_effects = std::max(chunk.outset_for_raster_effects,
                                                item.OutsetForRasterEffects());
@@ -50,6 +74,11 @@
 
   if (known_to_be_opaque_region.contains(EnclosingIntRect(chunk.bounds)))
     chunk.known_to_be_opaque = true;
+
+  if (items.begin() != items.end()) {
+    chunk.safe_opaque_background_color =
+        DisplayItemBackgroundColor(*items.begin());
+  }
 }
 
 // For PaintArtifact::AppendDebugDrawing().
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
index d109fb5..78f1c69 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
@@ -10,14 +10,15 @@
 namespace blink {
 
 struct SameSizeAsPaintChunk {
-  size_t begin;
-  size_t end;
+  size_t begin_index;
+  size_t end_index;
   PaintChunk::Id id;
   PropertyTreeState properties;
-  unsigned bools;
-  float extend;
   FloatRect bounds;
-  void* pointers[1];
+  float outset_for_raster_effects;
+  SkColor safe_opaque_background_color;
+  unsigned bools;  // known_to_be_opaque, is_cacheable, client_is_just_created
+  void* pointers[1];  // hit_test_data
 };
 
 static_assert(sizeof(PaintChunk) == sizeof(SameSizeAsPaintChunk),
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
index 4c8bb287..def3c9f 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
@@ -105,6 +105,8 @@
   // all clients of items in this chunk.
   float outset_for_raster_effects = 0;
 
+  SkColor safe_opaque_background_color = 0;
+
   // True if the bounds are filled entirely with opaque contents.
   bool known_to_be_opaque = false;
 
diff --git a/third_party/blink/renderer/platform/heap/blink_gc.h b/third_party/blink/renderer/platform/heap/blink_gc.h
index bc35c351..d6663b55 100644
--- a/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -25,7 +25,6 @@
 using TraceCallback = VisitorCallback;
 using WeakCallback = VisitorCallback;
 using EphemeronCallback = VisitorCallback;
-using NameCallback = const char* (*)(const void* self);
 
 // Simple alias to avoid heap compaction type signatures turning into
 // a sea of generic |void*|s.
diff --git a/third_party/blink/renderer/platform/heap/gc_info.h b/third_party/blink/renderer/platform/heap/gc_info.h
index 37925ae..f9934e8 100644
--- a/third_party/blink/renderer/platform/heap/gc_info.h
+++ b/third_party/blink/renderer/platform/heap/gc_info.h
@@ -24,23 +24,14 @@
 
 namespace blink {
 
-// GCInfo contains meta-data associated with object classes allocated in the
-// Blink heap. This meta-data consists of a function pointer used to trace the
-// pointers in the class instance during garbage collection, an indication of
-// whether or not the instance needs a finalization callback, and a function
-// pointer used to finalize the instance when the garbage collector determines
-// that the instance is no longer reachable. There is a GCInfo struct for each
-// class that directly inherits from GarbageCollected or
-// GarbageCollectedFinalized.
+// GCInfo contains metadata for objects that are instantiated from classes that
+// inherit for GarbageCollected or GarbageCollectedFinalized.
 struct GCInfo {
-  bool HasFinalizer() const { return non_trivial_finalizer_; }
-  bool HasVTable() const { return has_v_table_; }
-
-  TraceCallback trace_;
-  FinalizationCallback finalize_;
-  NameCallback name_;
-  bool non_trivial_finalizer_;
-  bool has_v_table_;
+  const TraceCallback trace;
+  const FinalizationCallback finalize;
+  const NameCallback name;
+  const bool non_trivial_finalizer;
+  const bool has_v_table;
 };
 
 #if DCHECK_IS_ON()
@@ -65,7 +56,7 @@
 
   inline const GCInfo* GCInfoFromIndex(uint32_t index) {
     DCHECK_GE(index, 1u);
-    DCHECK(index < kMaxIndex);
+    DCHECK_LT(index, kMaxIndex);
     DCHECK(table_);
     const GCInfo* info = table_[index];
     DCHECK(info);
@@ -74,21 +65,21 @@
 
   uint32_t EnsureGCInfoIndex(const GCInfo*, std::atomic_uint32_t*);
 
-  uint32_t GcInfoIndex() { return current_index_; }
+  uint32_t GcInfoIndex() const { return current_index_; }
 
  private:
   FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty);
   FRIEND_TEST_ALL_PREFIXES(GCInfoTest, ResizeToMaxIndex);
 
+  // Singleton for each process. Retrieved through Get().
+  static GCInfoTable* global_table_;
+
   // Use GCInfoTable::Get() for retrieving the global table outside of testing
   // code.
   GCInfoTable();
 
   void Resize();
 
-  // Singleton for each process. Retrieved through Get().
-  static GCInfoTable* global_table_;
-
   // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an
   // index into this table.
   const GCInfo** table_ = nullptr;
@@ -111,10 +102,9 @@
   static uint32_t Index() {
     static_assert(sizeof(T), "T must be fully defined");
     static const GCInfo kGcInfo = {
-        TraceTrait<T>::Trace,          FinalizerTrait<T>::Finalize,
-        NameTrait<T>::GetName,         FinalizerTrait<T>::kNonTrivialFinalizer,
-        std::is_polymorphic<T>::value,
-    };
+        TraceTrait<T>::Trace, FinalizerTrait<T>::Finalize,
+        NameTrait<T>::GetName, FinalizerTrait<T>::kNonTrivialFinalizer,
+        std::is_polymorphic<T>::value};
     // This is more complicated than using threadsafe initialization, but this
     // is instantiated many times (once for every GC type).
     static std::atomic_uint32_t gc_info_index{0};
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc
index ad950a9..3b62f5c1 100644
--- a/third_party/blink/renderer/platform/heap/heap.cc
+++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -632,7 +632,7 @@
   marking_worklist_->Push(
       WorklistTaskId::MainThread,
       {header->Payload(),
-       GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex())->trace_});
+       GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex())->trace});
 }
 
 ThreadHeap* ThreadHeap::main_thread_heap_ = nullptr;
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h
index 7f58d56..ab038ce 100644
--- a/third_party/blink/renderer/platform/heap/heap.h
+++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -697,7 +697,7 @@
   // TODO(haraken): We don't support reallocate() for finalizable objects.
   DCHECK(!GCInfoTable::Get()
               .GCInfoFromIndex(previous_header->GcInfoIndex())
-              ->HasFinalizer());
+              ->non_trivial_finalizer);
   DCHECK_EQ(previous_header->GcInfoIndex(), gc_info_index);
   HeapAllocHooks::FreeHookIfEnabled(static_cast<Address>(previous));
   Address address;
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index 6aa0768..96537e05 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -99,8 +99,8 @@
 void HeapObjectHeader::Finalize(Address object, size_t object_size) {
   HeapAllocHooks::FreeHookIfEnabled(object);
   const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex());
-  if (gc_info->HasFinalizer())
-    gc_info->finalize_(object);
+  if (gc_info->non_trivial_finalizer)
+    gc_info->finalize(object);
 
   ASAN_RETIRE_CONTAINER_ANNOTATION(object, object_size);
 }
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
index ed5bfd8..bfafd73 100644
--- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -38,7 +38,7 @@
     header->Unmark();
     GCInfoTable::Get()
         .GCInfoFromIndex(header->GcInfoIndex())
-        ->trace_(this, header->Payload());
+        ->trace(this, header->Payload());
   }
 
   void Visit(void* obj, TraceDescriptor desc) final {
diff --git a/third_party/blink/renderer/platform/heap/marking_verifier.h b/third_party/blink/renderer/platform/heap/marking_verifier.h
index d4955eb..8a5bc5c 100644
--- a/third_party/blink/renderer/platform/heap/marking_verifier.h
+++ b/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -25,10 +25,10 @@
     const GCInfo* info =
         GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
     const bool can_verify =
-        !info->HasVTable() || blink::VTableInitialized(header->Payload());
+        !info->has_v_table || blink::VTableInitialized(header->Payload());
     if (can_verify) {
       CHECK(header->IsValid());
-      info->trace_(this, header->Payload());
+      info->trace(this, header->Payload());
     }
   }
 
diff --git a/third_party/blink/renderer/platform/heap/marking_visitor.cc b/third_party/blink/renderer/platform/heap/marking_visitor.cc
index b95eb73..25feea2c 100644
--- a/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -49,7 +49,7 @@
   DCHECK(!header->IsInConstruction());
   const GCInfo* gc_info =
       GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
-  MarkHeader(header, gc_info->trace_);
+  MarkHeader(header, gc_info->trace);
 }
 
 void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
@@ -68,7 +68,7 @@
   const GCInfo* gc_info =
       GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
   if (!header->IsInConstruction()) {
-    MarkHeader(header, gc_info->trace_);
+    MarkHeader(header, gc_info->trace);
     return;
   }
 
@@ -154,7 +154,7 @@
   // strongifies them for the current cycle.
   GCInfoTable::Get()
       .GCInfoFromIndex(header->GcInfoIndex())
-      ->trace_(thread_state->CurrentVisitor(), value);
+      ->trace(thread_state->CurrentVisitor(), value);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/name_trait_test.cc b/third_party/blink/renderer/platform/heap/name_trait_test.cc
index 08203bd..44fb5e3 100644
--- a/third_party/blink/renderer/platform/heap/name_trait_test.cc
+++ b/third_party/blink/renderer/platform/heap/name_trait_test.cc
@@ -37,7 +37,7 @@
 
 TEST(NameTraitTest, DefaultName) {
   ClassWithoutName no_name;
-  const char* name = NameTrait<ClassWithoutName>::GetName(&no_name);
+  const char* name = NameTrait<ClassWithoutName>::GetName(&no_name).value;
   if (NameTrait<ClassWithoutName>::HideInternalName()) {
     EXPECT_EQ(0, strcmp(name, "InternalNode"));
   } else {
@@ -47,7 +47,7 @@
 
 TEST(NameTraitTest, CustomName) {
   ClassWithName with_name("CustomName");
-  const char* name = NameTrait<ClassWithName>::GetName(&with_name);
+  const char* name = NameTrait<ClassWithName>::GetName(&with_name).value;
   EXPECT_EQ(0, strcmp(name, "CustomName"));
 }
 
diff --git a/third_party/blink/renderer/platform/heap/name_traits.h b/third_party/blink/renderer/platform/heap/name_traits.h
index 941fc88b..c994d5e0 100644
--- a/third_party/blink/renderer/platform/heap/name_traits.h
+++ b/third_party/blink/renderer/platform/heap/name_traits.h
@@ -12,6 +12,13 @@
 
 namespace blink {
 
+struct HeapObjectName {
+  const char* value;
+  bool name_is_hidden;
+};
+
+using NameCallback = HeapObjectName (*)(const void*);
+
 template <typename T>
 class NameTrait {
   STATIC_ONLY(NameTrait);
@@ -25,16 +32,16 @@
 #endif
   }
 
-  static const char* GetName(const void* obj) {
+  static HeapObjectName GetName(const void* obj) {
     return GetNameFor(static_cast<const T*>(obj));
   }
 
  private:
-  static const char* GetNameFor(const NameClient* wrapper_tracable) {
-    return wrapper_tracable->NameInHeapSnapshot();
+  static HeapObjectName GetNameFor(const NameClient* wrapper_tracable) {
+    return {wrapper_tracable->NameInHeapSnapshot(), false};
   }
 
-  static const char* GetNameFor(...) {
+  static HeapObjectName GetNameFor(...) {
     // For non-official builds construct the name of a type from a compiler
     // intrinsic.
     //
@@ -43,12 +50,12 @@
     // (b) avoid exposing internal types until a proper DevTools frontend
     //     implementation is present.
 #if defined(OFFICIAL_BUILD) || !(defined(COMPILER_GCC) || defined(__clang__))
-    return "InternalNode";
+    return {"InternalNode", true};
 #else
     DCHECK(!HideInternalName());
     static const char* leaky_class_name = nullptr;
     if (leaky_class_name)
-      return leaky_class_name;
+      return {leaky_class_name, false};
 
     // Parsing string of structure:
     //   const char *WTF::GetStringWithTypeName<TYPE>() [T = TYPE]
@@ -59,7 +66,7 @@
     const auto len = raw.length() - start_pos - 1;
     const std::string name = raw.substr(start_pos, len).c_str();
     leaky_class_name = strcpy(new char[name.length() + 1], name.c_str());
-    return leaky_class_name;
+    return {leaky_class_name, false};
 #endif
   }
 };
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e881d26..3e2b2bb 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -989,6 +989,7 @@
     {
       name: "OverscrollCustomization",
       settable_from_internals: true,
+      status: "experimental",
     },
     // This feature refers to the API that delivers notifications to pages on
     // lifecycle state changes.
@@ -1044,6 +1045,7 @@
     },
     {
       name: "PaymentRequestHasEnrolledInstrument",
+      status: "stable",
     },
     {
       name: "PaymentRequestMerchantValidationEvent",
diff --git a/third_party/blink/renderer/platform/theme_types.h b/third_party/blink/renderer/platform/theme_types.h
index b43231ea..caf5d4b 100644
--- a/third_party/blink/renderer/platform/theme_types.h
+++ b/third_party/blink/renderer/platform/theme_types.h
@@ -71,14 +71,6 @@
   kMediaControlsFullscreenBackgroundPart,
   kMediaCurrentTimePart,
   kMediaTimeRemainingPart,
-  kMediaCastOffButtonPart,
-  kMediaOverlayCastOffButtonPart,
-  kMediaTrackSelectionCheckmarkPart,
-  kMediaClosedCaptionsIconPart,
-  kMediaSubtitlesIconPart,
-  kMediaOverflowMenuButtonPart,
-  kMediaDownloadIconPart,
-  kMediaRemotingCastIconPart,
   kMediaControlPart,
   kMenulistPart,
   kMenulistButtonPart,
@@ -96,7 +88,6 @@
   kSearchFieldCancelButtonPart,
   kTextFieldPart,
   kTextAreaPart,
-  kCapsLockIndicatorPart
 };
 
 enum SelectionPart { kSelectionBackground, kSelectionForeground };
diff --git a/third_party/blink/tools/blinkpy/common/system/executive_mock.py b/third_party/blink/tools/blinkpy/common/system/executive_mock.py
index 553cd01..aedb0fd0 100644
--- a/third_party/blink/tools/blinkpy/common/system/executive_mock.py
+++ b/third_party/blink/tools/blinkpy/common/system/executive_mock.py
@@ -60,6 +60,9 @@
     def kill(self):
         return
 
+    def terminate(self):
+        return
+
 
 MockCall = collections.namedtuple(
     'MockCall', ('args', 'kwargs'))
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/linux.py b/third_party/blink/tools/blinkpy/web_tests/port/linux.py
index a14f0a0f..29a3d19 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/linux.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/linux.py
@@ -29,6 +29,7 @@
 import logging
 import tempfile
 
+from blinkpy.common.exit_codes import SYS_DEPS_EXIT_STATUS
 from blinkpy.web_tests.breakpad.dump_reader_multipart import DumpReaderLinux
 from blinkpy.web_tests.port import base
 from blinkpy.web_tests.port import win
@@ -47,7 +48,7 @@
 
     BUILD_REQUIREMENTS_URL = 'https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md'
 
-    XVFB_START_TIMEOUT = 5.0  # Wait up to 5 seconds for Xvfb to start.
+    XVFB_START_STOP_TIMEOUT = 5.0  # Wait up to 5 seconds for Xvfb to start or stop.
 
     @classmethod
     def determine_full_port_name(cls, host, options, port_name):
@@ -109,7 +110,8 @@
 
     def setup_test_run(self):
         super(LinuxPort, self).setup_test_run()
-        self._start_xvfb()
+        if not self._start_xvfb():
+            return SYS_DEPS_EXIT_STATUS
         self._setup_dummy_home_dir()
 
     def clean_up_test_run(self):
@@ -161,7 +163,7 @@
         display = self._find_display()
         if not display:
             _log.critical('Failed to find a free display to start Xvfb.')
-            return
+            return False
 
         # Parts of Xvfb use a hard-coded "/tmp" for its temporary directory.
         # This can cause a failure when those parts expect to hardlink against
@@ -190,7 +192,7 @@
         # While xvfb is running, the poll() method will return None;
         # https://docs.python.org/2/library/subprocess.html#subprocess.Popen.poll
         start_time = self.host.time()
-        while self.host.time() - start_time < self.XVFB_START_TIMEOUT:
+        while self.host.time() - start_time < self.XVFB_START_STOP_TIMEOUT:
             if self._xvfb_process.poll() is not None:
                 break
             # We don't explicitly set the display, as we want to check the
@@ -199,13 +201,14 @@
                 ['xdpyinfo'], return_exit_code=True)
             if exit_code == 0:
                 _log.debug('Successfully started Xvfb with display "%s".', display)
-                return
+                return True
             _log.warn('xdpyinfo check failed with exit code %s while starting Xvfb on "%s".', exit_code, display)
             self.host.sleep(0.1)
 
         retcode = self._xvfb_process.poll()
         self._stop_xvfb(save_logs=True)
         _log.critical('Failed to start Xvfb on display "%s" (xvfb retcode: %r).', display, retcode)
+        return False
 
     def _find_display(self):
         """Tries to find a free X display, looping if necessary."""
@@ -228,9 +231,17 @@
         if self._xvfb_stderr:
             self._xvfb_stderr.close()
         if self._xvfb_process and self._xvfb_process.poll() is None:
-            _log.debug('Killing Xvfb process pid %d.', self._xvfb_process.pid)
-            self._xvfb_process.kill()
-            self._xvfb_process.wait()
+            self._xvfb_process.terminate()
+            start_time = self.host.time()
+            while self.host.time() - start_time < self.XVFB_START_STOP_TIMEOUT:
+                if self._xvfb_process.poll() is not None:
+                    _log.debug('Xvfb exited with code %d.', self._xvfb_process.poll())
+                    break
+                self.host.sleep(0.1)
+            else:
+                _log.debug('Killing Xvfb process pid %d.', self._xvfb_process.pid)
+                self._xvfb_process.kill()
+                self._xvfb_process.wait()
         if save_logs and self._xvfb_stdout and self.host.filesystem.exists(self._xvfb_stdout.name):
             for line in self.host.filesystem.read_text_file(self._xvfb_stdout.name).splitlines():
                 _log.warn('Xvfb stdout:  %s', line)
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/linux_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/linux_unittest.py
index 76199443..ad851beb 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/linux_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/linux_unittest.py
@@ -29,6 +29,7 @@
 import logging
 import optparse
 
+from blinkpy.common.exit_codes import SYS_DEPS_EXIT_STATUS
 from blinkpy.common.system.executive_mock import MockExecutive, MockProcess
 from blinkpy.common.system.log_testing import LoggingTestCase
 from blinkpy.common.system.system_host_mock import MockSystemHost
@@ -85,15 +86,23 @@
         self.assertEqual('linux', self.make_port().operating_system())
 
     def test_driver_name_option(self):
+        # pylint: disable=protected-access
         self.assertTrue(self.make_port()._path_to_driver().endswith('content_shell'))
         port = self.make_port(options=optparse.Values({'driver_name': 'OtherDriver'}))
-        self.assertTrue(port._path_to_driver().endswith('OtherDriver'))  # pylint: disable=protected-access
+        self.assertTrue(port._path_to_driver().endswith('OtherDriver'))
 
     def test_path_to_image_diff(self):
+        # pylint: disable=protected-access
         self.assertEqual(self.make_port()._path_to_image_diff(), '/mock-checkout/out/Release/image_diff')
 
     def test_dummy_home_dir_is_created_and_cleaned_up(self):
+        def run_command_fake(args):
+            if args[0:2] == ['xdpyinfo', '-display']:
+                return 1
+            return 0
+
         port = self.make_port()
+        port.host.executive = MockExecutive(run_command_fn=run_command_fake)
         port.host.environ['HOME'] = '/home/user'
         port.host.filesystem.files['/home/user/.Xauthority'] = ''
 
@@ -116,9 +125,9 @@
             return 0
 
         port = self.make_port()
-        port.host.executive = MockExecutive(
-            run_command_fn=run_command_fake)
-        port.setup_test_run()
+        port.host.executive = MockExecutive(run_command_fn=run_command_fake)
+
+        self.assertIsNone(port.setup_test_run())
         self.assertEqual(
             port.host.executive.calls,
             [
@@ -138,8 +147,8 @@
         port = self.make_port()
         port.host.environ['TMPDIR'] = '/foo/bar'
         port.host.executive = MockExecutive(run_command_fn=run_command_fake)
-        port.setup_test_run()
 
+        self.assertIsNone(port.setup_test_run())
         self.assertEqual(
             port.host.executive.calls,
             [
@@ -158,13 +167,14 @@
             return 0
 
         port = self.make_port()
-        port.host.executive = MockExecutive(
-            run_command_fn=run_command_fake)
-        port.setup_test_run()
+        port.host.filesystem.files['/tmp/.X99-lock'] = ''
+        port.host.executive = MockExecutive(run_command_fn=run_command_fake)
+
+        self.assertIsNone(port.setup_test_run())
         self.assertEqual(
             port.host.executive.calls,
             [
-                ['xdpyinfo', '-display', ':99'],
+                # Do not call `xdpyinfo -display :99` because the lock exists.
                 ['xdpyinfo', '-display', ':100'],
                 ['xdpyinfo', '-display', ':101'],
                 ['xdpyinfo', '-display', ':102'],
@@ -188,9 +198,9 @@
             return 0
 
         port = self.make_port()
-        port.host.executive = MockExecutive(
-            run_command_fn=run_command_fake)
-        port.setup_test_run()
+        port.host.executive = MockExecutive(run_command_fn=run_command_fake)
+
+        self.assertIsNone(port.setup_test_run())
         self.assertEqual(
             port.host.executive.calls,
             [
@@ -212,11 +222,10 @@
 
         host = MockSystemHost(os_name=self.os_name, os_version=self.os_version)
         port = self.make_port(host=host)
-        port.host.executive = MockExecutive(
-            run_command_fn=run_command_fake)
+        port.host.executive = MockExecutive(run_command_fn=run_command_fake)
         self.set_logging_level(logging.DEBUG)
 
-        port.setup_test_run()
+        self.assertEqual(port.setup_test_run(), SYS_DEPS_EXIT_STATUS)
         self.assertEqual(
             port.host.executive.calls,
             [
@@ -249,7 +258,7 @@
             run_command_fn=run_command_fake, proc=proc)
         self.set_logging_level(logging.DEBUG)
 
-        port.setup_test_run()
+        self.assertEqual(port.setup_test_run(), SYS_DEPS_EXIT_STATUS)
         self.assertEqual(
             port.host.executive.calls,
             [
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
index 4f5c6c5..f5ee624 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -431,3 +431,6 @@
 Bug(none) http/tests/devtools/layers/layer-compositing-reasons.js [ Failure ]
 # Missing WheelEventHandler
 Bug(none) http/tests/devtools/layers/layer-scroll-rects-get.js [ Failure ]
+
+# Other:
+crbug.com/935728 fast/frames/transparent-scrollbar.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0ab16a9..85ae8a2a 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -87,6 +87,11 @@
 crbug.com/922725 virtual/android/fullscreen/full-screen-iframe-zIndex.html [ Timeout ]
 crbug.com/922725 virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex.html [ Timeout ]
 
+# The following tests would pass with User Activation Delegation.
+crbug.com/928838 external/wpt/html/user-activation/activation-transfer-with-click.tentative.html [ Failure ]
+crbug.com/928838 external/wpt/html/user-activation/activation-transfer-without-click.tentative.html [ Failure ]
+crbug.com/928838 external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html [ Failure ]
+
 # The following fail only on Mac.
 crbug.com/891427 [ Mac ] fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
 crbug.com/891427 [ Mac ] virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ]
@@ -5919,3 +5924,15 @@
 
 # Wasm threads enabled by default
 crbug.com/754910 virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/wasm-threads-origin-trial-disabled.html [ Skip ]
+
+# Sheriff 2019-02-28
+crbug.com/936827 external/wpt/fullscreen/api/element-request-fullscreen-and-remove-manual.html [ Failure Pass ]
+
+# Enable WPT animation-worklet test to run with threaded-compositing
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/animation-worklet-inside-iframe.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/animator-animate.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/animator-with-options.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/scroll-timeline-writing-modes.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/worklet-animation-pause-resume.https.html [ Pass Failure ]
+crbug.com/915352 virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-fill-mode.https.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 5b09680..eb3ea0c 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -29,6 +29,11 @@
     "base": "animations/animationworklet",
     "args": ["--enable-threaded-compositing"]
   },
+   {
+    "prefix": "threaded",
+    "base": "external/wpt/animation-worklet",
+    "args": ["--enable-threaded-compositing"]
+  },
   {
     "prefix": "threaded",
     "base": "lifecycle",
diff --git a/third_party/blink/web_tests/compositing/overflow/tiled-mask-expected.png b/third_party/blink/web_tests/compositing/overflow/tiled-mask-expected.png
index 2fb86778..0eac266 100644
--- a/third_party/blink/web_tests/compositing/overflow/tiled-mask-expected.png
+++ b/third_party/blink/web_tests/compositing/overflow/tiled-mask-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_over_ineditable.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_over_ineditable.html
new file mode 100644
index 0000000..aaeae42
--- /dev/null
+++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_over_ineditable.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../assert_selection.js"></script>
+<script>
+// Regression tests for crbug.com/936613
+
+selection_test(
+    [
+      '<div contenteditable>',
+        '|<span contenteditable="false">line 1</span>',
+      '</div>'
+    ].join(''),
+    selection => selection.modify('move', 'right', 'character'),
+    [
+      '<div contenteditable>',
+        '<span contenteditable="false">line 1</span>|',
+      '</div>'
+    ].join(''),
+    'Move right over ineditable inline');
+
+selection_test(
+    [
+      '<div contenteditable>',
+        '|<span contenteditable="false">line 1</span>',
+      '</div>',
+      'some more content'
+    ].join(''),
+    selection => selection.modify('move', 'right', 'character'),
+    [
+      '<div contenteditable>',
+        '<span contenteditable="false">line 1</span>|',
+      '</div>',
+      'some more content'
+    ].join(''),
+    'Move right over ineditable inline ignoring content outside editing host');
+
+selection_test(
+    [
+      '<div contenteditable>',
+        '|<span contenteditable="false">line 1</span><br>',
+        'line 2',
+      '</div>',
+    ].join(''),
+    selection => selection.modify('move', 'right', 'character'),
+    [
+      '<div contenteditable>',
+        '<span contenteditable="false">line 1</span>|<br>',
+        'line 2',
+      '</div>',
+    ].join(''),
+    'Move right over ineditable inline with another editable line');
+
+selection_test(
+    [
+      '<div contenteditable>',
+        '|<span contenteditable="false">line 1</span>',
+        '<div>line 2</div>',
+      '</div>',
+    ].join(''),
+    selection => selection.modify('move', 'right', 'character'),
+    [
+      '<div contenteditable>',
+        // TODO(editing-dev): "</span>|" seems to be a better result. The
+        // current behavior might be an artifact of crrev.com/412925.
+        '<span contenteditable="false">line 1</span>',
+        '<div>|line 2</div>',
+      '</div>'
+    ].join(''),
+    'Move right over ineditable inline with another editable block');
+</script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index 32d5c47..d7a8d8a 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -186832,6 +186832,16 @@
      {}
     ]
    ],
+   "signed-exchange/resources/sxg/sxg-variants-match.sxg": [
+    [
+     {}
+    ]
+   ],
+   "signed-exchange/resources/sxg/sxg-variants-mismatch.sxg": [
+    [
+     {}
+    ]
+   ],
    "speech-api/META.yml": [
     [
      {}
@@ -278300,7 +278310,9 @@
    "screen-orientation/orientation-reading.html": [
     [
      "/screen-orientation/orientation-reading.html",
-     {}
+     {
+      "testdriver": true
+     }
     ]
    ],
    "scroll-animations/constructor-no-document.html": [
@@ -281151,6 +281163,18 @@
      {}
     ]
    ],
+   "signed-exchange/sxg-variants-match.tentative.html": [
+    [
+     "/signed-exchange/sxg-variants-match.tentative.html",
+     {}
+    ]
+   ],
+   "signed-exchange/sxg-variants-mismatch.tentative.html": [
+    [
+     "/signed-exchange/sxg-variants-mismatch.tentative.html",
+     {}
+    ]
+   ],
    "signed-exchange/sxg-version1b2.tentative.html": [
     [
      "/signed-exchange/sxg-version1b2.tentative.html",
@@ -332775,7 +332799,7 @@
    "support"
   ],
   "css/css-animations/Element-getAnimations.tentative.html": [
-   "23f9ec8e3841535fe4c1c089c7dd6d976a14daab",
+   "5690a7daf85845d342c5c0b5fb6224340b16aa2f",
    "testharness"
   ],
   "css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt": [
@@ -397079,7 +397103,7 @@
    "support"
   ],
   "editing/data/createlink.js": [
-   "87e59d281e5a6cfcd0546db9c90c4b7785146366",
+   "10734d950bb899222a29802a0e32faa324ebff5f",
    "support"
   ],
   "editing/data/delete-list-items-in-table-cells.js": [
@@ -397131,7 +397155,7 @@
    "support"
   ],
   "editing/data/insertimage.js": [
-   "c2e26cb56d4609165e6b281061b7819154b30185",
+   "b18388a7971dfd10fca5bcc0d15998b2989310af",
    "support"
   ],
   "editing/data/insertlinebreak.js": [
@@ -397303,7 +397327,7 @@
    "support"
   ],
   "editing/run/createlink-expected.txt": [
-   "c57e1904501438d36ba5c1a1ba3a1e1c2ee46a44",
+   "4865ecf24d113b2969dce718a2561f15dbd665ae",
    "support"
   ],
   "editing/run/createlink.html": [
@@ -397507,7 +397531,7 @@
    "testharness"
   ],
   "editing/run/insertimage-expected.txt": [
-   "f3883d9c77169614792bb452233d783660b5a8c5",
+   "64584ff9b6ec49990054bfb672c5f87d89c159f0",
    "support"
   ],
   "editing/run/insertimage.html": [
@@ -449131,7 +449155,7 @@
    "support"
   ],
   "screen-orientation/orientation-reading.html": [
-   "6d67dd3152d5442e2ab5d37cc0335884eadf5141",
+   "574258ff52522a14193408bbc8fb0db2f0d154d5",
    "testharness"
   ],
   "screen-orientation/page-visibility-manual.html": [
@@ -453763,7 +453787,7 @@
    "support"
   ],
   "signed-exchange/resources/generate-test-sxgs.sh": [
-   "bae4ce0eaed3ffcd36d70e4931ea39ff1a3c3346",
+   "cc2b6dd5a215046d2943b041620ba656b69ea0b0",
    "support"
   ],
   "signed-exchange/resources/inner-url.html": [
@@ -453902,6 +453926,14 @@
    "e90d9bc66de7fd3937c119afecec3cb4db5fa87c",
    "support"
   ],
+  "signed-exchange/resources/sxg/sxg-variants-match.sxg": [
+   "aed8bd175d5a45459448fb29211156779b43843c",
+   "support"
+  ],
+  "signed-exchange/resources/sxg/sxg-variants-mismatch.sxg": [
+   "ae96b7213fa7f3d056964a2eeab1528ff840486a",
+   "support"
+  ],
   "signed-exchange/sxg-double-prefetch.tentative.html": [
    "d682741744fed929bee8e62fbae4857a4bfbf1d5",
    "testharness"
@@ -453978,6 +454010,14 @@
    "85670a786af33c5dbfe19a018dba76847fa649cf",
    "testharness"
   ],
+  "signed-exchange/sxg-variants-match.tentative.html": [
+   "21d1b80d3c158894690e563930f06825509402f1",
+   "testharness"
+  ],
+  "signed-exchange/sxg-variants-mismatch.tentative.html": [
+   "b57ec8192628c0a35c24c09641e41439aea872c6",
+   "testharness"
+  ],
   "signed-exchange/sxg-version1b2.tentative.html": [
    "43b340dbb79f2585ef4acc4361ee94c6f22003f0",
    "testharness"
@@ -458531,7 +458571,7 @@
    "testharness"
   ],
   "web-animations/animation-model/animation-types/property-list.js": [
-   "0f644adce29ccb41cbc1f7465f1fbbbc8f60d2f3",
+   "2d45574a61fcb5d44147ba78dd2b9a79c09762ac",
    "support"
   ],
   "web-animations/animation-model/animation-types/property-types.js": [
@@ -462403,7 +462443,7 @@
    "testharness"
   ],
   "webrtc/RTCRtpTransceiver.https.html": [
-   "013fe6cf77192f829fbc09a4f1f1564f0e4131aa",
+   "8004fec9f0833d5e59ae48c92dc5ee06beafd4c2",
    "testharness"
   ],
   "webrtc/RTCSctpTransport-constructor-expected.txt": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html
index 23f9ec8..5690a7d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/Element-getAnimations.tentative.html
@@ -374,12 +374,12 @@
   assert_equals(animations[1].effect.target.type, '::before',
                 'The animation targeting the ::before pseudo-element ' +
                 'should be returned second');
-  assert_equals(animations[1].effect.target.parentElement, parent,
+  assert_equals(animations[1].effect.target.element, parent,
                 'This ::before element should be child of parent element');
   assert_equals(animations[2].effect.target.type, '::after',
                 'The animation targeting the ::after pesudo-element ' +
                 'should be returned third');
-  assert_equals(animations[2].effect.target.parentElement, parent,
+  assert_equals(animations[2].effect.target.element, parent,
                 'This ::after element should be child of parent element');
 
   assert_equals(animations[3].effect.target, child,
@@ -388,12 +388,12 @@
   assert_equals(animations[4].effect.target.type, '::before',
                 'The animation targeting the ::before pseudo-element ' +
                 'should be returned fifth');
-  assert_equals(animations[4].effect.target.parentElement, child,
+  assert_equals(animations[4].effect.target.element, child,
                 'This ::before element should be child of child element');
   assert_equals(animations[5].effect.target.type, '::after',
                 'The animation targeting the ::after pesudo-element ' +
                 'should be returned last');
-  assert_equals(animations[5].effect.target.parentElement, child,
+  assert_equals(animations[5].effect.target.element, child,
                 'This ::after element should be child of child element');
 }, '{ subtree: true } on an element with a child returns animations from the'
    + ' element, its pseudo-elements, its child and its child pseudo-elements');
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/createlink.js b/third_party/blink/web_tests/external/wpt/editing/data/createlink.js
index 87e59d2..10734d9 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/createlink.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/createlink.js
@@ -239,5 +239,10 @@
     [["createlink",""]],
     "foo[bar]baz",
     [false],
-    {"createlink":[false,false,"",false,false,""]}]
-]
+    {"createlink":[false,false,"",false,false,""]}],
+["foo[bar]baz",
+    [["createlink","http://www.google.com/\u65E5\u672C\u8A9E\u30D1\u30B9"]],
+    "foo<a href=\"http://www.google.com/\u65E5\u672C\u8A9E\u30D1\u30B9\">[bar]</a>baz",
+    [true],
+    {"createlink":[false,false,"",false,false,""]}],
+]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/insertimage.js b/third_party/blink/web_tests/external/wpt/editing/data/insertimage.js
index c2e26cb..b18388a7 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/insertimage.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/insertimage.js
@@ -349,5 +349,10 @@
     [["insertimage","/img/lion.svg"]],
     "<div>foo<p>bar<img src=\"/img/lion.svg\">{}baz</p></div>",
     [true],
-    {"insertimage":[false,false,"",false,false,""]}]
+    {"insertimage":[false,false,"",false,false,""]}],
+["foo[]bar",
+    [["insertimage","/\u65E5\u672C\u8A9E\u30D1\u30B9/lion.svg"]],
+    "foo<img src=\"/\u65E5\u672C\u8A9E\u30D1\u30B9/lion.svg\">{}bar",
+    [true],
+    {"insertimage":[false,false,"",false,false,""]}],
 ]
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/createlink-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/createlink-expected.txt
index c57e190..4865ecf 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/createlink-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/createlink-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 432 tests; 417 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 441 tests; 426 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["createlink","http://www.google.com/"]] "foo[]bar": execCommand("createlink", false, "http://www.google.com/") return value
 PASS [["createlink","http://www.google.com/"]] "foo[]bar" checks for modifications to non-editable content
 FAIL [["createlink","http://www.google.com/"]] "foo[]bar" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "foobar" but got "foo<a href=\"http://www.google.com/\">http://www.google.com/</a>bar"
@@ -432,5 +432,14 @@
 PASS [["createlink",""]] "foo[bar]baz" queryCommandIndeterm("createlink") after
 PASS [["createlink",""]] "foo[bar]baz" queryCommandState("createlink") after
 PASS [["createlink",""]] "foo[bar]baz" queryCommandValue("createlink") after
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz": execCommand("createlink", false, "http://www.google.com/日本語パス") return value
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" checks for modifications to non-editable content
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" compare innerHTML
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandIndeterm("createlink") before
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandState("createlink") before
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandValue("createlink") before
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandIndeterm("createlink") after
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandState("createlink") after
+PASS [["createlink","http://www.google.com/日本語パス"]] "foo[bar]baz" queryCommandValue("createlink") after
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/insertimage-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/insertimage-expected.txt
index f3883d9c..64584ff 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/insertimage-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/insertimage-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 938 tests; 906 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 947 tests; 915 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["insertimage","/img/lion.svg"]] "foo[]bar": execCommand("insertimage", false, "/img/lion.svg") return value
 PASS [["insertimage","/img/lion.svg"]] "foo[]bar" checks for modifications to non-editable content
 PASS [["insertimage","/img/lion.svg"]] "foo[]bar" compare innerHTML
@@ -938,5 +938,14 @@
 PASS [["insertimage","/img/lion.svg"]] "<div>foo<p>bar[</p></div>]baz" queryCommandIndeterm("insertimage") after
 PASS [["insertimage","/img/lion.svg"]] "<div>foo<p>bar[</p></div>]baz" queryCommandState("insertimage") after
 PASS [["insertimage","/img/lion.svg"]] "<div>foo<p>bar[</p></div>]baz" queryCommandValue("insertimage") after
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar": execCommand("insertimage", false, "/日本語パス/lion.svg") return value
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" checks for modifications to non-editable content
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" compare innerHTML
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandIndeterm("insertimage") before
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandState("insertimage") before
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandValue("insertimage") before
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandIndeterm("insertimage") after
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandState("insertimage") after
+PASS [["insertimage","/日本語パス/lion.svg"]] "foo[]bar" queryCommandValue("insertimage") after
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html
new file mode 100644
index 0000000..d39b680
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+  </head>
+  <body>
+    <script>
+var image = new Image();
+image.src = "./unoptimized-image.jpg";
+
+var check_report_format = (reports, observer) => {
+  let report = reports[0];
+  assert_equals(report.type, "feature-policy-violation");
+  assert_equals(report.url, document.location.href);
+  assert_equals(report.body.featureId, "unoptimized-images");
+  assert_equals(report.body.disposition, "enforce");
+};
+
+async_test(t => {
+  new ReportingObserver(t.step_func_done(check_report_format),
+                        {types: ['feature-policy-violation'], buffered: true}).observe();
+}, "unoptimized-images Report Format");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html.headers
new file mode 100644
index 0000000..10b41235
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/unoptimized-images-reporting-onload.html.headers
@@ -0,0 +1 @@
+Feature-Policy: unoptimized-images 'none'
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html
new file mode 100644
index 0000000..dca44dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-cross-origin-with-click.sub.tentative.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!--
+   Tentative due to:
+    https://github.com/whatwg/html/issues/4364
+
+-->
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+</head>
+<body>
+  <h1>User activation can be transferred to a cross-origin child frame via a postMessage option.</h1>
+  <ol id="instructions">
+    <li>Click this instruction text.
+  </ol>
+  <iframe id="child" width="200" height="200"></iframe>
+  <script>
+    async_test(function(t) {
+      var child = document.getElementById("child");
+      assert_false(navigator.userActivation.isActive);
+      assert_false(navigator.userActivation.hasBeenActive);
+
+      window.addEventListener("message", t.step_func(event => {
+        var msg = JSON.parse(event.data);
+        if (msg.type == 'child-four-loaded') {
+          // state should be false after load
+          assert_false(msg.isActive);
+          assert_false(msg.hasBeenActive);
+
+          // click in parent document
+          test_driver.click(document.getElementById('instructions'));
+        } else if (msg.type == 'child-four-report') {
+          assert_true(msg.isActive);
+          assert_true(msg.hasBeenActive);
+          assert_false(navigator.userActivation.isActive);
+          assert_false(navigator.userActivation.hasBeenActive);
+          t.done();
+        }
+      }));
+      window.addEventListener("click", t.step_func(event => {
+          assert_true(navigator.userActivation.isActive);
+          assert_true(navigator.userActivation.hasBeenActive);
+
+          // transfer user activation to the child frame
+          child.contentWindow.postMessage("transfer_user_activation", {targetOrigin: "*", transferUserActivation: true});
+      }));
+      child.src = "http://{{domains[www]}}:{{ports[http][0]}}/html/user-activation/resources/child-four.html";
+    }, "Cross-origin user activation transfer through postMessages");
+  </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html
new file mode 100644
index 0000000..ebb4f5f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-with-click.tentative.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!--
+   Tentative due to:
+    https://github.com/whatwg/html/issues/4364
+
+-->
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+</head>
+<body>
+  <h1>User activation can be transferred to a child frame via a postMessage option.</h1>
+  <ol id="instructions">
+    <li>Click this instruction text.
+  </ol>
+  <iframe id="child" width="200" height="200"></iframe>
+  <script>
+    async_test(function(t) {
+      var child = document.getElementById("child");
+      assert_false(navigator.userActivation.isActive);
+      assert_false(navigator.userActivation.hasBeenActive);
+
+      window.addEventListener("message", t.step_func(event => {
+        var msg = JSON.parse(event.data);
+        if (msg.type == 'child-four-loaded') {
+          // state should be false after load
+          assert_false(msg.isActive);
+          assert_false(msg.hasBeenActive);
+
+          // click in parent document
+          test_driver.click(document.getElementById('instructions'));
+        } else if (msg.type == 'child-four-report') {
+          assert_true(msg.isActive);
+          assert_true(msg.hasBeenActive);
+          assert_false(navigator.userActivation.isActive);
+          assert_false(navigator.userActivation.hasBeenActive);
+          t.done();
+        }
+      }));
+      window.addEventListener("click", t.step_func(event => {
+          assert_true(navigator.userActivation.isActive);
+          assert_true(navigator.userActivation.hasBeenActive);
+
+          // transfer user activation to the child frame
+          child.contentWindow.postMessage("transfer_user_activation", {transferUserActivation: true});
+      }));
+      child.src = "resources/child-four.html";
+    }, "User activation transfer through postMessages");
+  </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-without-click.tentative.html b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-without-click.tentative.html
new file mode 100644
index 0000000..50cce1f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/activation-transfer-without-click.tentative.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<!--
+   Tentative due to:
+    https://github.com/whatwg/html/issues/4364
+
+-->
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+  <h1>User activation transfer request from an inactive frame is ignored.</h1>
+  <iframe id="child" width="200" height="200"></iframe>
+  <script>
+    async_test(function(t) {
+      var child = document.getElementById("child");
+      var is_page_loaded = false;
+      var is_child_four_loaded = false;
+      assert_false(navigator.userActivation.isActive);
+      assert_false(navigator.userActivation.hasBeenActive);
+
+      function tryPostMessaging() {
+        if (is_page_loaded && is_child_four_loaded)
+          child.contentWindow.postMessage("transfer_user_activation", {transferUserActivation: true});
+      }
+
+      window.addEventListener("message", t.step_func(event => {
+        var msg = JSON.parse(event.data);
+        if (msg.type == 'child-four-loaded') {
+          // state should be false after load
+          assert_false(msg.isActive);
+          assert_false(msg.hasBeenActive);
+          is_child_four_loaded = true;
+
+          tryPostMessaging();
+        } else if (msg.type == 'child-four-report') {
+          assert_false(msg.isActive);
+          assert_false(msg.hasBeenActive);
+          assert_false(navigator.userActivation.isActive);
+          assert_false(navigator.userActivation.hasBeenActive);
+          t.done();
+        }
+      }));
+
+      window.addEventListener("load", function(event) {
+          is_page_loaded = true;
+          tryPostMessaging();
+      });
+      child.src = "resources/child-four.html";
+    }, "User activation transfer from inactive frame");
+  </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/child-four.html b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/child-four.html
new file mode 100644
index 0000000..d312803
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/child-four.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<body style="background: lightgrey;">
+  <script>
+    window.parent.postMessage(JSON.stringify({"type": "child-four-loaded", "isActive": navigator.userActivation.isActive,
+                                              "hasBeenActive": navigator.userActivation.hasBeenActive}), "*");
+
+    window.addEventListener("message", event => {
+        if (event.source === window.parent && event.data == "transfer_user_activation") {
+            window.parent.postMessage(JSON.stringify({"type": "child-four-report", "isActive": navigator.userActivation.isActive,
+                                                      "hasBeenActive": navigator.userActivation.hasBeenActive}), "*");
+        }
+    });
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https-expected.txt
index 6718c1b..20a6f53 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method-protection.https-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException. assert_equals: If it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "TypeError"
+FAIL Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException. assert_equals: If it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https-expected.txt
index 92e9c382..fe7f167 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.https-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once
-FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "TypeError: request.hasEnrolledInstrument is not a function"
-FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "TypeError: request.hasEnrolledInstrument is not a function"
+FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "UnknownError: Request failed"
+FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
 FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/orientation-reading.html b/third_party/blink/web_tests/external/wpt/screen-orientation/orientation-reading.html
index 6d67dd31..574258f 100644
--- a/third_party/blink/web_tests/external/wpt/screen-orientation/orientation-reading.html
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/orientation-reading.html
@@ -1,6 +1,8 @@
 <!DOCTYPE html>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
 <script>
 test(() => {
   assert_true('type' in screen.orientation);
@@ -20,6 +22,46 @@
   assert_true(angle == 0 || angle == 90 || angle == 180 || angle == 270);
 }, "Test screen.orientation default values.");
 
+promise_test(async t => {
+  await test_driver.bless("request full screen", () => {
+    return document.documentElement.requestFullscreen();
+  });
+  await screen.orientation.lock("portrait-primary");
+  const orientations =
+    screen.orientation.angle === 0
+      ? {
+          secondaryOrientation1: "portrait-secondary",
+          primaryOrientation2: "landscape-primary",
+          secondaryOrientation2: "landscape-secondary"
+        }
+      : {
+          secondaryOrientation1: "landscape-secondary",
+          primaryOrientation2: "portrait-primary",
+          secondaryOrientation2: "portrait-secondary"
+        };
+  await screen.orientation.lock(orientations.secondaryOrientation1);
+  assert_equals(
+    screen.orientation.angle,
+    180,
+    "Secondary orientation 1 angle must be 180"
+  );
+  await screen.orientation.lock(orientations.primaryOrientation2);
+  assert_true(
+    screen.orientation.angle == 90 || screen.orientation.angle == 270,
+    "Primary orientation 2 angle must be either 90 or 270"
+  );
+  const primaryOrientation2Angle = screen.orientation.angle;
+  const secondaryOrientation2Angle = primaryOrientation2Angle === 90 ? 270 : 90;
+  await screen.orientation.lock(orientations.secondaryOrientation2);
+  assert_equals(
+    screen.orientation.angle,
+    secondaryOrientation2Angle,
+    "Secondary orientation 2 angle must be the opposite angle to primary orientation 2"
+  );
+  screen.orientation.unlock();
+  return document.exitFullscreen();
+}, "Test the orientations and associated angles");
+
 test(() => {
   const type = screen.orientation.type;
   const angle = screen.orientation.angle;
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js
index 0f644ad..2d45574 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js
+++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-list.js
@@ -1445,7 +1445,7 @@
 function testAnimationSamples(animation, idlName, testSamples) {
   const type = animation.effect.target.type;
   const target = animation.effect.target.constructor.name === 'CSSPseudoElement'
-                 ? animation.effect.target.parentElement
+                 ? animation.effect.target.element
                  : animation.effect.target;
   for (const testSample of testSamples) {
     animation.currentTime = testSample.time;
@@ -1466,7 +1466,7 @@
 function testAnimationSamplesWithAnyOrder(animation, idlName, testSamples) {
   const type = animation.effect.target.type;
   const target = animation.effect.target.constructor.name === 'CSSPseudoElement'
-                 ? animation.effect.target.parentElement
+                 ? animation.effect.target.element
                  : animation.effect.target;
   for (const testSample of testSamples) {
     animation.currentTime = testSample.time;
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
index 013fe6c..8004fec 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
@@ -441,6 +441,42 @@
     await pc1.setRemoteDescription(answer);
   };
 
+  const checkNoMidAnswer = async t => {
+    const pc1 = new RTCPeerConnection();
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    t.add_cleanup(() => pc2.close());
+
+    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
+    t.add_cleanup(() => stopTracks(stream));
+    const track = stream.getAudioTracks()[0];
+    pc1.addTrack(track, stream);
+
+    const offer = await pc1.createOffer();
+    await pc1.setLocalDescription(offer);
+    await pc2.setRemoteDescription(offer);
+    let answer = await pc2.createAnswer();
+    // Remove mid attr
+    answer.sdp = answer.sdp.replace("a=mid:", "a=unknownattr:");
+    // Remove group attr also
+    answer.sdp = answer.sdp.replace("a=group:", "a=unknownattr:");
+    await pc1.setRemoteDescription(answer);
+
+    hasPropsAndUniqueMids(pc1.getTransceivers(),
+      [
+        {
+          receiver: {track: {kind: "audio"}},
+          sender: {track: {kind: "audio"}},
+          direction: "sendrecv",
+          currentDirection: "sendonly",
+          stopped: false
+        }
+      ]);
+
+    const reoffer = await pc1.createOffer();
+    await pc1.setLocalDescription(reoffer);
+  };
+
   const checkAddTransceiverNoTrackDoesntPair = async t => {
     const pc1 = new RTCPeerConnection();
     const pc2 = new RTCPeerConnection();
@@ -2156,6 +2192,7 @@
   checkAddTransceiverWithSetRemoteOfferNoSend,
   checkAddTransceiverBadKind,
   checkNoMidOffer,
+  checkNoMidAnswer,
   checkSetDirection,
   checkCurrentDirection,
   checkSendrecvWithNoSendTrack,
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
index 3d4e6bae..fe02ec3 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -131,6 +131,7 @@
 PASS oldChildWindow.onmousewheel is newChildWindow.onmousewheel
 PASS oldChildWindow.onoffline is newChildWindow.onoffline
 PASS oldChildWindow.ononline is newChildWindow.ononline
+PASS oldChildWindow.onoverscroll is newChildWindow.onoverscroll
 PASS oldChildWindow.onpagehide is newChildWindow.onpagehide
 PASS oldChildWindow.onpageshow is newChildWindow.onpageshow
 PASS oldChildWindow.onpause is newChildWindow.onpause
@@ -153,6 +154,7 @@
 PASS oldChildWindow.onreset is newChildWindow.onreset
 PASS oldChildWindow.onresize is newChildWindow.onresize
 PASS oldChildWindow.onscroll is newChildWindow.onscroll
+PASS oldChildWindow.onscrollend is newChildWindow.onscrollend
 PASS oldChildWindow.onsearch is newChildWindow.onsearch
 PASS oldChildWindow.onseeked is newChildWindow.onseeked
 PASS oldChildWindow.onseeking is newChildWindow.onseeking
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
index 4accc946..5846a13 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -96,6 +96,7 @@
 PASS childWindow.onmousewheel is null
 PASS childWindow.onoffline is null
 PASS childWindow.ononline is null
+PASS childWindow.onoverscroll is null
 PASS childWindow.onpagehide is null
 PASS childWindow.onpageshow is null
 PASS childWindow.onpause is null
@@ -118,6 +119,7 @@
 PASS childWindow.onreset is null
 PASS childWindow.onresize is null
 PASS childWindow.onscroll is null
+PASS childWindow.onscrollend is null
 PASS childWindow.onsearch is null
 PASS childWindow.onseeked is null
 PASS childWindow.onseeking is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
index 929d985..1c8a658 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -96,6 +96,7 @@
 PASS childWindow.onmousewheel is null
 PASS childWindow.onoffline is null
 PASS childWindow.ononline is null
+PASS childWindow.onoverscroll is null
 PASS childWindow.onpagehide is null
 PASS childWindow.onpageshow is null
 PASS childWindow.onpause is null
@@ -118,6 +119,7 @@
 PASS childWindow.onreset is null
 PASS childWindow.onresize is null
 PASS childWindow.onscroll is null
+PASS childWindow.onscrollend is null
 PASS childWindow.onsearch is null
 PASS childWindow.onseeked is null
 PASS childWindow.onseeking is null
diff --git a/third_party/blink/web_tests/fast/dom/shadow/input-color-in-content.html b/third_party/blink/web_tests/fast/dom/shadow/input-color-in-content.html
index ea75460..7b68095 100644
--- a/third_party/blink/web_tests/fast/dom/shadow/input-color-in-content.html
+++ b/third_party/blink/web_tests/fast/dom/shadow/input-color-in-content.html
@@ -3,7 +3,7 @@
 <body>
 <script src="../../../resources/js-test.js"></script>
 <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
-<script src="file:///gen/third_party/blink/public/mojom/color_chooser/color_chooser.mojom.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/choosers/color_chooser.mojom.js"></script>
 <script src="../../forms/color/mock-colorchooser.js"></script>
 <div id="host" tabindex="1">
   <input id="target" type="color" value="#000000">
diff --git a/third_party/blink/web_tests/fast/forms/color/display-none-input-color-chooser-shown.html b/third_party/blink/web_tests/fast/forms/color/display-none-input-color-chooser-shown.html
index cce8225..4b8ca787 100644
--- a/third_party/blink/web_tests/fast/forms/color/display-none-input-color-chooser-shown.html
+++ b/third_party/blink/web_tests/fast/forms/color/display-none-input-color-chooser-shown.html
@@ -2,7 +2,7 @@
 <script src="../../../resources/testharness.js"></script>
 <script src="../../../resources/testharnessreport.js"></script>
 <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
-<script src="file:///gen/third_party/blink/public/mojom/color_chooser/color_chooser.mojom.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/choosers/color_chooser.mojom.js"></script>
 <script src="../../forms/color/mock-colorchooser.js"></script>
 <input id="colorPick" type="color" />
 <label for="colorPick" id="labelPick">Pick a color</label>
diff --git a/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown-readonly.html b/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown-readonly.html
index cb8a8c5..7e321a0 100644
--- a/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown-readonly.html
+++ b/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown-readonly.html
@@ -4,7 +4,7 @@
 <script src="../../../resources/js-test.js"></script>
 <script src="../resources/common.js"></script>
 <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
-<script src="file:///gen/third_party/blink/public/mojom/color_chooser/color_chooser.mojom.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/choosers/color_chooser.mojom.js"></script>
 <script src="../../forms/color/mock-colorchooser.js"></script>
 <div id="host" tabindex="1">
   <input id="target" type="color" value="#000000" readonly>
diff --git a/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown.html b/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown.html
index b454f0b..79c72fe9 100644
--- a/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown.html
+++ b/third_party/blink/web_tests/fast/forms/color/input-color-chooser-shown.html
@@ -4,7 +4,7 @@
 <script src="../../../resources/js-test.js"></script>
 <script src="../resources/common.js"></script>
 <script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
-<script src="file:///gen/third_party/blink/public/mojom/color_chooser/color_chooser.mojom.js"></script>
+<script src="file:///gen/third_party/blink/public/mojom/choosers/color_chooser.mojom.js"></script>
 <script src="../../forms/color/mock-colorchooser.js"></script>
 <div id="host" tabindex="1">
   <input id="target" type="color" value="#000000">
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/snav-focusless-element-removed.html b/third_party/blink/web_tests/fast/spatial-navigation/snav-focusless-element-removed.html
new file mode 100644
index 0000000..7863dc11
--- /dev/null
+++ b/third_party/blink/web_tests/fast/spatial-navigation/snav-focusless-element-removed.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/snav-testharness.js"></script>
+
+<style>
+  div {
+    width: 100px;
+    height: 100px;
+    margin: 5px;
+    border: 1px solid black;
+  }
+</style>
+
+<div id="first" tabindex="0">First</div>
+<div id="second" tabindex="0">Second</div>
+<div id="third" tabindex="0">Third</div>
+
+<script>
+  snav.assertSnavEnabledAndTestable(true /* focuslessSpatNav */ );
+  let first = document.getElementById("first")
+  let second = document.getElementById("second")
+  let third = document.getElementById("third")
+
+  test(() => {
+    snav.triggerMove('Down');
+    snav.triggerMove('Down'); // Move interest to 'second'
+
+    assert_equals(window.internals.interestedElement,
+                  second,
+                  "'second' element has interest");
+
+    second.remove();
+
+    // Move interest 'down', since the interested element is disconnected, we
+    // should start the search from the top
+    snav.triggerMove('Down');
+
+    assert_equals(window.internals.interestedElement,
+                  first,
+                  "'first' element has interest");
+  }, "Disconnecting an interested element resets search");
+
+</script>
diff --git a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
index 9f880cef..4ab9a280 100644
--- a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
+++ b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
@@ -24,7 +24,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [320, 240]
     },
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
index e90e866..a2be4ec 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [352, 288]
     },
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
index 1737809..fd66c2f 100644
--- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [352, 288]
     },
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 77532a9..c8f0635 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4500,6 +4500,7 @@
     method abort
     method canMakePayment
     method constructor
+    method hasEnrolledInstrument
     method show
     setter onshippingaddresschange
     setter onshippingoptionchange
diff --git a/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/README.txt b/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/README.txt
new file mode 100644
index 0000000..e5a16fbc
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/threaded/external/wpt/animation-worklet/README.txt
@@ -0,0 +1,2 @@
+# This suite runs external/wpt/animation-worklet tests with threaded
+# compositing enabled (--enable-threaded-compositing flag).
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
index dcd20794..8cf9b13e 100644
--- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
@@ -9,6 +9,7 @@
 FAIL checkAddTransceiverWithSetRemoteOfferNoSend promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL checkAddTransceiverBadKind assert_true: addTransceiver("foo") throws a TypeError expected true got false
 FAIL checkNoMidOffer assert_equals: expected "[{currentDirection:null,direction:\"recvonly\",receiver:{track:{kind:\"audio\"}},sender:{track:null},stopped:false}]" but got "[]"
+FAIL checkNoMidAnswer assert_equals: expected "[{currentDirection:\"sendonly\",direction:\"sendrecv\",receiver:{track:{kind:\"audio\"}},sender:{track:{kind:\"audio\"}},stopped:false}]" but got "[]"
 FAIL checkSetDirection promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
 FAIL checkCurrentDirection assert_equals: expected "[{currentDirection:null}]" but got "[]"
 FAIL checkSendrecvWithNoSendTrack promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'. 'unified-plan' will become the default behavior in the future, but it is currently experimental. To try it out, construct the RTCPeerConnection with sdpSemantics:'unified-plan' present in the RTCConfiguration argument."
diff --git a/third_party/blink/web_tests/webaudio/internals/audiocontext-gc.html b/third_party/blink/web_tests/webaudio/internals/audiocontext-gc.html
new file mode 100644
index 0000000..b3f3d53
--- /dev/null
+++ b/third_party/blink/web_tests/webaudio/internals/audiocontext-gc.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Test GC of Closed AudioContext</title>
+    <script src="../../resources/gc.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+  </head>
+
+  <body>
+    <script>
+      const audit = Audit.createTaskRunner();
+
+      // Number of contexts to create for testing.  Fairly arbitrary, but should
+      // be at least 6 (previous max allowed contexts) but not too many.
+      const numberOfContexts = 10;
+
+      audit.define('Test GC of Closed AudioContexts', (task, should) => {
+        // Initial number of handlers.
+        let initialCount = 0;
+        asyncGC()
+            .then(() => {
+              initialCount = internals.audioHandlerCount();
+              // For information only
+              should(initialCount, 'Number of handlers before GC')
+                  .beEqualTo(initialCount);
+            })
+            .then(() => {
+              // Create a bunch of contexts for testing
+              const contexts = [];
+              for (let k = 0; k < numberOfContexts; ++k) {
+                let c = new AudioContext();
+                contexts.push(c.close());
+                c = null;
+              }
+
+              // Wait for all the close methods to resolve before we check.
+              Promise.all(contexts).then(() => {
+                asyncGC()
+                    .then(() => {
+                      should(contexts.length, 'Number of contexts created')
+                          .beEqualTo(numberOfContexts);
+                      should(
+                          internals.audioHandlerCount(),
+                          'Number of handlers after GC')
+                          .beEqualTo(initialCount);
+                    })
+                    .then(() => task.done());
+              })
+            });
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/webaudio/internals/offlineaudiocontext-gc.html b/third_party/blink/web_tests/webaudio/internals/offlineaudiocontext-gc.html
new file mode 100644
index 0000000..dafb724
--- /dev/null
+++ b/third_party/blink/web_tests/webaudio/internals/offlineaudiocontext-gc.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Test GC of OfflineAudioContext</title>
+    <script src="../../resources/gc.js"></script>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+  </head>
+
+  <body>
+    <script>
+      const audit = Audit.createTaskRunner();
+
+      // Number of contexts to create for testing.  Fairly arbitrary, but since
+      // we actually start rendering the context which creates a thread, we
+      // don't want too many.
+      const numberOfContexts = 20;
+
+      audit.define('Test GC of OfflineAudioContexts', (task, should) => {
+        // Initial number of handlers.
+        let initialCount = 0;
+        asyncGC()
+            .then(() => {
+              initialCount = internals.audioHandlerCount();
+              // For information only
+              should(initialCount, 'Number of handlers before GC')
+                  .beEqualTo(initialCount);
+            })
+            .then(() => {
+              // Create a bunch of contexts for testing.  The oscillators are
+              // important because they hold cause the context to exist until
+              // the oscillators are collected.
+              const contexts = [];
+              for (let k = 0; k < numberOfContexts; ++k) {
+                let c = new OfflineAudioContext(1, 44100, 44100);
+                let s = new OscillatorNode(c);
+                s.start();
+                contexts.push(c.startRendering());
+                c = null;
+              }
+
+              // Wait for all the close methods to resolve before we check.
+              Promise.all(contexts).then(() => {
+                asyncGC()
+                    .then(() => {
+                      should(contexts.length, 'Number of contexts created')
+                          .beEqualTo(numberOfContexts);
+                      should(
+                          internals.audioHandlerCount(),
+                          'Number of handlers after GC')
+                          .beEqualTo(initialCount);
+                    })
+                    .then(() => task.done());
+              })
+            });
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
index ff94f3d..c551ac05 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
@@ -215,6 +215,7 @@
     property onmouseover
     property onmouseup
     property onmousewheel
+    property onoverscroll
     property onpaste
     property onpause
     property onplay
@@ -233,6 +234,7 @@
     property onreset
     property onresize
     property onscroll
+    property onscrollend
     property onsearch
     property onseeked
     property onseeking
@@ -1378,6 +1380,7 @@
     property onmouseover
     property onmouseup
     property onmousewheel
+    property onoverscroll
     property onpaste
     property onpause
     property onplay
@@ -1396,6 +1399,7 @@
     property onreset
     property onresize
     property onscroll
+    property onscrollend
     property onsearch
     property onseeked
     property onseeking
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 9d52969..9adcccd 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1614,6 +1614,7 @@
     getter onmouseover
     getter onmouseup
     getter onmousewheel
+    getter onoverscroll
     getter onpaste
     getter onpause
     getter onplay
@@ -1636,6 +1637,7 @@
     getter onresize
     getter onresume
     getter onscroll
+    getter onscrollend
     getter onsearch
     getter onsecuritypolicyviolation
     getter onseeked
@@ -1802,6 +1804,7 @@
     setter onmouseover
     setter onmouseup
     setter onmousewheel
+    setter onoverscroll
     setter onpaste
     setter onpause
     setter onplay
@@ -1824,6 +1827,7 @@
     setter onresize
     setter onresume
     setter onscroll
+    setter onscrollend
     setter onsearch
     setter onsecuritypolicyviolation
     setter onseeked
@@ -2701,6 +2705,7 @@
     getter onmouseover
     getter onmouseup
     getter onmousewheel
+    getter onoverscroll
     getter onpaste
     getter onpause
     getter onplay
@@ -2719,6 +2724,7 @@
     getter onreset
     getter onresize
     getter onscroll
+    getter onscrollend
     getter onseeked
     getter onseeking
     getter onselect
@@ -2805,6 +2811,7 @@
     setter onmouseover
     setter onmouseup
     setter onmousewheel
+    setter onoverscroll
     setter onpaste
     setter onpause
     setter onplay
@@ -2823,6 +2830,7 @@
     setter onreset
     setter onresize
     setter onscroll
+    setter onscrollend
     setter onseeked
     setter onseeking
     setter onselect
@@ -5121,6 +5129,11 @@
     getter message
     getter name
     method constructor
+interface OverscrollEvent : Event
+    attribute @@toStringTag
+    getter deltaX
+    getter deltaY
+    method constructor
 interface PageTransitionEvent : Event
     attribute @@toStringTag
     getter persisted
@@ -5217,6 +5230,7 @@
     method abort
     method canMakePayment
     method constructor
+    method hasEnrolledInstrument
     method show
     setter onpaymentmethodchange
     setter onshippingaddresschange
@@ -6175,6 +6189,7 @@
     getter onmouseover
     getter onmouseup
     getter onmousewheel
+    getter onoverscroll
     getter onpaste
     getter onpause
     getter onplay
@@ -6193,6 +6208,7 @@
     getter onreset
     getter onresize
     getter onscroll
+    getter onscrollend
     getter onseeked
     getter onseeking
     getter onselect
@@ -6265,6 +6281,7 @@
     setter onmouseover
     setter onmouseup
     setter onmousewheel
+    setter onoverscroll
     setter onpaste
     setter onpause
     setter onplay
@@ -6283,6 +6300,7 @@
     setter onreset
     setter onresize
     setter onscroll
+    setter onscrollend
     setter onseeked
     setter onseeking
     setter onselect
@@ -10875,6 +10893,7 @@
     getter onmousewheel
     getter onoffline
     getter ononline
+    getter onoverscroll
     getter onpagehide
     getter onpageshow
     getter onpause
@@ -10897,6 +10916,7 @@
     getter onreset
     getter onresize
     getter onscroll
+    getter onscrollend
     getter onsearch
     getter onseeked
     getter onseeking
@@ -11070,6 +11090,7 @@
     setter onmousewheel
     setter onoffline
     setter ononline
+    setter onoverscroll
     setter onpagehide
     setter onpageshow
     setter onpause
@@ -11092,6 +11113,7 @@
     setter onreset
     setter onresize
     setter onscroll
+    setter onscrollend
     setter onsearch
     setter onseeked
     setter onseeking
diff --git a/tools/perf/contrib/leak_detection/leak_detection.py b/tools/perf/contrib/leak_detection/leak_detection.py
index 2957a1a..3fb2185c 100644
--- a/tools/perf/contrib/leak_detection/leak_detection.py
+++ b/tools/perf/contrib/leak_detection/leak_detection.py
@@ -24,8 +24,15 @@
     tbm_options.AddTimelineBasedMetric('leakDetectionMetric')
     return tbm_options
 
-  def SetExtraBrowserOptions(self, options):
-    options.AppendExtraBrowserArgs('--js-flags=--expose-gc')
+  def CustomizeOptions(self, options):
+    # TODO(crbug.com/936805): Note this is a hack. Perf benchmarks should not
+    # override the CustomizeOptions method.
+    options.browser_options.AppendExtraBrowserArgs('--js-flags=--expose-gc')
+
+  def CustomizeBrowserOptions(self, _):
+    # TODO(crbug.com/936805): Note this is a hack. Perf benchmarks should not
+    # override the CustomizeBrowserOptions method.
+    pass
 
 
 @benchmark.Info(emails=['yuzus@chromium.org'])
diff --git a/ui/android/features.gni b/ui/android/features.gni
index a8dfa500..5c5d56a 100644
--- a/ui/android/features.gni
+++ b/ui/android/features.gni
@@ -3,5 +3,5 @@
 # found in the LICENSE file.
 
 declare_args() {
-  enable_android_night_mode = false
+  enable_android_night_mode = is_android
 }
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index c596a628..2747836 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -636,6 +636,8 @@
   new_layer->SetTransform(cc_layer_->transform());
   new_layer->SetPosition(cc_layer_->position());
   new_layer->SetBackgroundColor(cc_layer_->background_color());
+  new_layer->SetSafeOpaqueBackgroundColor(
+      cc_layer_->SafeOpaqueBackgroundColor());
   new_layer->SetCacheRenderSurface(cc_layer_->cache_render_surface());
   new_layer->SetTrilinearFiltering(cc_layer_->trilinear_filtering());
 
@@ -814,6 +816,7 @@
 
   surface_layer_->SetSurfaceId(surface_id, deadline_policy);
   surface_layer_->SetBackgroundColor(default_background_color);
+  surface_layer_->SetSafeOpaqueBackgroundColor(default_background_color);
   surface_layer_->SetStretchContentToFillBounds(stretch_content_to_fill_bounds);
 
   frame_size_in_dip_ = frame_size_in_dip;
@@ -850,6 +853,7 @@
   surface_layer_->SetSurfaceId(surface_id,
                                cc::DeadlinePolicy::UseInfiniteDeadline());
   surface_layer_->SetBackgroundColor(SK_ColorBLACK);
+  surface_layer_->SetSafeOpaqueBackgroundColor(SK_ColorBLACK);
   // TODO(kylechar): Include UV transform and don't stretch to fill bounds.
   surface_layer_->SetStretchContentToFillBounds(true);
 
@@ -1238,6 +1242,7 @@
 void Layer::SetColorFromAnimation(SkColor color, PropertyChangeReason reason) {
   DCHECK_EQ(type_, LAYER_SOLID_COLOR);
   cc_layer_->SetBackgroundColor(color);
+  cc_layer_->SetSafeOpaqueBackgroundColor(color);
   SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
 }
 
@@ -1321,6 +1326,7 @@
   }
   cc_layer_->SetTransformOrigin(gfx::Point3F());
   cc_layer_->SetContentsOpaque(true);
+  cc_layer_->SetSafeOpaqueBackgroundColor(SK_ColorWHITE);
   cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
   cc_layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
   cc_layer_->SetElementId(cc::ElementId(cc_layer_->id()));