diff --git a/DEPS b/DEPS
index 979027ee..90565694 100644
--- a/DEPS
+++ b/DEPS
@@ -126,11 +126,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': '28bafb01c90c0ba1a281f322325f542f0e97e4b6',
+  'skia_revision': '34a2a76e209486e2baf42b18b4993380e67d11e3',
   # 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': 'b23ca2a5814cc9e54d7fd840a0c3a2c5161ecc77',
+  'v8_revision': '8d1908ecc1ef0422d33878dbacc27a34013bb8f3',
   # 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.
@@ -138,15 +138,15 @@
   # 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': 'aead8edf8c46ace321f0a5583cea21194a77baf1',
+  'angle_revision': 'b6c1c66d25476bf7041e8a790f3fbfddc53e0674',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '2bb0864b22e70df9907bb71ca985a110f33d29da',
+  'swiftshader_revision': '0eba65b14b60f9a1937c0c123eb0190b676a2d9d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '333ac4ae60ac700fe9089ffe60135b19984e0b89',
+  'pdfium_revision': '34fb6244cfec267b4f25024b534416f94a866f82',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -189,7 +189,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': '798bb03c8950ab6a87d5e9c9a1c0f1d101d2d335',
+  'catapult_revision': '1f97ac96e633e90e0f7053d051b07234817de37c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -253,7 +253,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': 'e1f0d4e639f64d598de410e3b03813427ceaf5c5',
+  'dawn_revision': '695b68d1009b9ed6274a9970e19acf029494fe4d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -406,7 +406,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '155f278b6080ae550e8b36e9c55958f65cac33c2',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '63faa33898c3041fcd87ca3abf173b6647e971f3',
       'condition': 'checkout_ios',
   },
 
@@ -737,7 +737,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '685ea8d6f03c3ad6d835efe7f4a835a8f4702458',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2b0f8cfb744046b3bae6a08c54cff73500da0b31',
       'condition': 'checkout_linux',
   },
 
@@ -748,7 +748,7 @@
     Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
 
   'src/third_party/crc32c/src':
-    Var('chromium_git') + '/external/github.com/google/crc32c.git' + '@' + 'f8925d027884dde9a8f567f1fa230b92048f6132',
+    Var('chromium_git') + '/external/github.com/google/crc32c.git' + '@' + 'e4dfc9f1b583c2f41fd547b783d4304d9b29a276',
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
@@ -762,7 +762,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2b14855de938012c055713a2943dc10ca1a730d3',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'efc7e91fa76494f7f134926a384f4c0101ae982c',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1097,7 +1097,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '5e577f20fc7c1a2cc8b011e200db79bac2529e72',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '7081b4fe0f79da24f4e5bdd482573beb70e57257',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1301,7 +1301,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0613361e6c4ff5f3563633ea70dc0bb92aa6bb0f',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@af2885953ccf44817567480ab8dc21c81d15e921',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 46db0fb..e8cff481 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 # Watchlist Rules
-# Refer: http://dev.chromium.org/developers/contributing-code/watchlists
+# Refer: https://dev.chromium.org/developers/contributing-code/watchlists
 
 # IMPORTANT: The regular expression filepath is tested against each path using
 # re.search, so it is not usually necessary to add .*.
@@ -1647,6 +1647,10 @@
                   '|ios/chrome/app/strings/ios(_.+)*_strings.grd'\
                   '|ui/strings/ui_strings.grd',
     },
+    'unified_consent': {
+      'filepath': 'components/unified_consent/'\
+                  '|chrome/browser/unified_consent/',
+    },
     'usb': {
       'filepath': '/usb/',
     },
@@ -2482,6 +2486,7 @@
     'ui_display_win': ['robliao+watch@chromium.org'],
     'ui_resources': ['oshima+watch@chromium.org'],
     'ui_strings': ['srahim+watch@chromium.org'],
+    'unified_consent': ['wfh+watch@chromuium.org'],
     'usb': ['mattreynolds+watch@chromium.org',
             'odejesush+watch@chromium.org'],
     'vaapi': ['vaapi-reviews@chromium.org'],
diff --git a/ash/accelerators/key_hold_detector.cc b/ash/accelerators/key_hold_detector.cc
index 74d6fcd4..e70622e 100644
--- a/ash/accelerators/key_hold_detector.cc
+++ b/ash/accelerators/key_hold_detector.cc
@@ -37,7 +37,7 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&DispatchPressedEvent, pressed_event, base::Passed(&tracker)));
+      base::BindOnce(&DispatchPressedEvent, pressed_event, std::move(tracker)));
 }
 
 }  // namespace
diff --git a/ash/app_list/app_list_export.h b/ash/app_list/app_list_export.h
index 655948f..3066b4f 100644
--- a/ash/app_list/app_list_export.h
+++ b/ash/app_list/app_list_export.h
@@ -9,21 +9,12 @@
 // module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(APP_LIST_IMPLEMENTATION)
-#define APP_LIST_EXPORT __declspec(dllexport)
-#else
-#define APP_LIST_EXPORT __declspec(dllimport)
-#endif  // defined(APP_LIST_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(APP_LIST_IMPLEMENTATION)
 #define APP_LIST_EXPORT __attribute__((visibility("default")))
 #else
 #define APP_LIST_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define APP_LIST_EXPORT
diff --git a/ash/app_list/model/app_list_model_export.h b/ash/app_list/model/app_list_model_export.h
index 03e0b87..ca6bb60 100644
--- a/ash/app_list/model/app_list_model_export.h
+++ b/ash/app_list/model/app_list_model_export.h
@@ -9,21 +9,12 @@
 // app_list_model module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(APP_LIST_MODEL_IMPLEMENTATION)
-#define APP_LIST_MODEL_EXPORT __declspec(dllexport)
-#else
-#define APP_LIST_MODEL_EXPORT __declspec(dllimport)
-#endif  // defined(APP_LIST_MODEL_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(APP_LIST_MODEL_IMPLEMENTATION)
 #define APP_LIST_MODEL_EXPORT __attribute__((visibility("default")))
 #else
 #define APP_LIST_MODEL_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define APP_LIST_MODEL_EXPORT
diff --git a/ash/app_list/presenter/app_list_presenter_export.h b/ash/app_list/presenter/app_list_presenter_export.h
index f05c1db..151cf9e 100644
--- a/ash/app_list/presenter/app_list_presenter_export.h
+++ b/ash/app_list/presenter/app_list_presenter_export.h
@@ -9,21 +9,12 @@
 // app_list presenter module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(APP_LIST_PRESENTER_IMPLEMENTATION)
-#define APP_LIST_PRESENTER_EXPORT __declspec(dllexport)
-#else
-#define APP_LIST_PRESENTER_EXPORT __declspec(dllimport)
-#endif  // defined(APP_LIST_PRESENTER_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(APP_LIST_PRESENTER_IMPLEMENTATION)
 #define APP_LIST_PRESENTER_EXPORT __attribute__((visibility("default")))
 #else
 #define APP_LIST_PRESENTER_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define APP_LIST_PRESENTER_EXPORT
diff --git a/ash/app_menu/app_menu_export.h b/ash/app_menu/app_menu_export.h
index a2e6131..8bad63a 100644
--- a/ash/app_menu/app_menu_export.h
+++ b/ash/app_menu/app_menu_export.h
@@ -9,21 +9,12 @@
 // module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(APP_MENU_IMPLEMENTATION)
-#define APP_MENU_EXPORT __declspec(dllexport)
-#else
-#define APP_MENU_EXPORT __declspec(dllimport)
-#endif  // defined(APP_MENU_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(APP_MENU_IMPLEMENTATION)
 #define APP_MENU_EXPORT __attribute__((visibility("default")))
 #else
 #define APP_MENU_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define APP_MENU_EXPORT
diff --git a/ash/ash_export.h b/ash/ash_export.h
index 2f59f09..fb2c330b 100644
--- a/ash/ash_export.h
+++ b/ash/ash_export.h
@@ -9,21 +9,12 @@
 // be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(ASH_IMPLEMENTATION)
-#define ASH_EXPORT __declspec(dllexport)
-#else
-#define ASH_EXPORT __declspec(dllimport)
-#endif  // defined(ASH_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(ASH_IMPLEMENTATION)
 #define ASH_EXPORT __attribute__((visibility("default")))
 #else
 #define ASH_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define ASH_EXPORT
diff --git a/ash/components/shortcut_viewer/ksv_export.h b/ash/components/shortcut_viewer/ksv_export.h
index 0d731ae13..3b5b59b 100644
--- a/ash/components/shortcut_viewer/ksv_export.h
+++ b/ash/components/shortcut_viewer/ksv_export.h
@@ -9,21 +9,12 @@
 // the keyboard shortcut viewer module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
 
 #if defined(KSV_IMPLEMENTATION)
-#define KSV_EXPORT __declspec(dllexport)
-#else
-#define KSV_EXPORT __declspec(dllimport)
-#endif  // defined(KSV_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(KSV_IMPLEMENTATION)
 #define KSV_EXPORT __attribute__((visibility("default")))
 #else
 #define KSV_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define KSV_EXPORT
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 28439f1..5239209 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -524,8 +524,8 @@
     } else {
       // See comment about this in OnGestureEvent().
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(&DragDropController::ForwardPendingLongTap,
-                                weak_factory_.GetWeakPtr()));
+          FROM_HERE, base::BindOnce(&DragDropController::ForwardPendingLongTap,
+                                    weak_factory_.GetWeakPtr()));
     }
   }
 }
diff --git a/ash/public/cpp/ash_public_export.h b/ash/public/cpp/ash_public_export.h
index 8108434..826cc0c 100644
--- a/ash/public/cpp/ash_public_export.h
+++ b/ash/public/cpp/ash_public_export.h
@@ -7,24 +7,12 @@
 
 #if defined(COMPONENT_BUILD)
 
-#if defined(WIN32)
-
-#if defined(ASH_PUBLIC_IMPLEMENTATION)
-#define ASH_PUBLIC_EXPORT __declspec(dllexport)
-#else
-#define ASH_PUBLIC_EXPORT __declspec(dllimport)
-#endif
-
-#else  // !defined(WIN32)
-
 #if defined(ASH_PUBLIC_IMPLEMENTATION)
 #define ASH_PUBLIC_EXPORT __attribute((visibility("default")))
 #else
 #define ASH_PUBLIC_EXPORT
 #endif
 
-#endif  // defined(WIN32)
-
 #else  // !defined(COMPONENT_BUILD)
 
 #define ASH_PUBLIC_EXPORT
diff --git a/ash/system/bluetooth/bluetooth_power_controller.cc b/ash/system/bluetooth/bluetooth_power_controller.cc
index f221662f..a136396 100644
--- a/ash/system/bluetooth/bluetooth_power_controller.cc
+++ b/ash/system/bluetooth/bluetooth_power_controller.cc
@@ -182,8 +182,9 @@
     // it has "initialized" signal in the future (http://crbug.com/765390).
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&BluetoothPowerController::TriggerRunPendingBluetoothTasks,
-                   weak_ptr_factory_.GetWeakPtr()),
+        base::BindOnce(
+            &BluetoothPowerController::TriggerRunPendingBluetoothTasks,
+            weak_ptr_factory_.GetWeakPtr()),
         base::TimeDelta::FromMilliseconds(kBluetoothInitializationDelay));
   }
 }
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index df999c8e..3d3e10eb 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -3649,24 +3649,18 @@
   }
 
   // Sends a gesture scroll sequence to TabletModeAppWindowDragController.
-  void SendGestureEvents(const gfx::Point& start, float scroll_delta) {
-    base::TimeTicks timestamp = base::TimeTicks::Now();
-    SendScrollStartAndUpdate(start, scroll_delta, timestamp);
+  void SendGestureEvents(const gfx::Point& location) {
+    SendScrollStartAndUpdate(location);
     EndScrollSequence();
   }
 
-  void SendScrollStartAndUpdate(const gfx::Point& start,
-                                float scroll_y,
-                                base::TimeTicks& timestamp,
-                                float scroll_x = 0.f) {
+  void SendScrollStartAndUpdate(const gfx::Point& location) {
     wm::WindowState* window_state = wm::GetWindowState(window());
-    window_state->CreateDragDetails(start, HTCAPTION,
+    window_state->CreateDragDetails(location, HTCAPTION,
                                     ::wm::WINDOW_MOVE_SOURCE_TOUCH);
     controller_ = std::make_unique<TabletModeWindowDragController>(
         window_state, std::make_unique<TabletModeBrowserWindowDragDelegate>());
-
-    timestamp += base::TimeDelta::FromMilliseconds(100);
-    controller_->Drag(start + gfx::Vector2d(scroll_x, scroll_y), 0);
+    controller_->Drag(location, 0);
   }
 
   void EndScrollSequence() {
@@ -3674,16 +3668,11 @@
     wm::GetWindowState(window())->DeleteDragDetails();
   }
 
-  void Fling(const gfx::Point& start,
-             float scroll_delta,
-             base::TimeTicks& timestamp,
-             float velocity_y,
-             float velocity_x) {
-    timestamp += base::TimeDelta::FromMilliseconds(100);
-    ui::GestureEvent event =
-        ui::GestureEvent(start.x(), start.y(), ui::EF_NONE, timestamp,
-                         ui::GestureEventDetails(ui::ET_SCROLL_FLING_START,
-                                                 velocity_x, velocity_y));
+  void Fling(const gfx::Point& location, float velocity_y, float velocity_x) {
+    ui::GestureEvent event = ui::GestureEvent(
+        location.x(), location.y(), ui::EF_NONE, base::TimeTicks::Now(),
+        ui::GestureEventDetails(ui::ET_SCROLL_FLING_START, velocity_x,
+                                velocity_y));
     ui::Event::DispatcherApi(&event).set_target(window());
     controller_->FlingOrSwipe(&event);
     wm::GetWindowState(window())->DeleteDragDetails();
@@ -3716,11 +3705,10 @@
           window());
   const float long_scroll_delta = display_bounds.height() / 4 + 5;
 
-  const gfx::Point start;
+  const gfx::Point location(0, long_scroll_delta);
   // Drag the window that cannot be snapped long enough, the window will be
   // dropped into overview.
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  SendScrollStartAndUpdate(location);
   OverviewController* overview_controller = Shell::Get()->overview_controller();
   EXPECT_TRUE(overview_controller->IsSelecting());
   EXPECT_FALSE(
@@ -3744,15 +3732,15 @@
 
   // Move the window by a small amount of distance will maximize the window
   // again.
-  const gfx::Point start;
-  SendGestureEvents(start, 10);
+  gfx::Point location(0, 10);
+  SendGestureEvents(location);
   EXPECT_TRUE(wm::GetWindowState(window())->IsMaximized());
 
   // Drag the window long enough (pass one fourth of the screen vertical
   // height) to snap the window to splitscreen.
   const float long_scroll_delta = display_bounds.height() / 4 + 5;
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  location.set_y(long_scroll_delta);
+  SendScrollStartAndUpdate(location);
   OverviewController* overview_controller = Shell::Get()->overview_controller();
   EXPECT_TRUE(overview_controller->IsSelecting());
   EXPECT_FALSE(
@@ -3767,21 +3755,20 @@
 
   // FLING the window with small velocity (smaller than
   // kFlingToOverviewThreshold) will not able to drop the window into overview.
-  timestamp = base::TimeTicks::Now();
-  SendScrollStartAndUpdate(start, 10, timestamp);
+  location.set_y(10);
+  SendScrollStartAndUpdate(location);
   overview_controller = Shell::Get()->overview_controller();
   EXPECT_TRUE(overview_controller->IsSelecting());
-  Fling(start, 10, timestamp,
+  Fling(location,
         TabletModeWindowDragDelegate::kFlingToOverviewThreshold - 10.f, 0);
   EXPECT_FALSE(overview_controller->IsSelecting());
 
   // FLING the window with large velocity (larger than
   // kFlingToOverviewThreshold) will drop the window into overview.
-  timestamp = base::TimeTicks::Now();
-  SendScrollStartAndUpdate(start, 10, timestamp);
+  SendScrollStartAndUpdate(location);
   overview_controller = Shell::Get()->overview_controller();
   EXPECT_TRUE(overview_controller->IsSelecting());
-  Fling(start, 10, timestamp,
+  Fling(location,
         TabletModeWindowDragDelegate::kFlingToOverviewThreshold + 10.f, 0);
   EXPECT_TRUE(overview_controller->IsSelecting());
 }
@@ -3808,16 +3795,15 @@
 
   // Drag the window by a small amount of distance, the window will back to
   // fullscreened, and shelf will be hidden again.
-  const gfx::Point start;
-  SendGestureEvents(start, 10);
+  gfx::Point location(0, 10);
+  SendGestureEvents(location);
   shelf_layout_manager->UpdateVisibilityState();
   EXPECT_TRUE(window_state->IsFullscreen());
   EXPECT_FALSE(shelf_layout_manager->IsVisible());
 
   // Shelf is visible during dragging.
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  const float long_scroll_delta = display_bounds.height() / 4 + 5;
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  location.set_y(display_bounds.height() / 4 + 5);
+  SendScrollStartAndUpdate(location);
   EXPECT_TRUE(shelf_layout_manager->IsVisible());
   EndScrollSequence();
   EXPECT_TRUE(split_view_controller()->IsSplitViewModeActive());
@@ -3844,10 +3830,8 @@
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
   EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
 
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  const gfx::Point start;
-  const float long_scroll_delta = display_bounds.height() / 4 + 5;
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  const gfx::Point location(0, display_bounds.height() / 4 + 5);
+  SendScrollStartAndUpdate(location);
   EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
   EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
   // Shelf should be shown during drag.
@@ -3881,16 +3865,13 @@
   float small_velocity =
       TabletModeWindowDragDelegate::kFlingToOverviewFromSnappingAreaThreshold -
       10.f;
-  gfx::Point start;
-  base::TimeTicks timestamp = base::TimeTicks::Now();
 
   // Fling to the right with large enough velocity when trying to snap the
   // window to the left should drop the window to overview.
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  gfx::Point location(0, long_scroll_delta);
+  SendScrollStartAndUpdate(location);
   EXPECT_EQ(IndicatorState::kPreviewAreaLeft, GetIndicatorState());
-  Fling(start, long_scroll_delta, timestamp,
-        /*velocity_y*/ 0,
-        /*velocity_x=*/large_velocity);
+  Fling(location, /*velocity_y*/ 0, /*velocity_x=*/large_velocity);
   OverviewController* overview_controller = Shell::Get()->overview_controller();
   OverviewSession* overview_session = overview_controller->overview_session();
   EXPECT_TRUE(overview_controller->IsSelecting());
@@ -3900,22 +3881,19 @@
 
   // Fling to the right with small velocity when trying to snap the
   // window to the left should still snap the window to left.
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  SendScrollStartAndUpdate(location);
   EXPECT_EQ(IndicatorState::kPreviewAreaLeft, GetIndicatorState());
-  Fling(start, long_scroll_delta, timestamp,
-        /*velocity_y*/ 0,
-        /*velocity_x=*/small_velocity);
+  Fling(location, /*velocity_y*/ 0, /*velocity_x=*/small_velocity);
   EXPECT_TRUE(wm::GetWindowState(window())->IsSnapped());
   EndSplitView();
   EXPECT_TRUE(wm::GetWindowState(window())->IsMaximized());
 
   // Fling to the left with large enough velocity when trying to snap the window
   // to the right should drop the window to overvie.
-  start = gfx::Point(display_bounds.right(), 0);
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  location = gfx::Point(display_bounds.right(), long_scroll_delta);
+  SendScrollStartAndUpdate(location);
   EXPECT_EQ(IndicatorState::kPreviewAreaRight, GetIndicatorState());
-  Fling(start, long_scroll_delta, timestamp, /*velocity_y*/ 0,
-        /*velocity_x=*/-large_velocity);
+  Fling(location, /*velocity_y*/ 0, /*velocity_x=*/-large_velocity);
   overview_session = overview_controller->overview_session();
   EXPECT_TRUE(overview_controller->IsSelecting());
   EXPECT_TRUE(overview_session->IsWindowInOverview(window()));
@@ -3923,11 +3901,9 @@
 
   // Fling to the left with small velocity when trying to snap the
   // window to the right should still snap the window to right.
-  SendScrollStartAndUpdate(start, long_scroll_delta, timestamp);
+  SendScrollStartAndUpdate(location);
   EXPECT_EQ(IndicatorState::kPreviewAreaRight, GetIndicatorState());
-  Fling(start, long_scroll_delta, timestamp,
-        /*velocity_y*/ 0,
-        /*velocity_x=*/-small_velocity);
+  Fling(location, /*velocity_y*/ 0, /*velocity_x=*/-small_velocity);
   EXPECT_TRUE(wm::GetWindowState(window())->IsSnapped());
 }
 
@@ -3947,26 +3923,20 @@
   float large_velocity =
       TabletModeWindowDragDelegate::kFlingToOverviewFromSnappingAreaThreshold +
       10.f;
-  const gfx::Point start;
 
   // Fling the window in left snapping area to left should still snap the
   // window.
-  base::TimeTicks timestamp = base::TimeTicks::Now();
-  SendScrollStartAndUpdate(start, long_scroll_y, timestamp);
-  Fling(start, long_scroll_y, timestamp,
-        /*velocity_y=*/0,
-        /*velocity_x=*/-large_velocity);
+  gfx::Point location(0, long_scroll_y);
+  SendScrollStartAndUpdate(location);
+  Fling(location, /*velocity_y=*/0, /*velocity_x=*/-large_velocity);
   EXPECT_TRUE(wm::GetWindowState(window())->IsSnapped());
   EXPECT_EQ(SplitViewController::BOTH_SNAPPED,
             split_view_controller()->state());
 
   // Fling the window in left snapping area to right should drop the window
   // into overview.
-  timestamp += base::TimeDelta::FromMilliseconds(1000);
-  SendScrollStartAndUpdate(start, long_scroll_y, timestamp);
-  Fling(start, long_scroll_y, timestamp,
-        /*velocity_y=*/0,
-        /*velocity_x=*/large_velocity);
+  SendScrollStartAndUpdate(location);
+  Fling(location, /*velocity_y=*/0, /*velocity_x=*/large_velocity);
   OverviewController* selector_controller = Shell::Get()->overview_controller();
   EXPECT_TRUE(
       selector_controller->overview_session()->IsWindowInOverview(window()));
@@ -3980,12 +3950,9 @@
   // overview.
   EXPECT_EQ(SplitViewController::BOTH_SNAPPED,
             split_view_controller()->state());
-  const int scroll_x = display_bounds.CenterPoint().x() + 10;
-  SendScrollStartAndUpdate(start, long_scroll_y, timestamp, scroll_x);
-  gfx::Point end(scroll_x, 0);
-  Fling(end, long_scroll_y, timestamp,
-        /*velocity_y=*/0,
-        /*velocity_x=*/-large_velocity);
+  location.set_x(display_bounds.CenterPoint().x() + 10);
+  SendScrollStartAndUpdate(location);
+  Fling(location, /*velocity_y=*/0, /*velocity_x=*/-large_velocity);
   EXPECT_TRUE(
       selector_controller->overview_session()->IsWindowInOverview(window()));
   EXPECT_EQ(SplitViewController::RIGHT_SNAPPED,
@@ -3994,12 +3961,10 @@
 
   // Fling the window in right snapping area to right should snap the window to
   // right side.
-  // EXPECT_EQ(SplitViewController::BOTH_SNAPPED,
-  //           split_view_controller()->state());
-  SendScrollStartAndUpdate(start, long_scroll_y, timestamp, scroll_x);
-  Fling(end, long_scroll_y, timestamp,
-        /*velocity_y=*/0,
-        /*velocity_x=*/large_velocity);
+  EXPECT_EQ(SplitViewController::BOTH_SNAPPED,
+            split_view_controller()->state());
+  SendScrollStartAndUpdate(location);
+  Fling(location, /*velocity_y=*/0, /*velocity_x=*/large_velocity);
   EXPECT_EQ(split_view_controller()->right_window(), window());
   EXPECT_TRUE(selector_controller->overview_session()->IsWindowInOverview(
       window2.get()));
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc
index b86dfe1..0352697 100644
--- a/ash/wm/toplevel_window_event_handler_unittest.cc
+++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -138,8 +138,9 @@
       ::wm::GetWindowMoveClient(w1->GetRootWindow());
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&ContinueAndCompleteDrag, base::Unretained(&generator),
-                 base::Unretained(window_state), base::Unretained(w1.get())));
+      base::BindOnce(&ContinueAndCompleteDrag, base::Unretained(&generator),
+                     base::Unretained(window_state),
+                     base::Unretained(w1.get())));
   EXPECT_EQ(::wm::MOVE_SUCCESSFUL,
             move_client->RunMoveLoop(w1.get(), gfx::Vector2d(100, 100),
                                      ::wm::WINDOW_MOVE_SOURCE_MOUSE));
@@ -156,8 +157,9 @@
   generator.PressLeftButton();
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&ContinueAndCompleteDrag, base::Unretained(&generator),
-                 base::Unretained(window_state), base::Unretained(w1.get())));
+      base::BindOnce(&ContinueAndCompleteDrag, base::Unretained(&generator),
+                     base::Unretained(window_state),
+                     base::Unretained(w1.get())));
   EXPECT_EQ(::wm::MOVE_SUCCESSFUL,
             move_client->RunMoveLoop(w1.get(), gfx::Vector2d(100, 100),
                                      ::wm::WINDOW_MOVE_SOURCE_MOUSE));
@@ -983,9 +985,9 @@
   ::wm::WindowMoveClient* move_client =
       ::wm::GetWindowMoveClient(window->GetRootWindow());
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&SendMouseReleaseAndReleaseCapture,
-                 base::Unretained(&generator), base::Unretained(window.get())));
+      FROM_HERE, base::BindOnce(&SendMouseReleaseAndReleaseCapture,
+                                base::Unretained(&generator),
+                                base::Unretained(window.get())));
   EXPECT_EQ(::wm::MOVE_SUCCESSFUL,
             move_client->RunMoveLoop(window.get(), gfx::Vector2d(),
                                      ::wm::WINDOW_MOVE_SOURCE_MOUSE));
@@ -1010,8 +1012,8 @@
   ::wm::WindowMoveClient* move_client =
       ::wm::GetWindowMoveClient(window->GetRootWindow());
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&CheckHasCaptureAndReleaseCapture,
-                            base::Unretained(window.get())));
+      FROM_HERE, base::BindOnce(&CheckHasCaptureAndReleaseCapture,
+                                base::Unretained(window.get())));
   EXPECT_EQ(::wm::MOVE_SUCCESSFUL,
             move_client->RunMoveLoop(window.get(), gfx::Vector2d(),
                                      ::wm::WINDOW_MOVE_SOURCE_TOUCH));
diff --git a/ash/ws/ax_ash_window_utils.cc b/ash/ws/ax_ash_window_utils.cc
index b89df60..299ac4a2 100644
--- a/ash/ws/ax_ash_window_utils.cc
+++ b/ash/ws/ax_ash_window_utils.cc
@@ -4,7 +4,11 @@
 
 #include "ash/ws/ax_ash_window_utils.h"
 
+#include <vector>
+
+#include "ash/shell.h"
 #include "ash/ws/window_lookup.h"
+#include "base/stl_util.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -57,10 +61,12 @@
 }
 
 bool AXAshWindowUtils::IsRootWindow(aura::Window* window) const {
+  if (!window->IsRootWindow())
+    return false;
   // SingleProcessMash behaves like classic ash. Only display roots are
-  // considered root windows for accessibility, not top-level Widgets.
-  return window->IsRootWindow() &&
-         !views::Widget::GetWidgetForNativeWindow(window);
+  // considered root windows for accessibility, not top-level Widgets or embeds.
+  std::vector<aura::Window*> roots = Shell::GetAllRootWindows();
+  return base::ContainsValue(roots, window);
 }
 
 views::Widget* AXAshWindowUtils::GetWidgetForNativeView(aura::Window* window) {
diff --git a/ash/ws/ax_ash_window_utils_unittest.cc b/ash/ws/ax_ash_window_utils_unittest.cc
index 0661a3f..35297dc 100644
--- a/ash/ws/ax_ash_window_utils_unittest.cc
+++ b/ash/ws/ax_ash_window_utils_unittest.cc
@@ -20,6 +20,8 @@
 #include "ui/aura/env.h"
 #include "ui/aura/mus/window_mus.h"
 #include "ui/aura/mus/window_tree_client.h"
+#include "ui/aura/mus/window_tree_host_mus.h"
+#include "ui/aura/mus/window_tree_host_mus_init_params.h"
 #include "ui/aura/test/mus/change_completion_waiter.h"
 #include "ui/aura/window.h"
 #include "ui/base/ui_base_features.h"
@@ -194,5 +196,29 @@
   EXPECT_EQ(textfield_wrapper, cache->GetFocus());
 }
 
+TEST_F(AXAshWindowUtilsTest, IsRootWindow) {
+  AXAshWindowUtils utils;
+
+  // From the client's perspective a widget's root window is a root.
+  aura::Window* widget_root = widget_->GetNativeWindow()->GetRootWindow();
+  EXPECT_TRUE(widget_root->IsRootWindow());
+
+  // Simulate an embedded remote client window.
+  aura::WindowTreeHostMus window_tree_host(aura::CreateInitParamsForTopLevel(
+      views::MusClient::Get()->window_tree_client()));
+  window_tree_host.InitHost();
+  window_tree_host.SetBounds(gfx::Rect(0, 0, 100, 200),
+                             viz::LocalSurfaceIdAllocation());
+  aura::Window* embed_root = window_tree_host.window();
+
+  // From the client's perspective the embed is a root.
+  EXPECT_TRUE(embed_root->IsRootWindow());
+
+  // Accessibility serialization only considers display roots to be roots.
+  EXPECT_TRUE(utils.IsRootWindow(Shell::GetPrimaryRootWindow()));
+  EXPECT_FALSE(utils.IsRootWindow(embed_root));
+  EXPECT_FALSE(utils.IsRootWindow(widget_root));
+}
+
 }  // namespace
 }  // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 59c33fc..f49e07a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1421,6 +1421,8 @@
       "fuchsia/service_directory_client.h",
       "fuchsia/service_provider_impl.cc",
       "fuchsia/service_provider_impl.h",
+      "fuchsia/startup_context.cc",
+      "fuchsia/startup_context.h",
       "memory/platform_shared_memory_region_fuchsia.cc",
       "memory/protected_memory_posix.cc",
       "memory/shared_memory_fuchsia.cc",
diff --git a/base/fuchsia/service_provider_impl.h b/base/fuchsia/service_provider_impl.h
index 35087ac..e8ac85e 100644
--- a/base/fuchsia/service_provider_impl.h
+++ b/base/fuchsia/service_provider_impl.h
@@ -12,8 +12,10 @@
 #include <lib/zx/channel.h>
 #include <string>
 
+#include "base/base_export.h"
 #include "base/callback.h"
 #include "base/fuchsia/service_directory_client.h"
+#include "base/macros.h"
 
 namespace base {
 namespace fuchsia {
diff --git a/base/fuchsia/startup_context.cc b/base/fuchsia/startup_context.cc
new file mode 100644
index 0000000..971f519
--- /dev/null
+++ b/base/fuchsia/startup_context.cc
@@ -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.
+
+#include "base/fuchsia/startup_context.h"
+
+#include <fuchsia/io/cpp/fidl.h>
+
+namespace base {
+namespace fuchsia {
+
+StartupContext::StartupContext(::fuchsia::sys::StartupInfo startup_info)
+    : startup_info_(std::move(startup_info)) {
+  // Component manager generates |flat_namespace|, so things are horribly broken
+  // if |flat_namespace| is malformed.
+  CHECK_EQ(startup_info_.flat_namespace.directories.size(),
+           startup_info_.flat_namespace.paths.size());
+
+  // Find the /svc directory and wrap it into a ServiceDirectoryClient.
+  for (size_t i = 0; i < startup_info_.flat_namespace.paths.size(); ++i) {
+    if (startup_info_.flat_namespace.paths[i] == "/svc") {
+      incoming_services_ = std::make_unique<ServiceDirectoryClient>(
+          fidl::InterfaceHandle<::fuchsia::io::Directory>(
+              std::move(startup_info_.flat_namespace.directories[i])));
+      break;
+    }
+  }
+}
+
+StartupContext::~StartupContext() = default;
+
+base::fuchsia::ServiceDirectory* StartupContext::public_services() {
+  if (!public_services_ && startup_info_.launch_info.directory_request) {
+    public_services_ = std::make_unique<ServiceDirectory>(
+        fidl::InterfaceRequest<::fuchsia::io::Directory>(
+            std::move(startup_info_.launch_info.directory_request)));
+  }
+  return public_services_.get();
+}
+
+}  // namespace fuchsia
+}  // namespace base
diff --git a/base/fuchsia/startup_context.h b/base/fuchsia/startup_context.h
new file mode 100644
index 0000000..0b5b706
--- /dev/null
+++ b/base/fuchsia/startup_context.h
@@ -0,0 +1,52 @@
+// 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 BASE_FUCHSIA_STARTUP_CONTEXT_H_
+#define BASE_FUCHSIA_STARTUP_CONTEXT_H_
+
+#include <fuchsia/sys/cpp/fidl.h>
+#include <memory>
+
+#include "base/base_export.h"
+#include "base/fuchsia/service_directory.h"
+#include "base/fuchsia/service_directory_client.h"
+#include "base/macros.h"
+
+namespace base {
+namespace fuchsia {
+
+// Helper for unpacking a fuchsia.sys.StartupInfo and creating convenience
+// wrappers for the various fields (e.g. the incoming & outgoing service
+// directories, resolve launch URL etc).
+// Embedders may derived from StartupContext to e.g. add bound pointers to
+// embedder-specific services, as required.
+class BASE_EXPORT StartupContext {
+ public:
+  explicit StartupContext(::fuchsia::sys::StartupInfo startup_info);
+  virtual ~StartupContext();
+
+  // Returns the namespace of services published for use by the component.
+  const ServiceDirectoryClient* incoming_services() const {
+    return incoming_services_.get();
+  }
+
+  // Returns the "public" directory into which this component binds services.
+  // Note that all services should be bound immediately after the first call to
+  // this API, before returning control to the message loop, at which point we
+  // will start processing service connection requests.
+  ServiceDirectory* public_services();
+
+ private:
+  ::fuchsia::sys::StartupInfo startup_info_;
+
+  std::unique_ptr<ServiceDirectoryClient> incoming_services_;
+  std::unique_ptr<ServiceDirectory> public_services_;
+
+  DISALLOW_COPY_AND_ASSIGN(StartupContext);
+};
+
+}  // namespace fuchsia
+}  // namespace base
+
+#endif  // BASE_FUCHSIA_STARTUP_CONTEXT_H_
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index cec3a133..ec20869 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -29,10 +29,6 @@
 
 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = nullptr;
 
-std::unique_ptr<MessagePump> ReturnPump(std::unique_ptr<MessagePump> pump) {
-  return pump;
-}
-
 }  // namespace
 
 // Unfortunately since we're not on C++17 we're required to provide an out of
@@ -45,13 +41,16 @@
 constexpr MessageLoop::Type MessageLoop::TYPE_JAVA;
 #endif
 
-MessageLoop::MessageLoop(Type type)
-    : MessageLoop(type, MessagePumpFactoryCallback()) {
+MessageLoop::MessageLoop(Type type) : MessageLoop(type, nullptr) {
+  // For TYPE_CUSTOM you must either use
+  // MessageLoop(std::unique_ptr<MessagePump> pump) or
+  // MessageLoop::CreateUnbound()
+  DCHECK_NE(type_, TYPE_CUSTOM);
   BindToCurrentThread();
 }
 
 MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump)
-    : MessageLoop(TYPE_CUSTOM, BindOnce(&ReturnPump, std::move(pump))) {
+    : MessageLoop(TYPE_CUSTOM, std::move(pump)) {
   BindToCurrentThread();
 }
 
@@ -165,22 +164,17 @@
 //------------------------------------------------------------------------------
 
 // static
-std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(
-    Type type,
-    MessagePumpFactoryCallback pump_factory) {
-  return WrapUnique(new MessageLoop(type, std::move(pump_factory)));
+std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(Type type) {
+  return WrapUnique(new MessageLoop(type, nullptr));
 }
 
-MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
+MessageLoop::MessageLoop(Type type, std::unique_ptr<MessagePump> custom_pump)
     : backend_(sequence_manager::internal::SequenceManagerImpl::CreateUnbound(
           sequence_manager::SequenceManager::Settings{.message_loop_type =
                                                           type})),
       default_task_queue_(CreateDefaultTaskQueue()),
       type_(type),
-      pump_factory_(std::move(pump_factory)) {
-  // If type is TYPE_CUSTOM non-null pump_factory must be given.
-  DCHECK(type_ != TYPE_CUSTOM || !pump_factory_.is_null());
-
+      custom_pump_(std::move(custom_pump)) {
   // Bound in BindToCurrentThread();
   DETACH_FROM_THREAD(bound_thread_checker_);
 }
@@ -213,8 +207,8 @@
 }
 
 std::unique_ptr<MessagePump> MessageLoop::CreateMessagePump() {
-  if (!pump_factory_.is_null()) {
-    return std::move(pump_factory_).Run();
+  if (custom_pump_) {
+    return std::move(custom_pump_);
   } else {
     return CreateMessagePumpForType(type_);
   }
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index f49f562..287f6c2 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -191,6 +191,7 @@
   friend class MessageLoopCurrent;
   friend class MessageLoopCurrentForIO;
   friend class MessageLoopCurrentForUI;
+  friend class Thread;
   friend class sequence_manager::internal::ThreadControllerImpl;
 
   // Explicitly allow or disallow task execution. Task execution is disallowed
@@ -204,6 +205,8 @@
   virtual void AttachToMessagePump() = 0;
 #endif
 
+  virtual Type GetType() const = 0;
+
   // Set the timer slack for this message loop.
   // TODO(alexclarke): Remove this as part of https://crbug.com/891670.
   virtual void SetTimerSlack(TimerSlack timer_slack) = 0;
@@ -226,7 +229,7 @@
   explicit MessageLoop(Type type = TYPE_DEFAULT);
   // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
   // be non-NULL.
-  explicit MessageLoop(std::unique_ptr<MessagePump> pump);
+  explicit MessageLoop(std::unique_ptr<MessagePump> custom_pump);
 
   virtual ~MessageLoop();
 
@@ -297,7 +300,7 @@
   // specific type with a custom loop. The implementation does not call
   // BindToCurrentThread. If this constructor is invoked directly by a subclass,
   // then the subclass must subsequently bind the message loop.
-  MessageLoop(Type type, MessagePumpFactoryCallback pump_factory);
+  MessageLoop(Type type, std::unique_ptr<MessagePump> pump);
 
   // Configure various members and bind this message loop to the current thread.
   void BindToCurrentThread();
@@ -324,9 +327,6 @@
   FRIEND_TEST_ALL_PREFIXES(MessageLoopTest, DeleteUnboundLoop);
 
   // Creates a MessageLoop without binding to a thread.
-  // If |type| is TYPE_CUSTOM non-null |pump_factory| must be also given
-  // to create a message pump for this message loop.  Otherwise a default
-  // message pump for the |type| is created.
   //
   // It is valid to call this to create a new message loop on one thread,
   // and then pass it to the thread where the message loop actually runs.
@@ -334,9 +334,7 @@
   // thread the message loop runs on, before calling Run().
   // Before BindToCurrentThread() is called, only Post*Task() functions can
   // be called on the message loop.
-  static std::unique_ptr<MessageLoop> CreateUnbound(
-      Type type,
-      MessagePumpFactoryCallback pump_factory);
+  static std::unique_ptr<MessageLoop> CreateUnbound(Type type);
 
   scoped_refptr<sequence_manager::TaskQueue> CreateDefaultTaskQueue();
 
@@ -344,9 +342,9 @@
 
   const Type type_;
 
-  // pump_factory_.Run() is called to create a message pump for this loop
-  // if |type_| is TYPE_CUSTOM and |pump_| is null.
-  MessagePumpFactoryCallback pump_factory_;
+  // If set this will be returned by the next call to CreateMessagePump().
+  // This is only set if |type_| is TYPE_CUSTOM and |pump_| is null.
+  std::unique_ptr<MessagePump> custom_pump_;
 
   // Id of the thread this message loop is bound to. Initialized once when the
   // MessageLoop is bound to its thread and constant forever after.
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index 86ae3f5..3488a04 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -612,8 +612,7 @@
   }
 
   std::unique_ptr<MessageLoop> CreateMessageLoop() {
-    auto message_loop = base::WrapUnique(
-        new MessageLoop(GetParam(), MessageLoop::MessagePumpFactoryCallback()));
+    auto message_loop = base::WrapUnique(new MessageLoop(GetParam(), nullptr));
     message_loop->BindToCurrentThread();
     return message_loop;
   }
@@ -2236,8 +2235,8 @@
   // It should be possible to delete an unbound message loop on a thread which
   // already has another active loop. This happens when thread creation fails.
   MessageLoop loop;
-  std::unique_ptr<MessageLoop> unbound_loop(MessageLoop::CreateUnbound(
-      MessageLoop::TYPE_DEFAULT, MessageLoop::MessagePumpFactoryCallback()));
+  std::unique_ptr<MessageLoop> unbound_loop(
+      MessageLoop::CreateUnbound(MessageLoop::TYPE_DEFAULT));
   unbound_loop.reset();
   EXPECT_TRUE(loop.IsBoundToCurrentThread());
   EXPECT_EQ(loop.task_runner(), ThreadTaskRunnerHandle::Get());
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc
index 6f900e6f3..68c7fd9 100644
--- a/base/message_loop/message_pump_perftest.cc
+++ b/base/message_loop/message_pump_perftest.cc
@@ -31,7 +31,7 @@
  public:
   ThreadForTest() : Thread("test") {}
 
-  using Thread::message_loop;
+  using Thread::message_loop_base;
 };
 
 class ScheduleWorkTest : public testing::Test {
@@ -56,10 +56,7 @@
     uint64_t schedule_calls = 0u;
     do {
       for (size_t i = 0; i < kBatchSize; ++i) {
-        target_message_loop()
-            ->GetMessageLoopBase()
-            ->GetMessagePump()
-            ->ScheduleWork();
+        target_message_loop_base()->GetMessagePump()->ScheduleWork();
         schedule_calls++;
       }
       now = base::TimeTicks::Now();
@@ -75,7 +72,7 @@
           base::ThreadTicks::Now() - thread_start;
     min_batch_times_[index] = minimum;
     max_batch_times_[index] = maximum;
-    target_message_loop()->task_runner()->PostTask(
+    target_message_loop_base()->GetTaskRunner()->PostTask(
         FROM_HERE, base::BindOnce(&ScheduleWorkTest::Increment,
                                   base::Unretained(this), schedule_calls));
   }
@@ -177,12 +174,12 @@
     }
   }
 
-  MessageLoop* target_message_loop() {
+  MessageLoopBase* target_message_loop_base() {
 #if defined(OS_ANDROID)
     if (java_thread_)
-      return java_thread_->message_loop();
+      return java_thread_->message_loop()->GetMessageLoopBase();
 #endif
-    return target_->message_loop();
+    return target_->message_loop_base();
   }
 
  private:
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
index 1f393456..3522e328 100644
--- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc
+++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -19,87 +19,49 @@
 #include "base/sampling_heap_profiler/lock_free_address_hash_set.h"
 #include "build/build_config.h"
 
-#if defined(OS_POSIX)
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
 #include <pthread.h>
 #endif
 
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-
 namespace base {
 
 using allocator::AllocatorDispatch;
 
 namespace {
 
-// PoissonAllocationSampler cannot use ThreadLocalStorage, as during thread
-// exiting when TLS storage is already released, there might be a call to
-// |free| which would trigger the profiler hook and would make it access TLS.
-// It instead uses OS primitives directly. As it only stores POD types it
-// does not need thread exit callbacks.
-#if defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
 
-using TLSKey = DWORD;
-
-void TLSInit(TLSKey* key) {
-  *key = ::TlsAlloc();
-  CHECK_NE(TLS_OUT_OF_INDEXES, *key);
-}
-
-uintptr_t TLSGetValue(const TLSKey& key) {
-  return reinterpret_cast<uintptr_t>(::TlsGetValue(key));
-}
-
-void TLSSetValue(const TLSKey& key, uintptr_t value) {
-  ::TlsSetValue(key, reinterpret_cast<LPVOID>(value));
-}
-
-#else  // defined(OS_WIN)
-
-using TLSKey = pthread_key_t;
-
-void TLSInit(TLSKey* key) {
-  int result = pthread_key_create(key, nullptr);
-  CHECK_EQ(0, result);
-}
-
-uintptr_t TLSGetValue(const TLSKey& key) {
-  return reinterpret_cast<uintptr_t>(pthread_getspecific(key));
-}
-
-void TLSSetValue(const TLSKey& key, uintptr_t value) {
-  pthread_setspecific(key, reinterpret_cast<void*>(value));
-}
-
-#endif
-
-// On MacOS the implementation of libmalloc sometimes calls malloc recursively,
+// The macOS implementation of libmalloc sometimes calls malloc recursively,
 // delegating allocations between zones. That causes our hooks being called
 // twice. The scoped guard allows us to detect that.
-#if defined(OS_MACOSX)
-
+//
+// Besides that the implementations of thread_local on macOS and Android
+// seem to allocate memory lazily on the first access to thread_local variables.
+// Make use of pthread TLS instead of C++ thread_local there.
 class ReentryGuard {
  public:
-  ReentryGuard() : allowed_(!TLSGetValue(entered_key_)) {
-    TLSSetValue(entered_key_, true);
+  ReentryGuard() : allowed_(!pthread_getspecific(entered_key_)) {
+    pthread_setspecific(entered_key_, reinterpret_cast<void*>(true));
   }
 
   ~ReentryGuard() {
     if (LIKELY(allowed_))
-      TLSSetValue(entered_key_, false);
+      pthread_setspecific(entered_key_, nullptr);
   }
 
   operator bool() { return allowed_; }
 
-  static void Init() { TLSInit(&entered_key_); }
+  static void Init() {
+    int error = pthread_key_create(&entered_key_, nullptr);
+    CHECK(!error);
+  }
 
  private:
   bool allowed_;
-  static TLSKey entered_key_;
+  static pthread_key_t entered_key_;
 };
 
-TLSKey ReentryGuard::entered_key_;
+pthread_key_t ReentryGuard::entered_key_;
 
 #else
 
@@ -111,21 +73,44 @@
 
 #endif
 
-TLSKey g_internal_reentry_guard;
-
 const size_t kDefaultSamplingIntervalBytes = 128 * 1024;
 
-// Accumulated bytes towards sample thread local key.
-TLSKey g_accumulated_bytes_tls;
+// Notes on TLS usage:
+//
+// * There's no safe way to use TLS in malloc() as both C++ thread_local and
+//   pthread do not pose any guarantees on whether they allocate or not.
+// * We think that we can safely use thread_local w/o re-entrancy guard because
+//   the compiler will use "tls static access model" for static builds of
+//   Chrome [https://www.uclibc.org/docs/tls.pdf].
+//   But there's no guarantee that this will stay true, and in practice
+//   it seems to have problems on macOS/Android. These platforms do allocate
+//   on the very first access to a thread_local on each thread.
+// * Directly using/warming-up platform TLS seems to work on all platforms,
+//   but is also not guaranteed to stay true. We make use of it for reentrancy
+//   guards on macOS/Android.
+// * We cannot use Windows Tls[GS]etValue API as it modifies the result of
+//   GetLastError.
+//
+// Android thread_local seems to be using __emutls_get_address from libgcc:
+// https://github.com/gcc-mirror/gcc/blob/master/libgcc/emutls.c
+// macOS version is based on _tlv_get_addr from dyld:
+// https://opensource.apple.com/source/dyld/dyld-635.2/src/threadLocalHelpers.s.auto.html
 
-// A boolean used to distinguish first allocation on a thread.
-//   false - first allocation on the thread.
-//   true  - otherwise
+// The guard protects against reentering on platforms other the macOS and
+// Android.
+thread_local bool g_internal_reentry_guard;
+
+// Accumulated bytes towards sample thread local key.
+thread_local intptr_t g_accumulated_bytes_tls;
+
+// A boolean used to distinguish first allocation on a thread:
+//   false - first allocation on the thread;
+//   true  - otherwise.
 // Since g_accumulated_bytes_tls is initialized with zero the very first
 // allocation on a thread would always trigger the sample, thus skewing the
 // profile towards such allocations. To mitigate that we use the flag to
 // ensure the first allocation is properly accounted.
-TLSKey g_sampling_interval_initialized_tls;
+thread_local bool g_sampling_interval_initialized_tls;
 
 // Controls if sample intervals should not be randomized. Used for testing.
 bool g_deterministic;
@@ -314,18 +299,18 @@
 }  // namespace
 
 PoissonAllocationSampler::ScopedMuteThreadSamples::ScopedMuteThreadSamples() {
-  DCHECK(!TLSGetValue(g_internal_reentry_guard));
-  TLSSetValue(g_internal_reentry_guard, true);
+  DCHECK(!g_internal_reentry_guard);
+  g_internal_reentry_guard = true;
 }
 
 PoissonAllocationSampler::ScopedMuteThreadSamples::~ScopedMuteThreadSamples() {
-  DCHECK(TLSGetValue(g_internal_reentry_guard));
-  TLSSetValue(g_internal_reentry_guard, false);
+  DCHECK(g_internal_reentry_guard);
+  g_internal_reentry_guard = false;
 }
 
 // static
 bool PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted() {
-  return TLSGetValue(g_internal_reentry_guard);
+  return g_internal_reentry_guard;
 }
 
 PoissonAllocationSampler* PoissonAllocationSampler::instance_;
@@ -343,9 +328,6 @@
 void PoissonAllocationSampler::Init() {
   static bool init_once = []() {
     ReentryGuard::Init();
-    TLSInit(&g_internal_reentry_guard);
-    TLSInit(&g_accumulated_bytes_tls);
-    TLSInit(&g_sampling_interval_initialized_tls);
     return true;
   }();
   ignore_result(init_once);
@@ -427,11 +409,11 @@
                                            const char* context) {
   if (UNLIKELY(!g_running.load(std::memory_order_relaxed)))
     return;
-  intptr_t accumulated_bytes = TLSGetValue(g_accumulated_bytes_tls) + size;
+  g_accumulated_bytes_tls += size;
+  intptr_t accumulated_bytes = g_accumulated_bytes_tls;
   if (LIKELY(accumulated_bytes < 0))
-    TLSSetValue(g_accumulated_bytes_tls, accumulated_bytes);
-  else
-    instance_->DoRecordAlloc(accumulated_bytes, size, address, type, context);
+    return;
+  instance_->DoRecordAlloc(accumulated_bytes, size, address, type, context);
 }
 
 void PoissonAllocationSampler::DoRecordAlloc(intptr_t accumulated_bytes,
@@ -452,10 +434,10 @@
     ++samples;
   } while (accumulated_bytes >= 0);
 
-  TLSSetValue(g_accumulated_bytes_tls, accumulated_bytes);
+  g_accumulated_bytes_tls = accumulated_bytes;
 
-  if (UNLIKELY(!TLSGetValue(g_sampling_interval_initialized_tls))) {
-    TLSSetValue(g_sampling_interval_initialized_tls, true);
+  if (UNLIKELY(!g_sampling_interval_initialized_tls)) {
+    g_sampling_interval_initialized_tls = true;
     // This is the very first allocation on the thread. It always produces an
     // extra sample because g_accumulated_bytes_tls is initialized with zero
     // due to TLS semantics.
@@ -464,7 +446,7 @@
       return;
   }
 
-  if (UNLIKELY(TLSGetValue(g_internal_reentry_guard)))
+  if (UNLIKELY(ScopedMuteThreadSamples::IsMuted()))
     return;
 
   ScopedMuteThreadSamples no_reentrancy_scope;
@@ -491,7 +473,7 @@
 }
 
 void PoissonAllocationSampler::DoRecordFree(void* address) {
-  if (UNLIKELY(TLSGetValue(g_internal_reentry_guard)))
+  if (UNLIKELY(ScopedMuteThreadSamples::IsMuted()))
     return;
   ScopedMuteThreadSamples no_reentrancy_scope;
   AutoLock lock(mutex_);
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc b/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
index 110d8256..8e08e01 100644
--- a/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
+++ b/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "base/allocator/allocator_shim.h"
 #include "base/debug/alias.h"
+#include "base/rand_util.h"
 #include "base/threading/simple_thread.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -200,4 +201,40 @@
   });
 }
 
+// Platform TLS: alloc+free[ns]: 22.184  alloc[ns]: 8.910  free[ns]: 13.274
+// thread_local: alloc+free[ns]: 18.353  alloc[ns]: 5.021  free[ns]: 13.331
+TEST_F(SamplingHeapProfilerTest, MANUAL_SamplerMicroBenchmark) {
+  // With the sampling interval of 100KB it happens to record ~ every 450th
+  // allocation in the browser process. We model this pattern here.
+  constexpr size_t sampling_interval = 100000;
+  constexpr size_t allocation_size = sampling_interval / 450;
+  SamplesCollector collector(0);
+  auto* sampler = PoissonAllocationSampler::Get();
+  sampler->SetSamplingInterval(sampling_interval);
+  sampler->AddSamplesObserver(&collector);
+  int kNumAllocations = 50000000;
+
+  base::TimeTicks t0 = base::TimeTicks::Now();
+  for (int i = 1; i <= kNumAllocations; ++i) {
+    sampler->RecordAlloc(
+        reinterpret_cast<void*>(static_cast<intptr_t>(i)), allocation_size,
+        PoissonAllocationSampler::AllocatorType::kMalloc, nullptr);
+  }
+  base::TimeTicks t1 = base::TimeTicks::Now();
+  for (int i = 1; i <= kNumAllocations; ++i)
+    sampler->RecordFree(reinterpret_cast<void*>(static_cast<intptr_t>(i)));
+  base::TimeTicks t2 = base::TimeTicks::Now();
+
+  printf(
+      "alloc+free[ns]: %.3f   alloc[ns]: %.3f   free[ns]: %.3f   "
+      "alloc+free[mln/s]: %.1f   total[ms]: %.1f\n",
+      (t2 - t0).InNanoseconds() * 1. / kNumAllocations,
+      (t1 - t0).InNanoseconds() * 1. / kNumAllocations,
+      (t2 - t1).InNanoseconds() * 1. / kNumAllocations,
+      kNumAllocations / (t2 - t0).InMicrosecondsF(),
+      (t2 - t0).InMillisecondsF());
+
+  sampler->RemoveSamplesObserver(&collector);
+}
+
 }  // namespace base
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index aceea17..a7af2a5 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -882,6 +882,10 @@
   return false;
 }
 
+MessageLoop::Type SequenceManagerImpl::GetType() const {
+  return type_;
+}
+
 void SequenceManagerImpl::SetTaskExecutionAllowed(bool allowed) {
   controller_->SetTaskExecutionAllowed(allowed);
 }
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index 6c5c85f0..0aea470f 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -155,6 +155,7 @@
   void BindToCurrentThread(std::unique_ptr<MessagePump> pump) override;
   void DeletePendingTasks() override;
   bool HasTasks() override;
+  MessageLoop::Type GetType() const override;
 
   // Requests that a task to process work is scheduled.
   void ScheduleWork();
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index cdb171359b..105950d 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -15,6 +15,7 @@
 #include "base/threading/thread_id_name_manager.h"
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_restrictions.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 
 #if defined(OS_POSIX) && !defined(OS_NACL)
@@ -43,7 +44,7 @@
 Thread::Options::Options(MessageLoop::Type type, size_t size)
     : message_loop_type(type), stack_size(size) {}
 
-Thread::Options::Options(const Options& other) = default;
+Thread::Options::Options(Options&& other) = default;
 
 Thread::Options::~Options() = default;
 
@@ -77,7 +78,7 @@
 
 bool Thread::StartWithOptions(const Options& options) {
   DCHECK(owning_sequence_checker_.CalledOnValidSequence());
-  DCHECK(!message_loop_);
+  DCHECK(!message_loop_base_);
   DCHECK(!IsRunning());
   DCHECK(!stopping_) << "Starting a non-joinable thread a second time? That's "
                      << "not allowed!";
@@ -97,9 +98,16 @@
     type = MessageLoop::TYPE_CUSTOM;
 
   timer_slack_ = options.timer_slack;
-  std::unique_ptr<MessageLoop> message_loop_owned =
-      MessageLoop::CreateUnbound(type, options.message_pump_factory);
-  message_loop_ = message_loop_owned.get();
+  std::unique_ptr<MessageLoop> message_loop_owned;
+
+  if (options.message_loop_base) {
+    message_loop_base_ = options.message_loop_base;
+  } else {
+    message_pump_factory_ = options.message_pump_factory;
+    message_loop_owned = MessageLoop::CreateUnbound(type);
+    message_loop_base_ = message_loop_owned->GetMessageLoopBase();
+  }
+
   start_event_.Reset();
 
   // Hold |thread_lock_| while starting the new thread to synchronize with
@@ -115,7 +123,7 @@
                   options.stack_size, this, options.priority);
     if (!success) {
       DLOG(ERROR) << "failed to create thread";
-      message_loop_ = nullptr;
+      message_loop_base_ = nullptr;
       return false;
     }
   }
@@ -126,7 +134,7 @@
   // within the ThreadMain.
   ignore_result(message_loop_owned.release());
 
-  DCHECK(message_loop_);
+  DCHECK(message_loop_base_);
   return true;
 }
 
@@ -141,7 +149,7 @@
 
 bool Thread::WaitUntilThreadStarted() const {
   DCHECK(owning_sequence_checker_.CalledOnValidSequence());
-  if (!message_loop_)
+  if (!message_loop_base_)
     return false;
   // https://crbug.com/918039
   base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
@@ -151,7 +159,7 @@
 
 void Thread::FlushForTesting() {
   DCHECK(owning_sequence_checker_.CalledOnValidSequence());
-  if (!message_loop_)
+  if (!message_loop_base_)
     return;
 
   WaitableEvent done(WaitableEvent::ResetPolicy::AUTOMATIC,
@@ -178,15 +186,14 @@
 
   // Wait for the thread to exit.
   //
-  // TODO(darin): Unfortunately, we need to keep |message_loop_| around until
-  // the thread exits.  Some consumers are abusing the API.  Make them stop.
-  //
+  // TODO(darin): Unfortunately, we need to keep |message_loop_base_| around
+  // until the thread exits. Some consumers are abusing the API. Make them stop.
   PlatformThread::Join(thread_);
   thread_ = base::PlatformThreadHandle();
 
-  // The thread should nullify |message_loop_| on exit (note: Join() adds an
-  // implicit memory barrier and no lock is thus required for this check).
-  DCHECK(!message_loop_);
+  // The thread should nullify |message_loop_base_| on exit (note: Join() adds
+  // an implicit memory barrier and no lock is thus required for this check).
+  DCHECK(!message_loop_base_);
 
   stopping_ = false;
 }
@@ -196,7 +203,7 @@
   // enable this check.
   // DCHECK(owning_sequence_checker_.CalledOnValidSequence());
 
-  if (stopping_ || !message_loop_)
+  if (stopping_ || !message_loop_base_)
     return;
 
   stopping_ = true;
@@ -206,7 +213,7 @@
     // thread to be considered "stopped" per it having never set its |running_|
     // bit by lack of its own ThreadMain.
     DCHECK(!IsRunning());
-    message_loop_ = nullptr;
+    message_loop_base_ = nullptr;
     return;
   }
 
@@ -231,11 +238,11 @@
   // enable this check.
   // DCHECK(owning_sequence_checker_.CalledOnValidSequence());
 
-  // If the thread's already started (i.e. |message_loop_| is non-null) and not
-  // yet requested to stop (i.e. |stopping_| is false) we can just return true.
-  // (Note that |stopping_| is touched only on the same sequence that starts /
-  // started the new thread so we need no locking here.)
-  if (message_loop_ && !stopping_)
+  // If the thread's already started (i.e. |message_loop_base_| is non-null) and
+  // not yet requested to stop (i.e. |stopping_| is false) we can just return
+  // true. (Note that |stopping_| is touched only on the same sequence that
+  // starts / started the new thread so we need no locking here.)
+  if (message_loop_base_ && !stopping_)
     return true;
   // Otherwise check the |running_| flag, which is set to true by the new thread
   // only while it is inside Run().
@@ -269,10 +276,10 @@
   DCHECK(owning_sequence_checker_.CalledOnValidSequence());
   DCHECK(message_loop);
 
-  // Setting |message_loop_| should suffice for this thread to be considered
-  // as "running", until Stop() is invoked.
+  // Setting |message_loop_base_| should suffice for this thread to be
+  // considered as "running", until Stop() is invoked.
   DCHECK(!IsRunning());
-  message_loop_ = message_loop;
+  message_loop_base_ = message_loop->GetMessageLoopBase();
   DCHECK(IsRunning());
 
   using_external_message_loop_ = true;
@@ -295,17 +302,23 @@
   ANNOTATE_THREAD_NAME(name_.c_str());  // Tell the name to race detector.
 
   // Lazily initialize the |message_loop| so that it can run on this thread.
-  DCHECK(message_loop_);
-  std::unique_ptr<MessageLoop> message_loop(message_loop_);
-  message_loop_->BindToCurrentThread();
-  message_loop_->SetTimerSlack(timer_slack_);
+  DCHECK(message_loop_base_);
+  std::unique_ptr<MessageLoopBase> message_loop_base(message_loop_base_);
+  // This binds MessageLoopCurrent and ThreadTaskRunnerHandle.
+  message_loop_base_->BindToCurrentThread(
+      message_pump_factory_ ? message_pump_factory_.Run()
+                            : MessageLoop::CreateMessagePumpForType(
+                                  message_loop_base_->GetType()));
+  DCHECK(MessageLoopCurrent::Get());
+  DCHECK(ThreadTaskRunnerHandle::Get());
+  message_loop_base_->SetTimerSlack(timer_slack_);
 
 #if defined(OS_POSIX) && !defined(OS_NACL)
   // Allow threads running a MessageLoopForIO to use FileDescriptorWatcher API.
   std::unique_ptr<FileDescriptorWatcher> file_descriptor_watcher;
   if (MessageLoopCurrentForIO::IsSet()) {
     file_descriptor_watcher.reset(
-        new FileDescriptorWatcher(message_loop_->task_runner()));
+        new FileDescriptorWatcher(message_loop_base_->GetTaskRunner()));
   }
 #endif
 
@@ -344,7 +357,7 @@
   com_initializer.reset();
 #endif
 
-  if (message_loop->type() != MessageLoop::TYPE_CUSTOM) {
+  if (message_loop_base->GetType() != MessageLoop::TYPE_CUSTOM) {
     // Assert that RunLoop::QuitWhenIdle was called by ThreadQuitHelper. Don't
     // check for custom message pumps, because their shutdown might not allow
     // this.
@@ -353,7 +366,7 @@
 
   // We can't receive messages anymore.
   // (The message loop is destructed at the end of this block)
-  message_loop_ = nullptr;
+  message_loop_base_ = nullptr;
   run_loop_ = nullptr;
 }
 
diff --git a/base/threading/thread.h b/base/threading/thread.h
index b8b890b..64a85aaec 100644
--- a/base/threading/thread.h
+++ b/base/threading/thread.h
@@ -64,13 +64,18 @@
 
     Options();
     Options(MessageLoop::Type type, size_t size);
-    Options(const Options& other);
+    Options(Options&& other);
     ~Options();
 
     // Specifies the type of message loop that will be allocated on the thread.
     // This is ignored if message_pump_factory.is_null() is false.
     MessageLoop::Type message_loop_type = MessageLoop::TYPE_DEFAULT;
 
+    // An unbound MessageLoopBase that will be bound to the thread. Ownership
+    // of |message_loop_base| will be transferred to the thread.
+    // TODO(alexclarke): This should be a std::unique_ptr
+    MessageLoopBase* message_loop_base = nullptr;
+
     // Specifies timer slack for thread message loop.
     TimerSlack timer_slack = TIMER_SLACK_NONE;
 
@@ -118,7 +123,7 @@
   // init_com_with_mta(false) and then StartWithOptions() with any message loop
   // type other than TYPE_UI.
   void init_com_with_mta(bool use_mta) {
-    DCHECK(!message_loop_);
+    DCHECK(!message_loop_base_);
     com_status_ = use_mta ? MTA : STA;
   }
 #endif
@@ -199,19 +204,20 @@
   // In addition to this Thread's owning sequence, this can also safely be
   // called from the underlying thread itself.
   scoped_refptr<SingleThreadTaskRunner> task_runner() const {
-    // This class doesn't provide synchronization around |message_loop_| and as
-    // such only the owner should access it (and the underlying thread which
-    // never sees it before it's set). In practice, many callers are coming from
-    // unrelated threads but provide their own implicit (e.g. memory barriers
-    // from task posting) or explicit (e.g. locks) synchronization making the
-    // access of |message_loop_| safe... Changing all of those callers is
-    // unfeasible; instead verify that they can reliably see
-    // |message_loop_ != nullptr| without synchronization as a proof that their
-    // external synchronization catches the unsynchronized effects of Start().
+    // This class doesn't provide synchronization around |message_loop_base_|
+    // and as such only the owner should access it (and the underlying thread
+    // which never sees it before it's set). In practice, many callers are
+    // coming from unrelated threads but provide their own implicit (e.g. memory
+    // barriers from task posting) or explicit (e.g. locks) synchronization
+    // making the access of |message_loop_base_| safe... Changing all of those
+    // callers is unfeasible; instead verify that they can reliably see
+    // |message_loop_base_ != nullptr| without synchronization as a proof that
+    // their external synchronization catches the unsynchronized effects of
+    // Start().
     DCHECK(owning_sequence_checker_.CalledOnValidSequence() ||
            (id_event_.IsSignaled() && id_ == PlatformThread::CurrentId()) ||
-           message_loop_);
-    return message_loop_ ? message_loop_->task_runner() : nullptr;
+           message_loop_base_);
+    return message_loop_base_ ? message_loop_base_->GetTaskRunner() : nullptr;
   }
 
   // Returns the name of this thread (for display in debugger too).
@@ -262,12 +268,12 @@
   //
   // In addition to this Thread's owning sequence, this can also safely be
   // called from the underlying thread itself.
-  MessageLoop* message_loop() const {
+  MessageLoopBase* message_loop_base() const {
     // See the comment inside |task_runner()|.
     DCHECK(owning_sequence_checker_.CalledOnValidSequence() ||
            (id_event_.IsSignaled() && id_ == PlatformThread::CurrentId()) ||
-           message_loop_);
-    return message_loop_;
+           message_loop_base_);
+    return message_loop_base_;
   }
 
  private:
@@ -317,16 +323,19 @@
   // Protects |id_| which must only be read while it's signaled.
   mutable WaitableEvent id_event_;
 
-  // The thread's MessageLoop and RunLoop. Valid only while the thread is alive.
-  // Set by the created thread.
-  MessageLoop* message_loop_ = nullptr;
+  // Supports creation of MessageLoopType::CUSTOM.
+  Options::MessagePumpFactory message_pump_factory_;
+
+  // The thread's MessageLooBase and RunLoop. Valid only while the thread is
+  // alive. Set by the created thread.
+  MessageLoopBase* message_loop_base_ = nullptr;
   RunLoop* run_loop_ = nullptr;
 
-  // True only if |message_loop_| was externally provided by |SetMessageLoop()|
-  // in which case this Thread has no underlying |thread_| and should merely
-  // drop |message_loop_| on Stop(). In that event, this remains true after
-  // Stop() was invoked so that subclasses can use this state to build their own
-  // cleanup logic as required.
+  // True only if |message_loop_base_| was externally provided by |
+  // SetMessageLoop()| in which case this Thread has no underlying |thread_| and
+  // should merely drop |message_loop_base_| on Stop(). In that event, this
+  // remains true after Stop() was invoked so that subclasses can use this state
+  // to build their own cleanup logic as required.
   bool using_external_message_loop_ = false;
 
   // Stores Options::timer_slack_ until the sequence manager has been bound to
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index 4414585..45e62da5 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/test/gtest_util.h"
 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
 #include "base/threading/platform_thread.h"
@@ -575,3 +576,29 @@
   // StopSoon() posted Thread::ThreadQuitHelper() while |run_loop_| was null).
   base::RunLoop().RunUntilIdle();
 }
+
+TEST_F(ThreadTest, ProvidedMessageLoopBase) {
+  Thread thread("ProvidedMessageLoopBase");
+  std::unique_ptr<base::sequence_manager::internal::SequenceManagerImpl>
+      sequence_manager =
+          base::sequence_manager::internal::SequenceManagerImpl::CreateUnbound(
+              base::sequence_manager::SequenceManager::Settings());
+  scoped_refptr<base::sequence_manager::TaskQueue> task_queue =
+      sequence_manager
+          ->CreateTaskQueueWithType<base::sequence_manager::TaskQueue>(
+              base::sequence_manager::TaskQueue::Spec("default_tq"));
+  sequence_manager->SetTaskRunner(task_queue->task_runner());
+
+  base::Thread::Options options;
+  options.message_loop_base = sequence_manager.release();
+  thread.StartWithOptions(options);
+
+  base::WaitableEvent event;
+
+  task_queue->task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&event)));
+  event.Wait();
+
+  thread.Stop();
+}
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 45dc192..93e58674 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-aca22aec66780aac24fecb9d9bb8a77c80b8aa2d
\ No newline at end of file
+6c3c8c98f7b3184140d110083e0d32d2f6405aae
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 0512955..c826aa4 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-631bd6065a518a7b2da0417e36fb0306936184f6
\ No newline at end of file
+8c767248ffb52088b77fb5301eb72367ec7c9871
\ No newline at end of file
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index d2c9ae2..f1c33d2 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -710,7 +710,7 @@
   if (!represents_yuv_image && image_->isTextureBacked()) {
     gl_id_ = GlIdFromSkImage(image_.get());
   } else {
-    gl_id_ = -1;
+    gl_id_ = 0;
   }
   OnSetLockedData(false /* out_of_raster */);
 }
@@ -758,6 +758,7 @@
   image_yuv_planes_.reset();
   gl_plane_ids_.reset();
   gl_id_ = 0;
+  is_alpha_ = false;
   transfer_cache_id_.reset();
   OnResetData();
 }
@@ -1683,7 +1684,7 @@
     pixmap.setColorSpace(color_space);
 
     if (image_data->is_yuv) {
-      DLOG(WARNING) << "GpuImageDecodeCache wants to do YUV decoding/rendering";
+      DVLOG(3) << "GpuImageDecodeCache wants to do YUV decoding/rendering";
       SkPixmap pixmap_y;
       SkPixmap pixmap_u;
       SkPixmap pixmap_v;
@@ -1693,14 +1694,15 @@
         DLOG(ERROR) << "DrawAndScaleImage failed.";
         backing_memory->Unlock();
         backing_memory.reset();
+      } else {
+        image_y = SkImage::MakeFromRaster(pixmap_y, release_proc, nullptr);
+        image_u = SkImage::MakeFromRaster(pixmap_u, release_proc, nullptr);
+        image_v = SkImage::MakeFromRaster(pixmap_v, release_proc, nullptr);
       }
-      image_y = SkImage::MakeFromRaster(pixmap_y, release_proc, nullptr);
-      image_u = SkImage::MakeFromRaster(pixmap_u, release_proc, nullptr);
-      image_v = SkImage::MakeFromRaster(pixmap_v, release_proc, nullptr);
     } else {  // RGBX decoding is the default path.
       if (!DrawAndScaleImage(draw_image, &pixmap, generator_client_id_,
                              image_data->is_yuv)) {
-        LOG(ERROR) << "DrawAndScaleImage failed.";
+        DLOG(ERROR) << "DrawAndScaleImage failed.";
         backing_memory->Unlock();
         backing_memory.reset();
       } else {
@@ -1833,7 +1835,6 @@
     sk_sp<SkImage> uploaded_y_image = image_data->decode.y_image();
     sk_sp<SkImage> uploaded_u_image = image_data->decode.u_image();
     sk_sp<SkImage> uploaded_v_image = image_data->decode.v_image();
-    image_data->decode.mark_used();
 
     // For kGpu, we upload and color convert (if necessary).
     if (image_data->mode == DecodedDataMode::kGpu) {
@@ -1862,7 +1863,7 @@
       uploaded_image = CreateImageFromYUVATexturesInternal(
           uploaded_y_image.get(), uploaded_u_image.get(),
           uploaded_v_image.get(), image_width, image_height, &yuva_color_space,
-          color_space);
+          decoded_target_colorspace);
     }
 
     // At-raster may have decoded this while we were unlocked. If so, ignore our
@@ -2003,9 +2004,8 @@
   const bool is_bitmap_backed = !draw_image.paint_image().IsLazyGenerated() &&
                                 upload_scale_mip_level == 0 &&
                                 !cache_color_conversion_on_cpu;
-  SkYUVASizeInfo temp_yuva_size_info;
-  const bool is_yuv = draw_image.paint_image().IsYuv(&temp_yuva_size_info) &&
-                      mode == DecodedDataMode::kGpu;
+  const bool is_yuv =
+      draw_image.paint_image().IsYuv() && mode == DecodedDataMode::kGpu;
 
   // TODO(crbug.com/910276): Change after alpha support.
   // TODO(crbug.com/915972): Remove YUV420 assumption.
@@ -2362,6 +2362,24 @@
   return image_data->decode.ImageForTesting();
 }
 
+sk_sp<SkImage> GpuImageDecodeCache::GetUploadedPlaneForTesting(
+    const DrawImage& draw_image,
+    size_t index) {
+  base::AutoLock lock(lock_);
+  ImageData* image_data = GetImageDataForDrawImage(
+      draw_image, InUseCacheKey::FromDrawImage(draw_image));
+  switch (index) {
+    case SkYUVAIndex::kY_Index:
+      return image_data->upload.y_image();
+    case SkYUVAIndex::kU_Index:
+      return image_data->upload.u_image();
+    case SkYUVAIndex::kV_Index:
+      return image_data->upload.v_image();
+    default:
+      return nullptr;
+  }
+}
+
 void GpuImageDecodeCache::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel level) {
   base::AutoLock lock(lock_);
@@ -2451,7 +2469,6 @@
 void GpuImageDecodeCache::UpdateMipsIfNeeded(const DrawImage& draw_image,
                                              ImageData* image_data) {
   CheckContextLockAcquiredIfNecessary();
-
   // If we already have mips, nothing to do.
   if (image_data->needs_mips)
     return;
@@ -2523,12 +2540,13 @@
     SkYUVColorSpace yuva_color_space = SkYUVColorSpace::kRec601_SkYUVColorSpace;
     size_t width = image_y_with_mips_owned->width();
     size_t height = image_y_with_mips_owned->height();
-    SkColorSpace* decoded_color_space = draw_image.paint_image().color_space();
+    sk_sp<SkColorSpace> decoded_color_space =
+        ColorSpaceForImageDecode(draw_image, image_data->mode);
     sk_sp<SkImage> yuv_image_with_mips_owned =
         CreateImageFromYUVATexturesInternal(
             image_y_with_mips_owned.get(), image_u_with_mips_owned.get(),
             image_v_with_mips_owned.get(), width, height, &yuva_color_space,
-            sk_ref_sp(decoded_color_space));
+            decoded_color_space);
     // In case of lost context
     if (!yuv_image_with_mips_owned) {
       DLOG(WARNING) << "TODO(crbug.com/740737): Context was lost. Early out.";
diff --git a/cc/tiles/gpu_image_decode_cache.h b/cc/tiles/gpu_image_decode_cache.h
index c5fb68c..3c3ff525 100644
--- a/cc/tiles/gpu_image_decode_cache.h
+++ b/cc/tiles/gpu_image_decode_cache.h
@@ -170,6 +170,8 @@
   bool IsInInUseCacheForTesting(const DrawImage& image) const;
   bool IsInPersistentCacheForTesting(const DrawImage& image) const;
   sk_sp<SkImage> GetSWImageDecodeForTesting(const DrawImage& image);
+  sk_sp<SkImage> GetUploadedPlaneForTesting(const DrawImage& draw_image,
+                                            size_t index);
   size_t paint_image_entries_count_for_testing() const {
     return paint_image_entries_.size();
   }
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index 9f3983e1..f78f4f4 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -409,6 +409,24 @@
     return static_cast<ServiceImageTransferCacheEntry*>(entry)->image();
   }
 
+  void CompareAllPlanesToMippedVersions(GpuImageDecodeCache* cache,
+                                        const DrawImage& draw_image,
+                                        bool should_have_mips) {
+    for (size_t i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
+      // TODO(crbug.com/910276): Skip alpha plane until supported in cache.
+      if (i != SkYUVAIndex::kA_Index) {
+        auto original_uploaded_plane =
+            cache->GetUploadedPlaneForTesting(draw_image, i);
+        ASSERT_TRUE(original_uploaded_plane);
+        auto plane_with_mips = original_uploaded_plane->makeTextureImage(
+            context_provider()->GrContext(), nullptr /* color space */,
+            GrMipMapped::kYes);
+        ASSERT_TRUE(plane_with_mips);
+        EXPECT_EQ(should_have_mips, original_uploaded_plane == plane_with_mips);
+      }
+    }
+  }
+
  protected:
   FakeDiscardableManager discardable_manager_;
   scoped_refptr<GPUImageDecodeTestMockContextProvider> context_provider_;
@@ -2558,10 +2576,6 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, BasicMips) {
-  if (do_yuv_decode_) {
-    // We will modify this test for YUV.
-    return;
-  }
   auto decode_and_check_mips = [this](SkFilterQuality filter_quality,
                                       SkSize scale,
                                       const gfx::ColorSpace& color_space,
@@ -2589,11 +2603,26 @@
     EXPECT_TRUE(decoded_draw_image.image());
     EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
-    sk_sp<SkImage> image_with_mips =
-        decoded_draw_image.image()->makeTextureImage(
-            context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
-    EXPECT_EQ(should_have_mips, image_with_mips == decoded_draw_image.image());
+    if (do_yuv_decode_) {
+      // As of M74, Skia will flatten a YUV SkImage upon calling
+      // makeTextureImage. Thus, we must separately request mips for each
+      // plane and compare to the original uploaded planes.
+      CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+                                       should_have_mips);
+      EXPECT_TRUE(
+          SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
+                                   ? color_space.ToSkColorSpace().get()
+                                   : nullptr,
+                               decoded_draw_image.image()->colorSpace()));
 
+    } else {
+      sk_sp<SkImage> image_with_mips =
+          decoded_draw_image.image()->makeTextureImage(
+              context_provider()->GrContext(), nullptr /* color space */,
+              GrMipMapped::kYes);
+      EXPECT_EQ(should_have_mips,
+                image_with_mips == decoded_draw_image.image());
+    }
     cache->DrawWithImageFinished(draw_image, decoded_draw_image);
     cache->UnrefImage(draw_image);
   };
@@ -2622,10 +2651,6 @@
 }
 
 TEST_P(GpuImageDecodeCacheTest, MipsAddedSubsequentDraw) {
-  if (do_yuv_decode_) {
-    // We will modify this test for YUV.
-    return;
-  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   auto filter_quality = kMedium_SkFilterQuality;
@@ -2654,12 +2679,20 @@
     EXPECT_TRUE(decoded_draw_image.image());
     EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
-    // No mips should be generated
-    sk_sp<SkImage> image_with_mips =
-        decoded_draw_image.image()->makeTextureImage(
-            context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
-    EXPECT_NE(image_with_mips, decoded_draw_image.image());
-
+    // No mips should be generated.
+    if (do_yuv_decode_) {
+      // As of M74, Skia will flatten a YUV SkImage upon calling
+      // makeTextureImage. Thus, we must separately request mips for each
+      // plane and compare to the original uploaded planes.
+      CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+                                       false /* should_have_mips */);
+    } else {
+      sk_sp<SkImage> image_with_mips =
+          decoded_draw_image.image()->makeTextureImage(
+              context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
+      ASSERT_TRUE(image_with_mips);
+      EXPECT_NE(image_with_mips, decoded_draw_image.image());
+    }
     cache->DrawWithImageFinished(draw_image, decoded_draw_image);
     cache->UnrefImage(draw_image);
   }
@@ -2690,20 +2723,26 @@
     EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
     // Mips should be generated
-    sk_sp<SkImage> image_with_mips =
-        decoded_draw_image.image()->makeTextureImage(
-            context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
-    EXPECT_EQ(image_with_mips, decoded_draw_image.image());
+    if (do_yuv_decode_) {
+      CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+                                       true /* should_have_mips */);
+      EXPECT_TRUE(
+          SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
+                                   ? DefaultColorSpace().ToSkColorSpace().get()
+                                   : nullptr,
+                               decoded_draw_image.image()->colorSpace()));
+    } else {
+      sk_sp<SkImage> image_with_mips =
+          decoded_draw_image.image()->makeTextureImage(
+              context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
+      EXPECT_EQ(image_with_mips, decoded_draw_image.image());
+    }
     cache->DrawWithImageFinished(draw_image, decoded_draw_image);
     cache->UnrefImage(draw_image);
   }
 }
 
 TEST_P(GpuImageDecodeCacheTest, MipsAddedWhileOriginalInUse) {
-  if (do_yuv_decode_) {
-    // We will modify this test for YUV.
-    return;
-  }
   auto cache = CreateCache();
   bool is_decomposable = true;
   auto filter_quality = kMedium_SkFilterQuality;
@@ -2735,15 +2774,22 @@
     viz::ContextProvider::ScopedContextLock context_lock(context_provider());
     DecodedDrawImage decoded_draw_image =
         EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
-    EXPECT_TRUE(decoded_draw_image.image());
-    EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
+    ASSERT_TRUE(decoded_draw_image.image());
+    ASSERT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
-    // No mips should be generated
-    sk_sp<SkImage> image_with_mips =
-        decoded_draw_image.image()->makeTextureImage(
-            context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
-    EXPECT_NE(image_with_mips, decoded_draw_image.image());
-
+    // No mips should be generated.
+    if (do_yuv_decode_) {
+      // As of M74, Skia will flatten a YUV SkImage upon calling
+      // makeTextureImage. Thus, we must separately request mips for each
+      // plane and compare to the original uploaded planes.
+      CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+                                       false /* should_have_mips */);
+    } else {
+      sk_sp<SkImage> image_with_mips =
+          decoded_draw_image.image()->makeTextureImage(
+              context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
+      EXPECT_NE(image_with_mips, decoded_draw_image.image());
+    }
     images_to_unlock.push_back({draw_image, decoded_draw_image});
   }
 
@@ -2764,15 +2810,24 @@
     DecodedDrawImage decoded_draw_image =
         EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image));
 
-    EXPECT_TRUE(decoded_draw_image.image());
-    EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
+    ASSERT_TRUE(decoded_draw_image.image());
+    ASSERT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
-    // Mips should be generated
-    sk_sp<SkImage> image_with_mips =
-        decoded_draw_image.image()->makeTextureImage(
-            context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
-    EXPECT_EQ(image_with_mips, decoded_draw_image.image());
-
+    // Mips should be generated.
+    if (do_yuv_decode_) {
+      CompareAllPlanesToMippedVersions(cache.get(), draw_image,
+                                       true /* should_have_mips */);
+      EXPECT_TRUE(
+          SkColorSpace::Equals(cache->SupportsColorSpaceConversion()
+                                   ? DefaultColorSpace().ToSkColorSpace().get()
+                                   : nullptr,
+                               decoded_draw_image.image()->colorSpace()));
+    } else {
+      sk_sp<SkImage> image_with_mips =
+          decoded_draw_image.image()->makeTextureImage(
+              context_provider()->GrContext(), nullptr, GrMipMapped::kYes);
+      EXPECT_EQ(image_with_mips, decoded_draw_image.image());
+    }
     images_to_unlock.push_back({draw_image, decoded_draw_image});
   }
 
@@ -2783,13 +2838,29 @@
   {
     // All images which are currently ref-ed must have locked textures.
     viz::ContextProvider::ScopedContextLock context_lock(context_provider());
-    for (const auto& decode : images_to_unlock) {
+    for (const auto& draw_and_decoded_draw_image : images_to_unlock) {
       if (!use_transfer_cache_) {
-        discardable_manager_.ExpectLocked(GpuImageDecodeCache::GlIdFromSkImage(
-            decode.decoded_image.image().get()));
+        if (do_yuv_decode_) {
+          DrawImage draw_image = draw_and_decoded_draw_image.image;
+          for (size_t i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
+            // TODO(crbug.com/910276): Skip alpha plane until supported in
+            // cache.
+            if (i != SkYUVAIndex::kA_Index) {
+              SkImage* plane_image =
+                  cache->GetUploadedPlaneForTesting(draw_image, i).get();
+              discardable_manager_.ExpectLocked(
+                  GpuImageDecodeCache::GlIdFromSkImage(plane_image));
+            }
+          }
+        } else {
+          discardable_manager_.ExpectLocked(
+              GpuImageDecodeCache::GlIdFromSkImage(
+                  draw_and_decoded_draw_image.decoded_image.image().get()));
+        }
       }
-      cache->DrawWithImageFinished(decode.image, decode.decoded_image);
-      cache->UnrefImage(decode.image);
+      cache->DrawWithImageFinished(draw_and_decoded_draw_image.image,
+                                   draw_and_decoded_draw_image.decoded_image);
+      cache->UnrefImage(draw_and_decoded_draw_image.image);
     }
   }
 }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 42a3ccaf..ca66d9d9c 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -854,12 +854,10 @@
         "javatests/src/org/chromium/chrome/browser/vr/nfc_apk/SimNfcActivity.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/ChromeTabbedActivityVrTestRule.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java",
-        "javatests/src/org/chromium/chrome/browser/vr/rules/HeadTrackingMode.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/VrActivityRestrictionRule.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/VrSettingsFile.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/VrTestRule.java",
         "javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java",
-        "javatests/src/org/chromium/chrome/browser/vr/util/HeadTrackingUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/NfcSimUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java",
diff --git a/chrome/android/java/AndroidManifest_trichrome_chrome.xml b/chrome/android/java/AndroidManifest_trichrome_chrome.xml
index 735f5ad0..7acbbd2 100644
--- a/chrome/android/java/AndroidManifest_trichrome_chrome.xml
+++ b/chrome/android/java/AndroidManifest_trichrome_chrome.xml
@@ -6,9 +6,6 @@
 
 ## Note: This is a jinja2 template, processed at build time into the final manifest.
 
-## TODO(torne): we may need a TrichromeApplication?
-{% block application_name %}org.chromium.chrome.browser.MonochromeApplication{% endblock %}
-
 {% block extra_application_attributes %}
 {{ super() }}
 android:multiArch="true"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
index 47c1ebe..d34b694 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackgroundService.java
@@ -14,7 +14,6 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.library_loader.ProcessInitException;
-import org.chromium.chrome.browser.background_sync.BackgroundSyncBackgroundTaskScheduler;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.init.ServiceManagerStartupUtils;
 import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge;
@@ -71,14 +70,6 @@
     }
 
     private void handleBackgroundSyncEvent(Context context, String tag) {
-        if (ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC)) {
-            // If BackgroundTaskScheduler has been used to schedule a background
-            // task for Background Sync, we simply reschedule the existing task(s).
-            BackgroundSyncBackgroundTaskScheduler.getInstance().reschedule();
-            return;
-        }
-
         if (!BackgroundSyncLauncher.hasInstance()) {
             // Start the browser. The browser's BackgroundSyncManager (for the active profile) will
             // start, check the network, and run any necessary sync events. This task runs with a
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/MonochromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/MonochromeApplication.java
index 33c3ddf9..dc0535f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/MonochromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/MonochromeApplication.java
@@ -16,6 +16,11 @@
  * You shouldn't add anything else in this file, this class is split off from
  * normal chrome in order to access Android system API through Android WebView
  * glue layer and have monochrome specific code.
+ *
+ * This class is NOT used by Trichrome. Do not add anything here which is only
+ * related to Monochrome's minimum SDK level or APK packaging decisions, because
+ * those are likely to apply to Trichrome as well - this must only be used for
+ * things specific to functioning as a WebView implementation.
  */
 public class MonochromeApplication extends ChromeApplication {
     @Override
@@ -23,7 +28,9 @@
         super.onCreate();
         LibraryLoader.getInstance().setNativeLibraryPreloader(new MonochromeLibraryPreloader());
         // ChildProcessCreationParams is only needed for browser process, though it is
-        // created and set in all processes.
+        // created and set in all processes. We must set isExternalService to true for
+        // Monochrome because Monochrome's renderer services are shared with WebView
+        // and are external, and will fail to bind otherwise.
         boolean bindToCaller = false;
         boolean ignoreVisibilityForImportance = false;
         ChildProcessCreationParams.set(getPackageName(), true /* isExternalService */,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/FakeAppUpdateManagerWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/FakeAppUpdateManagerWrapper.java
index 1ad91ea..02d6953f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/FakeAppUpdateManagerWrapper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/FakeAppUpdateManagerWrapper.java
@@ -74,6 +74,7 @@
     @Override
     public boolean startUpdateFlowForResult(AppUpdateInfo appUpdateInfo,
             @AppUpdateType int appUpdateType, Activity activity, int requestCode) {
+        // TODO(dtrainor): Simulate exceptions being thrown or returning false from the super call.
         boolean success =
                 super.startUpdateFlowForResult(appUpdateInfo, appUpdateType, activity, requestCode);
         if (!success) return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineAppUpdateManagerFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineAppUpdateManagerFactory.java
index e1630ba..387e4e7e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineAppUpdateManagerFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineAppUpdateManagerFactory.java
@@ -12,7 +12,7 @@
 
 /** A factory that creates an {@link AppUpdateManager} instance. */
 public class InlineAppUpdateManagerFactory {
-    private static final boolean sTest = false;
+    private static final boolean sTest = true;
 
     /** @return A new {@link AppUpdateManager} to use to interact with Play for inline updates. */
     public static AppUpdateManager create() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
index 874e000..1f0c12f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java
@@ -5,10 +5,19 @@
 package org.chromium.chrome.browser.omaha.inline;
 
 import android.app.Activity;
+import android.content.IntentSender.SendIntentException;
 import android.os.Handler;
 import android.os.Looper;
 import android.support.annotation.Nullable;
 
+import com.google.android.play.core.appupdate.AppUpdateInfo;
+import com.google.android.play.core.appupdate.AppUpdateManager;
+import com.google.android.play.core.install.InstallState;
+import com.google.android.play.core.install.InstallStateUpdatedListener;
+import com.google.android.play.core.install.model.AppUpdateType;
+import com.google.android.play.core.install.model.InstallStatus;
+import com.google.android.play.core.install.model.UpdateAvailability;
+
 import org.chromium.chrome.browser.omaha.UpdateStatusProvider.UpdateState;
 
 /**
@@ -16,20 +25,29 @@
  * involves hooking up to Play as a listener for install state changes, should only happen if we are
  * in the foreground.
  */
-public class InlineUpdateController {
+public class InlineUpdateController implements InstallStateUpdatedListener {
+    private static final int RESULT_IN_APP_UPDATE_FAILED = 1;
+    private static final int REQUEST_CODE = 8123;
+
     private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     private final Runnable mCallback;
+    private final AppUpdateManager mAppUpdateManager;
 
     private boolean mEnabled;
     private @Nullable @UpdateState Integer mUpdateState;
 
+    private AppUpdateInfo mAppUpdateInfo;
+    private @Nullable @UpdateAvailability Integer mUpdateAvailability;
+    private @Nullable @InstallStatus Integer mInstallStatus;
+
     /**
      * Builds an instance of {@link InlineUpdateController}.
      * @param callback The {@link Runnable} to notify when an inline update state change occurs.
      */
     public InlineUpdateController(Runnable callback) {
         mCallback = callback;
+        mAppUpdateManager = InlineAppUpdateManagerFactory.create();
 
         setEnabled(true);
     }
@@ -40,7 +58,10 @@
 
         if (mEnabled) {
             mUpdateState = UpdateState.NONE;
-            mHandler.post(mCallback);
+            mAppUpdateManager.registerListener(this);
+            pullCurrentState();
+        } else {
+            mAppUpdateManager.unregisterListener(this);
         }
     }
 
@@ -57,10 +78,91 @@
      * cause Chrome to move to the background.
      * @param activity The {@link Activity} to use to interact with Play.
      */
-    public void startUpdate(Activity activity) {}
+    public void startUpdate(Activity activity) {
+        try {
+            boolean success = mAppUpdateManager.startUpdateFlowForResult(
+                    mAppUpdateInfo, AppUpdateType.FLEXIBLE, activity, REQUEST_CODE);
+        } catch (SendIntentException exception) {
+            mInstallStatus = InstallStatus.FAILED;
+        }
+        // TODO(dtrainor): Use success.
+    }
 
     /**
      * Completes the Play installation process, if possible.  This may cause Chrome to restart.
      */
-    public void completeUpdate() {}
+    public void completeUpdate() {
+        mAppUpdateManager.completeUpdate()
+                .addOnSuccessListener(unused -> { pushStatus(); })
+                .addOnFailureListener(exception -> {
+                    mInstallStatus = InstallStatus.FAILED;
+                    pushStatus();
+                });
+    }
+
+    // InstallStateUpdatedListener implementation.
+    @Override
+    public void onStateUpdate(InstallState state) {
+        mInstallStatus = state.installStatus();
+        pushStatus();
+    }
+
+    private void pullCurrentState() {
+        mAppUpdateManager.getAppUpdateInfo()
+                .addOnSuccessListener(info -> {
+                    mAppUpdateInfo = info;
+                    mUpdateAvailability = info.updateAvailability();
+                    mInstallStatus = info.installStatus();
+                    pushStatus();
+                })
+                .addOnFailureListener(exception -> {
+                    mAppUpdateInfo = null;
+                    mUpdateAvailability = UpdateAvailability.UNKNOWN;
+                    mInstallStatus = InstallStatus.UNKNOWN;
+                    pushStatus();
+                });
+    }
+
+    private void pushStatus() {
+        if (!mEnabled || mUpdateAvailability == null || mInstallStatus == null) return;
+
+        @UpdateState
+        int newState = toUpdateState(mUpdateAvailability, mInstallStatus);
+        if (mUpdateState != null && mUpdateState == newState) return;
+
+        mUpdateState = newState;
+        mCallback.run();
+    }
+
+    private static @UpdateState int toUpdateState(
+            @UpdateAvailability int updateAvailability, @InstallStatus int installStatus) {
+        @UpdateState
+        int newStatus = UpdateState.NONE;
+
+        // Note, use InstallStatus first then UpdateAvailability if InstallStatus doesn't indicate
+        // a currently active install.
+        switch (installStatus) {
+            case InstallStatus.PENDING:
+                // Intentional fall through.
+            case InstallStatus.DOWNLOADING:
+                newStatus = UpdateState.INLINE_UPDATE_DOWNLOADING;
+                break;
+            case InstallStatus.DOWNLOADED:
+                newStatus = UpdateState.INLINE_UPDATE_READY;
+                break;
+            case InstallStatus.FAILED:
+                newStatus = UpdateState.INLINE_UPDATE_FAILED;
+                break;
+        }
+
+        if (newStatus == UpdateState.NONE) {
+            switch (updateAvailability) {
+                case UpdateAvailability.UPDATE_AVAILABLE:
+                    newStatus = UpdateState.INLINE_UPDATE_AVAILABLE;
+                    break;
+            }
+        }
+
+        return newStatus;
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java
index 3e50504..31754f5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java
@@ -23,7 +23,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 import java.util.Locale;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
@@ -33,12 +32,6 @@
     /** The pattern for a valid region code. */
     private static final String REGION_CODE_PATTERN = "^[A-Z]{2}$";
 
-    // Language/script code pattern and capture group numbers.
-    private static final String LANGUAGE_SCRIPT_CODE_PATTERN =
-            "^([a-z]{2})(-([A-Z][a-z]{3}))?(-[A-Za-z]+)*$";
-    private static final int LANGUAGE_CODE_GROUP = 1;
-    private static final int SCRIPT_CODE_GROUP = 3;
-
     @IntDef({CompletionStatus.COMPLETE, CompletionStatus.INVALID_ADDRESS,
             CompletionStatus.INVALID_PHONE_NUMBER, CompletionStatus.INVALID_RECIPIENT,
             CompletionStatus.INVALID_MULTIPLE_FIELDS})
@@ -69,7 +62,6 @@
 
     private Context mContext;
     private AutofillProfile mProfile;
-    @Nullable private Pattern mLanguageScriptCodePattern;
     @Nullable private String mShippingLabelWithCountry;
     @Nullable private String mShippingLabelWithoutCountry;
     @Nullable private String mBillingLabel;
@@ -318,22 +310,8 @@
         result.sortingCode = mProfile.getSortingCode();
         result.organization = mProfile.getCompanyName();
         result.recipient = mProfile.getFullName();
-        result.languageCode = "";
-        result.scriptCode = "";
         result.phone = mProfile.getPhoneNumber();
 
-        if (mProfile.getLanguageCode() == null) return result;
-
-        if (mLanguageScriptCodePattern == null) {
-            mLanguageScriptCodePattern = Pattern.compile(LANGUAGE_SCRIPT_CODE_PATTERN);
-        }
-
-        Matcher matcher = mLanguageScriptCodePattern.matcher(mProfile.getLanguageCode());
-        if (matcher.matches()) {
-            result.languageCode = ensureNotNull(matcher.group(LANGUAGE_CODE_GROUP));
-            result.scriptCode = ensureNotNull(matcher.group(SCRIPT_CODE_GROUP));
-        }
-
         return result;
     }
 
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 fe79143..864716d9 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
@@ -1490,7 +1490,6 @@
         return !TextUtils.isEmpty(errors.addressLine) || !TextUtils.isEmpty(errors.city)
                 || !TextUtils.isEmpty(errors.country)
                 || !TextUtils.isEmpty(errors.dependentLocality)
-                || !TextUtils.isEmpty(errors.languageCode)
                 || !TextUtils.isEmpty(errors.organization) || !TextUtils.isEmpty(errors.phone)
                 || !TextUtils.isEmpty(errors.postalCode) || !TextUtils.isEmpty(errors.recipient)
                 || !TextUtils.isEmpty(errors.region) || !TextUtils.isEmpty(errors.sortingCode);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index ee7fbfb6..4ea727f0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -128,12 +128,6 @@
 
     private static final long INVALID_TIMESTAMP = -1;
 
-    /**
-     * The required page load percentage for the page to be considered ready assuming the
-     * TextureView is also ready.
-     */
-    private static final int CONSIDERED_READY_LOAD_PERCENTAGE = 100;
-
     /** Used for logging. */
     private static final String TAG = "Tab";
 
@@ -838,15 +832,6 @@
         }
     }
 
-    /**
-     * @return Whether or not the loading and rendering of the page is done.
-     * TODO(jinsukkim): Delete this method once the refactoring is finished.
-     */
-    @VisibleForTesting
-    public boolean isLoadingAndRenderingDone() {
-        return isReady() && getProgress() >= CONSIDERED_READY_LOAD_PERCENTAGE;
-    }
-
     /** Stop the current navigation. */
     public void stopLoading() {
         if (isLoading()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherMediator.java
index dfb9902..52e3b85b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherMediator.java
@@ -12,7 +12,10 @@
 
 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
+import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
 import org.chromium.ui.modelutil.PropertyModel;
 
@@ -29,9 +32,16 @@
     private final PropertyModel mContainerViewModel;
     private final TabModelSelector mTabModelSelector;
     private final TabModelSelectorTabModelObserver mTabModelObserver;
+    private final TabModelSelectorObserver mTabModelSelectorObserver;
     private final List<OverviewModeObserver> mObservers = new ArrayList<>();
 
     /**
+     * In cases where a didSelectTab was due to closing a tab or switching models with a toggle,
+     * we don't change tab grid visibility.
+     */
+    private boolean mShouldIgnoreNextSelect;
+
+    /**
      * Basic constructor for the Mediator.
      * @param coordinator The {@link GridTabSwitcherCoordinator} that owns this Mediator.
      * @param containerViewModel The {@link PropertyModel} to keep state on the View containing the
@@ -44,12 +54,17 @@
         mContainerViewModel = containerViewModel;
         mTabModelSelector = tabModelSelector;
 
+        mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
+            @Override
+            public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
+                mShouldIgnoreNextSelect = true;
+                mCoordinator.resetWithTabModel(newModel);
+                mContainerViewModel.set(IS_INCOGNITO, newModel.isIncognito());
+            }
+        };
+        mTabModelSelector.addObserver(mTabModelSelectorObserver);
+
         mTabModelObserver = new TabModelSelectorTabModelObserver(mTabModelSelector) {
-            /**
-             * In cases where a didSelectTab was due to closing a tab, we don't change tab grid
-             * visibility.
-             */
-            private boolean mShouldIgnoreNextSelect;
 
             @Override
             public void didSelectTab(Tab tab, int type, int lastId) {
@@ -138,6 +153,7 @@
      * Destroy any members that needs clean up.
      */
     public void destroy() {
+        mTabModelSelector.removeObserver(mTabModelSelectorObserver);
         mTabModelObserver.destroy();
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
index 890e5af..08498791 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
@@ -270,7 +270,9 @@
         }
 
         boolean useLightIcons = mIsIncognito
-                && (usingHorizontalTabSwitcher() || DeviceClassManager.enableAccessibilityLayout());
+                && (usingHorizontalTabSwitcher()
+                        || FeatureUtilities.isGridTabSwitcherEnabled(getContext())
+                        || DeviceClassManager.enableAccessibilityLayout());
 
         if (mUseLightIcons == useLightIcons) return;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
index eabe577..1850d7a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
@@ -57,9 +57,10 @@
      * @return        Whether or not accessibility and touch exploration are enabled.
      */
     public static boolean isAccessibilityEnabled() {
-        TraceEvent.begin("AccessibilityManager::isAccessibilityEnabled");
         if (sIsAccessibilityEnabled != null) return sIsAccessibilityEnabled;
 
+        TraceEvent.begin("AccessibilityManager::isAccessibilityEnabled");
+
         AccessibilityManager manager =
                 (AccessibilityManager) ContextUtils.getApplicationContext().getSystemService(
                         Context.ACCESSIBILITY_SERVICE);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
index c7e9d78..c412172 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java
@@ -23,8 +23,6 @@
 import org.chromium.chrome.browser.ntp.snippets.SnippetsLauncher;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
-import java.util.HashMap;
-
 /**
  * Tests {@link ChromeBackgroundService}.
  */
@@ -80,13 +78,9 @@
 
     @Before
     public void setUp() throws Exception {
-        HashMap<String, Boolean> features = new HashMap<String, Boolean>();
-        features.put(ChromeFeatureList.BACKGROUND_TASK_SCHEDULER_FOR_BACKGROUND_SYNC, false);
-        ChromeFeatureList.setTestFeatures(features);
         BackgroundSyncLauncher.setGCMEnabled(false);
-        mSyncLauncher = BackgroundSyncLauncher.create();
-
         RecordHistogram.setDisabledForTests(true);
+        mSyncLauncher = BackgroundSyncLauncher.create();
         mSnippetsLauncher = SnippetsLauncher.create();
         mTaskService = new MockTaskService();
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
index 695ac6be..e239e738 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrBrowserDialogTest.java
@@ -28,7 +28,6 @@
 import org.chromium.chrome.browser.preferences.website.ContentSettingValues;
 import org.chromium.chrome.browser.preferences.website.PermissionInfo;
 import org.chromium.chrome.browser.vr.rules.ChromeTabbedActivityVrTestRule;
-import org.chromium.chrome.browser.vr.rules.HeadTrackingMode;
 import org.chromium.chrome.browser.vr.util.NativeUiUtils;
 import org.chromium.chrome.browser.vr.util.RenderTestUtils;
 import org.chromium.chrome.browser.vr.util.VrBrowserTransitionUtils;
@@ -165,7 +164,6 @@
      */
     @Test
     @LargeTest
-    @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN)
     @Feature({"Browser", "RenderTest"})
     public void testMicrophonePermissionPrompt()
             throws InterruptedException, TimeoutException, IOException {
@@ -180,7 +178,6 @@
      */
     @Test
     @LargeTest
-    @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN)
     @Feature({"Browser", "RenderTest"})
     @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM)
     public void testCameraPermissionPrompt()
@@ -195,7 +192,6 @@
      */
     @Test
     @LargeTest
-    @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN)
     @Feature({"Browser", "RenderTest"})
     public void testLocationPermissionPrompt()
             throws InterruptedException, TimeoutException, IOException {
@@ -210,7 +206,6 @@
      */
     @Test
     @LargeTest
-    @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN)
     @Feature({"Browser", "RenderTest"})
     public void testNotificationPermissionPrompt()
             throws InterruptedException, TimeoutException, IOException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/ChromeTabbedActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/ChromeTabbedActivityVrTestRule.java
index 0b184244..21236a6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/ChromeTabbedActivityVrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/ChromeTabbedActivityVrTestRule.java
@@ -21,7 +21,6 @@
  */
 public class ChromeTabbedActivityVrTestRule
         extends ChromeTabbedActivityTestRule implements VrTestRule {
-    private boolean mTrackerDirty;
     private boolean mDonEnabled;
 
     @Override
@@ -44,16 +43,6 @@
     }
 
     @Override
-    public boolean isTrackerDirty() {
-        return mTrackerDirty;
-    }
-
-    @Override
-    public void setTrackerDirty() {
-        mTrackerDirty = true;
-    }
-
-    @Override
     public boolean isDonEnabled() {
         return mDonEnabled;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
index 8c3e4f3..01900a8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/CustomTabActivityVrTestRule.java
@@ -20,7 +20,6 @@
  * opens up a CustomTabActivity to a blank page while performing some additional VR-only setup.
  */
 public class CustomTabActivityVrTestRule extends CustomTabActivityTestRule implements VrTestRule {
-    private boolean mTrackerDirty;
     private boolean mDonEnabled;
 
     @Override
@@ -47,16 +46,6 @@
     }
 
     @Override
-    public boolean isTrackerDirty() {
-        return mTrackerDirty;
-    }
-
-    @Override
-    public void setTrackerDirty() {
-        mTrackerDirty = true;
-    }
-
-    @Override
     public boolean isDonEnabled() {
         return mDonEnabled;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/HeadTrackingMode.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/HeadTrackingMode.java
deleted file mode 100644
index 8fc90b4..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/HeadTrackingMode.java
+++ /dev/null
@@ -1,50 +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.
-
-package org.chromium.chrome.browser.vr.rules;
-
-import android.support.annotation.IntDef;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * An annotation for setting the VrCore head tracking service's tracking mode during pre-test setup.
- *
- * The benefit of setting the mode this way instead of via HeadTrackingUtils during a test is that
- * starting services is asynchronous with no good way of waiting until whatever the service does
- * takes effect. When set during a test, the test must idle long enough to safely assume that the
- * service has taken effect. When applied during test setup, the Chrome startup period acts as the
- * wait, as Chrome startup is slow enough that it's safe to assume the service has started by the
- * time Chrome is ready.
- *
- * For example, the following would cause a test to start with its head position locked looking
- * straight forward:
- *     <code>
- *     @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN)
- *     </code>
- * If a test is not annotated with this, it will use whatever mode is currently set. This should
- * usually be the normal, sensor-based tracker, but is not guaranteed.
- */
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface HeadTrackingMode {
-    @IntDef({SupportedMode.FROZEN, SupportedMode.SWEEP, SupportedMode.ROTATE,
-            SupportedMode.CIRCLE_STRAFE, SupportedMode.MOTION_SICKNESS})
-    @Retention(RetentionPolicy.RUNTIME)
-    public @interface SupportedMode {
-        int FROZEN = 0; // Locked looking straight forward.
-        int SWEEP = 1; // Rotates back and forth horizontally in a 180 degree arc.
-        int ROTATE = 2; // Rotates 360 degrees.
-        int CIRCLE_STRAFE = 3; // Rotates 360 degrees, and if 6DOF is supported, changes position.
-        int MOTION_SICKNESS = 4; // Moves in a figure-eight-like pattern.
-    }
-
-    /**
-     * @return The supported mode.
-     */
-    public @SupportedMode int value();
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/VrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/VrTestRule.java
index 7ef12a6d..c38963a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/VrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/VrTestRule.java
@@ -11,18 +11,6 @@
  */
 public interface VrTestRule extends XrTestRule {
     /**
-     * Whether the head tracking mode has been changed.
-     *
-     * @return True if the head tracking mode has been changed, false otherwise.
-     */
-    public boolean isTrackerDirty();
-
-    /**
-     * Tells the rule that the head tracking mode has been changed.
-     */
-    public void setTrackerDirty();
-
-    /**
      * Whether the currently applied settings result in the DON flow being enabled.
      * @return True if the DON flow is enabled, false otherwise.
      */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java
index c588891..8df5f6d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java
@@ -19,7 +19,6 @@
  * up a WebappActivity to a blank page while performing some additional VR-only setup.
  */
 public class WebappActivityVrTestRule extends WebappActivityTestRule implements VrTestRule {
-    private boolean mTrackerDirty;
     private boolean mDonEnabled;
 
     @Override
@@ -42,16 +41,6 @@
     }
 
     @Override
-    public boolean isTrackerDirty() {
-        return mTrackerDirty;
-    }
-
-    @Override
-    public void setTrackerDirty() {
-        mTrackerDirty = true;
-    }
-
-    @Override
     public boolean isDonEnabled() {
         return mDonEnabled;
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/HeadTrackingUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/HeadTrackingUtils.java
deleted file mode 100644
index db025650..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/HeadTrackingUtils.java
+++ /dev/null
@@ -1,251 +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.
-
-package org.chromium.chrome.browser.vr.util;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
-
-import org.junit.Assert;
-import org.junit.runner.Description;
-
-import org.chromium.chrome.browser.vr.TestVrShellDelegate;
-import org.chromium.chrome.browser.vr.rules.HeadTrackingMode;
-import org.chromium.chrome.browser.vr.rules.HeadTrackingMode.SupportedMode;
-import org.chromium.chrome.browser.vr.rules.VrTestRule;
-
-import java.util.Arrays;
-
-/**
- * Utility class for interacting with the VrCore head tracking service, which allows fake head
- * poses to be submitted instead of using actual sensor data.
- *
- * Requires that either the O2 rendering path is enabled or EnableVrCoreHeadTracking is set to true
- * in the shared prefs file in order to actually work.
- */
-public class HeadTrackingUtils {
-    private static final ComponentName HEAD_TRACKING_COMPONENT = new ComponentName(
-            "com.google.vr.vrcore", "com.google.vr.vrcore.tracking.HeadTrackingService");
-
-    private static final String ACTION_SET_TRACKER_TYPE = "com.google.vr.vrcore.SET_TRACKER_TYPE";
-    private static final String ACTION_SET_FAKE_TRACKER_MODE =
-            "com.google.vr.vrcore.SET_FAKE_TRACKER_MODE";
-    private static final String ACTION_SET_FAKE_TRACKER_POSE =
-            "com.google.vr.vrcore.SET_FAKE_TRACKER_POSE";
-    private static final String EXTRA_FAKE_TRACKER_MODE = "com.google.vr.vrcore.FAKE_TRACKER_MODE";
-    private static final String EXTRA_FAKE_TRACKER_POSE = "com.google.vr.vrcore.FAKE_TRACKER_POSE";
-    private static final String EXTRA_TRACKER_TYPE = "com.google.vr.vrcore.TRACKER_TYPE";
-
-    private static final int HEAD_TRACKING_APPLICATION_DELAY_MS = 500;
-
-    /**
-     * Class for holding data necessary to set the head tracking service's head pose to an
-     * arbitarary, static value. Contains either a quaternion or set of rotation Euler angles
-     * describing the direction to look in and an optional position in room space if 6DOF is
-     * supported.
-     */
-    public static class FakePose {
-        private float[] mQuaternion;
-        private float[] mRotationEulerAngles;
-        private float[] mRoomSpacePosition;
-
-        /**
-         * Sets the head pose using a quaternion.
-         *
-         * @param x The X component of the quaternion.
-         * @param y The Y component of the quaternion.
-         * @param z The Z component of the quaternion.
-         * @param w The W component of the quaternion.
-         * @return The updated FakePose instance.
-         */
-        public FakePose setQuaternion(float x, float y, float z, float w) {
-            mQuaternion = new float[] {x, y, z, w};
-            mRotationEulerAngles = null;
-            return this;
-        }
-
-        /**
-         * Sets the head pose using Euler angles.
-         *
-         * @param rollDeg The head pose's roll component in degrees.
-         * @param pitchDeg The head pose's pitch component in degrees.
-         * @param yawDeg The head pose's yaw component in degrees.
-         * @return The updated FakePose instance.
-         */
-        public FakePose setRotationEulerAngles(float rollDeg, float pitchDeg, float yawDeg) {
-            mRotationEulerAngles = new float[] {rollDeg, pitchDeg, yawDeg};
-            mQuaternion = null;
-            return this;
-        }
-
-        /**
-         * Sets the head pose's positional coordinates in room space.
-         *
-         * @param x The X position of the head pose in meters.
-         * @param y The Y position of the head pose in meters.
-         * @param z The Z position of the head pose in meters.
-         * @return The updated FakePose instance.
-         */
-        public FakePose setRoomSpacePosition(float x, float y, float z) {
-            mRoomSpacePosition = new float[] {x, y, z};
-            return this;
-        }
-
-        /**
-         * Clears any previously set room space head pose position.
-         *
-         * @return The updated FakePose instance.
-         */
-        public FakePose clearRoomSpacePosition() {
-            mRoomSpacePosition = null;
-            return this;
-        }
-
-        /**
-         * Formats the FakePose's stored data into a format usable as an extra in an Intent.
-         *
-         * @return A float array containing all the data of the FakePose instance.
-         */
-        public float[] getDataForExtra() {
-            if (mQuaternion == null && mRotationEulerAngles == null) {
-                throw new IllegalArgumentException(
-                        "Tried to get FakePose data without setting either quaternion/angle data");
-            }
-            float[] orientationArray =
-                    mRotationEulerAngles == null ? mQuaternion : mRotationEulerAngles;
-            if (mRoomSpacePosition == null) return orientationArray;
-            float[] combinedArray = Arrays.copyOf(
-                    orientationArray, orientationArray.length + mRoomSpacePosition.length);
-            for (int i = 0; i < mRoomSpacePosition.length; i++) {
-                combinedArray[i + orientationArray.length] = mRoomSpacePosition[i];
-            }
-            return combinedArray;
-        }
-    }
-
-    /**
-     * Checks for the presence of a HeadTrackingMode annotation, and if found, sets the tracking
-     * mode to the specified value. If no annotation is found, the tracking mode is left at whatever
-     * the existing value is.
-     *
-     * @param rule The VrTestRule used by the current test case.
-     * @param desc The JUnit4 Description for the current test case.
-     */
-    public static void checkForAndApplyHeadTrackingModeAnnotation(
-            VrTestRule rule, Description desc) {
-        // This is even more broken on standalone devices, and can't be disabled at the shared
-        // preference level, so no-op here.
-        if (TestVrShellDelegate.isOnStandalone()) return;
-        // Check if the test has a HeadTrackingMode annotation
-        HeadTrackingMode annotation = desc.getAnnotation(HeadTrackingMode.class);
-        if (annotation == null) return;
-        applyHeadTrackingModeInternal(rule, annotation.value());
-    }
-
-    /**
-     * Sets the tracker type to the given mode and waits long enough to safely assume that the
-     * service has started.
-     *
-     * @param rule The VrTestRule used by the current test case.
-     * @param mode The HeadTrackingMode.SupportedMode value to set the fake head tracker mode to.
-     */
-    public static void applyHeadTrackingMode(VrTestRule rule, @SupportedMode int mode) {
-        applyHeadTrackingModeInternal(rule, mode);
-        // TODO(bsheedy): Remove this sleep if the head tracking service ever exposes a way to be
-        // notified when a setting has been applied.
-        SystemClock.sleep(HEAD_TRACKING_APPLICATION_DELAY_MS);
-    }
-
-    /**
-     * Sets the head pose to the pose described by the given FakePose and waits long enough to
-     * safely assume that the pose has taken effect.
-     *
-     * @param rule The VrTestRule used by the current test case.
-     * @param pose The FakePose instance containing the pose data that will be sent to the head
-     *        tracking service.
-     */
-    public static void setHeadPose(VrTestRule rule, FakePose pose) {
-        restartHeadTrackingServiceIfNecessary(rule);
-        // Set the head pose to the given value
-        Intent poseIntent = new Intent(ACTION_SET_FAKE_TRACKER_POSE);
-        poseIntent.putExtra(EXTRA_FAKE_TRACKER_POSE, pose.getDataForExtra());
-        poseIntent.setComponent(HEAD_TRACKING_COMPONENT);
-        Assert.assertTrue("Could not set head pose",
-                InstrumentationRegistry.getContext().startService(poseIntent) != null);
-        rule.setTrackerDirty();
-        // TODO(bsheedy): Remove this sleep. Could either expose poses up to Java and wait until
-        // we receive a pose that's the same as the one we set or see if the head tracking service
-        // adds the requested functionality of sending a notification when it's done applying
-        // settings.
-        SystemClock.sleep(HEAD_TRACKING_APPLICATION_DELAY_MS);
-    }
-
-    /**
-     * Reverts the tracking type back to values that a regular user would have (using real sensor
-     * data).
-     *
-     * Only meant to be called by rules after a test has run. Reseting the tracker to use sensor
-     * data during a test technically works, but messes up orientation if done while still in VR.
-     * until VR is exited and re-entered.
-     */
-    public static void revertTracker() {
-        Intent typeIntent = new Intent(ACTION_SET_TRACKER_TYPE);
-        typeIntent.putExtra(EXTRA_TRACKER_TYPE, "sensor");
-        typeIntent.setComponent(HEAD_TRACKING_COMPONENT);
-        InstrumentationRegistry.getContext().startService(typeIntent);
-    }
-
-    public static String supportedModeToString(@SupportedMode int mode) {
-        switch (mode) {
-            case SupportedMode.FROZEN:
-                return "frozen";
-            case SupportedMode.SWEEP:
-                return "sweep";
-            case SupportedMode.ROTATE:
-                return "rotate";
-            case SupportedMode.CIRCLE_STRAFE:
-                return "circle_strafe";
-            case SupportedMode.MOTION_SICKNESS:
-                return "motion_sickness";
-            default:
-                return "unknown_mode";
-        }
-    }
-
-    private static void applyHeadTrackingModeInternal(VrTestRule rule, @SupportedMode int mode) {
-        restartHeadTrackingServiceIfNecessary(rule);
-        // Set the fake tracker mode to the given value.
-        Intent modeIntent = new Intent(ACTION_SET_FAKE_TRACKER_MODE);
-        modeIntent.putExtra(EXTRA_FAKE_TRACKER_MODE, supportedModeToString(mode));
-        modeIntent.setComponent(HEAD_TRACKING_COMPONENT);
-        Assert.assertTrue("Could not set head tracking mode",
-                InstrumentationRegistry.getContext().startService(modeIntent) != null);
-        rule.setTrackerDirty();
-    }
-
-    private static void restartHeadTrackingServiceIfNecessary(VrTestRule rule) {
-        // If the tracker has already been dirtied, then we can assume that the tracker type
-        // has already been set to "fake".
-        if (rule.isTrackerDirty()) return;
-
-        // VR sessions from previous tests can somehow interfere with the setting of the tracker
-        // type, even if said previous sessions did not touch the head tracking service. Killing
-        // the service before attempting to set the tracker type appears to work around this
-        // issue.
-        // TODO(https://crbug.com/829127): Remove this once the root cause is fixed.
-        Intent stopIntent = new Intent();
-        stopIntent.setComponent(HEAD_TRACKING_COMPONENT);
-        InstrumentationRegistry.getContext().stopService(stopIntent);
-
-        // Set the tracker tracker type to "fake".
-        Intent typeIntent = new Intent(ACTION_SET_TRACKER_TYPE);
-        typeIntent.putExtra(EXTRA_TRACKER_TYPE, "fake");
-        typeIntent.setComponent(HEAD_TRACKING_COMPONENT);
-        Assert.assertTrue("Could not restart head tracking service",
-                InstrumentationRegistry.getContext().startService(typeIntent) != null);
-        rule.setTrackerDirty();
-    }
-}
\ No newline at end of file
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java
index 3e8cc7fe..85bf41e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java
@@ -66,7 +66,6 @@
         TestVrShellDelegate.setDescription(desc);
 
         VrTestRuleUtils.ensureNoVrActivitiesDisplayed();
-        HeadTrackingUtils.checkForAndApplyHeadTrackingModeAnnotation(rule, desc);
         launcher.launch();
         // Must be called after Chrome is started, as otherwise startService fails with an
         // IllegalStateException for being used from a backgrounded app.
@@ -83,11 +82,7 @@
             VrFeedbackStatus.setUserExitedAndEntered2DCount(0);
         }
 
-        try {
-            base.evaluate();
-        } finally {
-            if (rule.isTrackerDirty()) HeadTrackingUtils.revertTracker();
-        }
+        base.evaluate();
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/xr_instrumentation_deep_dive.md b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/xr_instrumentation_deep_dive.md
index 348b4b2..5b06471 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/xr_instrumentation_deep_dive.md
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/xr_instrumentation_deep_dive.md
@@ -117,8 +117,7 @@
 `XrActivityRestrictionRule`.
 
 Rules that implement `VrTestRule` do the same, but also perform some additional
-VR-specific setup such as ensuring that the test is not started in VR and
-allowing the use of the experimental/broken VrCore head tracking service.
+VR-specific setup such as ensuring that the test is not started in VR.
 
 ## Dynamic VrCore Settings
 
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 60e342c..36a0ef1 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -340,6 +340,8 @@
     "conflicts/enumerate_input_method_editors_win.h",
     "conflicts/enumerate_shell_extensions_win.cc",
     "conflicts/enumerate_shell_extensions_win.h",
+    "conflicts/inspection_results_cache_win.cc",
+    "conflicts/inspection_results_cache_win.h",
     "conflicts/module_database_observer_win.h",
     "conflicts/module_database_win.cc",
     "conflicts/module_database_win.h",
@@ -914,6 +916,10 @@
     "notifications/persistent_notification_handler.h",
     "notifications/platform_notification_service_impl.cc",
     "notifications/platform_notification_service_impl.h",
+    "notifications/scheduler/notification_data.cc",
+    "notifications/scheduler/notification_data.h",
+    "notifications/scheduler/schedule_params.cc",
+    "notifications/scheduler/schedule_params.h",
     "notifications/system_notification_helper.cc",
     "notifications/system_notification_helper.h",
     "ntp_snippets/bookmark_last_visit_updater.cc",
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS
index 2188813..5785734 100644
--- a/chrome/browser/OWNERS
+++ b/chrome/browser/OWNERS
@@ -41,9 +41,7 @@
 per-file chrome_site_per_process_browsertest.cc=file://content/OWNERS
 per-file chrome_site_per_process_browsertest.cc=kenrb@chromium.org
 
-per-file chrome_webusb_browser_client*=juncai@chromium.org
-per-file chrome_webusb_browser_client*=reillyg@chromium.org
-per-file chrome_webusb_browser_client*=rockot@google.com
+per-file chrome_webusb_browser_client*=file://chrome/browser/usb/OWNERS
 
 per-file exo_parts.*=reveman@chromium.org
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6e84d55f..3b916814 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3269,11 +3269,6 @@
      FEATURE_VALUE_TYPE(features::kAsyncDns)},
 #endif  // defined(OS_ANDROID)
 
-    {"enable-overflow-icons-for-media-controls",
-     flag_descriptions::kOverflowIconsForMediaControlsName,
-     flag_descriptions::kOverflowIconsForMediaControlsDescription, kOsAll,
-     FEATURE_VALUE_TYPE(media::kOverflowIconsForMediaControls)},
-
 #if defined(OS_ANDROID)
     {"enable-downloads-location-change",
      flag_descriptions::kDownloadsLocationChangeName,
@@ -3347,11 +3342,6 @@
      flag_descriptions::kClipboardContentSettingDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kClipboardContentSetting)},
 
-    {"enable-modern-media-controls",
-     flag_descriptions::kUseModernMediaControlsName,
-     flag_descriptions::kUseModernMediaControlsDescription, kOsAll,
-     FEATURE_VALUE_TYPE(media::kUseModernMediaControls)},
-
     {"enable-network-logging-to-file",
      flag_descriptions::kEnableNetworkLoggingToFileName,
      flag_descriptions::kEnableNetworkLoggingToFileDescription, kOsAll,
@@ -3529,6 +3519,10 @@
      flag_descriptions::kHorizontalTabSwitcherAndroidName,
      flag_descriptions::kHorizontalTabSwitcherAndroidDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kHorizontalTabSwitcherAndroid)},
+
+    {"enable-tab-grid-layout", flag_descriptions::kTabGridLayoutAndroidName,
+     flag_descriptions::kTabGridLayoutAndroidDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kTabGridLayoutAndroid)},
 #endif  // OS_ANDROID
 
 #if defined(OS_ANDROID)
@@ -3719,13 +3713,6 @@
      FEATURE_VALUE_TYPE(features::kExperimentalUi)},
 
 #if defined(OS_ANDROID)
-    {"enable-media-controls-expand-gesture",
-     flag_descriptions::kEnableMediaControlsExpandGestureName,
-     flag_descriptions::kEnableMediaControlsExpandGestureDescription,
-     kOsAndroid, FEATURE_VALUE_TYPE(media::kMediaControlsExpandGesture)},
-#endif
-
-#if defined(OS_ANDROID)
     {"cct-module", flag_descriptions::kCCTModuleName,
      flag_descriptions::kCCTModuleDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kCCTModule)},
diff --git a/chrome/browser/android/usage_stats/usage_stats_database.cc b/chrome/browser/android/usage_stats/usage_stats_database.cc
index dcf85a05..fe9efa6e 100644
--- a/chrome/browser/android/usage_stats/usage_stats_database.cc
+++ b/chrome/browser/android/usage_stats/usage_stats_database.cc
@@ -22,10 +22,6 @@
 
 const char kKeySeparator[] = "_";
 
-const char kWebsiteEventPrefix[] = "website_event";
-const char kSuspensionPrefix[] = "suspension";
-const char kTokenMappingPrefix[] = "token_mapping";
-
 const int kUnixTimeDigits = 11;
 // Formats an integer with a minimum width of 11, right-justified, and
 // zero-filled (example: 1548353315 => 01548353315).
@@ -46,13 +42,16 @@
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 
   website_event_db_ = db_provider->GetDB<WebsiteEvent>(
-      kNamespace, kWebsiteEventPrefix, usage_stats_dir, db_task_runner);
+      leveldb_proto::ProtoDbType::USAGE_STATS_WEBSITE_EVENT, usage_stats_dir,
+      db_task_runner);
 
   suspension_db_ = db_provider->GetDB<Suspension>(
-      kNamespace, kSuspensionPrefix, usage_stats_dir, db_task_runner);
+      leveldb_proto::ProtoDbType::USAGE_STATS_SUSPENSION, usage_stats_dir,
+      db_task_runner);
 
   token_mapping_db_ = db_provider->GetDB<TokenMapping>(
-      kNamespace, kTokenMappingPrefix, usage_stats_dir, db_task_runner);
+      leveldb_proto::ProtoDbType::USAGE_STATS_TOKEN_MAPPING, usage_stats_dir,
+      db_task_runner);
 
   InitializeDBs();
 }
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index 0e7ced1..e81a8c78 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -71,18 +71,7 @@
 
   content::Compositor::Initialize();
 
-  // Chrome on Android does not use default MessageLoop. It has its own
-  // Android specific MessageLoop.
-  DCHECK(!main_message_loop_.get());
-
-  // Create the MessageLoop if doesn't yet exist (and bind it to the native Java
-  // loop). This is a critical point in the startup process.
-  {
-    TRACE_EVENT0("startup",
-      "ChromeBrowserMainPartsAndroid::PreEarlyInitialization:CreateUiMsgLoop");
-    if (!base::MessageLoopCurrent::IsSet())
-      main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
-  }
+  CHECK(base::MessageLoopCurrent::IsSet());
 
   return ChromeBrowserMainParts::PreEarlyInitialization();
 }
diff --git a/chrome/browser/chrome_browser_main_android.h b/chrome/browser/chrome_browser_main_android.h
index fe11a5d..6ff8f3a7 100644
--- a/chrome/browser/chrome_browser_main_android.h
+++ b/chrome/browser/chrome_browser_main_android.h
@@ -26,7 +26,6 @@
   void ShowMissingLocaleMessageBox() override;
 
  private:
-  std::unique_ptr<base::MessageLoop> main_message_loop_;
   std::unique_ptr<android::ChromeBackupWatcher> backup_watcher_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsAndroid);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index fe4d8fb3..20926de 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -4864,7 +4864,9 @@
 std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
 ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
     content::NavigationUIData* navigation_ui_data,
-    int frame_tree_node_id) {
+    int frame_tree_node_id,
+    const scoped_refptr<network::SharedURLLoaderFactory>&
+        network_loader_factory) {
   std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
       interceptors;
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@@ -4876,14 +4878,15 @@
   }
 #endif
 
-  // TODO(ryansturm): plumb a network service url loader factory and page id
-  // generator through here. https://crbug.com/921740
+  // TODO(ryansturm): Once this is on the UI thread, stop passing
+  // |network_loader_factory| and have interceptors create one themselves.
+  // https://crbug.com/931786
   if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
       base::FeatureList::IsEnabled(
           previews::features::kHTTPSServerPreviewsUsingURLLoader)) {
     interceptors.push_back(
         std::make_unique<previews::PreviewsLitePageURLLoaderInterceptor>(
-            frame_tree_node_id));
+            network_loader_factory, frame_tree_node_id));
   }
 
   return interceptors;
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 4f7e87d..2bfe0ed 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -471,7 +471,9 @@
   std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
   WillCreateURLLoaderRequestInterceptors(
       content::NavigationUIData* navigation_ui_data,
-      int frame_tree_node_id) override;
+      int frame_tree_node_id,
+      const scoped_refptr<network::SharedURLLoaderFactory>&
+          network_loader_factory) override;
   void WillCreateWebSocket(
       content::RenderFrameHost* frame,
       network::mojom::WebSocketRequest* request,
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index ddb1759b..2e91feaa 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -630,6 +630,12 @@
     "child_accounts/event_based_status_reporting_service_factory.h",
     "child_accounts/parent_access_code/authenticator.cc",
     "child_accounts/parent_access_code/authenticator.h",
+    "child_accounts/parent_access_code/config_source.cc",
+    "child_accounts/parent_access_code/config_source.h",
+    "child_accounts/parent_access_code/parent_access_service.cc",
+    "child_accounts/parent_access_code/parent_access_service.h",
+    "child_accounts/parent_access_code/policy_config_source.cc",
+    "child_accounts/parent_access_code/policy_config_source.h",
     "child_accounts/screen_time_controller.cc",
     "child_accounts/screen_time_controller.h",
     "child_accounts/screen_time_controller_factory.cc",
@@ -2216,6 +2222,8 @@
     "certificate_provider/certificate_provider_service_unittest.cc",
     "child_accounts/event_based_status_reporting_service_unittest.cc",
     "child_accounts/parent_access_code/authenticator_unittest.cc",
+    "child_accounts/parent_access_code/test_utils.cc",
+    "child_accounts/parent_access_code/test_utils.h",
     "child_accounts/time_limit_notifier_unittest.cc",
     "child_accounts/time_limit_test_utils.cc",
     "child_accounts/usage_time_limit_processor_unittest.cc",
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.cc
index 69945a7..22614c9 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.cc
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.cc
@@ -9,10 +9,52 @@
 #include "base/big_endian.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
+#include "base/values.h"
 
 namespace chromeos {
 namespace parent_access {
 
+namespace {
+
+// Value ranges for access code config data.
+constexpr base::TimeDelta kMinCodeValidity = base::TimeDelta::FromSeconds(60);
+constexpr base::TimeDelta kMaxCodeValidity = base::TimeDelta::FromMinutes(60);
+constexpr base::TimeDelta kMinClockDriftTolerance =
+    base::TimeDelta::FromMinutes(0);
+constexpr base::TimeDelta kMaxClockDriftTolerance =
+    base::TimeDelta::FromMinutes(30);
+
+// Dictionary keys used to serialize access code config data.
+constexpr char kSharedSecretDictKey[] = "shared_secret";
+constexpr char kCodeValidityDictKey[] = "access_code_ttl";
+constexpr char kClockDriftDictKey[] = "clock_drift_tolerance";
+
+}  // namespace
+
+// static
+base::Optional<AccessCodeConfig> AccessCodeConfig::FromDictionary(
+    const base::DictionaryValue& dict) {
+  const std::string* secret = dict.FindStringKey(kSharedSecretDictKey);
+  if (!secret || secret->empty())
+    return base::nullopt;
+
+  base::Optional<int> validity = dict.FindIntKey(kCodeValidityDictKey);
+  if (!(validity.has_value() && *validity >= kMinCodeValidity.InSeconds() &&
+        *validity <= kMaxCodeValidity.InSeconds())) {
+    return base::nullopt;
+  }
+
+  base::Optional<int> clock_drift = dict.FindIntKey(kClockDriftDictKey);
+  if (!(clock_drift.has_value() &&
+        *clock_drift >= kMinClockDriftTolerance.InSeconds() &&
+        *clock_drift <= kMaxClockDriftTolerance.InSeconds())) {
+    return base::nullopt;
+  }
+
+  return AccessCodeConfig(*secret, base::TimeDelta::FromSeconds(*validity),
+                          base::TimeDelta::FromSeconds(*clock_drift));
+}
+
 AccessCodeConfig::AccessCodeConfig(const std::string& shared_secret,
                                    base::TimeDelta code_validity,
                                    base::TimeDelta clock_drift_tolerance)
@@ -20,9 +62,10 @@
       code_validity_(code_validity),
       clock_drift_tolerance_(clock_drift_tolerance) {
   DCHECK(!shared_secret_.empty());
-  DCHECK(code_validity_ >= base::TimeDelta::FromSeconds(60));
-  DCHECK(code_validity_ <= base::TimeDelta::FromMinutes(60));
-  DCHECK(clock_drift_tolerance_ <= base::TimeDelta::FromMinutes(30));
+  DCHECK(code_validity_ >= kMinCodeValidity);
+  DCHECK(code_validity_ <= kMaxCodeValidity);
+  DCHECK(clock_drift_tolerance_ >= kMinClockDriftTolerance);
+  DCHECK(clock_drift_tolerance_ <= kMaxClockDriftTolerance);
 }
 
 AccessCodeConfig::AccessCodeConfig(const AccessCodeConfig& rhs) = default;
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h
index 3190448..3030e80 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h
@@ -14,12 +14,22 @@
 #include "base/time/time.h"
 #include "crypto/hmac.h"
 
+namespace base {
+class DictionaryValue;
+}  // namespace base
+
 namespace chromeos {
 namespace parent_access {
 
 // Configuration used to generate and verify parent access code.
 class AccessCodeConfig {
  public:
+  // Returns AccessCodeConfig created from a |dictionary|, if the |dictionary|
+  // contains valid config data.
+  static base::Optional<AccessCodeConfig> FromDictionary(
+      const base::DictionaryValue& value);
+
+  // TODO(agawronska): Make constructor private.
   // To create valid AccessCodeConfig:
   // * |shared_secret| cannot be empty
   // * |code_validity| needs to be in between 30s and 3600s
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
index 98ee40b..7fe5cb8 100644
--- a/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/authenticator_unittest.cc
@@ -10,41 +10,12 @@
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
 namespace parent_access {
 
-namespace {
-
-constexpr char kTestSharedSecret[] = "AIfVJHITSar8keeq3779V70dWiS1xbPv8g";
-constexpr base::TimeDelta kDefaultValidity = base::TimeDelta::FromMinutes(10);
-constexpr base::TimeDelta kDefaultClockDrift = base::TimeDelta::FromMinutes(5);
-
-// Configuration that is currently used for PAC.
-AccessCodeConfig DefaultConfig() {
-  return AccessCodeConfig(kTestSharedSecret, kDefaultValidity,
-                          kDefaultClockDrift);
-}
-
-// Populates |test_values| with test Parent Access Code data (timestamp - code
-// value pairs) generated in Family Link Android app.
-void GetTestValues(std::map<base::Time, std::string>* test_values) {
-  base::Time timestamp;
-  ASSERT_TRUE(base::Time::FromString("8 Jan 2019 16:58:07 PST", &timestamp));
-  (*test_values)[timestamp] = "734261";
-  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:35:05 PST", &timestamp));
-  (*test_values)[timestamp] = "472150";
-  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:42:49 PST", &timestamp));
-  (*test_values)[timestamp] = "204984";
-  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:53:01 PST", &timestamp));
-  (*test_values)[timestamp] = "157758";
-  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 16:00:00 PST", &timestamp));
-  (*test_values)[timestamp] = "524186";
-}
-
-}  // namespace
-
 class ParentAccessCodeAuthenticatorTest : public testing::Test {
  protected:
   ParentAccessCodeAuthenticatorTest() = default;
@@ -65,9 +36,9 @@
   // Test generation against Parent Access Code values generated in Family
   // Link Android app.
   std::map<base::Time, std::string> test_values;
-  ASSERT_NO_FATAL_FAILURE(GetTestValues(&test_values));
+  ASSERT_NO_FATAL_FAILURE(GetTestAccessCodeValues(&test_values));
 
-  Authenticator gen(DefaultConfig());
+  Authenticator gen(GetDefaultTestConfig());
   for (const auto& it : test_values) {
     base::Optional<AccessCode> code = gen.Generate(it.first);
     ASSERT_NO_FATAL_FAILURE(Verify(code, it.first));
@@ -80,7 +51,7 @@
   // validity period.
   base::Time timestamp;
   ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:00:00 PST", &timestamp));
-  const AccessCodeConfig config = DefaultConfig();
+  const AccessCodeConfig config = GetDefaultTestConfig();
 
   Authenticator gen(config);
   base::Optional<AccessCode> first_code = gen.Generate(timestamp);
@@ -103,21 +74,21 @@
   ASSERT_TRUE(
       base::Time::FromString("14 Jan 2019 15:00:00 PST", &initial_timestamp));
 
-  Authenticator gen(DefaultConfig());
+  Authenticator gen(GetDefaultTestConfig());
   base::Optional<AccessCode> first_code = gen.Generate(initial_timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(first_code, initial_timestamp));
 
   for (int i = 1; i < 10; ++i) {
     // "Earlier" time bucket.
     {
-      const base::Time timestamp = initial_timestamp - i * kDefaultValidity;
+      const base::Time timestamp = initial_timestamp - i * kDefaultCodeValidity;
       base::Optional<AccessCode> code = gen.Generate(timestamp);
       ASSERT_NO_FATAL_FAILURE(Verify(code, timestamp));
       EXPECT_NE(*first_code, *code);
     }
     // "Later" time bucket.
     {
-      const base::Time timestamp = initial_timestamp + i * kDefaultValidity;
+      const base::Time timestamp = initial_timestamp + i * kDefaultCodeValidity;
       base::Optional<AccessCode> code = gen.Generate(timestamp);
       ASSERT_NO_FATAL_FAILURE(Verify(code, timestamp));
       EXPECT_NE(*first_code, *code);
@@ -127,7 +98,7 @@
 
 TEST_F(ParentAccessCodeAuthenticatorTest, GenerateWithSameTimestamp) {
   // Test that codes generated with the same timestamp and config are the same.
-  const AccessCodeConfig config = DefaultConfig();
+  const AccessCodeConfig config = GetDefaultTestConfig();
   const base::Time timestamp = base::Time::Now();
 
   Authenticator gen1(config);
@@ -145,13 +116,13 @@
   // Test that codes generated with the different secrets are not the same.
   const base::Time timestamp = base::Time::Now();
 
-  Authenticator gen1(AccessCodeConfig("AAAAAAAAAAAAAAAAAAA", kDefaultValidity,
-                                      kDefaultClockDrift));
+  Authenticator gen1(AccessCodeConfig(
+      "AAAAAAAAAAAAAAAAAAA", kDefaultCodeValidity, kDefaultClockDrift));
   base::Optional<AccessCode> code1 = gen1.Generate(timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(code1, timestamp));
 
-  Authenticator gen2(AccessCodeConfig("AAAAAAAAAAAAAAAAAAB", kDefaultValidity,
-                                      kDefaultClockDrift));
+  Authenticator gen2(AccessCodeConfig(
+      "AAAAAAAAAAAAAAAAAAB", kDefaultCodeValidity, kDefaultClockDrift));
   base::Optional<AccessCode> code2 = gen2.Generate(timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(code2, timestamp));
 
@@ -180,12 +151,12 @@
   // Test that clock drift tolerance does not affect code generation.
   const base::Time timestamp = base::Time::Now();
 
-  Authenticator gen1(AccessCodeConfig(kTestSharedSecret, kDefaultValidity,
+  Authenticator gen1(AccessCodeConfig(kTestSharedSecret, kDefaultCodeValidity,
                                       base::TimeDelta::FromMinutes(1)));
   base::Optional<AccessCode> code1 = gen1.Generate(timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(code1, timestamp));
 
-  Authenticator gen2(AccessCodeConfig(kTestSharedSecret, kDefaultValidity,
+  Authenticator gen2(AccessCodeConfig(kTestSharedSecret, kDefaultCodeValidity,
                                       base::TimeDelta::FromMinutes(10)));
   base::Optional<AccessCode> code2 = gen2.Generate(timestamp);
   ASSERT_NO_FATAL_FAILURE(Verify(code2, timestamp));
@@ -197,9 +168,9 @@
   // Test validation against Parent Access Code values generated in Family Link
   // Android app.
   std::map<base::Time, std::string> test_values;
-  ASSERT_NO_FATAL_FAILURE(GetTestValues(&test_values));
+  ASSERT_NO_FATAL_FAILURE(GetTestAccessCodeValues(&test_values));
 
-  Authenticator gen(AccessCodeConfig(kTestSharedSecret, kDefaultValidity,
+  Authenticator gen(AccessCodeConfig(kTestSharedSecret, kDefaultCodeValidity,
                                      base::TimeDelta::FromMinutes(0)));
   for (const auto& it : test_values) {
     base::Optional<AccessCode> code = gen.Validate(it.second, it.first);
@@ -213,7 +184,7 @@
   // Test validation against codes generated by separate
   // Authenticator object in and outside of the valid time
   // bucket.
-  const AccessCodeConfig config(kTestSharedSecret, kDefaultValidity,
+  const AccessCodeConfig config(kTestSharedSecret, kDefaultCodeValidity,
                                 base::TimeDelta::FromMinutes(0));
   Authenticator generator(config);
   Authenticator validator(config);
@@ -252,7 +223,7 @@
        ValidationAndGenerationOnSameAuthenticator) {
   // Test generation and validation on the same Authenticator
   // object in and outside of the valid time bucket.
-  const AccessCodeConfig config(kTestSharedSecret, kDefaultValidity,
+  const AccessCodeConfig config(kTestSharedSecret, kDefaultCodeValidity,
                                 base::TimeDelta::FromMinutes(0));
   Authenticator authenticator(config);
 
@@ -288,10 +259,11 @@
 
 TEST_F(ParentAccessCodeAuthenticatorTest, ValidationWithClockDriftTolerance) {
   // Test validation with clock drift tolerance.
-  Authenticator generator(DefaultConfig());
-  Authenticator validator_with_tolerance(DefaultConfig());
-  Authenticator validator_no_tolerance(AccessCodeConfig(
-      kTestSharedSecret, kDefaultValidity, base::TimeDelta::FromMinutes(0)));
+  Authenticator generator(GetDefaultTestConfig());
+  Authenticator validator_with_tolerance(GetDefaultTestConfig());
+  Authenticator validator_no_tolerance(
+      AccessCodeConfig(kTestSharedSecret, kDefaultCodeValidity,
+                       base::TimeDelta::FromMinutes(0)));
 
   // By default code will be valid [15:30:00-15:40:00).
   // With clock drift tolerance code will be valid [15:25:00-15:45:00).
@@ -304,7 +276,7 @@
   ASSERT_NO_FATAL_FAILURE(Verify(generated_code, generation_timestamp));
 
   // Both validators accept the code in valid period.
-  int range = kDefaultValidity / Authenticator::kAccessCodeGranularity;
+  int range = kDefaultCodeValidity / Authenticator::kAccessCodeGranularity;
   base::Time timestamp;
   base::Optional<AccessCode> validated_code_no_tolerance;
   base::Optional<AccessCode> validated_code_with_tolerance;
@@ -345,7 +317,8 @@
   EXPECT_FALSE(validated_code_with_tolerance);
 
   // Validator's device clock ahead by tolerated drift.
-  timestamp = generation_timestamp + kDefaultValidity + kDefaultClockDrift / 2;
+  timestamp =
+      generation_timestamp + kDefaultCodeValidity + kDefaultClockDrift / 2;
   validated_code_no_tolerance =
       validator_no_tolerance.Validate(generated_code->code(), timestamp);
   EXPECT_FALSE(validated_code_no_tolerance);
@@ -355,7 +328,7 @@
   EXPECT_TRUE(validated_code_with_tolerance);
 
   // Validator's device clock ahead outside of tolerated drift.
-  timestamp = generation_timestamp + kDefaultValidity + kDefaultClockDrift;
+  timestamp = generation_timestamp + kDefaultCodeValidity + kDefaultClockDrift;
   validated_code_no_tolerance =
       validator_no_tolerance.Validate(generated_code->code(), timestamp);
   EXPECT_FALSE(validated_code_no_tolerance);
@@ -369,7 +342,7 @@
   // Test authenticator with Unix Epoch timestamp.
   const base::Time unix_epoch = base::Time::UnixEpoch();
 
-  Authenticator authenticator(DefaultConfig());
+  Authenticator authenticator(GetDefaultTestConfig());
   base::Optional<AccessCode> generated = authenticator.Generate(unix_epoch);
   ASSERT_NO_FATAL_FAILURE(Verify(generated, unix_epoch));
   base::Optional<AccessCode> validated =
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.cc
new file mode 100644
index 0000000..06baaef4
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.cc
@@ -0,0 +1,36 @@
+// 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/child_accounts/parent_access_code/config_source.h"
+
+namespace chromeos {
+namespace parent_access {
+
+ConfigSource::ConfigSet::ConfigSet() = default;
+ConfigSource::ConfigSet::~ConfigSet() = default;
+ConfigSource::ConfigSet::ConfigSet(ConfigSet&&) = default;
+ConfigSource::ConfigSet& ConfigSource::ConfigSet::operator=(ConfigSet&&) =
+    default;
+
+ConfigSource::Observer::Observer() = default;
+ConfigSource::Observer::~Observer() = default;
+
+ConfigSource::ConfigSource() = default;
+ConfigSource::~ConfigSource() = default;
+
+void ConfigSource::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void ConfigSource::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void ConfigSource::NotifyConfigChanged(const ConfigSet& configs) {
+  for (auto& observer : observers_)
+    observer.OnConfigChanged(configs);
+}
+
+}  // namespace parent_access
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h b/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h
new file mode 100644
index 0000000..f6331ddc
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h
@@ -0,0 +1,81 @@
+// 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_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_CONFIG_SOURCE_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_CONFIG_SOURCE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "base/optional.h"
+#include "chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h"
+
+namespace chromeos {
+namespace parent_access {
+
+class AccessCodeConfig;
+
+// Base class for parent access code configuration providers.
+class ConfigSource {
+ public:
+  // Set of parent access code configurations used for generation and validation
+  // of parent access code.
+  struct ConfigSet {
+    ConfigSet();
+    ConfigSet(ConfigSet&&);
+    ConfigSet& operator=(ConfigSet&&);
+    ~ConfigSet();
+
+    // Primary config used for validation of parent access code.
+    base::Optional<AccessCodeConfig> future_config;
+
+    // Primary config used for generation of parent access code.
+    // Should be used for validation only when access code cannot be validated
+    // with |future_config|.
+    base::Optional<AccessCodeConfig> current_config;
+
+    // These configs should be used for validation of parent access code only
+    // when it cannot be validated with |future_config| nor |current_config|.
+    std::vector<AccessCodeConfig> old_configs;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(ConfigSet);
+  };
+
+  // Observer interface for ConfigSource that gets notified when parent access
+  // code configuration changed.
+  class Observer : public base::CheckedObserver {
+   public:
+    Observer();
+    ~Observer() override;
+
+    // Called when parent access code configuration changed.
+    virtual void OnConfigChanged(const ConfigSet& configs) = 0;
+  };
+
+  ConfigSource();
+  virtual ~ConfigSource();
+
+  // Returns current parent access code configurations.
+  virtual ConfigSet GetConfigSet() = 0;
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ protected:
+  void NotifyConfigChanged(const ConfigSet& configs);
+
+ private:
+  base::ObserverList<Observer> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConfigSource);
+};
+
+}  // namespace parent_access
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_CONFIG_SOURCE_H_
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc
new file mode 100644
index 0000000..036775a
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.cc
@@ -0,0 +1,75 @@
+// 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/child_accounts/parent_access_code/parent_access_service.h"
+
+#include <utility>
+
+#include "base/time/clock.h"
+#include "base/time/default_clock.h"
+#include "base/timer/timer.h"
+
+namespace chromeos {
+namespace parent_access {
+
+ParentAccessService::Delegate::Delegate() = default;
+ParentAccessService::Delegate::~Delegate() = default;
+
+ParentAccessService::ParentAccessService(
+    std::unique_ptr<ConfigSource> config_source)
+    : config_source_(std::move(config_source)),
+      clock_(base::DefaultClock::GetInstance()) {
+  CreateValidators(config_source_->GetConfigSet());
+}
+
+ParentAccessService::~ParentAccessService() = default;
+
+void ParentAccessService::SetDelegate(Delegate* delegate) {
+  DCHECK(!!delegate_ ^ !!delegate);
+  delegate_ = delegate;
+}
+
+void ParentAccessService::OnConfigChanged(
+    const ConfigSource::ConfigSet& configs) {
+  CreateValidators(configs);
+}
+
+void ParentAccessService::SetClockForTesting(base::Clock* clock) {
+  clock_ = clock;
+}
+
+void ParentAccessService::CreateValidators(
+    const ConfigSource::ConfigSet& configs) {
+  access_code_validators_.clear();
+
+  // Validators are added to |access_code_validators_| in the order that
+  // optimizes validation process. Parent access codes will be validated
+  // starting from the front of the vector. The correct validation order:
+  // * future configuration
+  // * current configuration
+  // * old configurations
+  if (configs.future_config.has_value()) {
+    access_code_validators_.push_back(
+        std::make_unique<Authenticator>(configs.future_config.value()));
+  } else {
+    LOG(WARNING) << "No future config for parent access code in the policy";
+  }
+
+  if (configs.current_config.has_value()) {
+    access_code_validators_.push_back(
+        std::make_unique<Authenticator>(configs.current_config.value()));
+  } else {
+    LOG(WARNING) << "No current config for parent access code in the policy";
+  }
+
+  for (const auto& config : configs.old_configs) {
+    access_code_validators_.push_back(std::make_unique<Authenticator>(config));
+  }
+
+  if (access_code_validators_.empty())
+    LOG(ERROR) << "No config to validate parent access available";
+}
+
+}  // namespace parent_access
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h
new file mode 100644
index 0000000..39a9cdef
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/parent_access_service.h
@@ -0,0 +1,79 @@
+// 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_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_SERVICE_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_SERVICE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h"
+#include "components/account_id/account_id.h"
+
+namespace base {
+class Clock;
+}  // namespace base
+
+namespace chromeos {
+namespace parent_access {
+
+class Authenticator;
+
+// Parent access code validation service.
+class ParentAccessService : public ConfigSource::Observer {
+ public:
+  // Delegate that gets notified about attempts to validate parent access code.
+  class Delegate {
+   public:
+    Delegate();
+    virtual ~Delegate();
+
+    // Called when access code validation was performed. |result| is true if
+    // validation finished with a success and false otherwise.
+    virtual void OnAccessCodeValidation(bool result) = 0;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(Delegate);
+  };
+
+  explicit ParentAccessService(std::unique_ptr<ConfigSource> config_source);
+  ~ParentAccessService() override;
+
+  void SetDelegate(Delegate* delegate);
+
+  // ConfigSource::Observer:
+  void OnConfigChanged(const ConfigSource::ConfigSet& configs) override;
+
+  // Allows to override the time for testing purposes.
+  void SetClockForTesting(base::Clock* clock);
+
+ private:
+  friend class ParentAccessServiceTest;
+
+  void CreateValidators(const ConfigSource::ConfigSet& configs);
+
+  // Delegate that will be notified about results of access code validation.
+  Delegate* delegate_ = nullptr;
+
+  // Provides configurations to be used for validation of access codes.
+  std::unique_ptr<ConfigSource> config_source_;
+
+  // Authenticators used for validation of parent access code.
+  // There is one validator per active parent access code configuration.
+  // Validators should be used in the order they are stored in
+  // |access_code_validators_|. Validation is considered successful if any of
+  // validators returns success.
+  std::vector<std::unique_ptr<Authenticator>> access_code_validators_;
+
+  // Points to the base::DefaultClock by default.
+  const base::Clock* clock_;
+
+  DISALLOW_COPY_AND_ASSIGN(ParentAccessService);
+};
+
+}  // namespace parent_access
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_PARENT_ACCESS_SERVICE_H_
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.cc
new file mode 100644
index 0000000..0da023c
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.cc
@@ -0,0 +1,77 @@
+// 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/child_accounts/parent_access_code/policy_config_source.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace chromeos {
+namespace parent_access {
+
+namespace {
+
+// Dictionary keys for ParentAccessCodeConfig policy.
+constexpr char kFutureConfigDictKey[] = "future_config";
+constexpr char kCurrentConfigDictKey[] = "current_config";
+constexpr char kOldConfigsDictKey[] = "old_configs";
+}  // namespace
+
+PolicyConfigSource::PolicyConfigSource(PrefService* pref_service)
+    : pref_service_(pref_service) {
+  DCHECK(pref_service_);
+
+  pref_change_registrar_.Init(pref_service_);
+  pref_change_registrar_.Add(
+      prefs::kParentAccessCodeConfig,
+      base::BindRepeating(&PolicyConfigSource::OnPolicyChanged,
+                          base::Unretained(this)));
+}
+
+PolicyConfigSource::~PolicyConfigSource() = default;
+
+ConfigSource::ConfigSet PolicyConfigSource::GetConfigSet() {
+  const base::DictionaryValue* dictionary =
+      pref_service_->GetDictionary(prefs::kParentAccessCodeConfig);
+
+  ConfigSet config_set;
+
+  const base::Value* future_config_value = dictionary->FindKeyOfType(
+      kFutureConfigDictKey, base::Value::Type::DICTIONARY);
+  if (future_config_value) {
+    config_set.future_config = AccessCodeConfig::FromDictionary(
+        static_cast<const base::DictionaryValue&>(*future_config_value));
+  } else {
+    LOG(WARNING) << "No future config for parent access code in the policy";
+  }
+
+  const base::Value* current_config_value = dictionary->FindKeyOfType(
+      kCurrentConfigDictKey, base::Value::Type::DICTIONARY);
+  if (future_config_value) {
+    config_set.current_config = AccessCodeConfig::FromDictionary(
+        static_cast<const base::DictionaryValue&>(*current_config_value));
+  } else {
+    LOG(WARNING) << "No current config for parent access code in the policy";
+  }
+
+  const base::Value* old_configs_value =
+      dictionary->FindKeyOfType(kOldConfigsDictKey, base::Value::Type::LIST);
+  if (old_configs_value) {
+    for (const auto& config : old_configs_value->GetList()) {
+      config_set.current_config = AccessCodeConfig::FromDictionary(
+          static_cast<const base::DictionaryValue&>(config));
+    }
+  }
+  return config_set;
+}
+
+void PolicyConfigSource::OnPolicyChanged() {
+  NotifyConfigChanged(GetConfigSet());
+}
+
+}  // namespace parent_access
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.h b/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.h
new file mode 100644
index 0000000..67171735
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/policy_config_source.h
@@ -0,0 +1,39 @@
+// 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_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_POLICY_CONFIG_SOURCE_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_POLICY_CONFIG_SOURCE_H_
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/child_accounts/parent_access_code/config_source.h"
+#include "components/prefs/pref_change_registrar.h"
+
+class PrefService;
+
+namespace chromeos {
+namespace parent_access {
+
+// Provides parent access code configuration from user policy.
+class PolicyConfigSource : public ConfigSource {
+ public:
+  explicit PolicyConfigSource(PrefService* pref_service);
+  ~PolicyConfigSource() override;
+
+  ConfigSet GetConfigSet() override;
+
+ private:
+  // Updates configuration when policy changes.
+  void OnPolicyChanged();
+
+  PrefService* pref_service_ = nullptr;
+
+  PrefChangeRegistrar pref_change_registrar_;
+
+  DISALLOW_COPY_AND_ASSIGN(PolicyConfigSource);
+};
+
+}  // namespace parent_access
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_POLICY_CONFIG_SOURCE_H_
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.cc b/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.cc
new file mode 100644
index 0000000..10dbd2e8
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.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/child_accounts/parent_access_code/test_utils.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace parent_access {
+
+AccessCodeConfig GetDefaultTestConfig() {
+  return AccessCodeConfig(kTestSharedSecret, kDefaultCodeValidity,
+                          kDefaultClockDrift);
+}
+
+AccessCodeConfig GetInvalidTestConfig() {
+  return AccessCodeConfig("AAAAaaaaBBBBbbbbccccCCCC", kDefaultCodeValidity,
+                          kDefaultClockDrift);
+}
+
+void GetTestAccessCodeValues(AccessCodeValues* test_values) {
+  base::Time timestamp;
+  ASSERT_TRUE(base::Time::FromString("8 Jan 2019 16:58:07 PST", &timestamp));
+  (*test_values)[timestamp] = "734261";
+  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:35:05 PST", &timestamp));
+  (*test_values)[timestamp] = "472150";
+  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:42:49 PST", &timestamp));
+  (*test_values)[timestamp] = "204984";
+  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 15:53:01 PST", &timestamp));
+  (*test_values)[timestamp] = "157758";
+  ASSERT_TRUE(base::Time::FromString("14 Jan 2019 16:00:00 PST", &timestamp));
+  (*test_values)[timestamp] = "524186";
+}
+
+}  // namespace parent_access
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.h b/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.h
new file mode 100644
index 0000000..8c7a15a
--- /dev/null
+++ b/chrome/browser/chromeos/child_accounts/parent_access_code/test_utils.h
@@ -0,0 +1,43 @@
+// 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_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_TEST_UTILS_H_
+#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_TEST_UTILS_H_
+
+#include <map>
+#include <string>
+
+#include "base/time/time.h"
+#include "chrome/browser/chromeos/child_accounts/parent_access_code/authenticator.h"
+
+namespace chromeos {
+namespace parent_access {
+
+// Values used in default parent access code configuration for tests.
+constexpr char kTestSharedSecret[] = "AIfVJHITSar8keeq3779V70dWiS1xbPv8g";
+constexpr base::TimeDelta kDefaultCodeValidity =
+    base::TimeDelta::FromMinutes(10);
+constexpr base::TimeDelta kDefaultClockDrift = base::TimeDelta::FromMinutes(5);
+
+// Used for storing sample parent access code data. Map that contains pairs of
+// corresponding timestamp and code.
+typedef std::map<base::Time, std::string> AccessCodeValues;
+
+// Returns default configuration that is currently used for PAC tests.
+// Sample test data were generated with this config.
+AccessCodeConfig GetDefaultTestConfig();
+
+// Returns configuration different that the default test config.
+// Testing sample test date against this config will result with validation
+// failures thus this config is referred to as 'invalid'.
+AccessCodeConfig GetInvalidTestConfig();
+
+// Populates |test_values| with test Parent Access Code data (timestamp - code
+// value pairs) generated in Family Link Android app with the default config.
+void GetTestAccessCodeValues(AccessCodeValues* test_values);
+
+}  // namespace parent_access
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_PARENT_ACCESS_CODE_TEST_UTILS_H_
diff --git a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc
index a12501c..4414f12 100644
--- a/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc
+++ b/chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.cc
@@ -164,11 +164,9 @@
   // Keep |close_callback| to close the file when the stream is destructed.
   DCHECK(!close_callback_on_ui_thread.is_null());
   close_callback_on_ui_thread_ = close_callback_on_ui_thread;
-  local_file_writer_.reset(storage::FileStreamWriter::CreateForLocalFile(
-      file_task_runner_.get(),
-      local_path,
-      offset_,
-      storage::FileStreamWriter::OPEN_EXISTING_FILE));
+  local_file_writer_ = storage::FileStreamWriter::CreateForLocalFile(
+      file_task_runner_.get(), local_path, offset_,
+      storage::FileStreamWriter::OPEN_EXISTING_FILE);
   int result = local_file_writer_->Write(
       buf, buf_len,
       base::BindOnce(&WebkitFileStreamWriterImpl::OnWrite,
diff --git a/chrome/browser/chromeos/fileapi/file_system_backend.cc b/chrome/browser/chromeos/fileapi/file_system_backend.cc
index 1958129a..b695deee 100644
--- a/chrome/browser/chromeos/fileapi/file_system_backend.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend.cc
@@ -440,10 +440,9 @@
           url, offset, context);
     case storage::kFileSystemTypeNativeLocal:
     case storage::kFileSystemTypeDriveFs:
-      return std::unique_ptr<storage::FileStreamWriter>(
-          storage::FileStreamWriter::CreateForLocalFile(
-              context->default_file_task_runner(), url.path(), offset,
-              storage::FileStreamWriter::OPEN_EXISTING_FILE));
+      return storage::FileStreamWriter::CreateForLocalFile(
+          context->default_file_task_runner(), url.path(), offset,
+          storage::FileStreamWriter::OPEN_EXISTING_FILE);
     case storage::kFileSystemTypeDeviceMediaAsFileStorage:
       return mtp_delegate_->CreateFileStreamWriter(url, offset, context);
     // Read only file systems.
diff --git a/chrome/browser/conflicts/inspection_results_cache_win.cc b/chrome/browser/conflicts/inspection_results_cache_win.cc
new file mode 100644
index 0000000..312d331
--- /dev/null
+++ b/chrome/browser/conflicts/inspection_results_cache_win.cc
@@ -0,0 +1,237 @@
+// 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/conflicts/inspection_results_cache_win.h"
+
+#include <algorithm>
+#include <string>
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/md5.h"
+#include "base/pickle.h"
+
+namespace {
+
+// The current version of the cache format. Must be incremented every time the
+// format changes.
+constexpr int kVersion = 1;
+
+// Serializes a [ModuleInfoKey, ModuleInspectionResult, time stamp] tuple into
+// |pickle|. The |time_stamp| represents the last time this specific inspection
+// result was used, and was calculated using CalculateTimeStamp().
+void SerializeInspectionResult(const ModuleInfoKey& module_key,
+                               const ModuleInspectionResult& inspection_result,
+                               uint32_t time_stamp,
+                               base::Pickle* pickle) {
+  // ModuleInfoKey:
+  module_key.module_path.WriteToPickle(pickle);
+  pickle->WriteUInt32(module_key.module_size);
+  pickle->WriteUInt32(module_key.module_time_date_stamp);
+
+  // ModuleInspectionResult:
+  pickle->WriteString16(inspection_result.location);
+  pickle->WriteString16(inspection_result.basename);
+  pickle->WriteString16(inspection_result.product_name);
+  pickle->WriteString16(inspection_result.description);
+  pickle->WriteString16(inspection_result.version);
+  pickle->WriteInt(static_cast<int>(inspection_result.certificate_info.type));
+  inspection_result.certificate_info.path.WriteToPickle(pickle);
+  pickle->WriteString16(inspection_result.certificate_info.subject);
+
+  // Time stamp:
+  pickle->WriteUInt32(time_stamp);
+}
+
+// Deserializes a [ModuleInfoKey, ModuleInspectionResult] pair into |result| by
+// reading from |pickle_iterator|. Skips pairs whose time stamp is older than
+// |min_time_stamp|. Returns true if |result| contains a valid inspection
+// result.
+bool DeserializeInspectionResult(uint32_t min_time_stamp,
+                                 base::PickleIterator* pickle_iterator,
+                                 InspectionResultsCache* result) {
+  DCHECK(pickle_iterator);
+  DCHECK(result);
+
+  // ModuleInfoKey:
+  base::FilePath module_path;
+  uint32_t module_size = 0;
+  uint32_t module_time_date_stamp = 0;
+  if (!module_path.ReadFromPickle(pickle_iterator) ||
+      !pickle_iterator->ReadUInt32(&module_size) ||
+      !pickle_iterator->ReadUInt32(&module_time_date_stamp)) {
+    return false;
+  }
+
+  std::pair<ModuleInfoKey, std::pair<ModuleInspectionResult, uint32_t>> value(
+      std::piecewise_construct,
+      std::forward_as_tuple(std::move(module_path), module_size,
+                            module_time_date_stamp),
+      std::forward_as_tuple());
+
+  // ModuleInspectionResult and time stamp:
+  ModuleInspectionResult& inspection_result = value.second.first;
+  uint32_t& time_stamp = value.second.second;
+
+  if (!pickle_iterator->ReadString16(&inspection_result.location) ||
+      !pickle_iterator->ReadString16(&inspection_result.basename) ||
+      !pickle_iterator->ReadString16(&inspection_result.product_name) ||
+      !pickle_iterator->ReadString16(&inspection_result.description) ||
+      !pickle_iterator->ReadString16(&inspection_result.version) ||
+      !pickle_iterator->ReadInt(
+          reinterpret_cast<int*>(&inspection_result.certificate_info.type)) ||
+      !inspection_result.certificate_info.path.ReadFromPickle(
+          pickle_iterator) ||
+      !pickle_iterator->ReadString16(
+          &inspection_result.certificate_info.subject) ||
+      !pickle_iterator->ReadUInt32(&time_stamp)) {
+    return false;
+  }
+
+  // Only keep this element if it is not expired. An expired entry is not an
+  // error.
+  if (time_stamp >= min_time_stamp)
+    result->insert(std::move(value));
+
+  return true;
+}
+
+// Serializes an InspectionResultsCache into a base::Pickle. The serialized data
+// contains a version number and a MD5 checksum at the end.
+base::Pickle SerializeInspectionResultsCache(
+    const InspectionResultsCache& inspection_results_cache) {
+  base::Pickle pickle;
+
+  pickle.WriteInt(kVersion);
+  pickle.WriteUInt64(inspection_results_cache.size());
+
+  for (const auto& inspection_result : inspection_results_cache) {
+    SerializeInspectionResult(inspection_result.first,
+                              inspection_result.second.first,
+                              inspection_result.second.second, &pickle);
+  }
+
+  // Append the md5 digest of the data to detect serializations errors.
+  base::MD5Digest md5_digest;
+  base::MD5Sum(pickle.payload(), pickle.payload_size(), &md5_digest);
+  pickle.WriteBytes(&md5_digest, sizeof(md5_digest));
+
+  return pickle;
+}
+
+// Deserializes an InspectionResultsCache from |pickle|. This function ensures
+// that both the version and the checksum of the data are valid. Returns a
+// ReadCacheResult value indicating what failed if unsuccessful.
+ReadCacheResult DeserializeInspectionResultsCache(
+    uint32_t min_time_stamp,
+    const base::Pickle& pickle,
+    InspectionResultsCache* result) {
+  DCHECK(result);
+
+  base::PickleIterator pickle_iterator(pickle);
+
+  // Check the version number.
+  int version = 0;
+  if (!pickle_iterator.ReadInt(&version))
+    return ReadCacheResult::kFailDeserializeVersion;
+  if (version != kVersion)
+    return ReadCacheResult::kFailInvalidVersion;
+
+  // Retrieve the count of inspection results.
+  uint64_t inspection_result_count = 0;
+  if (!pickle_iterator.ReadUInt64(&inspection_result_count))
+    return ReadCacheResult::kFailDeserializeCount;
+  if (inspection_result_count < 0)
+    return ReadCacheResult::kFailInvalidCount;
+
+  // Now deserialize all the ModuleInspectionResults. Failure to deserialize one
+  // inspection result counts as an invalid cache.
+  for (uint64_t i = 0; i < inspection_result_count; i++) {
+    if (!DeserializeInspectionResult(min_time_stamp, &pickle_iterator, result))
+      return ReadCacheResult::kFailDeserializeInspectionResult;
+  }
+
+  // Now check the md5 checksum.
+  const base::MD5Digest* read_md5_digest = nullptr;
+  if (!pickle_iterator.ReadBytes(
+          reinterpret_cast<const char**>(&read_md5_digest),
+          sizeof(*read_md5_digest))) {
+    return ReadCacheResult::kFailDeserializeMD5;
+  }
+
+  // Check if the md5 checksum matches.
+  base::MD5Digest md5_digest;
+  base::MD5Sum(pickle.payload(), pickle.payload_size() - sizeof(md5_digest),
+               &md5_digest);
+  if (!std::equal(std::begin(read_md5_digest->a), std::end(read_md5_digest->a),
+                  std::begin(md5_digest.a), std::end(md5_digest.a)))
+    return ReadCacheResult::kFailInvalidMD5;
+
+  return ReadCacheResult::kSuccess;
+}
+
+}  // namespace
+
+void AddInspectionResultToCache(
+    const ModuleInfoKey& module_key,
+    const ModuleInspectionResult& inspection_result,
+    InspectionResultsCache* inspection_results_cache) {
+  auto insert_result = inspection_results_cache->insert(std::make_pair(
+      module_key, std::make_pair(inspection_result,
+                                 CalculateTimeStamp(base::Time::Now()))));
+  // An insertion should always succeed because the user of this code never
+  // tries to insert an existing value.
+  DCHECK(insert_result.second);
+}
+
+base::Optional<ModuleInspectionResult> GetInspectionResultFromCache(
+    const ModuleInfoKey& module_key,
+    InspectionResultsCache* inspection_results_cache) {
+  base::Optional<ModuleInspectionResult> inspection_result;
+
+  auto it = inspection_results_cache->find(module_key);
+  if (it != inspection_results_cache->end()) {
+    // Update the time stamp.
+    it->second.second = CalculateTimeStamp(base::Time::Now());
+    inspection_result = it->second.first;
+  }
+
+  return inspection_result;
+}
+
+ReadCacheResult ReadInspectionResultsCache(
+    const base::FilePath& file_path,
+    uint32_t min_time_stamp,
+    InspectionResultsCache* inspection_results_cache) {
+  if (!base::FeatureList::IsEnabled(kInspectionResultsCache))
+    return ReadCacheResult::kSuccess;
+
+  std::string contents;
+  if (!ReadFileToString(file_path, &contents))
+    return ReadCacheResult::kFailReadFile;
+
+  base::Pickle pickle(contents.data(), contents.length());
+  InspectionResultsCache temporary_result;
+  ReadCacheResult read_result = DeserializeInspectionResultsCache(
+      min_time_stamp, pickle, &temporary_result);
+
+  // Only update the output cache when successful.
+  if (read_result == ReadCacheResult::kSuccess)
+    *inspection_results_cache = std::move(temporary_result);
+
+  return read_result;
+}
+
+bool WriteInspectionResultsCache(
+    const base::FilePath& file_path,
+    const InspectionResultsCache& inspection_results_cache) {
+  if (!base::FeatureList::IsEnabled(kInspectionResultsCache))
+    return true;
+
+  base::Pickle pickle =
+      SerializeInspectionResultsCache(inspection_results_cache);
+  return base::WriteFile(file_path, static_cast<const char*>(pickle.data()),
+                         pickle.size()) == static_cast<int>(pickle.size());
+}
diff --git a/chrome/browser/conflicts/inspection_results_cache_win.h b/chrome/browser/conflicts/inspection_results_cache_win.h
new file mode 100644
index 0000000..170cf05
--- /dev/null
+++ b/chrome/browser/conflicts/inspection_results_cache_win.h
@@ -0,0 +1,81 @@
+// 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_CONFLICTS_INSPECTION_RESULTS_CACHE_WIN_H_
+#define CHROME_BROWSER_CONFLICTS_INSPECTION_RESULTS_CACHE_WIN_H_
+
+#include <map>
+#include <utility>
+
+#include "base/feature_list.h"
+#include "base/optional.h"
+#include "chrome/browser/conflicts/module_info_win.h"
+
+namespace base {
+class FilePath;
+}
+
+// The possible result value when trying to read an existing inspection results
+// cache. These values are persisted to logs. Entries should not be renumbered
+// and numeric values should never be reused.
+enum class ReadCacheResult {
+  // A valid cache was successfully read.
+  kSuccess = 0,
+  // Failed to read the content of the file.
+  kFailReadFile = 1,
+  // Failed to deserialize the version number.
+  kFailDeserializeVersion = 2,
+  // The version of the cache was invalid.
+  kFailInvalidVersion = 3,
+  // Failed to deserialize the number of inspection results the cache contains.
+  kFailDeserializeCount = 4,
+  // A negative count was encountered.
+  kFailInvalidCount = 5,
+  // Failed to deserialize an inspection result.
+  kFailDeserializeInspectionResult = 6,
+  // Failed to deserialize the MD5 digest.
+  kFailDeserializeMD5 = 7,
+  // The cache was rejected because the MD5 digest did not match the content.
+  kFailInvalidMD5 = 8,
+  kMaxValue = kFailInvalidMD5
+};
+
+constexpr base::Feature kInspectionResultsCache{
+    "InspectionResultsCache", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// The InspectionResultsCache maps ModuleInfoKey to a ModuleInspectionResult.
+// The uint32_t is a time stamp that keep tracks of when the inspection result
+// was needed (i.e. It was queried using GetInspectionResultFromCache() or added
+// using AddInspectionResultToCache()) calculated by CalculateTimeStamp().
+using InspectionResultsCache =
+    std::map<ModuleInfoKey, std::pair<ModuleInspectionResult, uint32_t>>;
+
+// Helper function to add an inspection result to an existing cache.
+void AddInspectionResultToCache(
+    const ModuleInfoKey& module_key,
+    const ModuleInspectionResult& inspection_result,
+    InspectionResultsCache* inspection_results_cache);
+
+// Helper function to retrieve a ModuleInspectionResult from an existing cache.
+// Also updates the time stamp of the element found to base::Time::Now().
+// Returns base::nullopt if the cache does not contains an entry for
+// |module_key|.
+base::Optional<ModuleInspectionResult> GetInspectionResultFromCache(
+    const ModuleInfoKey& module_key,
+    InspectionResultsCache* inspection_results_cache);
+
+// Reads a serialized InspectionResultsCache from |file_path|. Returns a
+// ReadCacheResult value indicating what failed if unsuccessful.
+ReadCacheResult ReadInspectionResultsCache(
+    const base::FilePath& file_path,
+    uint32_t min_time_stamp,
+    InspectionResultsCache* inspection_results_cache);
+
+// Writes an InspectionResultsCache to disk at |file_path| location. Returns
+// false on failure.
+bool WriteInspectionResultsCache(
+    const base::FilePath& file_path,
+    const InspectionResultsCache& inspection_results_cache);
+
+#endif  // CHROME_BROWSER_CONFLICTS_INSPECTION_RESULTS_CACHE_WIN_H_
diff --git a/chrome/browser/conflicts/inspection_results_cache_win_unittest.cc b/chrome/browser/conflicts/inspection_results_cache_win_unittest.cc
new file mode 100644
index 0000000..d2afdd2
--- /dev/null
+++ b/chrome/browser/conflicts/inspection_results_cache_win_unittest.cc
@@ -0,0 +1,131 @@
+// 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/conflicts/inspection_results_cache_win.h"
+
+#include <memory>
+#include <tuple>
+#include <utility>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+ModuleInspectionResult CreateTestModuleInspectionResult() {
+  ModuleInspectionResult inspection_result;
+
+  inspection_result.location = L"location";
+  inspection_result.basename = L"basename";
+  inspection_result.product_name = L"product_name";
+  inspection_result.description = L"description";
+  inspection_result.version = L"version";
+  inspection_result.certificate_info.type =
+      CertificateInfo::Type::CERTIFICATE_IN_FILE;
+  inspection_result.certificate_info.path =
+      base::FilePath(L"certificate_info_path");
+  inspection_result.certificate_info.subject = L"certificate_info_subject";
+
+  return inspection_result;
+}
+
+bool InspectionResultsEqual(const ModuleInspectionResult& lhs,
+                            const ModuleInspectionResult& rhs) {
+  return std::tie(lhs.location, lhs.basename, lhs.product_name, lhs.description,
+                  lhs.version, lhs.certificate_info.type,
+                  lhs.certificate_info.path, lhs.certificate_info.subject) ==
+         std::tie(rhs.location, rhs.basename, rhs.product_name, rhs.description,
+                  rhs.version, rhs.certificate_info.type,
+                  rhs.certificate_info.path, rhs.certificate_info.subject);
+}
+
+}  // namespace
+
+class InspectionResultsCacheTest : public testing::Test {
+ public:
+  InspectionResultsCacheTest()
+      : scoped_task_environment_(
+            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
+
+  void SetUp() override {
+    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
+    scoped_feature_list_.InitAndEnableFeature(kInspectionResultsCache);
+  }
+
+  void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
+
+  base::FilePath GetCacheFilePath() {
+    return scoped_temp_dir_.GetPath().Append(L"cache.bin");
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+  base::ScopedTempDir scoped_temp_dir_;
+
+  DISALLOW_COPY_AND_ASSIGN(InspectionResultsCacheTest);
+};
+
+TEST_F(InspectionResultsCacheTest, ReadMissingCache) {
+  InspectionResultsCache read_inspection_results_cache;
+  EXPECT_EQ(ReadCacheResult::kFailReadFile,
+            ReadInspectionResultsCache(GetCacheFilePath(), 0,
+                                       &read_inspection_results_cache));
+}
+
+TEST_F(InspectionResultsCacheTest, WriteAndRead) {
+  ModuleInfoKey module_key(base::FilePath(L"file_path.exe"), 0x1234, 0xABCD);
+  ModuleInspectionResult inspection_result = CreateTestModuleInspectionResult();
+
+  InspectionResultsCache inspection_results_cache;
+  AddInspectionResultToCache(module_key, inspection_result,
+                             &inspection_results_cache);
+
+  EXPECT_TRUE(WriteInspectionResultsCache(GetCacheFilePath(),
+                                          inspection_results_cache));
+
+  // Now check that a cache read from the file is identical to the cache that
+  // was written.
+  InspectionResultsCache read_inspection_results_cache;
+  EXPECT_EQ(ReadCacheResult::kSuccess,
+            ReadInspectionResultsCache(GetCacheFilePath(), 0,
+                                       &read_inspection_results_cache));
+
+  auto read_inspection_result =
+      GetInspectionResultFromCache(module_key, &read_inspection_results_cache);
+  ASSERT_TRUE(read_inspection_result);
+  EXPECT_TRUE(
+      InspectionResultsEqual(inspection_result, *read_inspection_result));
+}
+
+TEST_F(InspectionResultsCacheTest, WriteAndReadExpired) {
+  ModuleInfoKey module_key(base::FilePath(L"file_path.exe"), 0x1234, 0xABCD);
+  ModuleInspectionResult inspection_result = CreateTestModuleInspectionResult();
+
+  InspectionResultsCache inspection_results_cache;
+  AddInspectionResultToCache(module_key, inspection_result,
+                             &inspection_results_cache);
+
+  EXPECT_TRUE(WriteInspectionResultsCache(GetCacheFilePath(),
+                                          inspection_results_cache));
+
+  // Now read the cache from disk with a minimum time stamp higher than
+  // base::Time::Now() and it should be empty because the only element it
+  // contains is expired.
+  InspectionResultsCache read_inspection_results_cache;
+  EXPECT_EQ(ReadCacheResult::kSuccess,
+            ReadInspectionResultsCache(
+                GetCacheFilePath(), CalculateTimeStamp(base::Time::Now()) + 1,
+                &read_inspection_results_cache));
+
+  EXPECT_TRUE(read_inspection_results_cache.empty());
+  auto read_inspection_result =
+      GetInspectionResultFromCache(module_key, &read_inspection_results_cache);
+  EXPECT_FALSE(read_inspection_result);
+}
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc
index 8e859d8..db1275c 100644
--- a/chrome/browser/conflicts/module_database_win.cc
+++ b/chrome/browser/conflicts/module_database_win.cc
@@ -76,6 +76,7 @@
       // base::Unretained().
       module_inspector_(base::Bind(&ModuleDatabase::OnModuleInspected,
                                    base::Unretained(this))) {
+  AddObserver(&module_inspector_);
   AddObserver(&third_party_metrics_);
 
 #if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/conflicts/module_info_win.cc b/chrome/browser/conflicts/module_info_win.cc
index 26615724..7189310 100644
--- a/chrome/browser/conflicts/module_info_win.cc
+++ b/chrome/browser/conflicts/module_info_win.cc
@@ -77,10 +77,14 @@
 ModuleInspectionResult::ModuleInspectionResult() = default;
 
 ModuleInspectionResult::ModuleInspectionResult(
-    ModuleInspectionResult&& other) noexcept = default;
+    const ModuleInspectionResult& other) = default;
+ModuleInspectionResult::ModuleInspectionResult(ModuleInspectionResult&& other) =
+    default;
 
 ModuleInspectionResult& ModuleInspectionResult::operator=(
-    ModuleInspectionResult&& other) noexcept = default;
+    const ModuleInspectionResult& other) = default;
+ModuleInspectionResult& ModuleInspectionResult::operator=(
+    ModuleInspectionResult&& other) = default;
 
 ModuleInspectionResult::~ModuleInspectionResult() = default;
 
@@ -103,6 +107,14 @@
   return inspection_result;
 }
 
+// Returns the time stamp to be used in the inspection results cache.
+// Represents the number of hours between |time| and the Windows epoch
+// (1601-01-01 00:00:00 UTC).
+uint32_t CalculateTimeStamp(base::Time time) {
+  const auto delta = time.ToDeltaSinceWindowsEpoch();
+  return delta < base::TimeDelta() ? 0 : static_cast<uint32_t>(delta.InHours());
+}
+
 std::string GenerateCodeId(const ModuleInfoKey& module_key) {
   return base::StringPrintf("%08X%x", module_key.module_time_date_stamp,
                             module_key.module_size);
diff --git a/chrome/browser/conflicts/module_info_win.h b/chrome/browser/conflicts/module_info_win.h
index 146cbae..98ab823 100644
--- a/chrome/browser/conflicts/module_info_win.h
+++ b/chrome/browser/conflicts/module_info_win.h
@@ -10,6 +10,7 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/optional.h"
+#include "base/time/time.h"
 #include "chrome/browser/conflicts/module_info_util_win.h"
 
 // ModuleInfoKey and ModuleInfoData are used in pair by the ModuleDatabase to
@@ -41,11 +42,17 @@
 // information is expensive to gather and requires disk access, it should be
 // collected via InspectModule() on a task runner that allow blocking.
 //
-// This struct is move-only to ensure it is not unnecessarily copied.
+// Note: Any modification to this structure should be reflected in
+//       SerializeInspectionResult() and DeserializeInspectionResult() in
+//       chrome/browser/conflicts/inspection_results_cache_win.cc.
 struct ModuleInspectionResult {
   ModuleInspectionResult();
-  ModuleInspectionResult(ModuleInspectionResult&& other) noexcept;
-  ModuleInspectionResult& operator=(ModuleInspectionResult&& other) noexcept;
+  ModuleInspectionResult(const ModuleInspectionResult& other);
+  ModuleInspectionResult(ModuleInspectionResult&& other);
+
+  ModuleInspectionResult& operator=(const ModuleInspectionResult& other);
+  ModuleInspectionResult& operator=(ModuleInspectionResult&& other);
+
   ~ModuleInspectionResult();
 
   // The lowercase module path, not including the basename.
@@ -66,9 +73,6 @@
 
   // The certificate info for the module.
   CertificateInfo certificate_info;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ModuleInspectionResult);
 };
 
 // Contains the inspection result of a module and additional information that is
@@ -112,6 +116,11 @@
 // disk. This is a blocking task that requires access to disk.
 ModuleInspectionResult InspectModule(const base::FilePath& module_path);
 
+// Returns the date stamp to be used in the inspection results cache.
+// Represents the number of hours between |time| and the Windows epoch
+// (1601-01-01 00:00:00 UTC).
+uint32_t CalculateTimeStamp(base::Time time);
+
 // Generate the code id of a module.
 std::string GenerateCodeId(const ModuleInfoKey& module_key);
 
diff --git a/chrome/browser/conflicts/module_inspector_win.cc b/chrome/browser/conflicts/module_inspector_win.cc
index a3f8fd6..0adab09 100644
--- a/chrome/browser/conflicts/module_inspector_win.cc
+++ b/chrome/browser/conflicts/module_inspector_win.cc
@@ -7,13 +7,15 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
+#include "base/path_service.h"
 #include "base/task/post_task.h"
 #include "base/task_runner_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
 #include "chrome/browser/after_startup_task_utils.h"
 #include "chrome/browser/conflicts/module_info_util_win.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/services/util_win/public/mojom/constants.mojom.h"
 #include "content/public/common/service_manager_connection.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -23,6 +25,10 @@
 constexpr base::Feature kWinOOPInspectModuleFeature = {
     "WinOOPInspectModule", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// The maximum amount of time a stale entry is kept in the cache before it is
+// deleted.
+constexpr base::TimeDelta kMaxEntryAge = base::TimeDelta::FromDays(30);
+
 constexpr int kConnectionErrorRetryCount = 10;
 
 StringMapping GetPathMapping() {
@@ -51,17 +57,59 @@
   base::UmaHistogramBoolean("Windows.InspectModule.ConnectionError", value);
 }
 
+base::FilePath GetInspectionResultsCachePath() {
+  base::FilePath user_data_dir;
+  if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
+    return base::FilePath();
+
+  return user_data_dir.Append(L"Module Info Cache");
+}
+
+// Reads the inspection results cache and records the result in UMA.
+InspectionResultsCache ReadInspectionResultsCacheOnBackgroundSequence(
+    const base::FilePath& file_path) {
+  InspectionResultsCache inspection_results_cache;
+
+  uint32_t min_time_stamp =
+      CalculateTimeStamp(base::Time::Now() - kMaxEntryAge);
+  ReadCacheResult read_result = ReadInspectionResultsCache(
+      file_path, min_time_stamp, &inspection_results_cache);
+  base::UmaHistogramEnumeration("Windows.ModuleInspector.ReadCacheResult",
+                                read_result);
+
+  return inspection_results_cache;
+}
+
+// Writes the inspection results cache to disk and records the result in UMA.
+void WriteInspectionResultCacheOnBackgroundSequence(
+    const base::FilePath& file_path,
+    const InspectionResultsCache& inspection_results_cache) {
+  bool succeeded =
+      WriteInspectionResultsCache(file_path, inspection_results_cache);
+  base::UmaHistogramBoolean("Windows.ModuleInspector.WriteCacheResult",
+                            succeeded);
+}
+
 }  // namespace
 
+// static
+constexpr base::Feature ModuleInspector::kEnableBackgroundModuleInspection;
+
 ModuleInspector::ModuleInspector(
     const OnModuleInspectedCallback& on_module_inspected_callback)
     : on_module_inspected_callback_(on_module_inspected_callback),
       is_after_startup_(false),
-      task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+      inspection_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
            base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
       path_mapping_(GetPathMapping()),
+      cache_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
+      inspection_results_cache_read_(false),
       connection_error_retry_count_(kConnectionErrorRetryCount),
+      background_inspection_enabled_(
+          base::FeatureList::IsEnabled(kEnableBackgroundModuleInspection)),
       weak_ptr_factory_(this) {
   // Use AfterStartupTaskUtils to be notified when startup is finished.
   AfterStartupTaskUtils::PostTask(
@@ -81,7 +129,7 @@
 
   // If the queue was empty before adding the current module, then the
   // inspection must be started.
-  if (is_after_startup_ && was_queue_empty)
+  if (inspection_results_cache_read_ && was_queue_empty)
     StartInspectingModule();
 }
 
@@ -89,18 +137,34 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Create a task runner with higher priority so that future inspections are
   // done faster.
-  task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+  inspection_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
       {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
        base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
 
   // Assume startup is finished to immediately begin inspecting modules.
   OnStartupFinished();
+
+  // Special case where this instance could be ready to start inspecting but
+  // wasn't because the background inspection feature was disabled.
+  if (!background_inspection_enabled_ && inspection_results_cache_read_ &&
+      !queue_.empty()) {
+    background_inspection_enabled_ = true;
+    StartInspectingModule();
+  }
 }
 
 bool ModuleInspector::IsIdle() {
   return queue_.empty();
 }
 
+void ModuleInspector::OnModuleDatabaseIdle() {
+  // Serialize cache.
+  cache_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&WriteInspectionResultCacheOnBackgroundSequence,
+                                GetInspectionResultsCachePath(),
+                                inspection_results_cache_));
+}
+
 void ModuleInspector::OnStartupFinished() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -111,6 +175,23 @@
 
   is_after_startup_ = true;
 
+  // Read the inspection cache now that it won't affect startup.
+  base::PostTaskAndReplyWithResult(
+      cache_task_runner_.get(), FROM_HERE,
+      base::BindOnce(&ReadInspectionResultsCacheOnBackgroundSequence,
+                     GetInspectionResultsCachePath()),
+      base::BindOnce(&ModuleInspector::OnInspectionResultsCacheRead,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ModuleInspector::OnInspectionResultsCacheRead(
+    InspectionResultsCache inspection_results_cache) {
+  DCHECK(is_after_startup_);
+  DCHECK(!inspection_results_cache_read_);
+
+  inspection_results_cache_read_ = true;
+  inspection_results_cache_ = std::move(inspection_results_cache);
+
   if (!queue_.empty())
     StartInspectingModule();
 }
@@ -130,11 +211,26 @@
 }
 
 void ModuleInspector::StartInspectingModule() {
-  DCHECK(is_after_startup_);
+  DCHECK(inspection_results_cache_read_);
   DCHECK(!queue_.empty());
 
+  if (!background_inspection_enabled_)
+    return;
+
   const ModuleInfoKey& module_key = queue_.front();
 
+  // First check if the cache already contains the inspection result.
+  auto inspection_result =
+      GetInspectionResultFromCache(module_key, &inspection_results_cache_);
+  if (inspection_result) {
+    // Send asynchronously or this might cause a stack overflow.
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(&ModuleInspector::OnInspectionFinished,
+                                  weak_ptr_factory_.GetWeakPtr(), module_key,
+                                  std::move(*inspection_result)));
+    return;
+  }
+
   // There is a small priority inversion that happens when
   // IncreaseInspectionPriority() is called while a module is currently being
   // inspected.
@@ -157,18 +253,18 @@
 
     util_win_ptr_->InspectModule(
         module_key.module_path,
-        base::BindOnce(&ModuleInspector::OnInspectionFinished,
+        base::BindOnce(&ModuleInspector::OnModuleNewlyInspected,
                        weak_ptr_factory_.GetWeakPtr(), module_key));
   } else {
     base::PostTaskAndReplyWithResult(
-        task_runner_.get(), FROM_HERE,
+        inspection_task_runner_.get(), FROM_HERE,
         base::BindOnce(&InspectModule, module_key.module_path),
-        base::BindOnce(&ModuleInspector::OnInspectionFinished,
+        base::BindOnce(&ModuleInspector::OnModuleNewlyInspected,
                        weak_ptr_factory_.GetWeakPtr(), module_key));
   }
 }
 
-void ModuleInspector::OnInspectionFinished(
+void ModuleInspector::OnModuleNewlyInspected(
     const ModuleInfoKey& module_key,
     ModuleInspectionResult inspection_result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -178,6 +274,17 @@
   // easily comparable.
   CollapseMatchingPrefixInPath(path_mapping_, &inspection_result.location);
 
+  AddInspectionResultToCache(module_key, inspection_result,
+                             &inspection_results_cache_);
+
+  OnInspectionFinished(module_key, std::move(inspection_result));
+}
+
+void ModuleInspector::OnInspectionFinished(
+    const ModuleInfoKey& module_key,
+    ModuleInspectionResult inspection_result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   // Pop first, because the callback may want to know if there is any work left
   // to be done, which is caracterized by a non-empty queue.
   queue_.pop();
diff --git a/chrome/browser/conflicts/module_inspector_win.h b/chrome/browser/conflicts/module_inspector_win.h
index 8e702fc..73637be 100644
--- a/chrome/browser/conflicts/module_inspector_win.h
+++ b/chrome/browser/conflicts/module_inspector_win.h
@@ -5,13 +5,18 @@
 #ifndef CHROME_BROWSER_CONFLICTS_MODULE_INSPECTOR_WIN_H_
 #define CHROME_BROWSER_CONFLICTS_MODULE_INSPECTOR_WIN_H_
 
+#include <map>
+
 #include "base/callback.h"
 #include "base/containers/queue.h"
+#include "base/feature_list.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/task/task_traits.h"
+#include "chrome/browser/conflicts/inspection_results_cache_win.h"
+#include "chrome/browser/conflicts/module_database_observer_win.h"
 #include "chrome/browser/conflicts/module_info_win.h"
 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
 
@@ -29,15 +34,22 @@
 // IncreaseInspectionPriority().
 //
 // This class is not thread safe and it enforces safety via a SEQUENCE_CHECKER.
-class ModuleInspector {
+class ModuleInspector : public ModuleDatabaseObserver {
  public:
+  // Temporary feature to control whether or not modules are inspected in a
+  // background sequence. It will be used to assess the impact of this work on
+  // Chrome's overall performance.
+  // TODO(pmonette): Remove when no longer needed. See https://crbug.com/928846.
+  static constexpr base::Feature kEnableBackgroundModuleInspection = {
+      "EnableBackgroundModuleInspection", base::FEATURE_ENABLED_BY_DEFAULT};
+
   using OnModuleInspectedCallback =
       base::Callback<void(const ModuleInfoKey& module_key,
                           ModuleInspectionResult inspection_result)>;
 
   explicit ModuleInspector(
       const OnModuleInspectedCallback& on_module_inspected_callback);
-  ~ModuleInspector();
+  ~ModuleInspector() override;
 
   // Adds the module to the queue of modules to inspect. Starts the inspection
   // process if the |queue_| is empty.
@@ -49,17 +61,29 @@
   // Returns true if ModuleInspector is not doing anything right now.
   bool IsIdle();
 
+  // ModuleDatabaseObserver:
+  void OnModuleDatabaseIdle() override;
+
  private:
   // Invoked when Chrome has finished starting up to initiate the inspection of
   // queued modules.
   void OnStartupFinished();
 
+  // Invoked when the InspectionResultsCache is available.
+  void OnInspectionResultsCacheRead(
+      InspectionResultsCache inspection_results_cache);
+
   // Handles a connection error to the UtilWin service.
   void OnUtilWinServiceConnectionError();
 
   // Starts inspecting the module at the front of the queue.
   void StartInspectingModule();
 
+  // Adds the newly inspected module to the cache then calls
+  // OnInspectionFinished().
+  void OnModuleNewlyInspected(const ModuleInfoKey& module_key,
+                              ModuleInspectionResult inspection_result);
+
   // Called back on the execution context on which the ModuleInspector was
   // created when a module has finished being inspected. The callback will be
   // executed and, if the |queue_| is not empty, the next module will be sent
@@ -84,18 +108,33 @@
   // The task runner where module inspections takes place. It originally starts
   // at BEST_EFFORT priority, but is changed to USER_VISIBLE when
   // IncreaseInspectionPriority() is called.
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> inspection_task_runner_;
 
   // The vector of paths to %env_var%, used to account for differences in
   // localization and where people keep their files.
   // e.g. c:\windows vs d:\windows
   StringMapping path_mapping_;
 
+  // This task runner handles updates to the inspection results cache.
+  scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
+
+  // Indicates if the inspection results cache was read from disk.
+  bool inspection_results_cache_read_;
+
+  // Contains the cached inspection results so that a module is not inspected
+  // more than once between restarts.
+  InspectionResultsCache inspection_results_cache_;
+
   // The number of time this class will try to restart the UtilWin service if a
   // connection error occurs. This is to prevent the degenerate case where the
   // service always fails to start and the restart cycle happens infinitely.
   int connection_error_retry_count_;
 
+  // Indicates if background inspection is enabled. Generally equal to the
+  // kBackgroundModuleInspection feature state, but will be set unconditionally
+  // to true if IncreaseInspectionPriority() is called.
+  bool background_inspection_enabled_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Weak pointers are used to safely post the inspection result back to the
diff --git a/chrome/browser/conflicts/module_inspector_win_unittest.cc b/chrome/browser/conflicts/module_inspector_win_unittest.cc
index 021f4c9..59fbeaa 100644
--- a/chrome/browser/conflicts/module_inspector_win_unittest.cc
+++ b/chrome/browser/conflicts/module_inspector_win_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -30,15 +31,8 @@
 }
 
 class ModuleInspectorTest : public testing::Test {
- protected:
-  ModuleInspectorTest()
-      : module_inspector_(base::Bind(&ModuleInspectorTest::OnModuleInspected,
-                                     base::Unretained(this))) {}
-
-  void AddModules(const std::vector<ModuleInfoKey>& modules) {
-    for (const auto& module : modules)
-      module_inspector_.AddModule(module);
-  }
+ public:
+  ModuleInspectorTest() = default;
 
   // Callback for ModuleInspector.
   void OnModuleInspected(const ModuleInfoKey& module_key,
@@ -46,11 +40,12 @@
     inspected_modules_.push_back(std::move(inspection_result));
   }
 
+  void RunUntilIdle() { test_browser_thread_bundle_.RunUntilIdle(); }
+
   const std::vector<ModuleInspectionResult>& inspected_modules() {
     return inspected_modules_;
   }
 
- protected:
   // A TestBrowserThreadBundle is required instead of a ScopedTaskEnvironment
   // because of AfterStartupTaskUtils (DCHECK for BrowserThread::UI).
   //
@@ -58,8 +53,6 @@
   content::TestBrowserThreadBundle test_browser_thread_bundle_;
 
  private:
-  ModuleInspector module_inspector_;
-
   std::vector<ModuleInspectionResult> inspected_modules_;
 
   DISALLOW_COPY_AND_ASSIGN(ModuleInspectorTest);
@@ -68,25 +61,59 @@
 }  // namespace
 
 TEST_F(ModuleInspectorTest, OneModule) {
-  AddModules({
-      {GetKernel32DllFilePath(), 0, 0},
-  });
+  ModuleInspector module_inspector(base::Bind(
+      &ModuleInspectorTest::OnModuleInspected, base::Unretained(this)));
 
-  test_browser_thread_bundle_.RunUntilIdle();
+  module_inspector.AddModule({GetKernel32DllFilePath(), 0, 0});
+
+  RunUntilIdle();
 
   ASSERT_EQ(1u, inspected_modules().size());
 }
 
 TEST_F(ModuleInspectorTest, MultipleModules) {
-  AddModules({
+  ModuleInfoKey kTestCases[] = {
+      {base::FilePath(), 0, 0}, {base::FilePath(), 0, 0},
+      {base::FilePath(), 0, 0}, {base::FilePath(), 0, 0},
       {base::FilePath(), 0, 0},
-      {base::FilePath(), 0, 0},
-      {base::FilePath(), 0, 0},
-      {base::FilePath(), 0, 0},
-      {base::FilePath(), 0, 0},
-  });
+  };
 
-  test_browser_thread_bundle_.RunUntilIdle();
+  ModuleInspector module_inspector(base::Bind(
+      &ModuleInspectorTest::OnModuleInspected, base::Unretained(this)));
+
+  for (const auto& module : kTestCases)
+    module_inspector.AddModule(module);
+
+  RunUntilIdle();
 
   EXPECT_EQ(5u, inspected_modules().size());
 }
+
+TEST_F(ModuleInspectorTest, DisableBackgroundInspection) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(
+      ModuleInspector::kEnableBackgroundModuleInspection);
+
+  ModuleInfoKey kTestCases[] = {
+      {base::FilePath(), 0, 0},
+      {base::FilePath(), 0, 0},
+  };
+
+  ModuleInspector module_inspector(base::Bind(
+      &ModuleInspectorTest::OnModuleInspected, base::Unretained(this)));
+
+  for (const auto& module : kTestCases)
+    module_inspector.AddModule(module);
+
+  RunUntilIdle();
+
+  // No inspected modules yet.
+  EXPECT_EQ(0u, inspected_modules().size());
+
+  // Increasing inspection priority will start the background inspection
+  // process.
+  module_inspector.IncreaseInspectionPriority();
+  RunUntilIdle();
+
+  EXPECT_EQ(2u, inspected_modules().size());
+}
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.cc b/chrome/browser/extensions/scripting_permissions_modifier.cc
index b136fa8..a6c1bd7 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier.cc
@@ -134,6 +134,77 @@
       std::make_unique<base::Value>(permissions_allowed));
 }
 
+// Retrieves the effective list of runtime-granted permissions for a given
+// |extension| from the |prefs|. ExtensionPrefs doesn't store the valid schemes
+// for URLPatterns, which results in the chrome:-scheme being included for
+// <all_urls> when retrieving it directly from the prefs; this then causes
+// CHECKs to fail when validating that permissions being revoked are present
+// (see https://crbug.com/930062).
+// Returns null if there are no stored runtime-granted permissions.
+// TODO(https://crbug.com/931881): ExtensionPrefs should return properly-bounded
+// permissions.
+std::unique_ptr<const PermissionSet> GetRuntimePermissionsFromPrefs(
+    const Extension& extension,
+    const ExtensionPrefs& prefs) {
+  std::unique_ptr<const PermissionSet> permissions =
+      prefs.GetRuntimeGrantedPermissions(extension.id());
+
+  // If there are no stored permissions, there's nothing to adjust.
+  if (!permissions)
+    return nullptr;
+
+  // If the extension is allowed to run on chrome:// URLs, then we don't have
+  // to adjust anything.
+  if (PermissionsData::AllUrlsIncludesChromeUrls(extension.id()))
+    return permissions;
+
+  // We need to adjust a pattern if it matches all URLs and includes the
+  // chrome:-scheme. These patterns would otherwise match hosts like
+  // chrome://settings, which should not be allowed.
+  // NOTE: We don't need to adjust for the file scheme, because
+  // ExtensionPrefs properly does that based on the extension's file access.
+  auto needs_chrome_scheme_adjustment = [](const URLPattern& pattern) {
+    return pattern.match_all_urls() &&
+           ((pattern.valid_schemes() & URLPattern::SCHEME_CHROMEUI) != 0);
+  };
+
+  // NOTE: We don't need to check scriptable_hosts, because the default
+  // scriptable_hosts scheme mask omits the chrome:-scheme in normal
+  // circumstances (whereas the default explicit scheme does not, in order to
+  // allow for patterns like chrome://favicon).
+
+  bool needs_adjustment = std::any_of(permissions->explicit_hosts().begin(),
+                                      permissions->explicit_hosts().end(),
+                                      needs_chrome_scheme_adjustment);
+  // If no patterns need adjustment, return the original set.
+  if (!needs_adjustment)
+    return permissions;
+
+  // Otherwise, iterate over the explicit hosts, and modify any that need to be
+  // tweaked, adding back in permitted chrome:-scheme hosts. This logic mirrors
+  // that in PermissionsParser, and is also similar to logic in
+  // permissions_api_helpers::UnpackOriginPermissions(), and has some overlap
+  // to URLPatternSet::Populate().
+  // TODO(devlin): ^^ Ouch. Refactor so that this isn't duplicated.
+  URLPatternSet new_explicit_hosts;
+  for (const auto& pattern : permissions->explicit_hosts()) {
+    if (!needs_chrome_scheme_adjustment(pattern)) {
+      new_explicit_hosts.AddPattern(pattern);
+      continue;
+    }
+
+    URLPattern new_pattern(pattern);
+    int new_valid_schemes =
+        pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI;
+    new_pattern.SetValidSchemes(new_valid_schemes);
+    new_explicit_hosts.AddPattern(std::move(new_pattern));
+  }
+
+  return std::make_unique<PermissionSet>(
+      permissions->apis().Clone(), permissions->manifest_permissions().Clone(),
+      std::move(new_explicit_hosts), permissions->scriptable_hosts());
+}
+
 }  // namespace
 
 ScriptingPermissionsModifier::ScriptingPermissionsModifier(
@@ -214,7 +285,7 @@
     // silently granted them) at any time.
     granted_permissions = &extension_->permissions_data()->active_permissions();
   } else {
-    permission_holder = prefs->GetRuntimeGrantedPermissions(extension_->id());
+    permission_holder = GetRuntimePermissionsFromPrefs(*extension_, *prefs);
     granted_permissions = permission_holder.get();
   }
 
@@ -285,7 +356,7 @@
     const GURL& url) const {
   DCHECK(CanAffectExtension());
 
-  return extension_prefs_->GetRuntimeGrantedPermissions(extension_->id())
+  return GetRuntimePermissionsFromPrefs(*extension_, *extension_prefs_)
       ->effective_hosts()
       .MatchesSecurityOrigin(url);
 }
@@ -297,7 +368,7 @@
 
   ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
   std::unique_ptr<const PermissionSet> runtime_permissions =
-      prefs->GetRuntimeGrantedPermissions(extension_->id());
+      GetRuntimePermissionsFromPrefs(*extension_, *prefs);
 
   URLPatternSet explicit_hosts;
   for (const auto& pattern : runtime_permissions->explicit_hosts()) {
@@ -346,7 +417,7 @@
   // runtime through the runtime host permissions feature or the optional
   // permissions API.
   std::unique_ptr<const PermissionSet> runtime_granted_permissions =
-      extension_prefs.GetRuntimeGrantedPermissions(extension.id());
+      GetRuntimePermissionsFromPrefs(extension, extension_prefs);
   PartitionHostPermissions(permissions, *runtime_granted_permissions,
                            granted_permissions_out);
 }
@@ -367,7 +438,7 @@
   // host permissions.
   const PermissionSet* current_granted_permissions = nullptr;
   std::unique_ptr<const PermissionSet> runtime_granted_permissions =
-      extension_prefs_->GetRuntimeGrantedPermissions(extension_->id());
+      GetRuntimePermissionsFromPrefs(*extension_, *extension_prefs_);
   std::unique_ptr<const PermissionSet> union_set;
   if (runtime_granted_permissions) {
     union_set = PermissionSet::CreateUnion(
diff --git a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
index a46c793..7a95b465 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
@@ -22,6 +22,7 @@
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_features.h"
 #include "extensions/common/extensions_client.h"
+#include "extensions/common/manifest_handlers/permissions_parser.h"
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/url_pattern.h"
@@ -804,4 +805,35 @@
                   .is_empty());
 }
 
+// Test that granting <all_urls> as an optional permission, and then revoking
+// it, behaves properly. Regression test for https://crbug.com/930062.
+TEST_F(ScriptingPermissionsModifierUnitTest,
+       RemoveAllURLsGrantedOptionalPermission) {
+  RuntimeHostPermissionsForcedScope enabled_scope(true);
+  InitializeEmptyExtensionService();
+
+  scoped_refptr<const Extension> extension =
+      ExtensionBuilder("extension")
+          .SetManifestKey("optional_permissions",
+                          ListBuilder().Append("<all_urls>").Build())
+          .Build();
+  InitializeExtensionPermissions(profile(), *extension);
+
+  // Also verify the extension doesn't have file access, so that <all_urls>
+  // shouldn't match file URLs either.
+  EXPECT_FALSE(util::AllowFileAccess(extension->id(), profile()));
+
+  {
+    PermissionsUpdater updater(profile());
+    updater.GrantOptionalPermissions(
+        *extension, PermissionsParser::GetOptionalPermissions(extension.get()),
+        base::DoNothing());
+  }
+
+  ScriptingPermissionsModifier(profile(), extension.get())
+      .SetWithholdHostPermissions(true);
+
+  EXPECT_THAT(GetEffectivePatternsAsStrings(*extension), testing::IsEmpty());
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 4876b35b..5796a493 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1378,11 +1378,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "enable-media-controls-expand-gesture",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "enable-media-session-service",
     "owners": [ "beccahughes", "media-dev" ],
     "expiry_milestone": 76
@@ -1398,11 +1393,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "enable-modern-media-controls",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "enable-myfiles-volume",
     "owners": [ "lucmult", "noel" ],
     "expiry_milestone": 76
@@ -1424,8 +1414,8 @@
   },
   {
     "name": "enable-navigation-tracing",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "tracing" ],
+    "expiry_milestone": 80
   },
   {
     "name": "enable-network-logging-to-file",
@@ -1553,11 +1543,6 @@
     "expiry_milestone": 76
   },
   {
-    "name": "enable-overflow-icons-for-media-controls",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "enable-parallel-downloading",
     // "owners": [ "your-team" ],
     "expiry_milestone": 76
@@ -1838,6 +1823,11 @@
     "expiry_milestone": 76
   },
   {
+    "name": "enable-tab-grid-layout",
+    "owners": [ "memex-team@google.com" ],
+    "expiry_milestone": 76
+  },
+  {
     "name": "enable-tab-switcher-on-return",
     "owners": [ "memex-team@google.com" ],
     "expiry_milestone": 76
@@ -2323,23 +2313,39 @@
   },
   {
     "name": "memlog",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "erikchen", "ssid", "etienneb", "alph" ],
+    // Memlog is Chrome's heap profiler. It is used for both automated and
+    // manual performance analysis. This flag allows a user or developer to
+    // capture a memlog without disturbing the situation under test by
+    // restarting to apply a switch. It should not be removed.
+    "expiry_milestone": -1
   },
   {
     "name": "memlog-keep-small-allocations",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "erikchen", "ssid", "etienneb", "alph" ],
+    // Memlog is Chrome's heap profiler. It is used for both automated and
+    // manual performance analysis. This flag allows a user or developer to
+    // capture a memlog without disturbing the situation under test by
+    // restarting to apply a switch. It should not be removed.
+    "expiry_milestone": -1
   },
   {
     "name": "memlog-sampling",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "erikchen", "ssid", "etienneb", "alph" ],
+    // Memlog is Chrome's heap profiler. It is used for both automated and
+    // manual performance analysis. This flag allows a user or developer to
+    // capture a memlog without disturbing the situation under test by
+    // restarting to apply a switch. It should not be removed.
+    "expiry_milestone": -1
   },
   {
     "name": "memlog-stack-mode",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "erikchen", "ssid", "etienneb", "alph" ],
+    // Memlog is Chrome's heap profiler. It is used for both automated and
+    // manual performance analysis. This flag allows a user or developer to
+    // capture a memlog without disturbing the situation under test by
+    // restarting to apply a switch. It should not be removed.
+    "expiry_milestone": -1
   },
   {
     "name": "memory-pressure-thresholds",
@@ -3001,8 +3007,8 @@
   },
   {
     "name": "trace-upload-url",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "tracing" ],
+    "expiry_milestone": 80
   },
   {
     "name": "translate-android-manual-trigger",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 0de0baf..e319c983 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1443,11 +1443,6 @@
 const char kOriginTrialsDescription[] =
     "Enables origin trials for controlling access to feature/API experiments.";
 
-const char kOverflowIconsForMediaControlsName[] =
-    "Icons on Media Controls Overflow Menu";
-const char kOverflowIconsForMediaControlsDescription[] =
-    "Displays icons on the overflow menu of the native media controls";
-
 const char kOverlayScrollbarsName[] = "Overlay Scrollbars";
 const char kOverlayScrollbarsDescription[] =
     "Enable the experimental overlay scrollbars implementation. You must also "
@@ -1860,6 +1855,10 @@
     "keyboard shortcuts and have the events routed directly to the website "
     "when in fullscreen mode.";
 
+const char kTabGridLayoutAndroidName[] = "Tab Grid Layout";
+const char kTabGridLayoutAndroidDescription[] =
+    "Allows users to see their tabs in a grid layout in the tab switcher.";
+
 const char kTabGroupsName[] = "Tab Groups";
 const char kTabGroupsDescription[] =
     "Allows users to organize tabs into visually distinct groups, e.g. to "
@@ -1971,10 +1970,6 @@
 const char kUseDdljsonApiDescription[] =
     "Enables the new ddljson API to fetch Doodles for the NTP.";
 
-const char kUseModernMediaControlsName[] = "New Media Controls";
-const char kUseModernMediaControlsDescription[] =
-    "Enables the new style native media controls.";
-
 const char kUsePdfCompositorServiceName[] =
     "Use PDF compositor service for printing";
 const char kUsePdfCompositorServiceDescription[] =
@@ -2351,12 +2346,6 @@
     "Enables a new context menu when a link, image, or video is pressed within "
     "Chrome.";
 
-const char kEnableMediaControlsExpandGestureName[] =
-    "Enable Media Controls Expand Gesture";
-const char kEnableMediaControlsExpandGestureDescription[] =
-    "Enables a gesture to be used on the media controls to extend the video "
-    "into the Display Cutout area.";
-
 const char kEnableOmniboxClipboardProviderName[] =
     "Omnibox clipboard URL suggestions";
 const char kEnableOmniboxClipboardProviderDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index f92ca09..f4110b9 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -867,9 +867,6 @@
 extern const char kOopRasterizationName[];
 extern const char kOopRasterizationDescription[];
 
-extern const char kOverflowIconsForMediaControlsName[];
-extern const char kOverflowIconsForMediaControlsDescription[];
-
 extern const char kOriginTrialsName[];
 extern const char kOriginTrialsDescription[];
 
@@ -1105,6 +1102,9 @@
 extern const char kSyncUSSAutofillWalletDataName[];
 extern const char kSyncUSSAutofillWalletDataDescription[];
 
+extern const char kTabGridLayoutAndroidName[];
+extern const char kTabGridLayoutAndroidDescription[];
+
 extern const char kTabGroupsName[];
 extern const char kTabGroupsDescription[];
 
@@ -1171,9 +1171,6 @@
 extern const char kUseDdljsonApiName[];
 extern const char kUseDdljsonApiDescription[];
 
-extern const char kUseModernMediaControlsName[];
-extern const char kUseModernMediaControlsDescription[];
-
 extern const char kUsePdfCompositorServiceName[];
 extern const char kUsePdfCompositorServiceDescription[];
 
@@ -1395,9 +1392,6 @@
 extern const char kEnableCustomContextMenuName[];
 extern const char kEnableCustomContextMenuDescription[];
 
-extern const char kEnableMediaControlsExpandGestureName[];
-extern const char kEnableMediaControlsExpandGestureDescription[];
-
 extern const char kEnableOmniboxClipboardProviderName[];
 extern const char kEnableOmniboxClipboardProviderDescription[];
 
diff --git a/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
index e98d7e9a..a2d3823 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_system_backend.cc
@@ -334,10 +334,9 @@
   }
 #endif
 
-  return std::unique_ptr<storage::FileStreamReader>(
-      storage::FileStreamReader::CreateForLocalFile(
-          context->default_file_task_runner(), url.path(), offset,
-          expected_modification_time));
+  return storage::FileStreamReader::CreateForLocalFile(
+      context->default_file_task_runner(), url.path(), offset,
+      expected_modification_time);
 }
 
 std::unique_ptr<storage::FileStreamWriter>
@@ -345,10 +344,9 @@
     const FileSystemURL& url,
     int64_t offset,
     FileSystemContext* context) const {
-  return std::unique_ptr<storage::FileStreamWriter>(
-      storage::FileStreamWriter::CreateForLocalFile(
-          context->default_file_task_runner(), url.path(), offset,
-          storage::FileStreamWriter::OPEN_EXISTING_FILE));
+  return storage::FileStreamWriter::CreateForLocalFile(
+      context->default_file_task_runner(), url.path(), offset,
+      storage::FileStreamWriter::OPEN_EXISTING_FILE);
 }
 
 storage::FileSystemQuotaUtil* MediaFileSystemBackend::GetQuotaUtil() {
diff --git a/chrome/browser/notifications/scheduler/OWNERS b/chrome/browser/notifications/scheduler/OWNERS
new file mode 100644
index 0000000..eae9c737
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/OWNERS
@@ -0,0 +1,2 @@
+dtrainor@chromium.org
+xingliu@chromium.org
\ No newline at end of file
diff --git a/chrome/browser/notifications/scheduler/notification_data.cc b/chrome/browser/notifications/scheduler/notification_data.cc
new file mode 100644
index 0000000..c2ef102
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/notification_data.cc
@@ -0,0 +1,17 @@
+// 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/notifications/scheduler/notification_data.h"
+
+#include "chrome/browser/notifications/scheduler/schedule_params.h"
+
+NotificationData::NotificationData(
+    Type type,
+    std::unique_ptr<message_center::Notification> notification,
+    std::unique_ptr<ScheduleParams> schedule_params)
+    : type_(type),
+      notification_(std::move(notification)),
+      schedule_params_(std::move(schedule_params)) {}
+
+NotificationData::~NotificationData() = default;
diff --git a/chrome/browser/notifications/scheduler/notification_data.h b/chrome/browser/notifications/scheduler/notification_data.h
new file mode 100644
index 0000000..6372ae1
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/notification_data.h
@@ -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.
+
+#ifndef CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_DATA_H_
+#define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_DATA_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "ui/message_center/public/cpp/notification.h"
+
+struct ScheduleParams;
+
+// Struct used to schedule a notification.
+class NotificationData {
+ public:
+  enum class Type {
+    PLACE_HOLDER,
+  };
+
+  NotificationData(Type type,
+                   std::unique_ptr<message_center::Notification> notification,
+                   std::unique_ptr<ScheduleParams> schedule_params);
+  ~NotificationData();
+
+  Type type() const { return type_; }
+
+ private:
+  Type type_;
+
+  // Notification data that the client can optionally choose to use when showing
+  // a notification. Client should only use this when the data is dynamically
+  // generated, such as URL to navigate when the user clicks the notification.
+  std::unique_ptr<message_center::Notification> notification_;
+
+  std::unique_ptr<ScheduleParams> schedule_params_;
+
+  DISALLOW_COPY_AND_ASSIGN(NotificationData);
+};
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_DATA_H_
diff --git a/chrome/browser/notifications/scheduler/schedule_params.cc b/chrome/browser/notifications/scheduler/schedule_params.cc
new file mode 100644
index 0000000..ec494ade
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/schedule_params.cc
@@ -0,0 +1,9 @@
+// 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/notifications/scheduler/schedule_params.h"
+
+ScheduleParams::ScheduleParams() = default;
+
+ScheduleParams::~ScheduleParams() = default;
diff --git a/chrome/browser/notifications/scheduler/schedule_params.h b/chrome/browser/notifications/scheduler/schedule_params.h
new file mode 100644
index 0000000..9c044c7
--- /dev/null
+++ b/chrome/browser/notifications/scheduler/schedule_params.h
@@ -0,0 +1,29 @@
+// 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_NOTIFICATIONS_SCHEDULER_SCHEDULE_PARAMS_H_
+#define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_SCHEDULE_PARAMS_H_
+
+// Specifies when to show the scheduled notification, and throttling details.
+struct ScheduleParams {
+  enum class Priority {
+    // No notification throttling logic is applied, every notification scheduled
+    // will be delivered.
+    NO_THROTTLE,
+    // Notification may be delivered if picked by display decision layer. Has
+    // higher chance to pick as the next notification to deliver than low
+    // priority.
+    HIGH,
+    // Notification may be delivered if picked by display decision layer. Most
+    // notification types should use this priority.
+    LOW,
+  };
+
+  ScheduleParams();
+  ~ScheduleParams();
+
+  Priority priority;
+};
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_SCHEDULE_PARAMS_H_
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc
index 52fe4e3..3ef580c9 100644
--- a/chrome/browser/previews/previews_lite_page_browsertest.cc
+++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -66,6 +66,7 @@
 #include "net/nqe/effective_connection_type.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
+#include "services/network/public/cpp/features.h"
 #include "services/network/test/test_network_quality_tracker.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
@@ -75,7 +76,9 @@
 const int kRedirectLoopCount = 3;
 }
 
-class PreviewsLitePageServerBrowserTest : public InProcessBrowserTest {
+class PreviewsLitePageServerBrowserTest
+    : public InProcessBrowserTest,
+      public testing::WithParamInterface<bool> {
  public:
   PreviewsLitePageServerBrowserTest() {}
 
@@ -230,6 +233,13 @@
          data_reduction_proxy::features::
              kDataReductionProxyEnabledWithNetworkService},
         {});
+
+    if (GetParam()) {
+      url_loader_feature_list_.InitWithFeatures(
+          {network::features::kNetworkService,
+           previews::features::kHTTPSServerPreviewsUsingURLLoader},
+          {});
+    }
   }
 
   void SetUpOnMainThread() override {
@@ -272,19 +282,22 @@
         PreviewsUITabHelper::FromWebContents(GetWebContents());
     previews::PreviewsUserData* previews_data =
         ui_tab_helper->previews_user_data();
-
-    EXPECT_TRUE(previews_data->server_lite_page_info());
-    EXPECT_EQ(previews_data->server_lite_page_info()->status, status);
-
+    if (!GetParam()) {
+      EXPECT_TRUE(previews_data->server_lite_page_info());
+      EXPECT_EQ(previews_data->server_lite_page_info()->status, status);
+    }
     // This UMA is not recorded for an unknown or control group status
     if (status == previews::ServerLitePageStatus::kUnknown ||
         status == previews::ServerLitePageStatus::kControl) {
       return;
     }
-    histogram_tester->ExpectTotalCount(
-        "Previews.ServerLitePage.Penalty." +
-            previews::ServerLitePageStatusToString(status),
-        1);
+
+    if (!GetParam()) {
+      histogram_tester->ExpectTotalCount(
+          "Previews.ServerLitePage.Penalty." +
+              previews::ServerLitePageStatusToString(status),
+          1);
+    }
   }
 
   void VerifyPreviewLoaded() const {
@@ -308,36 +321,41 @@
 
     const GURL loaded_url = GetLoadedURL();
     const GURL previews_host = previews_server();
-    EXPECT_TRUE(loaded_url.DomainIs(previews_host.host()) &&
-                loaded_url.EffectiveIntPort() ==
-                    previews_host.EffectiveIntPort());
+    EXPECT_TRUE(loaded_url.DomainIs(previews_host.host()));
+    EXPECT_EQ(loaded_url.EffectiveIntPort(), previews_host.EffectiveIntPort());
 
     content::NavigationEntry* entry =
         GetWebContents()->GetController().GetVisibleEntry();
 
-    // server_lite_page_info does not exist on forward/back navigations.
-    if (!(entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK)) {
-      EXPECT_TRUE(previews_data->server_lite_page_info());
-      EXPECT_NE(
-          previews_data->server_lite_page_info()->original_navigation_start,
-          base::TimeTicks());
-      EXPECT_NE(previews_data->server_lite_page_info()->page_id, 0U);
-      EXPECT_NE(previews_data->server_lite_page_info()->drp_session_key, "");
+    if (!GetParam()) {
+      // server_lite_page_info does not exist on forward/back navigations.
+      if (!(entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK)) {
+        EXPECT_TRUE(previews_data->server_lite_page_info());
+        EXPECT_NE(
+            previews_data->server_lite_page_info()->original_navigation_start,
+            base::TimeTicks());
+        EXPECT_NE(previews_data->server_lite_page_info()->page_id, 0U);
+        EXPECT_NE(previews_data->server_lite_page_info()->drp_session_key, "");
+      }
     }
 
     EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType());
     const GURL virtual_url = entry->GetVirtualURL();
 
-    // The loaded url should be the previews version of the virtual url.
-    EXPECT_EQ(
-        loaded_url,
-        PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(virtual_url));
+    if (!GetParam()) {
+      // The loaded url should be the previews version of the virtual url.
+      EXPECT_EQ(loaded_url,
+                PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(
+                    virtual_url));
+    }
 
     // The Virtual URL should not be on the previews server.
     // TODO(crbug.com/894854): Use a different hostname and check that here.
-    EXPECT_FALSE(virtual_url.DomainIs(previews_host.host()) &&
-                 virtual_url.EffectiveIntPort() ==
-                     previews_host.EffectiveIntPort());
+    if (!GetParam()) {
+      EXPECT_FALSE(virtual_url.DomainIs(previews_host.host()) &&
+                   virtual_url.EffectiveIntPort() ==
+                       previews_host.EffectiveIntPort());
+    }
   }
 
   void VerifyPreviewNotLoaded() const {
@@ -433,9 +451,9 @@
   GURL HttpLitePageURL(PreviewsServerAction action,
                        std::string* headers = nullptr,
                        int delay_ms = 0) const {
-    std::string query = "resp=" + base::NumberToString(action);
+    std::string query = "resp=" + base::IntToString(action);
     if (delay_ms != 0)
-      query += "&delay_ms=" + base::NumberToString(delay_ms);
+      query += "&delay_ms=" + base::IntToString(delay_ms);
     if (headers)
       query += "&headers=" + *headers;
     GURL::Replacements replacements;
@@ -696,6 +714,7 @@
 
   base::test::ScopedFeatureList scoped_parameterized_feature_list_;
   base::test::ScopedFeatureList scoped_feature_list_;
+  base::test::ScopedFeatureList url_loader_feature_list_;
   std::unique_ptr<net::EmbeddedTestServer> previews_server_;
   std::unique_ptr<net::EmbeddedTestServer> https_server_;
   std::unique_ptr<net::EmbeddedTestServer> http_server_;
@@ -714,6 +733,11 @@
   int subresources_requested_ = 0;
 };
 
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageServerBrowserTest,
+                        testing::Bool());
+
 // Previews InfoBar (which these tests trigger) does not work on Mac.
 // See https://crbug.com/782322 for detail.
 // Also occasional flakes on win7 (https://crbug.com/789542).
@@ -723,8 +747,10 @@
 #define DISABLE_ON_WIN_MAC(x) x
 #endif
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsTriggering)) {
+  if (GetParam())
+    return;
   // TODO(crbug.com/874150): Use ExpectUniqueSample in these tests.
   // The histograms in these tests can only be checked by the expected bucket,
   // and not by a unique sample. This is because each navigation to a preview
@@ -933,8 +959,10 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsReloadEnabled)) {
+  if (GetParam())
+    return;
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       {}, {previews::features::kPreviewsDisallowedOnReloads});
@@ -956,8 +984,10 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsReloadDisabled)) {
+  if (GetParam())
+    return;
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       {previews::features::kPreviewsDisallowedOnReloads}, {});
@@ -969,7 +999,7 @@
   VerifyPreviewNotLoaded();
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsLoadOriginal)) {
   base::HistogramTester histogram_tester;
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
@@ -981,8 +1011,10 @@
   VerifyPreviewNotLoaded();
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsRedirect)) {
+  if (GetParam())
+    return;
   {
     // Verify the preview is triggered when an HTTP page redirects to HTTPS.
     base::HistogramTester histogram_tester;
@@ -1042,8 +1074,10 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsResponse)) {
+  if (GetParam())
+    return;
   {
     // Verify the preview is not triggered when the server responds with bypass
     // 307.
@@ -1126,8 +1160,10 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsLoadshed)) {
+  if (GetParam())
+    return;
   PreviewsService* previews_service =
       PreviewsServiceFactory::GetForProfile(browser()->profile());
   ASSERT_TRUE(previews_service);
@@ -1171,8 +1207,10 @@
   VerifyPreviewLoaded();
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePageURLNotReportedToHistory)) {
+  if (GetParam())
+    return;
   base::CancelableTaskTracker tracker_;
   history::HistoryService* history_service =
       HistoryServiceFactory::GetForProfile(browser()->profile(),
@@ -1231,8 +1269,10 @@
   ClearDeciderState();
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsReportSavings)) {
+  if (GetParam())
+    return;
   PrefService* prefs = browser()->profile()->GetPrefs();
   prefs->SetBoolean(data_reduction_proxy::prefs::kDataUsageReportingEnabled,
                     true);
@@ -1252,8 +1292,10 @@
   EXPECT_EQ(GetDataUsage(), 20U);
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsClientRedirect)) {
+  if (GetParam())
+    return;
   // Navigate to a non-preview first.
   ui_test_utils::NavigateToURL(browser(), https_media_url());
   VerifyPreviewNotLoaded();
@@ -1266,8 +1308,10 @@
             https_media_url());
 }
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBrowserTest,
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsNavigation)) {
+  if (GetParam())
+    return;
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
   VerifyPreviewLoaded();
 
@@ -1307,8 +1351,15 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerTimeoutBrowserTest,
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageServerTimeoutBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerTimeoutBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsTimeout)) {
+  if (GetParam())
+    return;
   {
     // Ensure that a hung previews navigation doesn't wind up at the previews
     // server.
@@ -1348,8 +1399,15 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerBadServerBrowserTest,
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageServerBadServerBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerBadServerBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsBadServer)) {
+  if (GetParam())
+    return;
   // TODO(crbug.com/874150): Use ExpectUniqueSample in this tests.
   // The histograms in this tests can only be checked by the expected bucket,
   // and not by a unique sample. This is because each navigation to a preview
@@ -1395,8 +1453,15 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageServerDataSaverBrowserTest,
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageServerDataSaverBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageServerDataSaverBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsDSTriggering)) {
+  if (GetParam())
+    return;
   // Verify the preview is not triggered on HTTPS pageloads without DataSaver.
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
   VerifyPreviewNotLoaded();
@@ -1426,9 +1491,16 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageServerNoDataSaverHeaderBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(
     PreviewsLitePageServerNoDataSaverHeaderBrowserTest,
     DISABLE_ON_WIN_MAC(LitePagePreviewsDSNoHeaderTriggering)) {
+  if (GetParam())
+    return;
   // Verify the preview is not triggered on HTTPS pageloads without data saver.
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
   VerifyPreviewNotLoaded();
@@ -1457,9 +1529,16 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageNotificationDSEnabledBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(
     PreviewsLitePageNotificationDSEnabledBrowserTest,
     DISABLE_ON_WIN_MAC(LitePagePreviewsInfoBarDataSaverUser)) {
+  if (GetParam())
+    return;
   // Ensure the preview is not shown the first time before the infobar is shown
   // for users who have DRP enabled.
   base::HistogramTester histogram_tester;
@@ -1522,9 +1601,16 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageNotificationDSDisabledBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(
     PreviewsLitePageNotificationDSDisabledBrowserTest,
     DISABLE_ON_WIN_MAC(LitePagePreviewsInfoBarNonDataSaverUser)) {
+  if (GetParam())
+    return;
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
   VerifyPreviewNotLoaded();
   ClearDeciderState();
@@ -1545,8 +1631,15 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(PreviewsLitePageControlBrowserTest,
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageControlBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(PreviewsLitePageControlBrowserTest,
                        DISABLE_ON_WIN_MAC(LitePagePreviewsControlGroup)) {
+  if (GetParam())
+    return;
   base::HistogramTester histogram_tester;
   ui_test_utils::NavigateToURL(browser(), HttpsLitePageURL(kSuccess));
   VerifyPreviewNotLoaded();
@@ -1616,11 +1709,18 @@
       test_hints_component_creator_;
 };
 
-IN_PROC_BROWSER_TEST_F(
+// True if testing using the URLLoader Interceptor implementation.
+INSTANTIATE_TEST_CASE_P(URLLoaderImplementation,
+                        PreviewsLitePageAndPageHintsBrowserTest,
+                        testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(
     PreviewsLitePageAndPageHintsBrowserTest,
     DISABLE_ON_WIN_MAC(LitePagePreviewsDoesNotOverridePageHints)) {
   base::HistogramTester histogram_tester;
 
+  if (GetParam())
+    return;
   // Whitelist test URL for resource loading hints.
   GURL url = HttpsLitePageURL(kSuccess);
   SetResourceLoadingHints({url.host()});
diff --git a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
index 91b4192..c8eabbe 100644
--- a/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
+++ b/chrome/browser/previews/previews_lite_page_redirect_url_loader.cc
@@ -4,54 +4,162 @@
 
 #include "chrome/browser/previews/previews_lite_page_redirect_url_loader.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/previews/previews_lite_page_navigation_throttle.h"
+#include "components/previews/core/previews_lite_page_redirect.h"
 #include "content/public/common/previews_state.h"
+#include "net/http/http_status_code.h"
+#include "net/http/http_util.h"
+#include "net/url_request/redirect_util.h"
 #include "services/network/public/cpp/resource_request.h"
 
 namespace previews {
 
+namespace {
+// Used for mojo pipe size. Same constant as navigation code.
+constexpr size_t kRedirectDefaultAllocationSize = 512 * 1024;
+}  // namespace
+
 PreviewsLitePageRedirectURLLoader::PreviewsLitePageRedirectURLLoader(
     const network::ResourceRequest& tentative_resource_request,
     HandleRequest callback)
     : modified_resource_request_(tentative_resource_request),
       callback_(std::move(callback)),
+      binding_(this),
       weak_ptr_factory_(this) {}
 
 PreviewsLitePageRedirectURLLoader::~PreviewsLitePageRedirectURLLoader() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-std::unique_ptr<PreviewsLitePageRedirectURLLoader>
-PreviewsLitePageRedirectURLLoader::AttemptRedirectToPreview(
-    const network::ResourceRequest& tentative_resource_request,
-    HandleRequest callback) {
-  auto redirect_loader = base::WrapUnique(new PreviewsLitePageRedirectURLLoader(
-      tentative_resource_request, std::move(callback)));
-
-  redirect_loader->StartRedirectToPreview();
-
-  return redirect_loader;
-}
-
-void PreviewsLitePageRedirectURLLoader::StartRedirectToPreview() {
+void PreviewsLitePageRedirectURLLoader::StartRedirectToPreview(
+    const net::HttpRequestHeaders& chrome_proxy_headers,
+    const scoped_refptr<network::SharedURLLoaderFactory>&
+        network_loader_factory,
+    int frame_tree_node_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  modified_resource_request_.url =
-      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(
-          modified_resource_request_.url);
+
+  GURL lite_page_url = PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(
+      modified_resource_request_.url);
+
+  bool insecure_scheme_was_upgraded = false;
+  bool copy_fragment = true;
+
+  redirect_info_ = net::RedirectInfo::ComputeRedirectInfo(
+      modified_resource_request_.method, modified_resource_request_.url,
+      modified_resource_request_.site_for_cookies,
+      modified_resource_request_.top_frame_origin,
+      net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
+      modified_resource_request_.referrer_policy,
+      modified_resource_request_.referrer.spec(), net::HTTP_TEMPORARY_REDIRECT,
+      lite_page_url, base::nullopt, insecure_scheme_was_upgraded,
+      copy_fragment);
+
+  bool should_clear_upload = false;
+  net::RedirectUtil::UpdateHttpRequest(
+      modified_resource_request_.url, modified_resource_request_.method,
+      redirect_info_, base::nullopt, base::nullopt,
+      &modified_resource_request_.headers, &should_clear_upload);
+
+  modified_resource_request_.headers.MergeFrom(chrome_proxy_headers);
+
+  DCHECK(!should_clear_upload);
+
+  modified_resource_request_.url = redirect_info_.new_url;
+  modified_resource_request_.method = redirect_info_.new_method;
+  modified_resource_request_.site_for_cookies =
+      redirect_info_.new_site_for_cookies;
+  modified_resource_request_.top_frame_origin =
+      redirect_info_.new_top_frame_origin;
+  modified_resource_request_.referrer = GURL(redirect_info_.new_referrer);
+  modified_resource_request_.referrer_policy =
+      redirect_info_.new_referrer_policy;
 
   serving_url_loader_ = std::make_unique<PreviewsLitePageServingURLLoader>(
-      modified_resource_request_,
-      base::BindOnce(&PreviewsLitePageRedirectURLLoader::OnFallback,
+      base::BindOnce(&PreviewsLitePageRedirectURLLoader::OnResultDetermined,
                      weak_ptr_factory_.GetWeakPtr()));
+  // |serving_url_loader_| can be null after this call.
+  serving_url_loader_->StartNetworkRequest(
+      modified_resource_request_, network_loader_factory, frame_tree_node_id);
 }
 
-void PreviewsLitePageRedirectURLLoader::OnFallback() {
+void PreviewsLitePageRedirectURLLoader::OnResultDetermined(
+    ServingLoaderResult result) {
+  switch (result) {
+    case ServingLoaderResult::kSuccess:
+      OnLitePageSuccess();
+      return;
+    case ServingLoaderResult::kFallback:
+      OnLitePageFallback();
+      return;
+  }
+  NOTREACHED();
+}
+
+void PreviewsLitePageRedirectURLLoader::OnLitePageSuccess() {
+  std::move(callback_).Run(
+      std::move(serving_url_loader_),
+      base::BindOnce(
+          &PreviewsLitePageRedirectURLLoader::StartHandlingRedirectToLitePage,
+          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PreviewsLitePageRedirectURLLoader::OnLitePageFallback() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   std::move(callback_).Run(nullptr, {});
 }
 
+void PreviewsLitePageRedirectURLLoader::StartHandlingRedirectToLitePage(
+    const network::ResourceRequest& resource_request,
+    network::mojom::URLLoaderRequest request,
+    network::mojom::URLLoaderClientPtr client) {
+  network::ResourceResponseHead response_head;
+  response_head.request_start = base::TimeTicks::Now();
+  response_head.response_start = response_head.request_start;
+
+  std::string header_string = base::StringPrintf(
+      "HTTP/1.1 %i Temporary Redirect\n"
+      "Location: %s\n",
+      net::HTTP_TEMPORARY_REDIRECT,
+      modified_resource_request_.url.spec().c_str());
+
+  scoped_refptr<net::HttpResponseHeaders> fake_headers_for_redirect =
+      new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
+          header_string.c_str(), header_string.length()));
+
+  response_head.headers = fake_headers_for_redirect;
+  response_head.encoded_data_length = 0;
+
+  StartHandlingRedirect(redirect_info_, response_head, resource_request,
+                        std::move(request), std::move(client));
+}
+
+void PreviewsLitePageRedirectURLLoader::StartHandlingRedirect(
+    const net::RedirectInfo& redirect_info,
+    const network::ResourceResponseHead& head,
+    const network::ResourceRequest& /* resource_request */,
+    network::mojom::URLLoaderRequest request,
+    network::mojom::URLLoaderClientPtr client) {
+  DCHECK(!binding_.is_bound());
+  binding_.Bind(std::move(request));
+  binding_.set_connection_error_handler(
+      base::BindOnce(&PreviewsLitePageRedirectURLLoader::OnConnectionClosed,
+                     weak_ptr_factory_.GetWeakPtr()));
+  client_ = std::move(client);
+
+  mojo::DataPipe pipe(kRedirectDefaultAllocationSize);
+  if (!pipe.consumer_handle.is_valid()) {
+    delete this;
+    return;
+  }
+
+  client_->OnReceiveRedirect(redirect_info, head);
+}
+
 void PreviewsLitePageRedirectURLLoader::FollowRedirect(
     const std::vector<std::string>& removed_headers,
     const net::HttpRequestHeaders& modified_headers,
@@ -87,4 +195,12 @@
   serving_url_loader_->ResumeReadingBodyFromNet();
 }
 
+void PreviewsLitePageRedirectURLLoader::OnConnectionClosed() {
+  // This happens when content cancels the navigation. Close the network request
+  // and client handle and destroy |this|.
+  binding_.Close();
+  client_.reset();
+  delete this;
+}
+
 }  // namespace previews
diff --git a/chrome/browser/previews/previews_lite_page_redirect_url_loader.h b/chrome/browser/previews/previews_lite_page_redirect_url_loader.h
index cac79a0..dbde43a3 100644
--- a/chrome/browser/previews/previews_lite_page_redirect_url_loader.h
+++ b/chrome/browser/previews/previews_lite_page_redirect_url_loader.h
@@ -10,6 +10,10 @@
 #include "base/sequence_checker.h"
 #include "chrome/browser/previews/previews_lite_page_serving_url_loader.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
 namespace previews {
@@ -20,22 +24,25 @@
 
 // A URL loader that attempts to fetch an HTTPS server lite page, and if
 // successful, redirects to the lite page URL, and hands the underlying
-// network URLLoader to a success callback. Currently, it can only fallback to
-// default behavior.
+// network URLLoader to a success callback. Currently, it supports serving the
+// Preview and falling back to default behavior.
 class PreviewsLitePageRedirectURLLoader : public network::mojom::URLLoader {
  public:
-  static std::unique_ptr<PreviewsLitePageRedirectURLLoader>
-  AttemptRedirectToPreview(
-      const network::ResourceRequest& tentative_resource_request,
-      HandleRequest callback);
-
-  ~PreviewsLitePageRedirectURLLoader() override;
-
- private:
   PreviewsLitePageRedirectURLLoader(
       const network::ResourceRequest& tentative_resource_request,
       HandleRequest callback);
+  ~PreviewsLitePageRedirectURLLoader() override;
 
+  // Creates and starts |serving_url_loader_|. |chrome_proxy_headers| are added
+  // to the request, and the other parameters are used to start the network
+  // service URLLoader.
+  void StartRedirectToPreview(
+      const net::HttpRequestHeaders& chrome_proxy_headers,
+      const scoped_refptr<network::SharedURLLoaderFactory>&
+          network_loader_factory,
+      int frame_tree_node_id);
+
+ private:
   // network::mojom::URLLoader:
   void FollowRedirect(const std::vector<std::string>& removed_headers,
                       const net::HttpRequestHeaders& modified_headers,
@@ -46,11 +53,32 @@
   void PauseReadingBodyFromNet() override;
   void ResumeReadingBodyFromNet() override;
 
-  // Called when |serving_url_loader_| wants to fallback.
-  void OnFallback();
+  // Processes |result|. Used as a callback for |serving_url_loader_|.
+  void OnResultDetermined(ServingLoaderResult result);
 
-  // Creates and starts |serving_url_loader_|.
-  void StartRedirectToPreview();
+  // Called when the lite page can be successfully served.
+  void OnLitePageSuccess();
+
+  // Called when a non-200 response is received.
+  void OnLitePageFallback();
+
+  // The handler when trying to serve the lite page to the user. Serves a
+  // redirect to the lite page server URL.
+  void StartHandlingRedirectToLitePage(
+      const network::ResourceRequest& resource_request,
+      network::mojom::URLLoaderRequest request,
+      network::mojom::URLLoaderClientPtr client);
+
+  // Helper method for setting up and serving |redirect_info| to |client|.
+  void StartHandlingRedirect(
+      const net::RedirectInfo& redirect_info,
+      const network::ResourceResponseHead& head,
+      const network::ResourceRequest& /* resource_request */,
+      network::mojom::URLLoaderRequest request,
+      network::mojom::URLLoaderClientPtr client);
+
+  // Mojo error handling. Deletes |this|.
+  void OnConnectionClosed();
 
   // The underlying URLLoader that speculatively tries to fetch the lite page.
   std::unique_ptr<PreviewsLitePageServingURLLoader> serving_url_loader_;
@@ -59,11 +87,20 @@
   // lite page.
   network::ResourceRequest modified_resource_request_;
 
+  // Information about the redirect to the lite page server.
+  net::RedirectInfo redirect_info_;
+
   // Called upon success or failure to let content/ know whether this class
   // intends to intercept the request. Must be passed a handler if this class
   // intends to intercept the request.
   HandleRequest callback_;
 
+  // Binding to the URLLoader interface.
+  mojo::Binding<network::mojom::URLLoader> binding_;
+
+  // The owning client. Used for serving redirects.
+  network::mojom::URLLoaderClientPtr client_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<PreviewsLitePageRedirectURLLoader> weak_ptr_factory_;
diff --git a/chrome/browser/previews/previews_lite_page_serving_url_loader.cc b/chrome/browser/previews/previews_lite_page_serving_url_loader.cc
index 66ffbac3..1a28445 100644
--- a/chrome/browser/previews/previews_lite_page_serving_url_loader.cc
+++ b/chrome/browser/previews/previews_lite_page_serving_url_loader.cc
@@ -4,33 +4,200 @@
 
 #include "chrome/browser/previews/previews_lite_page_serving_url_loader.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/previews_state.h"
+#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
 
 namespace previews {
 
+namespace {
+// Used for mojo pipe size. Same constant as navigation code.
+constexpr size_t kServingDefaultAllocationSize = 512 * 1024;
+
+const net::NetworkTrafficAnnotationTag kPreviewsTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("https_server_previews_navigation", R"(
+      semantics {
+        sender: "HTTPS server previews navigation URL Loader"
+        description:
+          "This request is issued by a main frame navigation to fetch a server "
+          "generated lite page version of page."
+        trigger:
+          "Navigating Chrome (by clicking on a link, bookmark, history item, "
+          "using session restore, etc) on a slow page."
+        data:
+          "Arbitrary site-controlled data can be included in the URL, HTTP "
+          "headers, and request body."
+        destination: WEBSITE
+      }
+      policy {
+        cookies_allowed: YES
+        cookies_store: "user"
+        setting: "Disable Data Saver on Android (Settings > Data Saver)."
+        chrome_policy {
+          URLBlacklist {
+            URLBlacklist: { entries: '*' }
+          }
+        }
+        chrome_policy {
+          URLWhitelist {
+            URLWhitelist { }
+          }
+        }
+      }
+      )");
+
+}  // namespace
+
 PreviewsLitePageServingURLLoader::PreviewsLitePageServingURLLoader(
+    ResultCallback result_callback)
+    : url_loader_binding_(this),
+      result_callback_(std::move(result_callback)),
+      binding_(this),
+      weak_ptr_factory_(this) {}
+
+void PreviewsLitePageServingURLLoader::StartNetworkRequest(
     const network::ResourceRequest& request,
-    FallbackCallback fallback_callback)
-    : fallback_callback_(std::move(fallback_callback)),
-      weak_ptr_factory_(this) {
-  // TODO(ryansturm): Set up a network service URLLoader. For now, simulate a
-  // a fallback asynchronously.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(&PreviewsLitePageServingURLLoader::Fallback,
-                                weak_ptr_factory_.GetWeakPtr()));
+    const scoped_refptr<network::SharedURLLoaderFactory>&
+        network_loader_factory,
+    int frame_tree_node_id) {
+  network::mojom::URLLoaderClientPtr client;
+
+  url_loader_binding_.Bind(mojo::MakeRequest(&client),
+                           base::ThreadTaskRunnerHandle::Get());
+  url_loader_binding_.set_connection_error_handler(
+      base::BindOnce(&PreviewsLitePageServingURLLoader::OnConnectionError,
+                     base::Unretained(this)));
+
+  // Create a network service URL loader with passed in params.
+  network_loader_factory->CreateLoaderAndStart(
+      mojo::MakeRequest(&network_url_loader_), frame_tree_node_id, 0,
+      network::mojom::kURLLoadOptionNone, request, std::move(client),
+      net::MutableNetworkTrafficAnnotationTag(kPreviewsTrafficAnnotation));
 }
 
 PreviewsLitePageServingURLLoader::~PreviewsLitePageServingURLLoader() = default;
 
 void PreviewsLitePageServingURLLoader::Fallback() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::move(fallback_callback_).Run();
+  std::move(result_callback_).Run(ServingLoaderResult::kFallback);
+}
+
+RequestHandler PreviewsLitePageServingURLLoader::ServingResponseHandler() {
+  DCHECK(result_callback_.is_null());
+  return base::BindOnce(
+      &PreviewsLitePageServingURLLoader::SetUpForwardingClient,
+      weak_ptr_factory_.GetWeakPtr());
+}
+
+void PreviewsLitePageServingURLLoader::SetUpForwardingClient(
+    const network::ResourceRequest& /* resource_request */,
+    network::mojom::URLLoaderRequest request,
+    network::mojom::URLLoaderClientPtr forwarding_client) {
+  // Bind to the content/ navigation code.
+  DCHECK(!binding_.is_bound());
+  binding_.Bind(std::move(request));
+  binding_.set_connection_error_handler(
+      base::BindOnce(&PreviewsLitePageServingURLLoader::OnConnectionError,
+                     weak_ptr_factory_.GetWeakPtr()));
+  forwarding_client_ = std::move(forwarding_client);
+
+  // If there was an URLLoader error between handing off this handler and
+  // running it, don't handle the request.
+  if (!network_url_loader_) {
+    binding_.Close();
+    forwarding_client_.reset();
+    delete this;
+    return;
+  }
+
+  mojo::DataPipe pipe(kServingDefaultAllocationSize);
+  if (!pipe.consumer_handle.is_valid()) {
+    network_url_loader_.reset();
+    url_loader_binding_.Close();
+    delete this;
+    return;
+  }
+
+  forwarding_client_->OnReceiveResponse(resource_response_->head);
+
+  // Resume previously paused network service URLLoader.
+  url_loader_binding_.ResumeIncomingMethodCallProcessing();
+}
+
+void PreviewsLitePageServingURLLoader::OnReceiveResponse(
+    const network::ResourceResponseHead& head) {
+  DCHECK(!forwarding_client_);
+
+  // TODO: evaluate all the responses we allow, don't hard code 200.
+  if (head.headers->response_code() != net::HTTP_OK) {
+    Fallback();
+    return;
+  }
+
+  // Store head and pause new messages until the forwarding client is set up.
+  // Make a deep copy of ResourceResponseHead before passing it cross-thread.
+  resource_response_ = base::MakeRefCounted<network::ResourceResponse>();
+  resource_response_->head = head;
+
+  url_loader_binding_.PauseIncomingMethodCallProcessing();
+  std::move(result_callback_).Run(ServingLoaderResult::kSuccess);
+}
+
+void PreviewsLitePageServingURLLoader::OnReceiveRedirect(
+    const net::RedirectInfo& redirect_info,
+    const network::ResourceResponseHead& head) {
+  DCHECK(!forwarding_client_);
+  // We might receive a redirect from the lite page server, and we should treat
+  // that appropriately. For now fallback.
+  // TODO(ryansturm): Handle redirects. https://crbug.com/921744
+  Fallback();
+}
+
+void PreviewsLitePageServingURLLoader::OnUploadProgress(
+    int64_t current_position,
+    int64_t total_size,
+    OnUploadProgressCallback callback) {
+  // We only handle GETs.
+  NOTREACHED();
+}
+
+void PreviewsLitePageServingURLLoader::OnReceiveCachedMetadata(
+    const std::vector<uint8_t>& data) {
+  // Do nothing. This is not supported for navigation loader.
+}
+
+void PreviewsLitePageServingURLLoader::OnTransferSizeUpdated(
+    int32_t transfer_size_diff) {
+  DCHECK(forwarding_client_);
+  forwarding_client_->OnTransferSizeUpdated(transfer_size_diff);
+}
+
+void PreviewsLitePageServingURLLoader::OnStartLoadingResponseBody(
+    mojo::ScopedDataPipeConsumerHandle body) {
+  DCHECK(forwarding_client_);
+  forwarding_client_->OnStartLoadingResponseBody(std::move(body));
+}
+
+void PreviewsLitePageServingURLLoader::OnComplete(
+    const network::URLLoaderCompletionStatus& status) {
+  if (forwarding_client_) {
+    forwarding_client_->OnComplete(status);
+    return;
+  }
+
+  // If OnComplete is called before, OnReceiveResponse, this is indicative of a
+  // failure of some sort.
+  // TODO(ryansturm): Handle specific errors with a bypass pattern.
+  // https://crbug.com/921744
+  Fallback();
 }
 
 void PreviewsLitePageServingURLLoader::FollowRedirect(
@@ -44,24 +211,46 @@
 
 void PreviewsLitePageServingURLLoader::ProceedWithResponse() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(ryansturm): Pass through calls to a network service URLLoader.
+  // Pass through.
+  network_url_loader_->ProceedWithResponse();
 }
 
 void PreviewsLitePageServingURLLoader::SetPriority(
     net::RequestPriority priority,
     int32_t intra_priority_value) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(ryansturm): Pass through calls to a network service URLLoader.
+  // Pass through.
+  network_url_loader_->SetPriority(priority, intra_priority_value);
 }
 
 void PreviewsLitePageServingURLLoader::PauseReadingBodyFromNet() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(ryansturm): Pass through calls to a network service URLLoader.
+  // Pass through.
+  network_url_loader_->PauseReadingBodyFromNet();
 }
 
 void PreviewsLitePageServingURLLoader::ResumeReadingBodyFromNet() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(ryansturm): Pass through calls to a network service URLLoader.
+  // Pass through.
+  network_url_loader_->ResumeReadingBodyFromNet();
+}
+
+void PreviewsLitePageServingURLLoader::OnConnectionError() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // When we are not yet bound to the navigation code, fallback, which will
+  // destroy this object.
+  if (!result_callback_.is_null()) {
+    Fallback();
+    return;
+  }
+
+  network_url_loader_.reset();
+  url_loader_binding_.Close();
+
+  if (binding_.is_bound()) {
+    binding_.Close();
+    forwarding_client_.reset();
+    delete this;
+  }
 }
 
 }  // namespace previews
diff --git a/chrome/browser/previews/previews_lite_page_serving_url_loader.h b/chrome/browser/previews/previews_lite_page_serving_url_loader.h
index e05b0d1..d0d57c5 100644
--- a/chrome/browser/previews/previews_lite_page_serving_url_loader.h
+++ b/chrome/browser/previews/previews_lite_page_serving_url_loader.h
@@ -5,29 +5,57 @@
 #ifndef CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_SERVING_URL_LOADER_H_
 #define CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_SERVING_URL_LOADER_H_
 
+#include <vector>
+
 #include "base/callback.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
 namespace previews {
 
-using FallbackCallback = base::OnceCallback<void()>;
+enum class ServingLoaderResult {
+  kSuccess,  // The Preview can be served.
+  kFallback  // The Preview cannot be served and fallback to default URLLoader
+             // should occur.
+};
+
+using ResultCallback = base::OnceCallback<void(ServingLoaderResult)>;
+
+using RequestHandler =
+    base::OnceCallback<void(const network::ResourceRequest& resource_request,
+                            network::mojom::URLLoaderRequest,
+                            network::mojom::URLLoaderClientPtr)>;
 
 // This class attempts to fetch a LitePage from the LitePage server, and if
 // successful, calls a success callback. Otherwise, it calls fallback in the
 // case of a failure and redirect in the case of a redirect served from the lite
-// pages service. For now, it is only partially implemented.
-class PreviewsLitePageServingURLLoader : public network::mojom::URLLoader {
+// pages service.
+class PreviewsLitePageServingURLLoader
+    : public network::mojom::URLLoader,
+      public network::mojom::URLLoaderClient {
  public:
   // Creates a network service URLLoader, binds to the URL Loader, and stores
   // the various callbacks.
-  PreviewsLitePageServingURLLoader(const network::ResourceRequest& request,
-                                   FallbackCallback fallback_callback);
+  explicit PreviewsLitePageServingURLLoader(ResultCallback result_callback);
   ~PreviewsLitePageServingURLLoader() override;
 
+  // Begins the underlying network URLLoader to fetch the preview.
+  // |network_loader_factory| creates the URLLoader using the other parameters
+  // in this method.
+  void StartNetworkRequest(const network::ResourceRequest& request,
+                           const scoped_refptr<network::SharedURLLoaderFactory>&
+                               network_loader_factory,
+                           int frame_tree_node_id);
+
+  // Called when the response should be served to the user. Returns a handler.
+  RequestHandler ServingResponseHandler();
+
   // network::mojom::URLLoader:
   void FollowRedirect(const std::vector<std::string>& removed_headers,
                       const net::HttpRequestHeaders& modified_headers,
@@ -39,12 +67,50 @@
   void ResumeReadingBodyFromNet() override;
 
  private:
-  // Calls |fallback_callback_| and cleans up.
+  // network::mojom::URLLoaderClient
+  void OnReceiveResponse(const network::ResourceResponseHead& head) override;
+  void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+                         const network::ResourceResponseHead& head) override;
+  void OnUploadProgress(int64_t current_position,
+                        int64_t total_size,
+                        OnUploadProgressCallback callback) override;
+  void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
+  void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+  void OnStartLoadingResponseBody(
+      mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+
+  // When a connection error occurs in either mojo pipe, this objects lifetime
+  // needs to be managed and the connections need to be closed.
+  void OnConnectionError();
+
+  // Calls |result_callback_| with kFallback and cleans up.
   void Fallback();
 
-  // When an error occurs or the LitePage is not suitable, this callback resumes
-  // default behavior.
-  FallbackCallback fallback_callback_;
+  // Sets up mojo forwarding to the navigation path. Resumes
+  // |network_url_loader_| calls. Serves the start of the response to the
+  // navigation path.
+  void SetUpForwardingClient(
+      const network::ResourceRequest&,
+      network::mojom::URLLoaderRequest request,
+      network::mojom::URLLoaderClientPtr forwarding_client);
+
+  // The network URLLoader that fetches the LitePage URL and its binding.
+  network::mojom::URLLoaderPtr network_url_loader_;
+  mojo::Binding<network::mojom::URLLoaderClient> url_loader_binding_;
+
+  // When a result is determined, this callback should be run with the
+  // appropriate ServingLoaderResult.
+  ResultCallback result_callback_;
+
+  // Once the LitePage response is received and is ready to be served, the
+  // response info related to the request. When this becomes populated, the
+  // network URL Loader calls are paused.
+  scoped_refptr<network::ResourceResponse> resource_response_;
+
+  // Forwarding client binding.
+  mojo::Binding<network::mojom::URLLoader> binding_;
+  network::mojom::URLLoaderClientPtr forwarding_client_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/chrome/browser/previews/previews_lite_page_url_loader_interceptor.cc b/chrome/browser/previews/previews_lite_page_url_loader_interceptor.cc
index 57aeb48..50cfed0 100644
--- a/chrome/browser/previews/previews_lite_page_url_loader_interceptor.cc
+++ b/chrome/browser/previews/previews_lite_page_url_loader_interceptor.cc
@@ -4,12 +4,21 @@
 
 #include "chrome/browser/previews/previews_lite_page_url_loader_interceptor.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/profiles/profile_io_data.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/previews/core/previews_features.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/previews_state.h"
 #include "content/public/common/resource_type.h"
+#include "net/http/http_request_headers.h"
+#include "net/nqe/effective_connection_type.h"
 
 namespace previews {
 
@@ -31,14 +40,40 @@
   return true;
 }
 
+net::HttpRequestHeaders GetChromeProxyHeaders(
+    content::ResourceContext* context) {
+  net::HttpRequestHeaders headers;
+  // Return empty headers for unittests.
+  if (!context)
+    return headers;
+  // TODO(ryansturm): If this switches to the UI thread, this needs to be
+  // re-worked. This information is all available on the UI thread.
+  // https://crbug.com/931786
+  auto* io_data = ProfileIOData::FromResourceContext(context);
+  if (io_data && io_data->data_reduction_proxy_io_data()) {
+    DCHECK(data_reduction_proxy::params::IsEnabledWithNetworkService());
+    data_reduction_proxy::DataReductionProxyRequestOptions* request_options =
+        io_data->data_reduction_proxy_io_data()->request_options();
+    request_options->AddRequestHeader(&headers,
+                                      request_options->GeneratePageId());
+
+    headers.SetHeader(data_reduction_proxy::chrome_proxy_ect_header(),
+                      net::GetNameForEffectiveConnectionType(
+                          io_data->data_reduction_proxy_io_data()
+                              ->GetEffectiveConnectionType()));
+  }
+
+  return headers;
+}
+
 }  // namespace
 
 PreviewsLitePageURLLoaderInterceptor::PreviewsLitePageURLLoaderInterceptor(
-    int frame_tree_node_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // TODO(ryansturm): use frame_tree_node_id and pass in other members.
-  // https://crbug.com/921740
-}
+    const scoped_refptr<network::SharedURLLoaderFactory>&
+        network_loader_factory,
+    int frame_tree_node_id)
+    : network_loader_factory_(network_loader_factory),
+      frame_tree_node_id_(frame_tree_node_id) {}
 
 PreviewsLitePageURLLoaderInterceptor::~PreviewsLitePageURLLoaderInterceptor() {}
 
@@ -48,6 +83,14 @@
     content::URLLoaderRequestInterceptor::LoaderCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  if (serving_url_loader_) {
+    RequestHandler handler = serving_url_loader_->ServingResponseHandler();
+    // The serving loader manages its own lifetime at this point.
+    serving_url_loader_.release();
+    std::move(callback).Run(std::move(handler));
+    return;
+  }
+
   // TODO(ryansturm): Handle reloads by handling non-intercepted attempts at
   // fetching the lite page server. https://crbug.com/921756
 
@@ -68,12 +111,16 @@
 
   RecordInterceptAttempt(true);
 
-  redirect_url_loader_ =
-      PreviewsLitePageRedirectURLLoader::AttemptRedirectToPreview(
-          tentative_resource_request,
-          base::BindOnce(
-              &PreviewsLitePageURLLoaderInterceptor::HandleRedirectLoader,
-              base::Unretained(this), std::move(callback)));
+  redirect_url_loader_ = std::make_unique<PreviewsLitePageRedirectURLLoader>(
+      tentative_resource_request,
+      base::BindOnce(
+          &PreviewsLitePageURLLoaderInterceptor::HandleRedirectLoader,
+          base::Unretained(this), std::move(callback)));
+
+  // |redirect_url_loader_| can be null after this call.
+  redirect_url_loader_->StartRedirectToPreview(
+      GetChromeProxyHeaders(resource_context), network_loader_factory_,
+      frame_tree_node_id_);
 }
 
 void PreviewsLitePageURLLoaderInterceptor::HandleRedirectLoader(
@@ -82,11 +129,20 @@
     RequestHandler handler) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Handle any failure by using default loader.
-  // For now, only fallback is allowed.
-  DCHECK(!serving_url_loader);
-  DCHECK(handler.is_null());
-  redirect_url_loader_.reset();
-  std::move(callback).Run({});
+  if (!serving_url_loader) {
+    DCHECK(handler.is_null());
+    redirect_url_loader_.reset();
+    std::move(callback).Run({});
+    return;
+  }
+
+  // Save the serving loader to handle the next request.
+  serving_url_loader_ = std::move(serving_url_loader);
+
+  // |redirect_url_loader_| now manages its own lifetime via a mojo channel.
+  // |handler| is guaranteed to be called.
+  redirect_url_loader_.release();
+  std::move(callback).Run(std::move(handler));
 }
 
 }  // namespace previews
diff --git a/chrome/browser/previews/previews_lite_page_url_loader_interceptor.h b/chrome/browser/previews/previews_lite_page_url_loader_interceptor.h
index fb50d29..2b1b9c7 100644
--- a/chrome/browser/previews/previews_lite_page_url_loader_interceptor.h
+++ b/chrome/browser/previews/previews_lite_page_url_loader_interceptor.h
@@ -5,10 +5,14 @@
 #ifndef CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_URL_LOADER_INTERCEPTOR_H_
 #define CHROME_BROWSER_PREVIEWS_PREVIEWS_LITE_PAGE_URL_LOADER_INTERCEPTOR_H_
 
+#include <memory>
+
+#include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
 #include "chrome/browser/previews/previews_lite_page_redirect_url_loader.h"
 #include "chrome/browser/previews/previews_lite_page_serving_url_loader.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
+#include "net/http/http_request_headers.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace previews {
@@ -18,13 +22,11 @@
 // code. Currently, not fully implemented.
 class PreviewsLitePageURLLoaderInterceptor
     : public content::URLLoaderRequestInterceptor {
-  using RequestHandler =
-      base::OnceCallback<void(const network::ResourceRequest& resource_request,
-                              network::mojom::URLLoaderRequest,
-                              network::mojom::URLLoaderClientPtr)>;
-
  public:
-  explicit PreviewsLitePageURLLoaderInterceptor(int frame_tree_node_id);
+  PreviewsLitePageURLLoaderInterceptor(
+      const scoped_refptr<network::SharedURLLoaderFactory>&
+          network_loader_factory,
+      int frame_tree_node_id);
   ~PreviewsLitePageURLLoaderInterceptor() override;
 
   // content::URLLaoderRequestInterceptor:
@@ -51,6 +53,18 @@
   // made regarding serving the preview, this object will be null.
   std::unique_ptr<PreviewsLitePageRedirectURLLoader> redirect_url_loader_;
 
+  // Once a decision to serve the lite page has been made (based on server
+  // response), this object will exist until a redirect to the lite page URL has
+  // been handed off to the navigation stack and the next request is being
+  // handled.
+  std::unique_ptr<PreviewsLitePageServingURLLoader> serving_url_loader_;
+
+  // Factory to create a network service URLLoader.
+  scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
+
+  // Used to create the network service URLLoader.
+  int frame_tree_node_id_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(PreviewsLitePageURLLoaderInterceptor);
diff --git a/chrome/browser/previews/previews_lite_page_url_loader_interceptor_unittest.cc b/chrome/browser/previews/previews_lite_page_url_loader_interceptor_unittest.cc
index 45190ad..95cbf2a1 100644
--- a/chrome/browser/previews/previews_lite_page_url_loader_interceptor_unittest.cc
+++ b/chrome/browser/previews/previews_lite_page_url_loader_interceptor_unittest.cc
@@ -4,26 +4,77 @@
 
 #include "chrome/browser/previews/previews_lite_page_url_loader_interceptor.h"
 
+#include <memory>
+#include <string>
+
 #include "base/bind.h"
+#include "base/optional.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
+#include "chrome/browser/previews/previews_lite_page_navigation_throttle.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/url_loader_request_interceptor.h"
 #include "content/public/common/previews_state.h"
 #include "content/public/common/resource_type.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace previews {
 
 namespace {
 
-void EmptyCallback(
-    content::URLLoaderRequestInterceptor::RequestHandler callback) {}
+class PreviewsLitePageURLLoaderInterceptorTest : public testing::Test {
+ public:
+  PreviewsLitePageURLLoaderInterceptorTest()
+      : shared_factory_(
+            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+                &test_url_loader_factory_)) {}
+  ~PreviewsLitePageURLLoaderInterceptorTest() override {}
 
-TEST(PreviewsLitePageURLLoaderInterceptorTest, InterceptRequest) {
-  base::test::ScopedTaskEnvironment scoped_task_environment;
-  PreviewsLitePageURLLoaderInterceptor interceptor(1);
+  void TearDown() override {}
 
+  void SetUp() override {
+    interceptor_ = std::make_unique<PreviewsLitePageURLLoaderInterceptor>(
+        shared_factory_, 1);
+  }
+
+  void SetFakeResponse(const GURL& url,
+                       const std::string& data,
+                       net::HttpStatusCode code,
+                       int net_error) {
+    test_url_loader_factory_.AddResponse(
+        url, network::CreateResourceResponseHead(code), data,
+        network::URLLoaderCompletionStatus(net_error));
+  }
+
+  void HandlerCallback(
+      content::URLLoaderRequestInterceptor::RequestHandler callback) {
+    callback_was_empty_ = callback.is_null();
+  }
+
+  base::Optional<bool> callback_was_empty() { return callback_was_empty_; }
+
+  void ResetTest() { callback_was_empty_ = base::nullopt; }
+
+  PreviewsLitePageURLLoaderInterceptor& interceptor() { return *interceptor_; }
+
+ protected:
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+ private:
+  base::Optional<bool> callback_was_empty_;
+
+  std::unique_ptr<PreviewsLitePageURLLoaderInterceptor> interceptor_;
+  network::TestURLLoaderFactory test_url_loader_factory_;
+  scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
+};
+
+TEST_F(PreviewsLitePageURLLoaderInterceptorTest,
+       InterceptRequestPreviewsState) {
   base::HistogramTester histogram_tester;
 
   network::ResourceRequest request;
@@ -31,23 +82,144 @@
   request.resource_type = static_cast<int>(content::RESOURCE_TYPE_MAIN_FRAME);
   request.method = "GET";
 
+  SetFakeResponse(
+      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(request.url),
+      "Fake Body", net::HTTP_OK, net::URLRequestStatus::SUCCESS);
+
   // Check that we don't trigger when previews are not allowed.
   request.previews_state = content::PREVIEWS_OFF;
-  interceptor.MaybeCreateLoader(request, nullptr,
-                                base::BindOnce(&EmptyCallback));
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
 
   histogram_tester.ExpectUniqueSample(
       "Previews.ServerLitePage.URLLoader.Attempted", false, 1);
 
+  scoped_task_environment_.RunUntilIdle();
+
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_TRUE(callback_was_empty().value());
+
+  ResetTest();
+  SetFakeResponse(request.url, "Fake Body", net::HTTP_OK,
+                  net::URLRequestStatus::SUCCESS);
+
   // Check that we trigger when previews are allowed.
   request.previews_state = content::LITE_PAGE_REDIRECT_ON;
-  interceptor.MaybeCreateLoader(request, nullptr,
-                                base::BindOnce(&EmptyCallback));
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
 
   histogram_tester.ExpectBucketCount(
       "Previews.ServerLitePage.URLLoader.Attempted", true, 1);
   histogram_tester.ExpectTotalCount(
       "Previews.ServerLitePage.URLLoader.Attempted", 2);
+
+  scoped_task_environment_.RunUntilIdle();
+
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_FALSE(callback_was_empty().value());
+}
+
+TEST_F(PreviewsLitePageURLLoaderInterceptorTest, InterceptRequestRedirect) {
+  base::HistogramTester histogram_tester;
+  network::ResourceRequest request;
+  request.url = GURL("https://google.com");
+  request.resource_type = static_cast<int>(content::RESOURCE_TYPE_MAIN_FRAME);
+  request.method = "GET";
+  request.previews_state = content::LITE_PAGE_REDIRECT_ON;
+  SetFakeResponse(
+      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(request.url),
+      "Fake Body", net::HTTP_TEMPORARY_REDIRECT,
+      net::URLRequestStatus::SUCCESS);
+
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
+
+  histogram_tester.ExpectUniqueSample(
+      "Previews.ServerLitePage.URLLoader.Attempted", true, 1);
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_TRUE(callback_was_empty().value());
+}
+
+TEST_F(PreviewsLitePageURLLoaderInterceptorTest,
+       InterceptRequestServerOverloaded) {
+  base::HistogramTester histogram_tester;
+  network::ResourceRequest request;
+  request.url = GURL("https://google.com");
+  request.resource_type = static_cast<int>(content::RESOURCE_TYPE_MAIN_FRAME);
+  request.method = "GET";
+  request.previews_state = content::LITE_PAGE_REDIRECT_ON;
+  SetFakeResponse(
+      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(request.url),
+      "Fake Body", net::HTTP_SERVICE_UNAVAILABLE,
+      net::URLRequestStatus::SUCCESS);
+
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
+
+  histogram_tester.ExpectUniqueSample(
+      "Previews.ServerLitePage.URLLoader.Attempted", true, 1);
+  scoped_task_environment_.RunUntilIdle();
+
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_TRUE(callback_was_empty().value());
+}
+
+TEST_F(PreviewsLitePageURLLoaderInterceptorTest,
+       InterceptRequestServerNotHandling) {
+  base::HistogramTester histogram_tester;
+  network::ResourceRequest request;
+  request.url = GURL("https://google.com");
+  request.resource_type = static_cast<int>(content::RESOURCE_TYPE_MAIN_FRAME);
+  request.method = "GET";
+  request.previews_state = content::LITE_PAGE_REDIRECT_ON;
+  SetFakeResponse(
+      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(request.url),
+      "Fake Body", net::HTTP_FORBIDDEN, net::URLRequestStatus::SUCCESS);
+
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
+
+  histogram_tester.ExpectUniqueSample(
+      "Previews.ServerLitePage.URLLoader.Attempted", true, 1);
+
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_TRUE(callback_was_empty().value());
+}
+
+TEST_F(PreviewsLitePageURLLoaderInterceptorTest, NetStackError) {
+  base::HistogramTester histogram_tester;
+  network::ResourceRequest request;
+  request.url = GURL("https://google.com");
+  request.resource_type = static_cast<int>(content::RESOURCE_TYPE_MAIN_FRAME);
+  request.method = "GET";
+  request.previews_state = content::LITE_PAGE_REDIRECT_ON;
+  SetFakeResponse(
+      PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(request.url),
+      "Fake Body", net::HTTP_OK, net::URLRequestStatus::FAILED);
+
+  interceptor().MaybeCreateLoader(
+      request, nullptr,
+      base::BindOnce(&PreviewsLitePageURLLoaderInterceptorTest::HandlerCallback,
+                     base::Unretained(this)));
+
+  histogram_tester.ExpectUniqueSample(
+      "Previews.ServerLitePage.URLLoader.Attempted", true, 1);
+
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_TRUE(callback_was_empty().has_value());
+  EXPECT_TRUE(callback_was_empty().value());
 }
 
 }  // namespace
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc
index d4fbee9..00a2008e 100644
--- a/chrome/browser/profiling_host/memlog_browsertest.cc
+++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -87,8 +87,7 @@
 
 // Ensure invocations via TracingController can generate a valid JSON file with
 // expected data.
-// TODO(crbug.com/843467): Disabled due to flakiness.
-IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, DISABLED_EndToEnd) {
+IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, EndToEnd) {
   LOG(INFO) << "Memlog mode: " << static_cast<int>(GetParam().mode);
   LOG(INFO) << "Memlog stack mode: " << static_cast<int>(GetParam().stack_mode);
   LOG(INFO) << "Stream samples: " << GetParam().stream_samples;
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
index f9b633c..f485241 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -127,16 +127,6 @@
   position: relative;
 }
 
-#wallpaper-set-by-message {
-  height: 30px;
-  padding-inline-end: 5px;
-  padding-inline-start: 15px;
-}
-
-#wallpaper-set-by-message:empty {
-  display: none;
-}
-
 .image-picker {
   display: block;
   /* Set font size to 0 to remove the extra vertical margin between two rows of
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
index b56242b..35ffb17 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
@@ -303,26 +303,26 @@
       }
 
       // If the built-in Wallpaper Picker App is open, update the check mark
-      // and the corresponding 'wallpaper-set-by-message' in time.
+      // and the corresponding message in time.
       var updateCheckMarkAndAppNameIfAppliable = function(appName) {
         if (!wallpaperPickerWindow)
           return;
         var wpDocument = wallpaperPickerWindow.contentWindow.document;
+        var messageContainer = wpDocument.querySelector('#message-container');
 
         if (!!appName) {
           chrome.wallpaperPrivate.getStrings(function(strings) {
             var message =
                 strings.currentWallpaperSetByMessage.replace(/\$1/g, appName);
-            wpDocument.querySelector('#wallpaper-set-by-message').textContent =
-                message;
+            messageContainer.textContent = message;
+            messageContainer.style.visibility = 'visible';
             wpDocument.querySelector('#wallpaper-grid').classList.add('small');
             wpDocument.querySelector('#checkbox').classList.remove('checked');
             wpDocument.querySelector('#categories-list').disabled = false;
             wpDocument.querySelector('#wallpaper-grid').disabled = false;
           });
         } else {
-          wpDocument.querySelector('#wallpaper-set-by-message').textContent =
-              '';
+          messageContainer.style.visibility = 'hidden';
           wpDocument.querySelector('#wallpaper-grid').classList.remove('small');
           Constants.WallpaperSyncStorage.get(
               Constants.AccessSyncSurpriseMeEnabledKey, function(item) {
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
index 5f65858..8e0926e 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js
@@ -380,10 +380,12 @@
 
   getThirdPartyAppName(function(appName) {
     if (!!appName) {
-      $('wallpaper-set-by-message').textContent =
+      $('message-container').textContent =
           loadTimeData.getStringF('currentWallpaperSetByMessage', appName);
+      $('message-container').style.visibility = 'visible';
       $('wallpaper-grid').classList.add('small');
     } else {
+      $('message-container').style.visibility = 'hidden';
       $('wallpaper-grid').classList.remove('small');
     }
   });
@@ -655,8 +657,6 @@
   this.wallpaperGrid_.activeItem = activeItem;
   this.currentWallpaper_ = currentWallpaperURL;
   this.decorateCurrentWallpaperInfoBar_();
-  // Hides the wallpaper set by message.
-  $('wallpaper-set-by-message').textContent = '';
   $('wallpaper-grid').classList.remove('small');
 
     this.wallpaperGrid_.checkmark.focus();
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
index 56e22416..e7b65f8b2 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/main.html
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/main.html
@@ -98,7 +98,6 @@
       </div>
       <div class="dialog-main">
         <div id="category-container">
-          <div id="wallpaper-set-by-message"></div>
           <div id="current-wallpaper-info-bar">
             <img id="current-wallpaper-image" aria-hidden="true"></img>
             <div id="current-wallpaper-spinner" hidden></div>
diff --git a/chrome/browser/resources/usb_internals/OWNERS b/chrome/browser/resources/usb_internals/OWNERS
new file mode 100644
index 0000000..8dc3166
--- /dev/null
+++ b/chrome/browser/resources/usb_internals/OWNERS
@@ -0,0 +1,4 @@
+file://chrome/browser/usb/OWNERS
+
+# COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
index 8bea421..28d92f5d 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
@@ -116,6 +116,10 @@
         margin-inline-start: 6px;
         width: 20px;
       }
+
+      :host-context([dir=rtl]) iron-icon {
+        transform: scaleX(-1);
+      }
     </style>
     <div class="ntp-background-logo"></div>
     <h1 tabindex="-1">$i18n{ntpBackgroundDescription}</h1>
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index 51d3c9e9..8531e557 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -1182,7 +1182,14 @@
   const bool removed = apps->Remove(app_id, nullptr);
   DCHECK(removed);
 
-  DCHECK(tracked_apps_.count(app_id));
+  // |tracked_apps_| contains apps that are reported externally as available.
+  // However, in case ARC++ appears as disbled on next start and had some apps
+  // left in prefs from the previous session, app clean up is performed on very
+  // early stage. Don't report |OnAppRemoved| in this case once the app was not
+  // reported as available for the current session.
+  if (!tracked_apps_.count(app_id))
+    return;
+
   for (auto& observer : observer_list_)
     observer.OnAppRemoved(app_id);
   tracked_apps_.erase(app_id);
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc
index 83aa8188..6fe3a0f3 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -114,10 +114,12 @@
     WaitForDefaultApps();
 
   // Check initial conditions.
-  if (!arc::ShouldArcAlwaysStart())
-    arc::SetArcPlayStoreEnabledForProfile(profile_, true);
-  if (!arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile_))
-    EXPECT_TRUE(arc_session_manager_->enable_requested());
+  if (activate_arc_on_start_) {
+    if (!arc::ShouldArcAlwaysStart())
+      arc::SetArcPlayStoreEnabledForProfile(profile_, true);
+    if (!arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile_))
+      EXPECT_TRUE(arc_session_manager_->enable_requested());
+  }
 
   app_instance_ = std::make_unique<arc::FakeAppInstance>(arc_app_list_pref_);
   arc_service_manager_->arc_bridge_service()->app()->SetInstance(
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.h b/chrome/browser/ui/app_list/arc/arc_app_test.h
index f46e1e76..69324d8 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.h
@@ -95,6 +95,10 @@
     wait_default_apps_ = wait_default_apps;
   }
 
+  void set_activate_arc_on_start(bool activate_arc_on_start) {
+    activate_arc_on_start_ = activate_arc_on_start;
+  }
+
  private:
   const user_manager::User* CreateUserAndLogin();
   bool FindPackage(const std::string& package_name);
@@ -107,6 +111,9 @@
 
   bool wait_default_apps_ = true;
 
+  // If set to true ARC would be automatically enabled on test start up.
+  bool activate_arc_on_start_ = true;
+
   std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
   std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
   std::unique_ptr<arc::ArcPlayStoreEnabledPreferenceHandler>
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
index 66887815..948fa68 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -513,15 +513,22 @@
  protected:
   // Simulates ARC restart.
   void RestartArc() {
-    arc_test()->TearDown();
-    ResetBuilder();
+    StopArc();
+    StartArc();
+  }
 
+  void StartArc() {
     ArcAppListPrefsFactory::GetInstance()->RecreateServiceInstanceForTesting(
         profile_.get());
     arc_test()->SetUp(profile_.get());
     CreateBuilder();
   }
 
+  void StopArc() {
+    arc_test()->TearDown();
+    ResetBuilder();
+  }
+
   // ArcAppModelBuilderTest:
   void OnBeforeArcTestSetup() override {
     arc::ArcPackageSyncableServiceFactory::GetInstance()->SetTestingFactory(
@@ -1477,6 +1484,39 @@
   EXPECT_EQ(fake_apps().size(), GetArcItemCount());
 }
 
+// Verifies that no OnAppRegistered/OnAppRemoved is called in case ARC++ started
+// next time disabled.
+TEST_P(ArcAppModelBuilderRecreate, AppsNotReportedNextSessionDisabled) {
+  ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_.get());
+  ASSERT_TRUE(prefs);
+
+  // Register one app first.
+  const arc::mojom::AppInfo& app = fake_apps()[0];
+  const std::string app_id = ArcAppTest::GetAppId(app);
+  app_instance()->RefreshAppList();
+  app_instance()->SendRefreshAppList({app});
+
+  // We will wait for default apps manually once observer is set.
+  arc_test()->set_wait_default_apps(false);
+  arc_test()->set_activate_arc_on_start(false);
+  StopArc();
+  // Disable ARC in beetwen sessions.
+  arc::SetArcPlayStoreEnabledForProfile(profile(), false);
+  StartArc();
+
+  prefs = ArcAppListPrefs::Get(profile_.get());
+
+  arc::MockArcAppListPrefsObserver observer;
+  prefs->AddObserver(&observer);
+  EXPECT_CALL(observer,
+              OnAppRegistered(
+                  app_id, GetAppInfoExpectation(app, true /* launchable */)))
+      .Times(0);
+  EXPECT_CALL(observer, OnAppRemoved(app_id)).Times(0);
+
+  arc_test()->WaitForDefaultApps();
+}
+
 TEST_P(ArcPlayStoreAppTest, PlayStore) {
   ASSERT_TRUE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
index c687a787..d114bb9c 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -70,6 +70,7 @@
     {autofill::kUnionPay, IDR_AUTOFILL_CC_UNIONPAY, IDS_AUTOFILL_CC_UNION_PAY},
     {autofill::kVisaCard, IDR_AUTOFILL_CC_VISA, IDS_AUTOFILL_CC_VISA},
     {"googlePay", IDR_AUTOFILL_GOOGLE_PAY, kResourceNotFoundId},
+    {"googlePayDark", IDR_AUTOFILL_GOOGLE_PAY_DARK, kResourceNotFoundId},
 #if defined(OS_ANDROID)
     {"httpWarning", IDR_AUTOFILL_HTTP_WARNING, kResourceNotFoundId},
     {"httpsInvalid", IDR_AUTOFILL_HTTPS_INVALID_WARNING, kResourceNotFoundId},
diff --git a/chrome/browser/ui/omnibox/clipboard_utils.cc b/chrome/browser/ui/omnibox/clipboard_utils.cc
index de83f73..a8d32974 100644
--- a/chrome/browser/ui/omnibox/clipboard_utils.cc
+++ b/chrome/browser/ui/omnibox/clipboard_utils.cc
@@ -16,6 +16,7 @@
                                    ui::CLIPBOARD_TYPE_COPY_PASTE)) {
     base::string16 text;
     clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &text);
+    text = text.substr(0, kMaxClipboardTextLength);
     return OmniboxView::SanitizeTextForPaste(text);
   }
 
diff --git a/chrome/browser/ui/omnibox/clipboard_utils.h b/chrome/browser/ui/omnibox/clipboard_utils.h
index 716be85..5cab1c4 100644
--- a/chrome/browser/ui/omnibox/clipboard_utils.h
+++ b/chrome/browser/ui/omnibox/clipboard_utils.h
@@ -9,6 +9,18 @@
 
 #include "base/strings/string16.h"
 
+// Truncates the clipboard text returned in order to improve performance and
+// prevent unresponsiveness. For reference, a book is about ~500k characters and
+// data URLs served by google images are usually 30k characters or less.
+// We don't use url::kMaxURLChars (2M), as it's too large; it adds 2s+ delays
+// when right clicking the omnibox for clipboards larger than 2M. Additionally,
+// a 500k limit also allows us to not have to worry about length when
+// classifying the text: OmniboxViewViews::GetLabelForCommandId and
+// OmniboxEditModel::CanPasteAndGo. If we used a larger limit here (e.g. 2M),
+// then we'd need to limit the text to ~500k later anyways when classifying,
+// because classifying text longer than 500k adds a ~1s delays.
+static const size_t kMaxClipboardTextLength = 500 * 1024;
+
 // Returns the current clipboard contents as a string that can be pasted in.
 // In addition to just getting CF_UNICODETEXT out, this can also extract URLs
 // from bookmarks on the clipboard.
diff --git a/chrome/browser/ui/omnibox/clipboard_utils_unittest.cc b/chrome/browser/ui/omnibox/clipboard_utils_unittest.cc
index 85a23991..3bc1d62 100644
--- a/chrome/browser/ui/omnibox/clipboard_utils_unittest.cc
+++ b/chrome/browser/ui/omnibox/clipboard_utils_unittest.cc
@@ -88,4 +88,22 @@
   EXPECT_TRUE(GetClipboardText().empty());
 }
 
+TEST_F(ClipboardUtilsTest, TruncateLongText) {
+  const base::string16 almost_long_text =
+      base::ASCIIToUTF16(std::string(kMaxClipboardTextLength, '.'));
+  {
+    ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
+    clipboard_writer.WriteText(almost_long_text);
+  }
+  EXPECT_EQ(almost_long_text, GetClipboardText());
+
+  const base::string16 long_text =
+      base::ASCIIToUTF16(std::string(kMaxClipboardTextLength + 1, '.'));
+  {
+    ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
+    clipboard_writer.WriteText(long_text);
+  }
+  EXPECT_EQ(almost_long_text, GetClipboardText());
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
index 6f3c8e5..3e45a1a 100644
--- a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
+++ b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
@@ -98,12 +98,12 @@
     LocalCardMigrationDialogState view_state,
     int card_list_size,
     const base::string16& user_email) {
-  DCHECK_NE((int)user_email.length(), 0);
   auto explanation_text =
       std::make_unique<views::Label>(base::string16(), CONTEXT_BODY_TEXT_LARGE,
                                      ChromeTextStyle::STYLE_SECONDARY);
   switch (view_state) {
     case LocalCardMigrationDialogState::kOffered:
+      DCHECK(!user_email.empty());
       explanation_text->SetText(
           base::i18n::MessageFormatter::FormatWithNumberedArgs(
               l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 5e884bff..6eb2ed07 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -737,8 +737,16 @@
   if (omnibox_view_->model()->is_caret_visible()) {
     background_color = border_color = GetColor(OmniboxPart::RESULTS_BACKGROUND);
   } else {
-    const SkColor normal = GetOmniboxColor(OmniboxPart::LOCATION_BAR_BACKGROUND,
-                                           tint(), OmniboxPartState::NORMAL);
+    // If the white omnibox background experiment is enabled, use the color of
+    // the results box rather than the normal location bar background color.
+    OmniboxPart normal_color_part =
+        base::FeatureList::IsEnabled(
+            omnibox::kUIExperimentWhiteBackgroundOnBlur)
+            ? OmniboxPart::RESULTS_BACKGROUND
+            : OmniboxPart::LOCATION_BAR_BACKGROUND;
+    const SkColor normal =
+        GetOmniboxColor(normal_color_part, tint(), OmniboxPartState::NORMAL);
+
     const SkColor hovered =
         GetOmniboxColor(OmniboxPart::LOCATION_BAR_BACKGROUND, tint(),
                         OmniboxPartState::HOVERED);
@@ -750,10 +758,18 @@
   if (is_popup_mode_) {
     SetBackground(views::CreateSolidBackground(background_color));
   } else {
-    // High contrast schemes get a border stroke even on a rounded omnibox.
-    SkColor stroke_color = GetNativeTheme()->UsesHighContrastColors()
-                               ? border_color
-                               : SK_ColorTRANSPARENT;
+    SkColor stroke_color = SK_ColorTRANSPARENT;
+
+    if (GetNativeTheme()->UsesHighContrastColors()) {
+      // High contrast schemes get a border stroke even on a rounded omnibox.
+      stroke_color = border_color;
+    } else if (base::FeatureList::IsEnabled(
+                   omnibox::kUIExperimentWhiteBackgroundOnBlur)) {
+      const double opacity = hover_animation_.GetCurrentValue();
+      stroke_color = gfx::Tween::ColorValueBetween(opacity, border_color,
+                                                   SK_ColorTRANSPARENT);
+    }
+
     SetBackground(CreateRoundRectBackground(background_color, stroke_color));
   }
 
@@ -1216,6 +1232,7 @@
                    GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
                    GetSecurityChipColor(
                        GetLocationBarModel()->GetSecurityLevel(false)),
+                   GetColor(OmniboxPart::RESULTS_TEXT_URL),
                    std::move(on_icon_fetched))
              : gfx::ImageSkia();
 }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index e283e0b6..d1ae278 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -429,8 +429,17 @@
 // OmniboxResultView, private:
 
 gfx::Image OmniboxResultView::GetIcon() const {
-  return popup_contents_view_->GetMatchIcon(
-      match_, GetColor(OmniboxPart::RESULTS_ICON));
+  SkColor color = GetColor(OmniboxPart::RESULTS_ICON);
+
+  // If the blue search loop experiment is enabled, set the color of search
+  // match icons to be the same as result URLs (conventionally blue).
+  if (base::FeatureList::IsEnabled(
+          omnibox::kUIExperimentBlueSearchLoopAndSearchQuery) &&
+      AutocompleteMatch::IsSearchType(match_.type)) {
+    color = GetColor(OmniboxPart::RESULTS_TEXT_URL);
+  }
+
+  return popup_contents_view_->GetMatchIcon(match_, color);
 }
 
 void OmniboxResultView::SetHovered(bool hovered) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
index 23f1e98d..ae8fb39 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_text_view.cc
@@ -99,6 +99,10 @@
     case SuggestionAnswer::TextStyle::BOLD:
       style = {part_color, .baseline = gfx::NORMAL_BASELINE,
                .weight = gfx::Font::Weight::BOLD};
+      if (base::FeatureList::IsEnabled(
+              omnibox::kUIExperimentUnboldSuggestionText)) {
+        style.weight = gfx::Font::Weight::NORMAL;
+      }
       break;
     case SuggestionAnswer::TextStyle::NORMAL:
     case SuggestionAnswer::TextStyle::NORMAL_DIM:
@@ -258,9 +262,12 @@
             : text_length;
     const gfx::Range current_range(text_start, text_end);
 
-    // Calculate style-related data.
-    if (classifications[i].style & ACMatchClassification::MATCH)
-      render_text_->ApplyWeight(gfx::Font::Weight::BOLD, current_range);
+    if (!base::FeatureList::IsEnabled(
+            omnibox::kUIExperimentUnboldSuggestionText)) {
+      // Calculate style-related data.
+      if (classifications[i].style & ACMatchClassification::MATCH)
+        render_text_->ApplyWeight(gfx::Font::Weight::BOLD, current_range);
+    }
 
     OmniboxPart part = OmniboxPart::RESULTS_TEXT_DEFAULT;
     if (classifications[i].style & ACMatchClassification::URL) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 7024c524..150c087 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -975,16 +975,8 @@
   base::string16 selection_text = gfx::TruncateString(
       clipboard_text, kMaxSelectionTextLength, gfx::WORD_BREAK);
 
-  // If the clipboard text is too long, this command will be disabled, so
-  // we skip the potentially expensive classification of the text and default to
-  // IDS_PASTE_AND_SEARCH.
-  bool paste_and_search =
-      clipboard_text.size() > OmniboxEditModel::kMaxPasteAndGoTextLength ||
-      model()->ClassifiesAsSearch(clipboard_text);
-
-  if (paste_and_search) {
+  if (model()->ClassifiesAsSearch(clipboard_text))
     return l10n_util::GetStringFUTF16(IDS_PASTE_AND_SEARCH, selection_text);
-  }
 
   // To ensure the search and url strings began to truncate at the exact same
   // number of characters, the pixel width at which the url begins to elide is
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc
index afc0e46..3c50c08 100644
--- a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc
@@ -56,7 +56,7 @@
   ExpectBodyContains(
       {"\"billingAddress\": {", "\"666 Erebus St.\"", "\"Apt 8\"",
        "\"city\": \"Elysium\"", "\"dependentLocality\": \"\"",
-       "\"country\": \"US\"", "\"sortingCode\": \"\"", "\"languageCode\": \"\"",
+       "\"country\": \"US\"", "\"sortingCode\": \"\"",
        "\"organization\": \"Underworld\"", "\"phone\": \"+16502111111\"",
        "\"postalCode\": \"91111\"", "\"recipient\": \"John H. Doe\"",
        "\"region\": \"CA\""});
@@ -96,13 +96,12 @@
   PayWithCreditCardAndWait(base::ASCIIToUTF16("123"));
 
   // Test that the shipping address was sent to the merchant.
-  ExpectBodyContains({"\"country\": \"US\"", "\"123 Main Street\"",
-                      "\"Unit 1\"", "\"region\": \"MI\"",
-                      "\"city\": \"Greensdale\"", "\"dependentLocality\": \"\"",
-                      "\"postalCode\": \"48838\"", "\"sortingCode\": \"\"",
-                      "\"languageCode\": \"\"", "\"organization\": \"ACME\"",
-                      "\"recipient\": \"Jane A. Smith\"",
-                      "\"phone\": \"+13105557889\""});
+  ExpectBodyContains(
+      {"\"country\": \"US\"", "\"123 Main Street\"", "\"Unit 1\"",
+       "\"region\": \"MI\"", "\"city\": \"Greensdale\"",
+       "\"dependentLocality\": \"\"", "\"postalCode\": \"48838\"",
+       "\"sortingCode\": \"\"", "\"organization\": \"ACME\"",
+       "\"recipient\": \"Jane A. Smith\"", "\"phone\": \"+13105557889\""});
 
   // Test that the shipping option was sent to the merchant.
   ExpectBodyContains({"\"shippingOption\": \"freeShippingOption\""});
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
index 4baec26..8092e070 100644
--- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.cc
@@ -20,8 +20,10 @@
 #include "components/arc/arc_prefs.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/host_zoom_map.h"
+#include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/content_features.h"
 #include "net/base/url_util.h"
 #include "ui/views/widget/widget.h"
 
@@ -43,6 +45,11 @@
   return gurl;
 }
 
+void DisablePolymer2(content::URLDataSource* shared_source) {
+  if (shared_source)
+    shared_source->DisablePolymer2ForHost(chrome::kChromeUIAssistantOptInHost);
+}
+
 }  // namespace
 
 AssistantOptInUI::AssistantOptInUI(content::WebUI* web_ui)
@@ -70,6 +77,17 @@
       content::HostZoomMap::GetForWebContents(web_ui->GetWebContents());
   DCHECK(zoom_map);
   zoom_map->SetZoomLevelForHost(web_ui->GetWebContents()->GetURL().host(), 0);
+
+  // If allowed, request that the shared resources send this page Polymer 1
+  // resources instead of Polymer 2.
+  // TODO (https://crbug.com/739611): Remove this exception by migrating to
+  // Polymer 2.
+  if (base::FeatureList::IsEnabled(features::kWebUIPolymer2Exceptions)) {
+    content::URLDataSource::GetSourceForURL(
+        Profile::FromWebUI(web_ui),
+        GURL("chrome://resources/polymer/v1_0/polymer/polymer.html"),
+        base::BindOnce(DisablePolymer2));
+  }
 }
 
 AssistantOptInUI::~AssistantOptInUI() = default;
diff --git a/chrome/browser/ui/webui/usb_internals/OWNERS b/chrome/browser/ui/webui/usb_internals/OWNERS
index 08850f4..e59c8c5 100644
--- a/chrome/browser/ui/webui/usb_internals/OWNERS
+++ b/chrome/browser/ui/webui/usb_internals/OWNERS
@@ -1,2 +1,7 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+file://chrome/browser/usb/OWNERS
+
+# COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
diff --git a/chrome/browser/usb/OWNERS b/chrome/browser/usb/OWNERS
index 0b2d5cb..3ca4aa6 100644
--- a/chrome/browser/usb/OWNERS
+++ b/chrome/browser/usb/OWNERS
@@ -1,5 +1,7 @@
 juncai@chromium.org
+odejesush@chromium.org
 reillyg@chromium.org
 rockot@google.com
 
-# COMPONENT: Blink>USB
\ No newline at end of file
+# COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
index b5fd753..600e269 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -87,7 +87,7 @@
   void DisableUI() override;
   bool IsWebAuthnUIEnabled() override;
 
-  // device::FidoRequestHandlerBase::TransportAvailabilityObserver:
+  // device::FidoRequestHandlerBase::Observer:
   void OnTransportAvailabilityEnumerated(
       device::FidoRequestHandlerBase::TransportAvailabilityInfo data) override;
   bool EmbedderControlsAuthenticatorDispatch(
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index a60b250c..af0d0769 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -385,6 +385,7 @@
     content::kChromeUIMediaInternalsHost,
     content::kChromeUINetworkErrorHost,
     content::kChromeUINetworkErrorsListingHost,
+    content::kChromeUIProcessInternalsHost,
     content::kChromeUIServiceWorkerInternalsHost,
 #if !defined(OS_ANDROID)
     content::kChromeUITracingHost,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 8d4e568..c31751e 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2556,6 +2556,7 @@
     "../browser/component_updater/sw_reporter_installer_win_unittest.cc",
     "../browser/conflicts/enumerate_input_method_editors_win_unittest.cc",
     "../browser/conflicts/enumerate_shell_extensions_win_unittest.cc",
+    "../browser/conflicts/inspection_results_cache_win_unittest.cc",
     "../browser/conflicts/module_database_win_unittest.cc",
     "../browser/conflicts/module_event_sink_impl_win_unittest.cc",
     "../browser/conflicts/module_info_util_win_unittest.cc",
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index d5f21fe..a610a86 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -72,7 +72,6 @@
 // that support the Security DevTools domain on the browser target.
 const char* const kCommonSwitches[] = {
     "disable-popup-blocking", "enable-automation", "ignore-certificate-errors",
-    "metrics-recording-only",
 };
 
 const char* const kDesktopSwitches[] = {
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index a9e8f0d..010b6a5 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -349,6 +349,13 @@
     ]
   }
 
+  if (!is_android && !is_ios) {
+    deps += [
+      "//ui/native_theme",
+      "//ui/native_theme:native_theme_browser",
+    ]
+  }
+
   configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
 }
 
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 397c8a9f..dca2d40 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -29,6 +29,10 @@
 #include "ui/accessibility/platform/ax_platform_node.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+#include "ui/native_theme/native_theme.h"  // nogncheck
+#endif
+
 namespace autofill {
 
 namespace {
@@ -352,8 +356,16 @@
   suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS;
   // On Android and Desktop, Google Pay branding is shown along with Settings.
   // So Google Pay Icon is just attached to an existing menu item.
-  if (is_all_server_suggestions)
+  if (is_all_server_suggestions) {
+#if defined(OS_ANDROID) || defined(OS_IOS)
     suggestions->back().icon = "googlePay";
+#else
+    suggestions->back().icon =
+        ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled()
+            ? "googlePayDark"
+            : "googlePay";
+#endif
+  }
 
 // On iOS, GooglePayIcon comes at the begining and hence prepended to the list.
 #if defined(OS_IOS)
diff --git a/components/feature_engagement/internal/tracker_impl.cc b/components/feature_engagement/internal/tracker_impl.cc
index 3e8ce5f..e77243a8 100644
--- a/components/feature_engagement/internal/tracker_impl.cc
+++ b/components/feature_engagement/internal/tracker_impl.cc
@@ -38,7 +38,7 @@
 namespace feature_engagement {
 
 namespace {
-const char kFeatureName[] = "FeatureEngagement";
+
 const char kEventDBName[] = "EventDB";
 const char kAvailabilityDBName[] = "AvailabilityDB";
 
@@ -99,7 +99,7 @@
   base::FilePath event_storage_dir =
       storage_dir.AppendASCII(std::string(kEventDBName));
   auto event_db = db_provider->GetDB<Event>(
-      std::string(kFeatureName), std::string(kEventDBName), event_storage_dir,
+      leveldb_proto::ProtoDbType::FEATURE_ENGAGEMENT_EVENT, event_storage_dir,
       background_task_runner);
 
   auto event_store =
@@ -124,7 +124,7 @@
   base::FilePath availability_storage_dir =
       storage_dir.AppendASCII(std::string(kAvailabilityDBName));
   auto availability_db = db_provider->GetDB<Availability>(
-      std::string(kFeatureName), std::string(kAvailabilityDBName),
+      leveldb_proto::ProtoDbType::FEATURE_ENGAGEMENT_AVAILABILITY,
       availability_storage_dir, background_task_runner);
   auto availability_store_loader = base::BindOnce(
       &PersistentAvailabilityStore::LoadAndUpdateStore,
diff --git a/components/leveldb_proto/internal/proto_database_impl.h b/components/leveldb_proto/internal/proto_database_impl.h
index aa0a6e5..39659c10 100644
--- a/components/leveldb_proto/internal/proto_database_impl.h
+++ b/components/leveldb_proto/internal/proto_database_impl.h
@@ -68,8 +68,7 @@
 
   // Internal implementation is free to choose between unique and shared
   // database to use here (transparently).
-  ProtoDatabaseImpl(const std::string& client_namespace,
-                    const std::string& type_prefix,
+  ProtoDatabaseImpl(ProtoDbType db_type,
                     const base::FilePath& db_dir,
                     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
                     std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
@@ -168,6 +167,7 @@
 
   void PostTransaction(base::OnceClosure task);
 
+  ProtoDbType db_type_;
   scoped_refptr<ProtoDatabaseSelector> db_wrapper_;
   const bool force_unique_db_;
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
@@ -309,7 +309,8 @@
 template <typename T>
 ProtoDatabaseImpl<T>::ProtoDatabaseImpl(
     const scoped_refptr<base::SequencedTaskRunner>& task_runner)
-    : db_wrapper_(new ProtoDatabaseSelector("", "", task_runner, nullptr)),
+    : db_type_(ProtoDbType::LAST),
+      db_wrapper_(new ProtoDatabaseSelector(db_type_, task_runner, nullptr)),
       force_unique_db_(true),
       task_runner_(task_runner),
       weak_ptr_factory_(
@@ -317,13 +318,12 @@
 
 template <typename T>
 ProtoDatabaseImpl<T>::ProtoDatabaseImpl(
-    const std::string& client_namespace,
-    const std::string& type_prefix,
+    ProtoDbType db_type,
     const base::FilePath& db_dir,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
-    : db_wrapper_(new ProtoDatabaseSelector(client_namespace,
-                                            type_prefix,
+    : db_type_(db_type),
+      db_wrapper_(new ProtoDatabaseSelector(db_type_,
                                             task_runner,
                                             std::move(db_provider))),
       force_unique_db_(false),
@@ -357,7 +357,7 @@
     typename Callbacks::InitStatusCallback callback) {
   bool use_shared_db =
       !force_unique_db_ &&
-      SharedProtoDatabaseClientList::ShouldUseSharedDB(client_uma_name);
+      SharedProtoDatabaseClientList::ShouldUseSharedDB(db_type_);
   Init(client_uma_name, use_shared_db, std::move(callback));
 }
 
diff --git a/components/leveldb_proto/internal/proto_database_impl_unittest.cc b/components/leveldb_proto/internal/proto_database_impl_unittest.cc
index f0f6d4f..54a2d89 100644
--- a/components/leveldb_proto/internal/proto_database_impl_unittest.cc
+++ b/components/leveldb_proto/internal/proto_database_impl_unittest.cc
@@ -17,8 +17,6 @@
 
 namespace {
 
-const std::string kDefaultNamespace = "namespace";
-const std::string kDefaultTypePrefix = "prefix";
 const std::string kDefaultClientName = "client";
 
 }  // namespace
@@ -72,14 +70,12 @@
   }
 
   std::unique_ptr<ProtoDatabaseImpl<TestProto>> CreateWrapper(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       const base::FilePath& db_dir,
       const scoped_refptr<base::SequencedTaskRunner>& task_runner,
       std::unique_ptr<SharedProtoDatabaseProvider> db_provider) {
     return std::make_unique<ProtoDatabaseImpl<TestProto>>(
-        client_namespace, type_prefix, db_dir, task_runner,
-        std::move(db_provider));
+        db_type, db_dir, task_runner, std::move(db_provider));
   }
 
   std::unique_ptr<TestProtoDatabaseProvider> CreateProviderNoSharedDB() {
@@ -172,7 +168,7 @@
       SharedDBMetadataProto::MigrationStatus migration_status) {
     base::RunLoop init_wait;
     auto client = shared_db_->GetClientForTesting(
-        kDefaultNamespace, kDefaultTypePrefix, /*create_if_missing=*/true,
+        ProtoDbType::TEST_DATABASE1, /*create_if_missing=*/true,
         base::BindOnce(
             [](base::OnceClosure closure, Enums::InitStatus status,
                SharedDBMetadataProto::MigrationStatus migration_status) {
@@ -200,7 +196,7 @@
     SharedDBMetadataProto::MigrationStatus migration_status;
     base::RunLoop init_wait;
     auto client = shared_db_->GetClientForTesting(
-        kDefaultNamespace, kDefaultTypePrefix, /*create_if_missing=*/true,
+        ProtoDbType::TEST_DATABASE1, /*create_if_missing=*/true,
         base::BindOnce(
             [](base::OnceClosure closure,
                SharedDBMetadataProto::MigrationStatus* output,
@@ -236,8 +232,8 @@
 TEST_F(ProtoDatabaseImplTest, FailsBothDatabases) {
   auto db_provider = CreateProviderNoSharedDB();
   auto shared_db_provider = CreateSharedProvider(db_provider.get());
-  auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                               temp_dir(), GetTestThreadTaskRunner(),
+  auto wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                               GetTestThreadTaskRunner(),
                                CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kError);
@@ -246,8 +242,8 @@
 TEST_F(ProtoDatabaseImplTest, SucceedsWithUnique_DontUseShared_NoSharedDB) {
   auto db_provider = CreateProviderNoSharedDB();
   auto shared_db_provider = CreateSharedProvider(db_provider.get());
-  auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                               temp_dir(), GetTestThreadTaskRunner(),
+  auto wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                               GetTestThreadTaskRunner(),
                                CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
@@ -255,8 +251,8 @@
 
 TEST_F(ProtoDatabaseImplTest, Fails_UseShared_NoSharedDB_NoUniqueDB) {
   auto db_provider = CreateProviderNoSharedDB();
-  auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                               temp_dir(), GetTestThreadTaskRunner(),
+  auto wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                               GetTestThreadTaskRunner(),
                                CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kError);
@@ -265,16 +261,16 @@
 TEST_F(ProtoDatabaseImplTest, SucceedsWithUnique_UseShared_NoSharedDB) {
   // First we create a unique DB so our second pass has a unique DB available.
   auto db_provider = CreateProviderNoSharedDB();
-  auto unique_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                                      temp_dir(), GetTestThreadTaskRunner(),
+  auto unique_wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                                      GetTestThreadTaskRunner(),
                                       CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   // Kill the wrapper so it doesn't have a lock on the DB anymore.
   unique_wrapper.reset();
 
-  auto shared_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                                      temp_dir(), GetTestThreadTaskRunner(),
+  auto shared_wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                                      GetTestThreadTaskRunner(),
                                       CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
@@ -282,8 +278,8 @@
 
 TEST_F(ProtoDatabaseImplTest, SucceedsWithShared_UseShared_HasSharedDB) {
   auto db_provider = CreateProviderWithSharedDB();
-  auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                               temp_dir(), GetTestThreadTaskRunner(),
+  auto wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                               GetTestThreadTaskRunner(),
                                CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
@@ -291,8 +287,8 @@
 
 TEST_F(ProtoDatabaseImplTest, SucceedsWithUnique_DontUseShared_HasSharedDB) {
   auto db_provider = CreateProviderWithSharedDB();
-  auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                               temp_dir(), GetTestThreadTaskRunner(),
+  auto wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                               GetTestThreadTaskRunner(),
                                CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
@@ -302,20 +298,18 @@
 TEST_F(ProtoDatabaseImplTest, Migration_EmptyDBs_UniqueToShared) {
   // First we create a unique DB so our second pass has a unique DB available.
   auto db_provider_noshared = CreateProviderNoSharedDB();
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_noshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_noshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   // Kill the wrapper so it doesn't have a lock on the DB anymore.
   unique_wrapper.reset();
 
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
 
@@ -326,16 +320,16 @@
 TEST_F(ProtoDatabaseImplTest, Migration_EmptyDBs_SharedToUnique) {
   // First we create a unique DB so our second pass has a unique DB available.
   auto db_provider = CreateProviderWithSharedDB();
-  auto shared_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                                      temp_dir(), GetTestThreadTaskRunner(),
+  auto shared_wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                                      GetTestThreadTaskRunner(),
                                       CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
   EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
             GetClientMigrationStatus());
 
-  auto unique_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
-                                      temp_dir(), GetTestThreadTaskRunner(),
+  auto unique_wrapper = CreateWrapper(ProtoDbType::TEST_DATABASE1, temp_dir(),
+                                      GetTestThreadTaskRunner(),
                                       CreateSharedProvider(db_provider.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
@@ -351,10 +345,9 @@
 
   // First we create a unique DB so our second pass has a unique DB available.
   auto db_provider_noshared = CreateProviderNoSharedDB();
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_noshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_noshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(unique_wrapper.get(), data_set.get());
@@ -362,10 +355,9 @@
   unique_wrapper.reset();
 
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
   VerifyDataInWrapper(shared_wrapper.get(), data_set.get());
@@ -382,10 +374,9 @@
 
   // First we create a shared DB so our second pass has a shared DB available.
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(shared_wrapper.get(), data_set.get());
@@ -393,10 +384,9 @@
   EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
             GetClientMigrationStatus());
 
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   VerifyDataInWrapper(unique_wrapper.get(), data_set.get());
@@ -412,10 +402,9 @@
 
   // First we create a unique DB so our second pass has a unique DB available.
   auto db_provider_noshared = CreateProviderNoSharedDB();
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_noshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_noshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(unique_wrapper.get(), data_set.get());
@@ -426,10 +415,9 @@
       SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
 
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
 
@@ -448,20 +436,18 @@
 
   // First we create a shared DB so our second pass has a shared DB available.
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(shared_wrapper.get(), data_set.get());
 
   // Force create an uniquedb, which was deleted by migration.
   auto db_provider_noshared = CreateProviderNoSharedDB();
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_noshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_noshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   unique_wrapper.reset();
@@ -474,10 +460,9 @@
   shared_wrapper.reset();
   db_provider_withshared = CreateProviderWithSharedDB();
 
-  auto shared_wrapper1 =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper1 = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper1.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
 
@@ -496,10 +481,9 @@
 
   // First we create a shared DB so our second pass has a shared DB available.
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(shared_wrapper.get(), data_set.get());
@@ -510,10 +494,9 @@
   UpdateClientMetadata(
       SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
 
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
 
@@ -532,10 +515,9 @@
 
   // First we create a shared DB so our second pass has a shared DB available.
   auto db_provider_noshared = CreateProviderNoSharedDB();
-  auto unique_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_noshared.get()));
+  auto unique_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_noshared.get()));
   InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
   AddDataToWrapper(unique_wrapper.get(), data_set.get());
@@ -546,10 +528,9 @@
   unique_wrapper.reset();
 
   auto db_provider_withshared = CreateProviderWithSharedDB();
-  auto shared_wrapper =
-      CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
-                    GetTestThreadTaskRunner(),
-                    CreateSharedProvider(db_provider_withshared.get()));
+  auto shared_wrapper = CreateWrapper(
+      ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+      CreateSharedProvider(db_provider_withshared.get()));
   InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, false,
                      Enums::InitStatus::kOK);
 
diff --git a/components/leveldb_proto/internal/proto_database_selector.cc b/components/leveldb_proto/internal/proto_database_selector.cc
index 7a8dd7ac..3562345 100644
--- a/components/leveldb_proto/internal/proto_database_selector.cc
+++ b/components/leveldb_proto/internal/proto_database_selector.cc
@@ -26,12 +26,10 @@
 }  // namespace
 
 ProtoDatabaseSelector::ProtoDatabaseSelector(
-    const std::string& client_namespace,
-    const std::string& type_prefix,
+    ProtoDbType db_type,
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
-    : client_namespace_(client_namespace),
-      type_prefix_(type_prefix),
+    : db_type_(db_type),
       task_runner_(task_runner),
       db_provider_(std::move(db_provider)),
       migration_delegate_(std::make_unique<MigrationDelegate>()) {
@@ -134,7 +132,7 @@
   if (shared_db) {
     // If we have a reference to the shared database, try to get a client.
     shared_db->GetClientAsync(
-        client_namespace_, type_prefix_, use_shared_db,
+        db_type_, use_shared_db,
         base::BindOnce(&ProtoDatabaseSelector::OnGetSharedDBClient, this,
                        std::move(unique_db), use_shared_db,
                        std::move(callback)));
diff --git a/components/leveldb_proto/internal/proto_database_selector.h b/components/leveldb_proto/internal/proto_database_selector.h
index 2550ba4f..cd353a4 100644
--- a/components/leveldb_proto/internal/proto_database_selector.h
+++ b/components/leveldb_proto/internal/proto_database_selector.h
@@ -12,6 +12,7 @@
 #include "base/files/file_path.h"
 #include "base/sequenced_task_runner.h"
 #include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
 
 namespace leveldb_proto {
 
@@ -28,8 +29,7 @@
     : public base::RefCountedThreadSafe<ProtoDatabaseSelector> {
  public:
   ProtoDatabaseSelector(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       scoped_refptr<base::SequencedTaskRunner> task_runner,
       std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
 
@@ -153,8 +153,7 @@
       bool success);
   void OnInitDone();
 
-  const std::string client_namespace_;
-  const std::string type_prefix_;
+  ProtoDbType db_type_;
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
   const std::unique_ptr<SharedProtoDatabaseProvider> db_provider_;
   const std::unique_ptr<MigrationDelegate> migration_delegate_;
diff --git a/components/leveldb_proto/internal/shared_proto_database.cc b/components/leveldb_proto/internal/shared_proto_database.cc
index aabb6e1..01802f6 100644
--- a/components/leveldb_proto/internal/shared_proto_database.cc
+++ b/components/leveldb_proto/internal/shared_proto_database.cc
@@ -421,12 +421,11 @@
 }
 
 void SharedProtoDatabase::GetClientAsync(
-    const std::string& client_namespace,
-    const std::string& type_prefix,
+    ProtoDbType db_type,
     bool create_if_missing,
     base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient>)>
         callback) {
-  auto client = GetClientInternal(client_namespace, type_prefix);
+  auto client = GetClientInternal(db_type);
   DCHECK(base::SequencedTaskRunnerHandle::IsSet());
   auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
   SharedProtoDatabaseClient* client_ptr = client.get();
@@ -442,13 +441,12 @@
 // TODO(thildebr): Need to pass the client name into this call as well, and use
 // it with the pending requests too so we can clean up the database.
 std::unique_ptr<SharedProtoDatabaseClient>
-SharedProtoDatabase::GetClientForTesting(const std::string& client_namespace,
-                                         const std::string& type_prefix,
+SharedProtoDatabase::GetClientForTesting(ProtoDbType db_type,
                                          bool create_if_missing,
                                          SharedClientInitCallback callback) {
   DCHECK(base::SequencedTaskRunnerHandle::IsSet());
   auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
-  auto client = GetClientInternal(client_namespace, type_prefix);
+  auto client = GetClientInternal(db_type);
   task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&SharedProtoDatabase::Init, this, create_if_missing,
@@ -458,11 +456,10 @@
 }
 
 std::unique_ptr<SharedProtoDatabaseClient>
-SharedProtoDatabase::GetClientInternal(const std::string& client_namespace,
-                                       const std::string& type_prefix) {
+SharedProtoDatabase::GetClientInternal(ProtoDbType db_type) {
   return base::WrapUnique(new SharedProtoDatabaseClient(
-      std::make_unique<ProtoLevelDBWrapper>(task_runner_, db_.get()),
-      client_namespace, type_prefix, this));
+      std::make_unique<ProtoLevelDBWrapper>(task_runner_, db_.get()), db_type,
+      this));
 }
 
 LevelDB* SharedProtoDatabase::GetLevelDBForTesting() const {
diff --git a/components/leveldb_proto/internal/shared_proto_database.h b/components/leveldb_proto/internal/shared_proto_database.h
index 1470e5b..fb0791bf 100644
--- a/components/leveldb_proto/internal/shared_proto_database.h
+++ b/components/leveldb_proto/internal/shared_proto_database.h
@@ -32,16 +32,14 @@
   // Always returns a SharedProtoDatabaseClient pointer, but that should ONLY
   // be used if the callback returns success.
   std::unique_ptr<SharedProtoDatabaseClient> GetClientForTesting(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       bool create_if_missing,
       SharedClientInitCallback callback);
 
   // A version of GetClient that returns the client in a callback instead of
   // giving back a client instance immediately.
   void GetClientAsync(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       bool create_if_missing,
       base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient>)>
           callback);
@@ -94,8 +92,7 @@
   void ProcessInitRequests(Enums::InitStatus status);
 
   std::unique_ptr<SharedProtoDatabaseClient> GetClientInternal(
-      const std::string& client_namespace,
-      const std::string& type_prefix);
+      ProtoDbType db_type);
 
   void OnGetClientMetadata(
       const std::string& client_db_id,
diff --git a/components/leveldb_proto/internal/shared_proto_database_client.cc b/components/leveldb_proto/internal/shared_proto_database_client.cc
index 56f6441..3038bbc 100644
--- a/components/leveldb_proto/internal/shared_proto_database_client.cc
+++ b/components/leveldb_proto/internal/shared_proto_database_client.cc
@@ -8,14 +8,14 @@
 #include <utility>
 
 #include "base/strings/strcat.h"
-#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
 #include "components/leveldb_proto/internal/shared_proto_database.h"
 #include "components/leveldb_proto/public/shared_proto_database_client_list.h"
 
 namespace leveldb_proto {
 namespace {
-const char* const* g_obsolete_client_list_for_testing = nullptr;
+const ProtoDbType* g_obsolete_client_list_for_testing = nullptr;
 
 // Holds the db wrapper alive and callback is called at destruction. This class
 // is used to post multiple update tasks on |db_wrapper| and keep the instance
@@ -86,10 +86,10 @@
   scoped_refptr<ObsoleteClientsDbHolder> db_holder =
       new ObsoleteClientsDbHolder(std::move(db_wrapper), std::move(callback));
 
-  const char* const* list = g_obsolete_client_list_for_testing
+  const ProtoDbType* list = g_obsolete_client_list_for_testing
                                 ? g_obsolete_client_list_for_testing
-                                : kObsoleteSharedProtoDatabaseClients;
-  for (size_t i = 0; list[i] != nullptr; ++i) {
+                                : kObsoleteSharedProtoDbTypeClients;
+  for (size_t i = 0; list[i] != ProtoDbType::LAST; ++i) {
     // Callback keeps a ref pointer to db_holder alive till the changes are
     // done. |db_holder| will be destroyed once all the RemoveKeys() calls
     // return.
@@ -102,22 +102,26 @@
     // the prefix contains the client namespace at the beginning.
     db_wrapper_ptr->RemoveKeys(
         base::BindRepeating([](const std::string& key) { return true; }),
-        list[i], std::move(callback_wrapper));
+        SharedProtoDatabaseClient::PrefixForDatabase(list[i]),
+        std::move(callback_wrapper));
   }
 }
 
-void SetObsoleteClientListForTesting(const char* const* list) {
+void SetObsoleteClientListForTesting(const ProtoDbType* list) {
   g_obsolete_client_list_for_testing = list;
 }
 
+// static
+std::string SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType db_type) {
+  return base::StringPrintf("%d_", static_cast<int>(db_type));
+}
+
 SharedProtoDatabaseClient::SharedProtoDatabaseClient(
     std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
-    const std::string& client_namespace,
-    const std::string& type_prefix,
+    ProtoDbType db_type,
     const scoped_refptr<SharedProtoDatabase>& parent_db)
     : UniqueProtoDatabase(std::move(db_wrapper)),
-      prefix_(base::JoinString({client_namespace, type_prefix, std::string()},
-                               "_")),
+      prefix_(PrefixForDatabase(db_type)),
       parent_db_(parent_db),
       weak_ptr_factory_(this) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
diff --git a/components/leveldb_proto/internal/shared_proto_database_client.h b/components/leveldb_proto/internal/shared_proto_database_client.h
index b0f93d1..995fec2 100644
--- a/components/leveldb_proto/internal/shared_proto_database_client.h
+++ b/components/leveldb_proto/internal/shared_proto_database_client.h
@@ -13,6 +13,7 @@
 #include "components/leveldb_proto/internal/leveldb_database.h"
 #include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h"
 #include "components/leveldb_proto/internal/unique_proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
 
 namespace leveldb_proto {
 
@@ -52,15 +53,17 @@
     Callbacks::UpdateCallback callback);
 
 // Sets list of client names that are obsolete and will be cleared by next call
-// to DestroyObsoleteSharedProtoDatabaseClients(). |list| is list of c strings
-// with a nullptr to mark the end of list.
-void SetObsoleteClientListForTesting(const char* const* list);
+// to DestroyObsoleteSharedProtoDatabaseClients(). |list| is list of dbs
+// with a |LAST| to mark the end of list.
+void SetObsoleteClientListForTesting(const ProtoDbType* list);
 
 // An implementation of ProtoDatabase<T> that uses a shared LevelDB and task
 // runner.
 // Should be created, destroyed, and used on the same sequenced task runner.
 class SharedProtoDatabaseClient : public UniqueProtoDatabase {
  public:
+  static std::string PrefixForDatabase(ProtoDbType db_type);
+
   ~SharedProtoDatabaseClient() override;
 
   void Init(const std::string& client_uma_name,
@@ -142,8 +145,7 @@
   // Hide this so clients can only be created by the SharedProtoDatabase.
   SharedProtoDatabaseClient(
       std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       const scoped_refptr<SharedProtoDatabase>& parent_db);
 
   static void StripPrefixLoadKeysCallback(
@@ -171,7 +173,6 @@
       SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED;
 
   const std::string prefix_;
-  const std::string client_name_;
 
   scoped_refptr<SharedProtoDatabase> parent_db_;
 
diff --git a/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc b/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
index 9583cd7..86e5662c0 100644
--- a/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
+++ b/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
@@ -13,16 +13,16 @@
 namespace leveldb_proto {
 
 namespace {
-const char kTestClientName[] = "TestClientName";
+const char kTestClientName[] = "TEST_DATABASE1";
 }
 
 class SharedProtoDatabaseClientListTest : public testing::Test {
  public:
   void SetUpExperimentParam(std::string key, std::string value) {
     std::map<std::string, std::string> params = {
-        {"migrate_ClientNameFoo", "true"},
+        {"migrate_TEST_DATABASE0", "true"},
         {"migrate_" + key, value},
-        {"migrate_ClientNameBar", "false"},
+        {"migrate_TEST_DATABASE2", "false"},
     };
 
     scoped_feature_list_.InitAndEnableFeatureWithParameters(
@@ -37,18 +37,18 @@
   // Parameter value is case sensitive
   SetUpExperimentParam(kTestClientName, "true");
 
-  bool use_shared =
-      SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+  bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+      ProtoDbType::TEST_DATABASE1);
 
   ASSERT_TRUE(use_shared);
 }
 
 TEST_F(SharedProtoDatabaseClientListTest,
        ShouldUseSharedDBTest_OnlyWhenParamMatchesName) {
-  SetUpExperimentParam("AnotherClientName", "true");
+  SetUpExperimentParam("TEST_DATABASE10", "true");
 
-  bool use_shared =
-      SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+  bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+      ProtoDbType::TEST_DATABASE1);
 
   ASSERT_FALSE(use_shared);
 }
@@ -57,8 +57,8 @@
        ShouldUseSharedDBTest_OnlyWhenParamValueIsTrue) {
   SetUpExperimentParam(kTestClientName, "false");
 
-  bool use_shared =
-      SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+  bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+      ProtoDbType::TEST_DATABASE1);
 
   ASSERT_FALSE(use_shared);
 }
diff --git a/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc b/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
index d1ed799c..e64ba45 100644
--- a/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
+++ b/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
@@ -15,20 +15,12 @@
 #include "base/test/scoped_task_environment.h"
 #include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
 #include "components/leveldb_proto/internal/shared_proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
 #include "components/leveldb_proto/testing/proto/test_db.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace leveldb_proto {
 
-namespace {
-
-const char* kDefaultNamespace = "abc";
-const char* kDefaultNamespace1 = "cde";
-const char* kDefaultNamespace2 = "cfd";
-const char* kDefaultTypePrefix = "tp";
-
-}  // namespace
-
 class SharedProtoDatabaseClientTest : public testing::Test {
  public:
   void SetUp() override {
@@ -50,14 +42,13 @@
   LevelDB* GetLevelDB() const { return db_->GetLevelDBForTesting(); }
 
   std::unique_ptr<SharedProtoDatabaseClient> GetClient(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       bool create_if_missing,
       Callbacks::InitStatusCallback callback,
       SharedDBMetadataProto::MigrationStatus expected_migration_status =
           SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED) {
     return db_->GetClientForTesting(
-        client_namespace, type_prefix, create_if_missing,
+        db_type, create_if_missing,
         base::BindOnce(
             [](SharedDBMetadataProto::MigrationStatus expected_migration_status,
                Callbacks::InitStatusCallback callback, Enums::InitStatus status,
@@ -69,15 +60,14 @@
   }
 
   std::unique_ptr<SharedProtoDatabaseClient> GetClientAndWait(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       bool create_if_missing,
       Enums::InitStatus* status,
       SharedDBMetadataProto::MigrationStatus expected_migration_status =
           SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED) {
     base::RunLoop loop;
     auto client =
-        GetClient(client_namespace, type_prefix, create_if_missing,
+        GetClient(db_type, create_if_missing,
                   base::BindOnce(
                       [](Enums::InitStatus* status_out,
                          base::OnceClosure closure, Enums::InitStatus status) {
@@ -92,14 +82,13 @@
 
   bool ContainsKeys(const leveldb_proto::KeyVector& db_keys,
                     const leveldb_proto::KeyVector& keys,
-                    const std::string& client_namespace,
-                    const std::string& prefix) {
+                    ProtoDbType db_type) {
     std::set<std::string> key_set(db_keys.begin(), db_keys.end());
     for (auto& key : keys) {
       auto full_key =
-          client_namespace.empty() || prefix.empty()
+          db_type == ProtoDbType::LAST
               ? key
-              : base::JoinString({client_namespace, prefix, key}, "_");
+              : SharedProtoDatabaseClient::PrefixForDatabase(db_type) + key;
       if (key_set.find(full_key) == key_set.end())
         return false;
     }
@@ -108,15 +97,13 @@
 
   bool ContainsEntries(const leveldb_proto::KeyVector& db_keys,
                        const ValueVector& entries,
-                       const std::string& client_namespace,
-                       const std::string& type_prefix) {
+                       ProtoDbType db_type) {
     std::set<std::string> entry_id_set;
     for (auto& entry : entries)
       entry_id_set.insert(entry);
 
     // Entry IDs don't include the full prefix, so we don't look for that here.
-    auto prefix =
-        base::JoinString({client_namespace, type_prefix, std::string()}, "_");
+    auto prefix = SharedProtoDatabaseClient::PrefixForDatabase(db_type);
     for (auto& key : db_keys) {
       if (entry_id_set.find(prefix + key) == entry_id_set.end())
         return false;
@@ -266,7 +253,7 @@
 
   // Sets the obsolete client list to given list, runs clean up tasks and waits
   // for them to complete.
-  void DestroyObsoleteClientsAndWait(const char* const* client_list) {
+  void DestroyObsoleteClientsAndWait(const ProtoDbType* client_list) {
     SetObsoleteClientListForTesting(client_list);
     base::RunLoop wait_loop;
     Callbacks::UpdateCallback wait_callback = base::BindOnce(
@@ -309,7 +296,7 @@
 
 TEST_F(SharedProtoDatabaseClientTest, InitSuccess) {
   auto status = Enums::InitStatus::kError;
-  auto client = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                  true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -320,7 +307,7 @@
 
 TEST_F(SharedProtoDatabaseClientTest, InitFail) {
   auto status = Enums::InitStatus::kError;
-  auto client = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                  false /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kInvalidOperation);
 
@@ -333,7 +320,7 @@
 // removes prefixed entries correctly.
 TEST_F(SharedProtoDatabaseClientTest, UpdateEntriesAppropriatePrefix) {
   auto status = Enums::InitStatus::kError;
-  auto client = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                  true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -345,8 +332,7 @@
   LevelDB* db = GetLevelDB();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), 3U);
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
 
   auto remove_keys = {key_list[0]};
   // Now try to delete one entry.
@@ -355,17 +341,17 @@
   keys.clear();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), 2U);
-  ASSERT_TRUE(ContainsKeys(keys, {key_list[1], key_list[2]}, kDefaultNamespace,
-                           kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, {key_list[1], key_list[2]},
+                           ProtoDbType::TEST_DATABASE0));
 }
 
 TEST_F(SharedProtoDatabaseClientTest,
        UpdateEntries_DeletesCorrectClientEntries) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -377,24 +363,21 @@
   LevelDB* db = GetLevelDB();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), 6U);
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
 
   // Now delete from client_b and ensure only client A's values exist.
   UpdateEntries(client_b.get(), leveldb_proto::KeyVector(), key_list, true);
   keys.clear();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), 3U);
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
 }
 
 TEST_F(SharedProtoDatabaseClientTest,
        UpdateEntriesWithRemoveFilter_DeletesCorrectEntries) {
   auto status = Enums::InitStatus::kError;
-  auto client = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                  true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -418,16 +401,16 @@
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), 2U);
   // Make sure "testentry3" was removed.
-  ASSERT_TRUE(ContainsKeys(keys, {"entry1", "entry2"}, kDefaultNamespace,
-                           kDefaultTypePrefix));
+  ASSERT_TRUE(
+      ContainsKeys(keys, {"entry1", "entry2"}, ProtoDbType::TEST_DATABASE0));
 }
 
 TEST_F(SharedProtoDatabaseClientTest, LoadEntriesWithFilter) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -440,14 +423,14 @@
   LoadEntriesWithFilter(client_a.get(), leveldb_proto::KeyFilter(),
                         leveldb::ReadOptions(), std::string(), true, &entries);
   ASSERT_EQ(entries->size(), 3U);
-  ASSERT_TRUE(ContainsEntries(key_list_a, *entries, kDefaultNamespace,
-                              kDefaultTypePrefix));
+  ASSERT_TRUE(
+      ContainsEntries(key_list_a, *entries, ProtoDbType::TEST_DATABASE0));
 
   LoadEntriesWithFilter(client_b.get(), leveldb_proto::KeyFilter(),
                         leveldb::ReadOptions(), std::string(), true, &entries);
   ASSERT_EQ(entries->size(), 3U);
-  ASSERT_TRUE(ContainsEntries(key_list_b, *entries, kDefaultNamespace2,
-                              kDefaultTypePrefix));
+  ASSERT_TRUE(
+      ContainsEntries(key_list_b, *entries, ProtoDbType::TEST_DATABASE2));
 
   // Now test the actual filtering functionality.
   LoadEntriesWithFilter(
@@ -458,16 +441,16 @@
       }),
       leveldb::ReadOptions(), std::string(), true, &entries);
   ASSERT_EQ(entries->size(), 1U);
-  ASSERT_TRUE(ContainsEntries({"entry2124"}, *entries, kDefaultNamespace2,
-                              kDefaultTypePrefix));
+  ASSERT_TRUE(
+      ContainsEntries({"entry2124"}, *entries, ProtoDbType::TEST_DATABASE2));
 }
 
 TEST_F(SharedProtoDatabaseClientTest, LoadKeysAndEntriesInRange) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -494,15 +477,15 @@
   ASSERT_EQ(keys_and_entries_a->size(), 3U);
   ASSERT_EQ(keys_and_entries_b->size(), 0U);
   ASSERT_TRUE(ContainsEntries({"entry1", "entry2", "entry3"}, entries,
-                              kDefaultNamespace, kDefaultTypePrefix));
+                              ProtoDbType::TEST_DATABASE0));
 }
 
 TEST_F(SharedProtoDatabaseClientTest, LoadKeys) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -514,18 +497,18 @@
   std::unique_ptr<KeyVector> keys;
   LoadKeys(client_a.get(), true, &keys);
   ASSERT_EQ(keys->size(), 4U);
-  ASSERT_TRUE(ContainsKeys(*keys, key_list_a, std::string(), std::string()));
+  ASSERT_TRUE(ContainsKeys(*keys, key_list_a, ProtoDbType::LAST));
   LoadKeys(client_b.get(), true, &keys);
   ASSERT_EQ(keys->size(), 3U);
-  ASSERT_TRUE(ContainsKeys(*keys, key_list_b, std::string(), std::string()));
+  ASSERT_TRUE(ContainsKeys(*keys, key_list_b, ProtoDbType::LAST));
 }
 
 TEST_F(SharedProtoDatabaseClientTest, GetEntry) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -535,10 +518,10 @@
   UpdateEntries(client_a.get(), key_list, leveldb_proto::KeyVector(), true);
   UpdateEntries(client_b.get(), key_list, leveldb_proto::KeyVector(), true);
 
-  auto a_prefix = base::JoinString(
-      {kDefaultNamespace, kDefaultTypePrefix, std::string()}, "_");
-  auto b_prefix = base::JoinString(
-      {kDefaultNamespace2, kDefaultTypePrefix, std::string()}, "_");
+  auto a_prefix =
+      SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType::TEST_DATABASE0);
+  auto b_prefix =
+      SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType::TEST_DATABASE2);
 
   for (auto& key : key_list) {
     auto entry = GetEntry(client_a.get(), key, true);
@@ -550,13 +533,13 @@
 
 TEST_F(SharedProtoDatabaseClientTest, TestCleanupObsoleteClients) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace1, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE1,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_c = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_c = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -574,24 +557,23 @@
   EXPECT_EQ(keys.size(), test_keys.size() * 3);
 
   // Mark some DBs obsolete.
-  const char* const kObsoleteList1[] = {kDefaultNamespace, kDefaultNamespace1,
-                                        nullptr};
+  const ProtoDbType kObsoleteList1[] = {ProtoDbType::TEST_DATABASE0,
+                                        ProtoDbType::TEST_DATABASE1,
+                                        ProtoDbType::LAST};
   DestroyObsoleteClientsAndWait(kObsoleteList1);
 
   keys.clear();
   db->LoadKeys(&keys);
 
   EXPECT_EQ(keys.size(), test_keys.size());
-  EXPECT_FALSE(
-      ContainsKeys(keys, test_keys, kDefaultNamespace, kDefaultTypePrefix));
-  EXPECT_FALSE(
-      ContainsKeys(keys, test_keys, kDefaultNamespace1, kDefaultTypePrefix));
-  EXPECT_TRUE(
-      ContainsKeys(keys, test_keys, kDefaultNamespace2, kDefaultTypePrefix));
+  EXPECT_FALSE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE0));
+  EXPECT_FALSE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE1));
+  EXPECT_TRUE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE2));
 
   // Make all the DBs obsolete.
-  const char* const kObsoleteList2[] = {kDefaultNamespace, kDefaultNamespace1,
-                                        kDefaultNamespace2, nullptr};
+  const ProtoDbType kObsoleteList2[] = {
+      ProtoDbType::TEST_DATABASE0, ProtoDbType::TEST_DATABASE1,
+      ProtoDbType::TEST_DATABASE2, ProtoDbType::LAST};
   DestroyObsoleteClientsAndWait(kObsoleteList2);
 
   // Nothing should remain.
@@ -602,10 +584,10 @@
 
 TEST_F(SharedProtoDatabaseClientTest, TestDestroy) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  auto client_b = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -620,18 +602,15 @@
   LevelDB* db = GetLevelDB();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), key_list.size() * 2);
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
   Destroy(client_a.get(), true);
 
   // Make sure only client B remains and delete client B.
   keys.clear();
   db->LoadKeys(&keys);
   ASSERT_EQ(keys.size(), key_list.size());
-  ASSERT_TRUE(
-      ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+  ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
   Destroy(client_b.get(), true);
 
   // Nothing should remain.
@@ -642,19 +621,19 @@
 
 TEST_F(SharedProtoDatabaseClientTest, UpdateClientMetadataAsync) {
   auto status = Enums::InitStatus::kError;
-  auto client_a = GetClientAndWait(kDefaultNamespace, kDefaultTypePrefix,
+  auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
                                    true /* create_if_missing */, &status);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
   EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
             client_a->migration_status());
 
-  auto client_b = GetClientAndWait(kDefaultNamespace1, kDefaultTypePrefix,
+  auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE1,
                                    true /* create_if_missing */, &status);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
   EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
             client_b->migration_status());
 
-  auto client_c = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_c = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
   EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
@@ -671,16 +650,16 @@
   client_c.reset();
 
   auto client_d = GetClientAndWait(
-      kDefaultNamespace, kDefaultTypePrefix, true /* create_if_missing */,
-      &status, SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
+      ProtoDbType::TEST_DATABASE0, true /* create_if_missing */, &status,
+      SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
 
   auto client_e = GetClientAndWait(
-      kDefaultNamespace1, kDefaultTypePrefix, true /* create_if_missing */,
-      &status, SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+      ProtoDbType::TEST_DATABASE1, true /* create_if_missing */, &status,
+      SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
 
-  auto client_f = GetClientAndWait(kDefaultNamespace2, kDefaultTypePrefix,
+  auto client_f = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
                                    true /* create_if_missing */, &status);
   EXPECT_EQ(status, Enums::InitStatus::kOK);
 
diff --git a/components/leveldb_proto/internal/shared_proto_database_unittest.cc b/components/leveldb_proto/internal/shared_proto_database_unittest.cc
index a2699101..e2a59649 100644
--- a/components/leveldb_proto/internal/shared_proto_database_unittest.cc
+++ b/components/leveldb_proto/internal/shared_proto_database_unittest.cc
@@ -18,16 +18,11 @@
 
 namespace {
 
-const std::string kDefaultNamespace = "ns";
-const std::string kDefaultNamespace2 = "ns2";
-const std::string kDefaultTypePrefix = "tp";
-
 inline void GetClientFromTaskRunner(SharedProtoDatabase* db,
-                                    const std::string& client_namespace,
-                                    const std::string& type_prefix,
+                                    ProtoDbType db_type,
                                     base::OnceClosure closure) {
   db->GetClientForTesting(
-      client_namespace, type_prefix, true /* create_if_missing */,
+      db_type, true /* create_if_missing */,
       base::BindOnce(
           [](base::OnceClosure closure, Enums::InitStatus status,
              SharedDBMetadataProto::MigrationStatus migration_status) {
@@ -69,13 +64,12 @@
 
   std::unique_ptr<SharedProtoDatabaseClient> GetClientAndWait(
       SharedProtoDatabase* db,
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       bool create_if_missing,
       Enums::InitStatus* status) {
     base::RunLoop loop;
     auto client = db->GetClientForTesting(
-        client_namespace, type_prefix, create_if_missing,
+        db_type, create_if_missing,
         base::BindOnce(
             [](Enums::InitStatus* status_out, base::OnceClosure closure,
                Enums::InitStatus status,
@@ -106,7 +100,7 @@
 
 TEST_F(SharedProtoDatabaseTest, CreateClient_SucceedsWithCreate) {
   auto status = Enums::InitStatus::kError;
-  GetClientAndWait(db(), kDefaultNamespace, kDefaultTypePrefix,
+  GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 }
@@ -118,7 +112,7 @@
 TEST_F(SharedProtoDatabaseTest, CreateClient_FailsWithoutCreate) {
 #endif
   auto status = Enums::InitStatus::kError;
-  GetClientAndWait(db(), kDefaultNamespace, kDefaultTypePrefix,
+  GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
                    false /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kInvalidOperation);
 }
@@ -126,17 +120,17 @@
 TEST_F(SharedProtoDatabaseTest,
        CreateClient_SucceedsWithoutCreateIfAlreadyCreated) {
   auto status = Enums::InitStatus::kError;
-  GetClientAndWait(db(), kDefaultNamespace2, kDefaultTypePrefix,
+  GetClientAndWait(db(), ProtoDbType::TEST_DATABASE2,
                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
-  GetClientAndWait(db(), kDefaultNamespace, kDefaultTypePrefix,
+  GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
                    false /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 }
 
 TEST_F(SharedProtoDatabaseTest, GetClient_DifferentThreads) {
   auto status = Enums::InitStatus::kError;
-  GetClientAndWait(db(), kDefaultNamespace, kDefaultTypePrefix,
+  GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
                    true /* create_if_missing */, &status);
   ASSERT_EQ(status, Enums::InitStatus::kOK);
 
@@ -144,9 +138,9 @@
   ASSERT_TRUE(t.Start());
   base::RunLoop run_loop;
   t.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&GetClientFromTaskRunner,
-                                base::Unretained(db()), kDefaultNamespace2,
-                                kDefaultTypePrefix, run_loop.QuitClosure()));
+      FROM_HERE,
+      base::BindOnce(&GetClientFromTaskRunner, base::Unretained(db()),
+                     ProtoDbType::TEST_DATABASE2, run_loop.QuitClosure()));
   run_loop.Run();
   base::RunLoop quit_cooldown;
   GetMainThreadTaskRunner()->PostDelayedTask(
@@ -157,7 +151,7 @@
 // backing LevelDB has been initialized on another thread.
 TEST_F(SharedProtoDatabaseTest, TestDBDestructionAfterInit) {
   base::RunLoop run_init_loop;
-  InitDB(true /* create_if_missing */, kDefaultNamespace,
+  InitDB(true /* create_if_missing */, "TestDatabaseUMA",
          base::BindOnce(
              [](base::OnceClosure signal, Enums::InitStatus status,
                 SharedDBMetadataProto::MigrationStatus migration_status) {
diff --git a/components/leveldb_proto/public/proto_database_provider.h b/components/leveldb_proto/public/proto_database_provider.h
index a5817d5..bd221b0b 100644
--- a/components/leveldb_proto/public/proto_database_provider.h
+++ b/components/leveldb_proto/public/proto_database_provider.h
@@ -11,6 +11,7 @@
 #include "components/leveldb_proto/internal/proto_database_impl.h"
 #include "components/leveldb_proto/internal/shared_proto_database_provider.h"
 #include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
 
 namespace leveldb_proto {
 
@@ -31,19 +32,15 @@
     return std::make_unique<ProtoDatabaseImpl<T>>(task_runner);
   }
 
-  // |client_namespace| is the unique prefix to be used in the shared database
-  // if the database returned is a SharedDatabaseClient<T>. This name must be
-  // present in |kCurrentSharedProtoDatabaseClients|. |type_prefix| is a unique
-  // prefix within the |client_namespace| to be used in the shared database if
-  // the database returned is a SharedProtoDatabaseClient<T>. |unique_db_dir|:
+  // |db_type|: Each database should have a type specified in ProtoDbType enum.
+  // This type is used to index data in the shared database. |unique_db_dir|:
   // the subdirectory this database should live in within the profile directory.
   // |task_runner|: the SequencedTaskRunner to run all database operations on.
   // This isn't used by SharedProtoDatabaseClients since all calls using
   // the SharedProtoDatabase will run on its TaskRunner.
   template <typename T>
   std::unique_ptr<ProtoDatabase<T>> GetDB(
-      const std::string& client_namespace,
-      const std::string& type_prefix,
+      ProtoDbType db_type,
       const base::FilePath& unique_db_dir,
       const scoped_refptr<base::SequencedTaskRunner>& task_runner);
 
@@ -78,12 +75,11 @@
 
 template <typename T>
 std::unique_ptr<ProtoDatabase<T>> ProtoDatabaseProvider::GetDB(
-    const std::string& client_namespace,
-    const std::string& type_prefix,
+    ProtoDbType db_type,
     const base::FilePath& unique_db_dir,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
   return base::WrapUnique(new ProtoDatabaseImpl<T>(
-      client_namespace, type_prefix, unique_db_dir, task_runner,
+      db_type, unique_db_dir, task_runner,
       base::WrapUnique(new SharedProtoDatabaseProvider(
           creation_sequence_, weak_factory_.GetWeakPtr()))));
 }
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.cc b/components/leveldb_proto/public/shared_proto_database_client_list.cc
index ccb7b6e7..64d46e1 100644
--- a/components/leveldb_proto/public/shared_proto_database_client_list.cc
+++ b/components/leveldb_proto/public/shared_proto_database_client_list.cc
@@ -15,11 +15,49 @@
 
 namespace leveldb_proto {
 
+namespace {
+
+std::string PtotoDbTypeToString(ProtoDbType db_type) {
+  switch (db_type) {
+    case ProtoDbType::FEATURE_ENGAGEMENT_EVENT:
+      return "FEATURE_ENGAGEMENT_EVENT";
+    case ProtoDbType::FEATURE_ENGAGEMENT_AVAILABILITY:
+      return "FEATURE_ENGAGEMENT_AVAILABILITY";
+    case ProtoDbType::USAGE_STATS_WEBSITE_EVENT:
+      return "USAGE_STATS_WEBSITE_EVENT";
+    case ProtoDbType::USAGE_STATS_SUSPENSION:
+      return "USAGE_STATS_SUSPENSION";
+    case ProtoDbType::USAGE_STATS_TOKEN_MAPPING:
+      return "USAGE_STATS_TOKEN_MAPPING";
+    case ProtoDbType::LAST:
+      NOTREACHED();
+      break;
+    case ProtoDbType::TEST_DATABASE0:
+      return "TEST_DATABASE0";
+    case ProtoDbType::TEST_DATABASE1:
+      return "TEST_DATABASE1";
+    case ProtoDbType::TEST_DATABASE2:
+      return "TEST_DATABASE2";
+  }
+  return std::string();
+}
+
+constexpr ProtoDbType kWhitelistedListForSharedImpl[]{
+    ProtoDbType::LAST,  // Marks the end of list.
+};
+
 const char* const kDBNameParamPrefix = "migrate_";
 
+}  // namespace
+
 // static
-bool SharedProtoDatabaseClientList::ShouldUseSharedDB(
-    const std::string& client_name) {
+bool SharedProtoDatabaseClientList::ShouldUseSharedDB(ProtoDbType db_type) {
+  for (size_t i = 0; kWhitelistedListForSharedImpl[i] != ProtoDbType::LAST;
+       ++i) {
+    if (kWhitelistedListForSharedImpl[i] == db_type)
+      return true;
+  }
+
   if (!base::FeatureList::IsEnabled(kProtoDBSharedMigration))
     return false;
 
@@ -27,8 +65,9 @@
   if (!base::GetFieldTrialParamsByFeature(kProtoDBSharedMigration, &params))
     return false;
 
+  std::string name = PtotoDbTypeToString(db_type);
   return base::GetFieldTrialParamByFeatureAsBool(
-      kProtoDBSharedMigration, kDBNameParamPrefix + client_name, false);
+      kProtoDBSharedMigration, kDBNameParamPrefix + name, false);
 }
 
 }  // namespace leveldb_proto
\ No newline at end of file
diff --git a/components/leveldb_proto/public/shared_proto_database_client_list.h b/components/leveldb_proto/public/shared_proto_database_client_list.h
index 5fefa7e7..211a24ab 100644
--- a/components/leveldb_proto/public/shared_proto_database_client_list.h
+++ b/components/leveldb_proto/public/shared_proto_database_client_list.h
@@ -13,21 +13,37 @@
 
 const char* const kFeatureEngagementName = "FeatureEngagement";
 
-// NOTE: The client names should not have partial or complete prefix overlap
-// with any other client name, current or obsolete. Internally the stored data
-// is grouped by the prefix of client name. These names cannot be renamed
-// without adding the old name to obsolete client list and such rename would
-// make the client be treated as a new client.
-const char* const kCurrentSharedProtoDatabaseClients[] = {
-    kFeatureEngagementName, nullptr};
+// The enum values are used to index into the shared database. Do not rearrange
+// or reuse the integer values. Add new database types at the end of the enum,
+// and update the string mapping in client_list.cc file.
+enum class ProtoDbType {
+  TEST_DATABASE0 = 0,
+  TEST_DATABASE1 = 1,
+  TEST_DATABASE2 = 2,
+  FEATURE_ENGAGEMENT_EVENT = 3,
+  FEATURE_ENGAGEMENT_AVAILABILITY = 4,
+  USAGE_STATS_WEBSITE_EVENT = 5,
+  USAGE_STATS_SUSPENSION = 6,
+  USAGE_STATS_TOKEN_MAPPING = 7,
 
-const char* const kObsoleteSharedProtoDatabaseClients[] = {
-    nullptr  // Marks the last element.
+  LAST,
+};
+
+// List of databases that were introduced after shared db implementation was
+// created. These will be forced to use shared database implementation.
+constexpr ProtoDbType kWhitelistedDbForSharedImpl[]{
+    ProtoDbType::LAST,  // Marks the end of list.
+};
+
+// Add any obsolete databases in this list so that, if the data is no longer
+// needed.
+constexpr ProtoDbType kObsoleteSharedProtoDbTypeClients[] = {
+    ProtoDbType::LAST,  // Marks the end of list.
 };
 
 class SharedProtoDatabaseClientList {
  public:
-  static bool ShouldUseSharedDB(const std::string& client_name);
+  static bool ShouldUseSharedDB(ProtoDbType db_type);
 };
 
 }  // namespace leveldb_proto
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index 526ff27..980c13e 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -235,6 +235,29 @@
     search_provider_ = new SearchProvider(provider_client_.get(), this);
     providers_.push_back(search_provider_);
   }
+  // It's important that the HistoryURLProvider gets added after SearchProvider:
+  // AutocompleteController::Start() calls each providers' Start() function
+  // synchronously in the order they're in in providers_.
+  // - SearchProvider::Start() synchronously queries the history database's
+  //   keyword_search_terms and url table.
+  // - HistoryUrlProvider::Start schedules a background task that also accesses
+  //   the history database.
+  // If both db accesses happen concurrently, TSan complains.
+  // So put HistoryURLProvider later to make sure that SearchProvider is done
+  // doing its thing by the time the HistoryURLProvider task runs.
+  // (And hope that it completes before AutocompleteController::Start() is
+  // called the next time.)
+  // ZeroSuggestProvider and ClipboardURLProvider take a reference to
+  // HistoryURLProvider. If we're going to need either, we should initialize
+  // history_url_provider_.
+  if (provider_types & (AutocompleteProvider::TYPE_HISTORY_URL |
+                        AutocompleteProvider::TYPE_ZERO_SUGGEST |
+                        AutocompleteProvider::TYPE_CLIPBOARD_URL)) {
+    history_url_provider_ =
+        new HistoryURLProvider(provider_client_.get(), this);
+    if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL)
+      providers_.push_back(history_url_provider_);
+  }
   if (provider_types & AutocompleteProvider::TYPE_SHORTCUTS)
     providers_.push_back(new ShortcutsProvider(provider_client_.get()));
   if (provider_types & AutocompleteProvider::TYPE_ZERO_SUGGEST) {
@@ -269,25 +292,6 @@
     }
   }
 
-  // It's important that the HistoryURLProvider gets added last, or at least
-  // after SearchProvider:
-  // AutocompleteController::Start() calls each providers' Start() function
-  // synchronously in the order they're in in providers_.
-  // - SearchProvider::Start() synchronously queries the history database's
-  //   keyword_search_terms and url table.
-  // - HistoryUrlProvider::Start schedules a background task that also accesses
-  //   the history database.
-  // If both db accesses happen concurrently, TSan complains.
-  // So put HistoryURLProvider later to make sure that SearchProvider is done
-  // doing its thing by the time the HistoryURLProvider task runs.
-  // (And hope that it completes before AutocompleteController::Start() is
-  // called the next time.)
-  if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) {
-    history_url_provider_ =
-        new HistoryURLProvider(provider_client_.get(), this);
-    providers_.push_back(history_url_provider_);
-  }
-
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
       this, "AutocompleteController", base::ThreadTaskRunnerHandle::Get());
 }
diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc
index c13b07d..573db1f 100644
--- a/components/omnibox/browser/autocomplete_provider.cc
+++ b/components/omnibox/browser/autocomplete_provider.cc
@@ -8,15 +8,17 @@
 #include <set>
 #include <string>
 
+#include "base/feature_list.h"
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
 #include "components/omnibox/browser/autocomplete_i18n.h"
 #include "components/omnibox/browser/autocomplete_input.h"
 #include "components/omnibox/browser/autocomplete_match.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/url_formatter/url_fixer.h"
 #include "url/gurl.h"
 
@@ -110,13 +112,24 @@
 
   base::string16 text_lowercase(base::i18n::ToLower(text));
 
-  const ACMatchClassification::Style& class_of_find_text =
+  ACMatchClassification::Style class_of_find_text =
       text_is_search_query ? ACMatchClassification::NONE
                            : ACMatchClassification::MATCH;
-  const ACMatchClassification::Style& class_of_additional_text =
+  ACMatchClassification::Style class_of_additional_text =
       text_is_search_query ? ACMatchClassification::MATCH
                            : ACMatchClassification::NONE;
 
+  // For this experiment, we want to color the search query text blue like URLs.
+  // Therefore, we add the URL class to the find and additional text.
+  if (base::FeatureList::IsEnabled(
+          omnibox::kUIExperimentBlueSearchLoopAndSearchQuery) &&
+      text_is_search_query) {
+    class_of_find_text = (ACMatchClassification::Style)(
+        class_of_find_text | ACMatchClassification::URL);
+    class_of_additional_text = (ACMatchClassification::Style)(
+        class_of_additional_text | ACMatchClassification::URL);
+  }
+
   ACMatchClassifications match_class;
   size_t current_position = 0;
 
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index fb00a1c..cd3a09ef 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -533,9 +533,6 @@
   if (!client_->IsPasteAndGoEnabled())
     return false;
 
-  if (text.length() > kMaxPasteAndGoTextLength)
-    return false;
-
   AutocompleteMatch match;
   ClassifyString(text, &match, nullptr);
   return match.destination_url.is_valid();
diff --git a/components/omnibox/browser/omnibox_edit_model.h b/components/omnibox/browser/omnibox_edit_model.h
index 9bfda32..72d7fc76 100644
--- a/components/omnibox/browser/omnibox_edit_model.h
+++ b/components/omnibox/browser/omnibox_edit_model.h
@@ -72,11 +72,6 @@
     DISALLOW_ASSIGN(State);
   };
 
-  // This is a mirror of content::kMaxURLDisplayChars because ios cannot depend
-  // on content. If clipboard contains more than kMaxPasteAndGoTextLength
-  // characters, then the paste & go option will be disabled.
-  static const size_t kMaxPasteAndGoTextLength = 32 * 1024;
-
   OmniboxEditModel(OmniboxView* view,
                    OmniboxEditController* controller,
                    std::unique_ptr<OmniboxClient> client);
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc
index 5b2f744a..e59363a 100644
--- a/components/omnibox/browser/omnibox_edit_model_unittest.cc
+++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -391,19 +391,6 @@
   EXPECT_TRUE(model()->ShouldShowCurrentPageIcon());
 }
 
-TEST_F(OmniboxEditModelTest, DisablePasteAndGoForLongTexts) {
-  EXPECT_TRUE(model()->OmniboxEditModel::CanPasteAndGo(
-      base::ASCIIToUTF16("short text")));
-
-  base::string16 almost_long_text = base::ASCIIToUTF16(
-      std::string(OmniboxEditModel::kMaxPasteAndGoTextLength, '.'));
-  EXPECT_TRUE(model()->OmniboxEditModel::CanPasteAndGo(almost_long_text));
-
-  base::string16 long_text = base::ASCIIToUTF16(
-      std::string(OmniboxEditModel::kMaxPasteAndGoTextLength + 1, '.'));
-  EXPECT_FALSE(model()->OmniboxEditModel::CanPasteAndGo(long_text));
-}
-
 // The tab-switching system sometimes focuses the Omnibox even if it was not
 // previously focused. In those cases, ignore the saved focus state.
 TEST_F(OmniboxEditModelTest, IgnoreInvalidSavedFocusStates) {
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 4a45405d..45a1bfd 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -227,18 +227,37 @@
 const base::Feature kUIExperimentVerticalMargin{
     "OmniboxUIExperimentVerticalMargin", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to color "blue" the generic search icon and search terms.
+// Technically, this makes the search icon and search terms match the color of
+// Omnibox link text, which is blue by convention.
+const base::Feature kUIExperimentBlueSearchLoopAndSearchQuery{
+    "OmniboxUIExperimentBlueSearchLoopAndSearchQuery",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Feature used to show a " - Google Search", " - Bing Search", etc. suffix on
 // all search suggestions instead of just the first one in each cluster.
 const base::Feature kUIExperimentShowSuffixOnAllSearchSuggestions{
     "OmniboxUIExperimentShowSuffixOnAllSearchSuggestions",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to show a white background in the omnibox while it's unfocused.
+// More technically, with this flag on, it uses the same background color as
+// the results popup (conventionally white).
+const base::Feature kUIExperimentWhiteBackgroundOnBlur{
+    "OmniboxUIExperimentWhiteBackgroundOnBlur",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Feature used to show a generic vector icon for omnibox search instead of the
 // search engine favicon.
 extern const base::Feature kUIExperimentUseGenericSearchEngineIcon{
     "OminboxUIExperimentUseGenericSearchEngineIcon",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to unbold suggestion text.
+const base::Feature kUIExperimentUnboldSuggestionText{
+    "OmniboxUIExperimentUnboldSuggestionText",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Feature used to enable speculatively starting a service worker associated
 // with the destination of the default match when the user's input looks like a
 // query.
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index c90faa54..4ad7bbc 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -51,8 +51,11 @@
 extern const base::Feature kUIExperimentShowSuggestionFavicons;
 extern const base::Feature kUIExperimentSwapTitleAndUrl;
 extern const base::Feature kUIExperimentVerticalMargin;
+extern const base::Feature kUIExperimentBlueSearchLoopAndSearchQuery;
 extern const base::Feature kUIExperimentShowSuffixOnAllSearchSuggestions;
+extern const base::Feature kUIExperimentWhiteBackgroundOnBlur;
 extern const base::Feature kUIExperimentUseGenericSearchEngineIcon;
+extern const base::Feature kUIExperimentUnboldSuggestionText;
 extern const base::Feature kSpeculativeServiceWorkerStartOnQueryInput;
 extern const base::Feature kDocumentProvider;
 extern const base::Feature kDedupeGoogleDriveURLs;
diff --git a/components/omnibox/browser/omnibox_view.cc b/components/omnibox/browser/omnibox_view.cc
index e476b479..c426c56 100644
--- a/components/omnibox/browser/omnibox_view.cc
+++ b/components/omnibox/browser/omnibox_view.cc
@@ -110,6 +110,7 @@
 // want to consider reusing the same code for both the popup and omnibox icons.
 gfx::ImageSkia OmniboxView::GetIcon(int dip_size,
                                     SkColor color,
+                                    SkColor search_alternate_color,
                                     IconFetchedCallback on_icon_fetched) const {
 #if defined(OS_ANDROID) || defined(OS_IOS)
   // This is used on desktop only.
@@ -166,6 +167,16 @@
       bookmark_model && bookmark_model->IsBookmarked(match.destination_url);
 
   const gfx::VectorIcon& vector_icon = match.GetVectorIcon(is_bookmarked);
+
+  // When the blue search loop experiment is enabled, the in-omnibox vector
+  // icon for search type matches should be blue as well. This icon is used if
+  // the default search engine favicon has not yet been fetched, or is disabled.
+  if (base::FeatureList::IsEnabled(
+          omnibox::kUIExperimentBlueSearchLoopAndSearchQuery) &&
+      AutocompleteMatch::IsSearchType(match.type)) {
+    return gfx::CreateVectorIcon(vector_icon, dip_size, search_alternate_color);
+  }
+
   return gfx::CreateVectorIcon(vector_icon, dip_size, color);
 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
 }
diff --git a/components/omnibox/browser/omnibox_view.h b/components/omnibox/browser/omnibox_view.h
index d5b3cd41..15e0f53 100644
--- a/components/omnibox/browser/omnibox_view.h
+++ b/components/omnibox/browser/omnibox_view.h
@@ -91,8 +91,11 @@
 
   // Returns the icon to display as the location icon. If a favicon is
   // available, |on_icon_fetched| may be called later asynchronously.
+  // |search_alternate_color| should match the color used for URL text, and may
+  // be used for search suggestions depending on some flags.
   gfx::ImageSkia GetIcon(int dip_size,
                          SkColor color,
+                         SkColor search_alternate_color,
                          IconFetchedCallback on_icon_fetched) const;
 
   // The user text is the text the user has manually keyed in.  When present,
diff --git a/components/omnibox/browser/omnibox_view_unittest.cc b/components/omnibox/browser/omnibox_view_unittest.cc
index 1d3c68d..628b261 100644
--- a/components/omnibox/browser/omnibox_view_unittest.cc
+++ b/components/omnibox/browser/omnibox_view_unittest.cc
@@ -145,8 +145,9 @@
   gfx::ImageSkia expected_icon = gfx::CreateVectorIcon(
       vector_icons::kSearchIcon, gfx::kFaviconSize, gfx::kPlaceholderColor);
 
-  gfx::ImageSkia icon = view()->GetIcon(
-      gfx::kFaviconSize, gfx::kPlaceholderColor, base::DoNothing());
+  gfx::ImageSkia icon =
+      view()->GetIcon(gfx::kFaviconSize, gfx::kPlaceholderColor,
+                      gfx::kPlaceholderColor, base::DoNothing());
 
   EXPECT_EQ(icon.bitmap(), expected_icon.bitmap());
 }
@@ -165,8 +166,9 @@
   gfx::ImageSkia expected_icon = gfx::CreateVectorIcon(
       omnibox::kBookmarkIcon, gfx::kFaviconSize, gfx::kPlaceholderColor);
 
-  gfx::ImageSkia icon = view()->GetIcon(
-      gfx::kFaviconSize, gfx::kPlaceholderColor, base::DoNothing());
+  gfx::ImageSkia icon =
+      view()->GetIcon(gfx::kFaviconSize, gfx::kPlaceholderColor,
+                      gfx::kPlaceholderColor, base::DoNothing());
 
   EXPECT_EQ(icon.bitmap(), expected_icon.bitmap());
 }
@@ -180,7 +182,8 @@
   match.destination_url = kUrl;
   model()->SetCurrentMatchForTest(match);
 
-  view()->GetIcon(gfx::kFaviconSize, gfx::kPlaceholderColor, base::DoNothing());
+  view()->GetIcon(gfx::kFaviconSize, gfx::kPlaceholderColor,
+                  gfx::kPlaceholderColor, base::DoNothing());
 
   EXPECT_EQ(client()->GetPageUrlForLastFaviconRequest(), kUrl);
 }
diff --git a/components/payments/content/payment_request_state_unittest.cc b/components/payments/content/payment_request_state_unittest.cc
index a5d932af..e53508b 100644
--- a/components/payments/content/payment_request_state_unittest.cc
+++ b/components/payments/content/payment_request_state_unittest.cc
@@ -446,7 +446,6 @@
   EXPECT_EQ("", selected_shipping_address()->dependent_locality);
   EXPECT_EQ("91111", selected_shipping_address()->postal_code);
   EXPECT_EQ("", selected_shipping_address()->sorting_code);
-  EXPECT_EQ("", selected_shipping_address()->language_code);
   EXPECT_EQ("Underworld", selected_shipping_address()->organization);
   EXPECT_EQ("John H. Doe", selected_shipping_address()->recipient);
   EXPECT_EQ("16502111111", selected_shipping_address()->phone);
@@ -472,7 +471,6 @@
                                  "jon.doe@exampl.com", "Example Inc",
                                  "Roppongi", "6 Chrome-10-1", "Tokyo", "",
                                  "106-6126", "JP", "+81363849000");
-  profile.set_language_code("ja-Latn");
 
   state()->SetSelectedShippingProfile(&profile);
   EXPECT_EQ(0, num_on_selected_information_changed_called());
@@ -500,8 +498,6 @@
   EXPECT_EQ("", selected_shipping_address()->dependent_locality);
   EXPECT_EQ("106-6126", selected_shipping_address()->postal_code);
   EXPECT_EQ("", selected_shipping_address()->sorting_code);
-  EXPECT_EQ("ja", selected_shipping_address()->language_code);
-  EXPECT_EQ("Latn", selected_shipping_address()->script_code);
   EXPECT_EQ("Example Inc", selected_shipping_address()->organization);
   EXPECT_EQ("Jon V. Doe", selected_shipping_address()->recipient);
   EXPECT_EQ("+81363849000", selected_shipping_address()->phone);
diff --git a/components/payments/content/payment_response_helper_unittest.cc b/components/payments/content/payment_response_helper_unittest.cc
index 07abec8c..c28795f9 100644
--- a/components/payments/content/payment_response_helper_unittest.cc
+++ b/components/payments/content/payment_response_helper_unittest.cc
@@ -121,7 +121,6 @@
       "\"city\":\"Elysium\","
       "\"country\":\"US\","
       "\"dependentLocality\":\"\","
-      "\"languageCode\":\"\","
       "\"organization\":\"Underworld\","
       "\"phone\":\"16502111111\","
       "\"postalCode\":\"91111\","
@@ -160,7 +159,6 @@
       "\"city\":\"Elysium\","
       "\"country\":\"US\","
       "\"dependentLocality\":\"\","
-      "\"languageCode\":\"\","
       "\"organization\":\"Underworld\","
       "\"phone\":\"16502111111\","
       "\"postalCode\":\"91111\","
@@ -204,7 +202,6 @@
   EXPECT_EQ("", response()->shipping_address->dependent_locality);
   EXPECT_EQ("91111", response()->shipping_address->postal_code);
   EXPECT_EQ("", response()->shipping_address->sorting_code);
-  EXPECT_EQ("", response()->shipping_address->language_code);
   EXPECT_EQ("Underworld", response()->shipping_address->organization);
   EXPECT_EQ("John H. Doe", response()->shipping_address->recipient);
   EXPECT_EQ("16502111111", response()->shipping_address->phone);
diff --git a/components/payments/core/payment_address.cc b/components/payments/core/payment_address.cc
index e316b5e..78cfdd02 100644
--- a/components/payments/core/payment_address.cc
+++ b/components/payments/core/payment_address.cc
@@ -16,7 +16,6 @@
 static const char kAddressCity[] = "city";
 static const char kAddressCountry[] = "country";
 static const char kAddressDependentLocality[] = "dependentLocality";
-static const char kAddressLanguageCode[] = "languageCode";
 static const char kAddressOrganization[] = "organization";
 static const char kAddressPhone[] = "phone";
 static const char kAddressPostalCode[] = "postalCode";
@@ -41,7 +40,6 @@
   result->SetString(kAddressDependentLocality, address.dependent_locality);
   result->SetString(kAddressPostalCode, address.postal_code);
   result->SetString(kAddressSortingCode, address.sorting_code);
-  result->SetString(kAddressLanguageCode, address.language_code);
   result->SetString(kAddressOrganization, address.organization);
   result->SetString(kAddressRecipient, address.recipient);
   result->SetString(kAddressPhone, address.phone);
diff --git a/components/payments/core/payment_address_unittest.cc b/components/payments/core/payment_address_unittest.cc
index 82efff3c..17d7555 100644
--- a/components/payments/core/payment_address_unittest.cc
+++ b/components/payments/core/payment_address_unittest.cc
@@ -71,13 +71,6 @@
   address2.sorting_code = "14390";
   EXPECT_TRUE(address1.Equals(address2));
 
-  address1.language_code = "fr";
-  EXPECT_FALSE(address1.Equals(address2));
-  address2.language_code = "zh-HK";
-  EXPECT_FALSE(address1.Equals(address2));
-  address2.language_code = "fr";
-  EXPECT_TRUE(address1.Equals(address2));
-
   address1.organization = "The Willy Wonka Candy Company";
   EXPECT_FALSE(address1.Equals(address2));
   address2.organization = "Sears";
diff --git a/components/payments/core/payment_request_data_util.cc b/components/payments/core/payment_request_data_util.cc
index 12a624b6..21006b10 100644
--- a/components/payments/core/payment_request_data_util.cc
+++ b/components/payments/core/payment_request_data_util.cc
@@ -56,13 +56,6 @@
   payment_address->recipient =
       base::UTF16ToUTF8(profile.GetInfo(autofill::NAME_FULL, app_locale));
 
-  // The autofill profile |language_code| is the BCP-47 language tag (e.g.,
-  // "ja-Latn"), which can be split into a language code (e.g., "ja") and a
-  // script code (e.g., "Latn").
-  PaymentsValidators::SplitLanguageTag(profile.language_code(),
-                                       &payment_address->language_code,
-                                       &payment_address->script_code);
-
   // TODO(crbug.com/705945): Format phone number according to spec.
   payment_address->phone =
       base::UTF16ToUTF8(profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER));
diff --git a/components/payments/core/payment_request_data_util_unittest.cc b/components/payments/core/payment_request_data_util_unittest.cc
index ec4e86e..9186ad1 100644
--- a/components/payments/core/payment_request_data_util_unittest.cc
+++ b/components/payments/core/payment_request_data_util_unittest.cc
@@ -35,7 +35,6 @@
       "\"city\":\"Elysium\","
       "\"country\":\"US\","
       "\"dependentLocality\":\"\","
-      "\"languageCode\":\"\","
       "\"organization\":\"Underworld\","
       "\"phone\":\"16502111111\","
       "\"postalCode\":\"91111\","
@@ -63,7 +62,6 @@
       "\"city\":\"Elysium\","
       "\"country\":\"US\","
       "\"dependentLocality\":\"\","
-      "\"languageCode\":\"\","
       "\"organization\":\"Underworld\","
       "\"phone\":\"16502111111\","
       "\"postalCode\":\"91111\","
diff --git a/components/payments/core/payments_validators.cc b/components/payments/core/payments_validators.cc
index 4bdbd5e9..bd5669f9 100644
--- a/components/payments/core/payments_validators.cc
+++ b/components/payments/core/payments_validators.cc
@@ -59,47 +59,6 @@
 }
 
 // static
-bool PaymentsValidators::IsValidLanguageCodeFormat(
-    const std::string& code,
-    std::string* optional_error_message) {
-  if (RE2::FullMatch(code, "([a-z]{2,3})?"))
-    return true;
-
-  if (optional_error_message)
-    *optional_error_message =
-        "'" + code +
-        "' is not a valid BCP-47 language code, should be "
-        "2-3 lower case letters [a-z]";
-
-  return false;
-}
-
-// static
-bool PaymentsValidators::IsValidScriptCodeFormat(
-    const std::string& code,
-    std::string* optional_error_message) {
-  if (RE2::FullMatch(code, "([A-Z][a-z]{3})?"))
-    return true;
-
-  if (optional_error_message)
-    *optional_error_message =
-        "'" + code +
-        "' is not a valid ISO 15924 script code, should be "
-        "an upper case letter [A-Z] followed by 3 lower "
-        "case letters [a-z]";
-
-  return false;
-}
-
-// static
-void PaymentsValidators::SplitLanguageTag(const std::string& tag,
-                                          std::string* language_code,
-                                          std::string* script_code) {
-  RE2::FullMatch(tag, "^([a-z]{2})(-([A-Z][a-z]{3}))?(-[A-Za-z]+)*$",
-                 language_code, (void*)nullptr, script_code);
-}
-
-// static
 bool PaymentsValidators::IsValidErrorMsgFormat(
     const std::string& error,
     std::string* optional_error_message) {
@@ -123,7 +82,6 @@
          IsValidErrorMsgFormat(errors->country, optional_error_message) &&
          IsValidErrorMsgFormat(errors->dependent_locality,
                                optional_error_message) &&
-         IsValidErrorMsgFormat(errors->language_code, optional_error_message) &&
          IsValidErrorMsgFormat(errors->organization, optional_error_message) &&
          IsValidErrorMsgFormat(errors->phone, optional_error_message) &&
          IsValidErrorMsgFormat(errors->postal_code, optional_error_message) &&
diff --git a/components/payments/core/payments_validators.h b/components/payments/core/payments_validators.h
index 6570d38..1d48796 100644
--- a/components/payments/core/payments_validators.h
+++ b/components/payments/core/payments_validators.h
@@ -28,19 +28,6 @@
   static bool IsValidCountryCodeFormat(const std::string& code,
                                        std::string* optional_error_message);
 
-  // Returns true if |code| is a valid ISO 639 language code.
-  static bool IsValidLanguageCodeFormat(const std::string& code,
-                                        std::string* optional_error_message);
-
-  // Returns true if |code| is a valid ISO 15924 script code.
-  static bool IsValidScriptCodeFormat(const std::string& code,
-                                      std::string* optional_error_message);
-
-  // Splits BCP-57 |tag| into |language_code| and |script_code|.
-  static void SplitLanguageTag(const std::string& tag,
-                               std::string* language_code,
-                               std::string* script_code);
-
   // Returns false if |error| is too long (greater than 2048).
   static bool IsValidErrorMsgFormat(const std::string& code,
                                     std::string* optional_error_message);
diff --git a/components/payments/core/payments_validators_unittest.cc b/components/payments/core/payments_validators_unittest.cc
index e19f67d..502b3a2 100644
--- a/components/payments/core/payments_validators_unittest.cc
+++ b/components/payments/core/payments_validators_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/payments/core/payments_validators.h"
 
 #include <ostream>  // NOLINT
+
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace payments {
@@ -149,108 +150,6 @@
                                          TestCase("USA", false),
                                          TestCase("", false)));
 
-class PaymentsLanguageValidatorTest : public testing::TestWithParam<TestCase> {
-};
-
-TEST_P(PaymentsLanguageValidatorTest, IsValidLanguageCodeFormat) {
-  std::string error_message;
-  EXPECT_EQ(GetParam().expected_valid,
-            payments::PaymentsValidators::IsValidLanguageCodeFormat(
-                GetParam().input, &error_message))
-      << error_message;
-  EXPECT_EQ(GetParam().expected_valid, error_message.empty()) << error_message;
-
-  EXPECT_EQ(GetParam().expected_valid,
-            payments::PaymentsValidators::IsValidLanguageCodeFormat(
-                GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(LanguageCodes,
-                         PaymentsLanguageValidatorTest,
-                         testing::Values(TestCase("", true),
-                                         TestCase("en", true),
-                                         TestCase("eng", true),
-                                         // Invalid language code formats
-                                         TestCase("e1", false),
-                                         TestCase("en1", false),
-                                         TestCase("e", false),
-                                         TestCase("engl", false),
-                                         TestCase("EN", false)));
-
-class PaymentsScriptValidatorTest : public testing::TestWithParam<TestCase> {};
-
-TEST_P(PaymentsScriptValidatorTest, IsValidScriptCodeFormat) {
-  std::string error_message;
-  EXPECT_EQ(GetParam().expected_valid,
-            payments::PaymentsValidators::IsValidScriptCodeFormat(
-                GetParam().input, &error_message))
-      << error_message;
-  EXPECT_EQ(GetParam().expected_valid, error_message.empty()) << error_message;
-
-  EXPECT_EQ(GetParam().expected_valid,
-            payments::PaymentsValidators::IsValidScriptCodeFormat(
-                GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(ScriptCodes,
-                         PaymentsScriptValidatorTest,
-                         testing::Values(TestCase("", true),
-                                         TestCase("Latn", true),
-                                         // Invalid script code formats
-                                         TestCase("Lat1", false),
-                                         TestCase("1lat", false),
-                                         TestCase("Latin", false),
-                                         TestCase("Lat", false),
-                                         TestCase("latn", false),
-                                         TestCase("LATN", false)));
-
-struct LanguageTagTestCase {
-  LanguageTagTestCase(const char* language_tag,
-                      const char* expected_language_code,
-                      const char* expected_script_code)
-      : language_tag(language_tag),
-        expected_language_code(expected_language_code),
-        expected_script_code(expected_script_code) {}
-  ~LanguageTagTestCase() {}
-
-  const char* language_tag;
-  const char* expected_language_code;
-  const char* expected_script_code;
-};
-
-class PaymentsLanguageTagSplitTest
-    : public testing::TestWithParam<LanguageTagTestCase> {};
-
-TEST_P(PaymentsLanguageTagSplitTest, Test) {
-  std::string language_code;
-  std::string script_code;
-
-  PaymentsValidators::SplitLanguageTag(GetParam().language_tag, &language_code,
-                                       &script_code);
-
-  EXPECT_EQ(GetParam().expected_language_code, language_code);
-  EXPECT_EQ(GetParam().expected_script_code, script_code);
-  EXPECT_TRUE(
-      PaymentsValidators::IsValidLanguageCodeFormat(language_code, nullptr));
-  EXPECT_TRUE(
-      PaymentsValidators::IsValidScriptCodeFormat(script_code, nullptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    LanguageTags,
-    PaymentsLanguageTagSplitTest,
-    testing::Values(LanguageTagTestCase("", "", ""),
-                    LanguageTagTestCase("ja", "ja", ""),
-                    LanguageTagTestCase("ja-Latn", "ja", "Latn"),
-                    LanguageTagTestCase("ja-Latn-JP", "ja", "Latn"),
-                    LanguageTagTestCase("ja-JP", "ja", ""),
-                    LanguageTagTestCase("Latn", "", ""),
-                    LanguageTagTestCase("JP", "", ""),
-                    LanguageTagTestCase("en", "en", ""),
-                    LanguageTagTestCase("en-Latn", "en", "Latn"),
-                    LanguageTagTestCase("en-Latn-US", "en", "Latn"),
-                    LanguageTagTestCase("en-US", "en", "")));
-
 struct ValidationErrorsTestCase {
   explicit ValidationErrorsTestCase(bool expected_valid)
       : expected_valid(expected_valid) {}
@@ -262,7 +161,6 @@
   const char* m_shipping_address_city = "";
   const char* m_shipping_address_country = "";
   const char* m_shipping_address_dependent_locality = "";
-  const char* m_shipping_address_language_code = "";
   const char* m_shipping_address_organization = "";
   const char* m_shipping_address_phone = "";
   const char* m_shipping_address_postal_code = "";
@@ -295,7 +193,6 @@
   shipping_address->country = test_case.m_shipping_address_country;
   shipping_address->dependent_locality =
       test_case.m_shipping_address_dependent_locality;
-  shipping_address->language_code = test_case.m_shipping_address_language_code;
   shipping_address->organization = test_case.m_shipping_address_organization;
   shipping_address->phone = test_case.m_shipping_address_phone;
   shipping_address->postal_code = test_case.m_shipping_address_postal_code;
@@ -340,9 +237,6 @@
         VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
                                     "test",
                                     true),
-        VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
-                                    "test",
-                                    true),
         VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
                                     "test",
                                     true),
@@ -371,9 +265,6 @@
         VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
                                     LongString2049(),
                                     false),
-        VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
-                                    LongString2049(),
-                                    false),
         VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
                                     LongString2049(),
                                     false),
diff --git a/components/payments/mojom/payment_request_data.mojom b/components/payments/mojom/payment_request_data.mojom
index 19f56b9..cbe693db 100644
--- a/components/payments/mojom/payment_request_data.mojom
+++ b/components/payments/mojom/payment_request_data.mojom
@@ -17,15 +17,6 @@
   string dependent_locality;
   string postal_code;
   string sorting_code;
-
-  // Optional shortest ISO 639 language code. Two or three lower case ASCII
-  // letters.
-  string language_code;
-
-  // Optional ISO 15924 script code. Four ASCII letters. The first letter is
-  // upper case; the rest are lower case.
-  string script_code;
-
   string organization;
   string recipient;
   string phone;
@@ -68,7 +59,6 @@
   string city;
   string country;
   string dependent_locality;
-  string language_code;
   string organization;
   string phone;
   string postal_code;
diff --git a/components/resources/autofill_scaled_resources.grdp b/components/resources/autofill_scaled_resources.grdp
index 968175c..85ee0d7e 100644
--- a/components/resources/autofill_scaled_resources.grdp
+++ b/components/resources/autofill_scaled_resources.grdp
@@ -11,6 +11,7 @@
   <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_UNIONPAY" file="autofill/unionpay.png" />
   <structure type="chrome_scaled_image" name="IDR_AUTOFILL_CC_VISA" file="autofill/visa.png" />
   <structure type="chrome_scaled_image" name="IDR_AUTOFILL_GOOGLE_PAY" file="autofill/googlepay.png" />
+  <structure type="chrome_scaled_image" name="IDR_AUTOFILL_GOOGLE_PAY_DARK" file="autofill/googlepay_dark.png" />
 
   <!-- These are not used on desktop, only Android, so use a placeholder file.
        TODO(rouslan): Remove non-keyboard-accessory icon when keyboard
diff --git a/components/resources/default_100_percent/autofill/googlepay_dark.png b/components/resources/default_100_percent/autofill/googlepay_dark.png
new file mode 100644
index 0000000..0299246
--- /dev/null
+++ b/components/resources/default_100_percent/autofill/googlepay_dark.png
Binary files differ
diff --git a/components/resources/default_200_percent/autofill/googlepay_dark.png b/components/resources/default_200_percent/autofill/googlepay_dark.png
new file mode 100644
index 0000000..45b0e25
--- /dev/null
+++ b/components/resources/default_200_percent/autofill/googlepay_dark.png
Binary files differ
diff --git a/components/resources/default_300_percent/autofill/googlepay_dark.png b/components/resources/default_300_percent/autofill/googlepay_dark.png
new file mode 100644
index 0000000..18bbe69a
--- /dev/null
+++ b/components/resources/default_300_percent/autofill/googlepay_dark.png
Binary files differ
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc
index 57a2668..297f4c8 100644
--- a/components/viz/service/display/display.cc
+++ b/components/viz/service/display/display.cc
@@ -117,6 +117,16 @@
 }
 
 Display::~Display() {
+#if defined(OS_ANDROID)
+  // In certain cases, drivers hang when tearing down the display. Finishing
+  // before teardown appears to address this. As we're during display teardown,
+  // an additional finish should have minimal impact.
+  // TODO(ericrk): Add a more robust workaround. crbug.com/899705
+  if (auto* context = output_surface_->context_provider()) {
+    context->ContextGL()->Finish();
+  }
+#endif
+
   for (auto& observer : observers_)
     observer.OnDisplayDestroyed();
   observers_.Clear();
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 1f4c047..2d5b996a 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -900,11 +900,11 @@
     }
 #endif
 
-    // Create a MessageLoop if one does not already exist for the current
-    // thread. This thread won't be promoted as BrowserThread::UI until
-    // BrowserMainLoop::MainMessageLoopStart().
-    if (!base::MessageLoopCurrentForUI::IsSet())
-      main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
+    // Register the TaskExecutor for posting task to the BrowserThreads. It is
+    // incorrect to post to a BrowserThread before this point. This instantiates
+    // and binds the MessageLoopForUI on the main thread (but it's only labeled
+    // as BrowserThread::UI in BrowserMainLoop::MainMessageLoopStart).
+    BrowserTaskExecutor::Create();
 
     delegate_->PostEarlyInitialization(main_params.ui_task != nullptr);
 
@@ -913,9 +913,7 @@
       StartBrowserTaskScheduler();
     }
 
-    // Register the TaskExecutor for posting task to the BrowserThreads. It is
-    // incorrect to post to a BrowserThread before this point.
-    BrowserTaskExecutor::Create();
+    BrowserTaskExecutor::PostFeatureListSetup();
 
     if (!base::FeatureList::IsEnabled(
             features::kAllowStartingServiceManagerOnly)) {
@@ -968,8 +966,8 @@
   }
 
 #if !defined(CHROME_MULTIPLE_DLL_CHILD)
-  // The message loop needs to be destroyed before |exit_manager_|.
-  main_message_loop_.reset();
+  // The BrowserTaskExecutor needs to be destroyed before |exit_manager_|.
+  BrowserTaskExecutor::Shutdown();
 #endif  // !defined(CHROME_MULTIPLE_DLL_CHILD)
 
 #if defined(OS_WIN)
diff --git a/content/app/content_main_runner_impl.h b/content/app/content_main_runner_impl.h
index 29c9675f..1e5a57b 100644
--- a/content/app/content_main_runner_impl.h
+++ b/content/app/content_main_runner_impl.h
@@ -9,7 +9,6 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
 #include "build/build_config.h"
 #include "content/browser/service_manager/service_manager_context.h"
@@ -54,8 +53,6 @@
 
   bool is_browser_main_loop_started_ = false;
 
-  std::unique_ptr<base::MessageLoop> main_message_loop_;
-
   std::unique_ptr<StartupDataImpl> startup_data_;
   std::unique_ptr<base::FieldTrialList> field_trial_list_;
   std::unique_ptr<BrowserProcessSubThread> service_manager_thread_;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 8fc1c9ec..0b8d10a 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -681,10 +681,7 @@
   // PostMainMessageLoopStart() below.
 
   TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart");
-
-  if (!base::MessageLoopCurrentForUI::IsSet())
-    main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
-
+  DCHECK(base::MessageLoopCurrentForUI::IsSet());
   InitializeMainThread();
 }
 
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h
index 9a8f3e26..2d642405 100644
--- a/content/browser/browser_main_loop.h
+++ b/content/browser/browser_main_loop.h
@@ -36,7 +36,6 @@
 class FilePath;
 class HighResolutionTimerManager;
 class MemoryPressureMonitor;
-class MessageLoop;
 class PowerMonitor;
 class SingleThreadTaskRunner;
 class SystemMonitor;
@@ -303,7 +302,6 @@
       scoped_execution_fence_;
 
   // Members initialized in |MainMessageLoopStart()| ---------------------------
-  std::unique_ptr<base::MessageLoop> main_message_loop_;
 
   // Members initialized in |PostMainMessageLoopStart()| -----------------------
   std::unique_ptr<BrowserProcessSubThread> io_thread_;
diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc
index 6acfec4..ee52d18 100644
--- a/content/browser/browser_thread_impl.cc
+++ b/content/browser/browser_thread_impl.cc
@@ -24,10 +24,6 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/content_browser_client.h"
 
-#if defined(OS_ANDROID)
-#include "base/android/task_scheduler/post_task_android.h"
-#endif
-
 namespace content {
 
 namespace {
@@ -107,12 +103,7 @@
   DCHECK(!globals.task_runners[identifier_]);
   globals.task_runners[identifier_] = std::move(task_runner);
 
-  // TODO(alexclarke): Move this to the BrowserUIThreadScheduler.
   if (identifier_ == BrowserThread::ID::UI) {
-#if defined(OS_ANDROID)
-    base::PostTaskAndroid::SignalNativeSchedulerReady();
-#endif
-
 #if defined(OS_POSIX)
     // Allow usage of the FileDescriptorWatcher API on the UI thread, using the
     // IO thread to watch the file descriptors.
@@ -132,12 +123,6 @@
   BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
   DCHECK_CALLED_ON_VALID_THREAD(globals.main_thread_checker_);
 
-#if defined(OS_ANDROID)
-  // TODO(alexclarke): Move this to the BrowserUIThreadScheduler.
-  if (identifier_ == BrowserThread::ID::UI)
-    base::PostTaskAndroid::SignalNativeSchedulerShutdown();
-#endif
-
   DCHECK_EQ(base::subtle::NoBarrier_Load(&globals.states[identifier_]),
             BrowserThreadState::RUNNING);
   base::subtle::NoBarrier_Store(&globals.states[identifier_],
diff --git a/content/browser/browser_thread_unittest.cc b/content/browser/browser_thread_unittest.cc
index b7d4168f7..5f1f796 100644
--- a/content/browser/browser_thread_unittest.cc
+++ b/content/browser/browser_thread_unittest.cc
@@ -13,12 +13,14 @@
 #include "base/sequenced_task_runner_helpers.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task/post_task.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "content/browser/browser_process_sub_thread.h"
 #include "content/browser/browser_thread_impl.h"
 #include "content/browser/scheduler/browser_task_executor.h"
+#include "content/browser/startup_helper.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -40,10 +42,20 @@
 
  protected:
   void SetUp() override {
-    BrowserTaskExecutor::Create();
-
     ui_thread_ = std::make_unique<BrowserProcessSubThread>(BrowserThread::UI);
-    ui_thread_->Start();
+    std::unique_ptr<base::sequence_manager::internal::SequenceManagerImpl>
+        sequence_manager = base::sequence_manager::internal::
+            SequenceManagerImpl::CreateUnbound(
+                base::sequence_manager::SequenceManager::Settings());
+    default_task_queue_ =
+        sequence_manager
+            ->CreateTaskQueueWithType<base::sequence_manager::TaskQueue>(
+                base::sequence_manager::TaskQueue::Spec("default_tq"));
+    sequence_manager->SetTaskRunner(default_task_queue_->task_runner());
+    BrowserTaskExecutor::CreateForTesting(default_task_queue_->task_runner());
+    base::Thread::Options ui_options;
+    ui_options.message_loop_base = sequence_manager.release();
+    ui_thread_->StartWithOptions(ui_options);
 
     io_thread_ = std::make_unique<BrowserProcessSubThread>(BrowserThread::IO);
     base::Thread::Options io_options;
@@ -97,6 +109,7 @@
  private:
   std::unique_ptr<BrowserProcessSubThread> ui_thread_;
   std::unique_ptr<BrowserProcessSubThread> io_thread_;
+  scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue_;
 
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   // Must be set before Release() to verify the deletion is intentional. Will be
diff --git a/content/browser/frame_host/debug_urls.cc b/content/browser/frame_host/debug_urls.cc
index 8dd06415..d47b030 100644
--- a/content/browser/frame_host/debug_urls.cc
+++ b/content/browser/frame_host/debug_urls.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/debug/asan_invalid_access.h"
 #include "base/debug/profiler.h"
+#include "base/sanitizer_buildflags.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task/post_task.h"
@@ -93,7 +94,7 @@
 }
 
 bool HandleAsanDebugURL(const GURL& url) {
-#if defined(ADDRESS_SANITIZER)
+#if defined(ADDRESS_SANITIZER) || BUILDFLAG(IS_HWASAN)
 #if defined(OS_WIN)
   if (url.path_piece() == kAsanCorruptHeapBlock) {
     base::debug::AsanCorruptHeapBlock();
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc
index e17622d6..52596270 100644
--- a/content/browser/frame_host/render_frame_message_filter.cc
+++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -618,10 +618,14 @@
     return;
   }
 
+  // |callback| needs to be fired even if network process crashes as it's for
+  // sync IPC.
   net::CookieStore::SetCookiesCallback net_callback =
-      base::BindOnce([](SetCookieCallback callback,
-                        bool success) { std::move(callback).Run(); },
-                     std::move(callback));
+      mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+          base::BindOnce([](SetCookieCallback callback,
+                            bool success) { std::move(callback).Run(); },
+                         std::move(callback)),
+          false);
   (*GetCookieManager())
       ->SetCanonicalCookie(*cookie, url.SchemeIsCryptographic(),
                            !options.exclude_httponly(),
@@ -688,12 +692,16 @@
       &RenderFrameMessageFilter::CheckPolicyForCookies, this, render_frame_id,
       url, site_for_cookies, std::move(callback));
 
-  auto wrapped_callback = base::BindOnce(
-      [](net::CookieStore::GetCookieListCallback callback,
-         const net::CookieList& cookies) {
-        std::move(callback).Run(cookies, net::CookieStatusList());
-      },
-      std::move(bound_callback));
+  // |callback| needs to be fired even if network process crashes as it's for
+  // sync IPC.
+  auto wrapped_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+      base::BindOnce(
+          [](net::CookieStore::GetCookieListCallback callback,
+             const net::CookieList& cookies) {
+            std::move(callback).Run(cookies, net::CookieStatusList());
+          },
+          std::move(bound_callback)),
+      net::CookieList());
 
   (*GetCookieManager())
       ->GetCookieList(url, options, std::move(wrapped_callback));
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc
index ca2d0e4..ece2186 100644
--- a/content/browser/indexed_db/database_impl.cc
+++ b/content/browser/indexed_db/database_impl.cc
@@ -116,6 +116,10 @@
                    int64_t object_store_id,
                    const IndexedDBKeyRange& key_range,
                    scoped_refptr<IndexedDBCallbacks> callbacks);
+  void GetKeyGeneratorCurrentNumber(
+      int64_t transaction_id,
+      int64_t object_store_id,
+      scoped_refptr<IndexedDBCallbacks> callbacks);
   void Clear(int64_t transaction_id,
              int64_t object_store_id,
              scoped_refptr<IndexedDBCallbacks> callbacks);
@@ -426,6 +430,20 @@
                      std::move(callbacks)));
 }
 
+void DatabaseImpl::GetKeyGeneratorCurrentNumber(
+    int64_t transaction_id,
+    int64_t object_store_id,
+    blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info) {
+  scoped_refptr<IndexedDBCallbacks> callbacks(
+      new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
+                             std::move(callbacks_info), idb_runner_));
+  idb_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&IDBSequenceHelper::GetKeyGeneratorCurrentNumber,
+                     base::Unretained(helper_), transaction_id, object_store_id,
+                     std::move(callbacks)));
+}
+
 void DatabaseImpl::Clear(
     int64_t transaction_id,
     int64_t object_store_id,
@@ -807,6 +825,22 @@
       std::make_unique<IndexedDBKeyRange>(key_range), std::move(callbacks));
 }
 
+void DatabaseImpl::IDBSequenceHelper::GetKeyGeneratorCurrentNumber(
+    int64_t transaction_id,
+    int64_t object_store_id,
+    scoped_refptr<IndexedDBCallbacks> callbacks) {
+  if (!connection_->IsConnected())
+    return;
+
+  IndexedDBTransaction* transaction =
+      connection_->GetTransaction(transaction_id);
+  if (!transaction)
+    return;
+
+  connection_->database()->GetKeyGeneratorCurrentNumber(
+      transaction, object_store_id, std::move(callbacks));
+}
+
 void DatabaseImpl::IDBSequenceHelper::Clear(
     int64_t transaction_id,
     int64_t object_store_id,
diff --git a/content/browser/indexed_db/database_impl.h b/content/browser/indexed_db/database_impl.h
index ce43ae9..c1a3b43 100644
--- a/content/browser/indexed_db/database_impl.h
+++ b/content/browser/indexed_db/database_impl.h
@@ -105,6 +105,10 @@
       int64_t object_store_id,
       const IndexedDBKeyRange& key_range,
       blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override;
+  void GetKeyGeneratorCurrentNumber(
+      int64_t transaction_id,
+      int64_t object_store_id,
+      blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override;
   void Clear(int64_t transaction_id,
              int64_t object_store_id,
              blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override;
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index 8c5aa686..f17d03e 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -1455,10 +1455,10 @@
                                  std::unique_ptr<storage::BlobDataHandle> blob,
                                  const base::Time& last_modified) {
     DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-    std::unique_ptr<storage::FileStreamWriter> writer(
+    std::unique_ptr<storage::FileStreamWriter> writer =
         storage::FileStreamWriter::CreateForLocalFile(
             task_runner_.get(), file_path, 0,
-            storage::FileStreamWriter::CREATE_NEW_FILE));
+            storage::FileStreamWriter::CREATE_NEW_FILE);
     std::unique_ptr<FileWriterDelegate> delegate(
         std::make_unique<FileWriterDelegate>(
             std::move(writer), storage::FlushPolicy::FLUSH_ON_COMPLETION));
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h
index bb1048f2..a821936 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.h
+++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -107,6 +107,7 @@
   // IndexedDBDatabase::Count
   // IndexedDBFactory::DeleteDatabase
   // IndexedDBDatabase::DeleteRange
+  // IndexedDBDatabase::GetKeyGeneratorCurrentNumber
   virtual void OnSuccess(int64_t value);
 
   // IndexedDBCursor::Continue / Advance (when complete)
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index e655c64..1387bd6c 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "content/browser/indexed_db/indexed_db_database.h"
-
 #include <math.h>
 
 #include <algorithm>
@@ -1684,6 +1683,39 @@
   return s;
 }
 
+void IndexedDBDatabase::GetKeyGeneratorCurrentNumber(
+    IndexedDBTransaction* transaction,
+    int64_t object_store_id,
+    scoped_refptr<IndexedDBCallbacks> callbacks) {
+  DCHECK(transaction);
+  if (!ValidateObjectStoreId(object_store_id)) {
+    callbacks->OnError(CreateError(blink::kWebIDBDatabaseExceptionDataError,
+                                   "Object store id not valid.", transaction));
+    return;
+  }
+  transaction->ScheduleTask(
+      base::BindOnce(&IndexedDBDatabase::GetKeyGeneratorCurrentNumberOperation,
+                     this, object_store_id, callbacks));
+}
+
+Status IndexedDBDatabase::GetKeyGeneratorCurrentNumberOperation(
+    int64_t object_store_id,
+    scoped_refptr<IndexedDBCallbacks> callbacks,
+    IndexedDBTransaction* transaction) {
+  int64_t current_number;
+  Status s = backing_store_.get()->GetKeyGeneratorCurrentNumber(
+      transaction->BackingStoreTransaction(), id(), object_store_id,
+      &current_number);
+  if (!s.ok()) {
+    callbacks->OnError(CreateError(
+        blink::kWebIDBDatabaseExceptionDataError,
+        "Failed to get the current number of key generator.", transaction));
+    return s;
+  }
+  callbacks->OnSuccess(current_number);
+  return s;
+}
+
 void IndexedDBDatabase::Clear(IndexedDBTransaction* transaction,
                               int64_t object_store_id,
                               scoped_refptr<IndexedDBCallbacks> callbacks) {
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index 6bf67bf..d29251f9 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -197,6 +197,10 @@
                    int64_t object_store_id,
                    std::unique_ptr<blink::IndexedDBKeyRange> key_range,
                    scoped_refptr<IndexedDBCallbacks> callbacks);
+  void GetKeyGeneratorCurrentNumber(
+      IndexedDBTransaction* transaction,
+      int64_t object_store_id,
+      scoped_refptr<IndexedDBCallbacks> callbacks);
   void Clear(IndexedDBTransaction* transaction,
              int64_t object_store_id,
              scoped_refptr<IndexedDBCallbacks> callbacks);
@@ -268,6 +272,10 @@
       std::unique_ptr<blink::IndexedDBKeyRange> key_range,
       scoped_refptr<IndexedDBCallbacks> callbacks,
       IndexedDBTransaction* transaction);
+  leveldb::Status GetKeyGeneratorCurrentNumberOperation(
+      int64_t object_store_id,
+      scoped_refptr<IndexedDBCallbacks> callbacks,
+      IndexedDBTransaction* transaction);
   leveldb::Status ClearOperation(int64_t object_store_id,
                                  scoped_refptr<IndexedDBCallbacks> callbacks,
                                  IndexedDBTransaction* transaction);
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 81809b2..ef91af1 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -632,10 +632,12 @@
       std::unique_ptr<NavigationUIData> navigation_ui_data,
       network::mojom::URLLoaderFactoryPtrInfo factory_for_webui,
       int frame_tree_node_id,
-      bool needs_loader_factory_interceptor) {
+      bool needs_loader_factory_interceptor,
+      base::Time ui_post_time) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
     DCHECK(!started_);
+    ui_to_io_time_ += (base::Time::Now() - ui_post_time);
     global_request_id_ = MakeGlobalRequestID();
     frame_tree_node_id_ = frame_tree_node_id;
     started_ = true;
@@ -762,11 +764,12 @@
 
     // See if embedders want to add interceptors.
     std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
-        browser_interceptors = GetContentClient()
-                                   ->browser()
-                                   ->WillCreateURLLoaderRequestInterceptors(
-                                       navigation_ui_data_.get(),
-                                       request_info->frame_tree_node_id);
+        browser_interceptors =
+            GetContentClient()
+                ->browser()
+                ->WillCreateURLLoaderRequestInterceptors(
+                    navigation_ui_data_.get(), request_info->frame_tree_node_id,
+                    network_loader_factory_);
     if (!browser_interceptors.empty()) {
       for (auto& browser_interceptor : browser_interceptors) {
         interceptors_.push_back(
@@ -1049,9 +1052,11 @@
 
   void FollowRedirect(const std::vector<std::string>& removed_headers,
                       const net::HttpRequestHeaders& modified_headers,
-                      PreviewsState new_previews_state) {
+                      PreviewsState new_previews_state,
+                      base::Time ui_post_time) {
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
     DCHECK(!redirect_info_.new_url.is_empty());
+    ui_to_io_time_ += (base::Time::Now() - ui_post_time);
     if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
       auto* common_params =
           const_cast<CommonNavigationParams*>(&request_info_->common_params);
@@ -1305,11 +1310,11 @@
     // response. https://crbug.com/416050
     base::PostTaskWithTraits(
         FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(&NavigationURLLoaderImpl::OnReceiveResponse, owner_,
-                       response->DeepCopy(),
-                       std::move(url_loader_client_endpoints),
-                       std::move(cloned_navigation_data), global_request_id_,
-                       is_download, is_stream));
+        base::BindOnce(
+            &NavigationURLLoaderImpl::OnReceiveResponse, owner_,
+            response->DeepCopy(), std::move(url_loader_client_endpoints),
+            std::move(cloned_navigation_data), global_request_id_, is_download,
+            is_stream, ui_to_io_time_, base::Time::Now()));
   }
 
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -1345,7 +1350,7 @@
     base::PostTaskWithTraits(
         FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&NavigationURLLoaderImpl::OnReceiveRedirect, owner_,
-                       redirect_info, response->DeepCopy()));
+                       redirect_info, response->DeepCopy(), base::Time::Now()));
   }
 
   void OnUploadProgress(int64_t current_position,
@@ -1576,6 +1581,9 @@
   // SignedExchangeRequestHandler will handle the response.
   base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
 
+  // Counts the time overhead of all the hops from the UI to the IO threads.
+  base::TimeDelta ui_to_io_time_;
+
   mutable base::WeakPtrFactory<URLLoaderRequestController> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
@@ -1761,7 +1769,7 @@
                      std::move(signed_exchange_prefetch_metric_recorder),
                      std::move(request_info), std::move(navigation_ui_data),
                      std::move(factory_for_webui), frame_tree_node_id,
-                     needs_loader_factory_interceptor));
+                     needs_loader_factory_interceptor, base::Time::Now()));
 }
 
 NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
@@ -1777,7 +1785,8 @@
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&URLLoaderRequestController::FollowRedirect,
                      base::Unretained(request_controller_.get()),
-                     removed_headers, modified_headers, new_previews_state));
+                     removed_headers, modified_headers, new_previews_state,
+                     base::Time::Now()));
 }
 
 void NavigationURLLoaderImpl::ProceedWithResponse() {}
@@ -1788,7 +1797,17 @@
     std::unique_ptr<NavigationData> navigation_data,
     const GlobalRequestID& global_request_id,
     bool is_download,
-    bool is_stream) {
+    bool is_stream,
+    base::TimeDelta total_ui_to_io_time,
+    base::Time io_post_time) {
+  const base::TimeDelta kMinTime = base::TimeDelta::FromMicroseconds(1);
+  const base::TimeDelta kMaxTime = base::TimeDelta::FromMilliseconds(100);
+  const int kBuckets = 50;
+  io_to_ui_time_ += (base::Time::Now() - io_post_time);
+  UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+      "Navigation.NavigationURLLoaderImplIOPostTime",
+      io_to_ui_time_ + total_ui_to_io_time, kMinTime, kMaxTime, kBuckets);
+
   TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
                          "&NavigationURLLoaderImpl", this, "success", true);
 
@@ -1807,8 +1826,10 @@
 
 void NavigationURLLoaderImpl::OnReceiveRedirect(
     const net::RedirectInfo& redirect_info,
-    scoped_refptr<network::ResourceResponse> response) {
+    scoped_refptr<network::ResourceResponse> response,
+    base::Time io_post_time) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  io_to_ui_time_ += (base::Time::Now() - io_post_time);
   delegate_->OnRequestRedirected(redirect_info, std::move(response));
 }
 
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 20b270d0..2afea45 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -57,9 +57,12 @@
       std::unique_ptr<NavigationData> navigation_data,
       const GlobalRequestID& global_request_id,
       bool is_download,
-      bool is_stream);
+      bool is_stream,
+      base::TimeDelta total_ui_to_io_time,
+      base::Time io_post_time);
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
-                         scoped_refptr<network::ResourceResponse> response);
+                         scoped_refptr<network::ResourceResponse> response,
+                         base::Time io_post_time);
   void OnComplete(const network::URLLoaderCompletionStatus& status);
 
   // Overrides loading of frame requests when the network service is disabled.
@@ -107,6 +110,9 @@
   ContentBrowserClient::NonNetworkURLLoaderFactoryMap
       non_network_url_loader_factories_;
 
+  // Counts the time overhead of all the hops from the IO to the UI threads.
+  base::TimeDelta io_to_ui_time_;
+
   base::WeakPtrFactory<NavigationURLLoaderImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(NavigationURLLoaderImpl);
diff --git a/content/browser/media/media_internals_audio_focus_helper.cc b/content/browser/media/media_internals_audio_focus_helper.cc
index fc827c3..5399809 100644
--- a/content/browser/media/media_internals_audio_focus_helper.cc
+++ b/content/browser/media/media_internals_audio_focus_helper.cc
@@ -34,6 +34,7 @@
 const char kAudioFocusTypeGain[] = "Gain";
 const char kAudioFocusTypeGainTransient[] = "GainTransient";
 const char kAudioFocusTypeGainTransientMayDuck[] = "GainTransientMayDuck";
+const char kAudioFocusTypeAmbient[] = "Ambient";
 
 const char kMediaSessionStateActive[] = "Active";
 const char kMediaSessionStateDucking[] = "Ducking";
@@ -268,6 +269,9 @@
     case media_session::mojom::AudioFocusType::kGainTransientMayDuck:
       stream << " " << kAudioFocusTypeGainTransientMayDuck;
       break;
+    case media_session::mojom::AudioFocusType::kAmbient:
+      stream << " " << kAudioFocusTypeAmbient;
+      break;
   }
 
   // Convert the MediaSessionInfo::SessionState mojo enum to a string.
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index 18270d21..ffadd93 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -753,8 +753,9 @@
         // media session.
         OnSuspendInternal(SuspendType::kSystem, State::SUSPENDED);
         break;
+      case AudioFocusType::kAmbient:
       case AudioFocusType::kGainTransient:
-        // MediaSessionImpl does not use |kGainTransient|.
+        // MediaSessionImpl does not use |kGainTransient| or |kAmbient|.
         NOTREACHED();
         break;
       case AudioFocusType::kGainTransientMayDuck:
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc
index ddefef9..9b314e2a 100644
--- a/content/browser/network_service_browsertest.cc
+++ b/content/browser/network_service_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/bind.h"
 #include "base/memory/ref_counted_memory.h"
+#include "base/test/bind_test_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "content/browser/storage_partition_impl.h"
@@ -16,6 +17,7 @@
 #include "content/public/browser/web_ui_controller_factory.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/network_service_util.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/common/url_utils.h"
@@ -27,6 +29,8 @@
 #include "content/shell/browser/shell.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_response_headers.h"
+#include "net/test/embedded_test_server/default_handlers.h"
+#include "net/test/embedded_test_server/http_request.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/network_switches.h"
@@ -139,12 +143,12 @@
     return xhr_result && execute_result;
   }
 
-  bool FetchResource(const GURL& url) {
+  bool FetchResource(const GURL& url, bool synchronous = false) {
     if (!url.is_valid())
       return false;
     std::string script = JsReplace(
         "var xhr = new XMLHttpRequest();"
-        "xhr.open('GET', $1, true);"
+        "xhr.open('GET', $1, $2);"
         "xhr.onload = function (e) {"
         "  if (xhr.readyState === 4) {"
         "    window.domAutomationController.send(xhr.status === 200);"
@@ -153,8 +157,12 @@
         "xhr.onerror = function () {"
         "  window.domAutomationController.send(false);"
         "};"
-        "xhr.send(null);",
-        url);
+        "try {"
+        "  xhr.send(null);"
+        "} catch (error) {"
+        "  window.domAutomationController.send(false);"
+        "}",
+        url, !synchronous);
     return ExecuteScript(script);
   }
 
@@ -387,6 +395,35 @@
             base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
 }
 
+// Verifies that sync XHRs don't hang if the network service crashes.
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest, SyncXHROnCrash) {
+  if (IsInProcessNetworkService())
+    return;
+
+  network::mojom::NetworkServiceTestPtr network_service_test;
+  ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
+      mojom::kNetworkServiceName, &network_service_test);
+  network::mojom::NetworkServiceTestPtrInfo network_service_test_info =
+      network_service_test.PassInterface();
+
+  net::EmbeddedTestServer http_server;
+  net::test_server::RegisterDefaultHandlers(&http_server);
+  http_server.RegisterRequestMonitor(base::BindLambdaForTesting(
+      [&](const net::test_server::HttpRequest& request) {
+        if (request.relative_url == "/hung") {
+          network::mojom::NetworkServiceTestPtr network_service_test2(
+              std::move(network_service_test_info));
+          network_service_test2->SimulateCrash();
+        }
+      }));
+  EXPECT_TRUE(http_server.Start());
+
+  NavigateToURL(shell(), http_server.GetURL("/empty.html"));
+
+  FetchResource(http_server.GetURL("/hung"), true);
+  // If the renderer is hung the test will hang.
+}
+
 class NetworkServiceInProcessBrowserTest : public ContentBrowserTest {
  public:
   NetworkServiceInProcessBrowserTest() {
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc
index 1039f523..a6d280f 100644
--- a/content/browser/scheduler/browser_task_executor.cc
+++ b/content/browser/scheduler/browser_task_executor.cc
@@ -9,8 +9,13 @@
 #include "base/bind.h"
 #include "base/deferred_sequenced_task_runner.h"
 #include "base/no_destructor.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "content/browser/browser_thread_impl.h"
 
+#if defined(OS_ANDROID)
+#include "base/android/task_scheduler/post_task_android.h"
+#endif
+
 namespace content {
 namespace {
 
@@ -144,19 +149,74 @@
 
 }  // namespace
 
-BrowserTaskExecutor::BrowserTaskExecutor() = default;
+BrowserTaskExecutor::BrowserTaskExecutor(
+    std::unique_ptr<base::MessageLoopForUI> message_loop,
+    scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
+    : message_loop_(std::move(message_loop)),
+      ui_thread_task_runner_(std::move(ui_thread_task_runner)) {}
+
 BrowserTaskExecutor::~BrowserTaskExecutor() = default;
 
 // static
 void BrowserTaskExecutor::Create() {
   DCHECK(!g_browser_task_executor);
-  g_browser_task_executor = new BrowserTaskExecutor();
+  DCHECK(!base::ThreadTaskRunnerHandle::IsSet());
+  std::unique_ptr<base::MessageLoopForUI> message_loop =
+      std::make_unique<base::MessageLoopForUI>();
+  scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner =
+      message_loop->task_runner();
+  g_browser_task_executor = new BrowserTaskExecutor(
+      std::move(message_loop), std::move(ui_thread_task_runner));
   base::RegisterTaskExecutor(BrowserTaskTraitsExtension::kExtensionId,
                              g_browser_task_executor);
+#if defined(OS_ANDROID)
+  base::PostTaskAndroid::SignalNativeSchedulerReady();
+#endif
+}
+
+// static
+void BrowserTaskExecutor::CreateForTesting(
+    scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) {
+  DCHECK(!g_browser_task_executor);
+  DCHECK(base::ThreadTaskRunnerHandle::IsSet());
+  DCHECK(ui_thread_task_runner);
+  g_browser_task_executor =
+      new BrowserTaskExecutor(nullptr, std::move(ui_thread_task_runner));
+  base::RegisterTaskExecutor(BrowserTaskTraitsExtension::kExtensionId,
+                             g_browser_task_executor);
+#if defined(OS_ANDROID)
+  base::PostTaskAndroid::SignalNativeSchedulerReady();
+#endif
+}
+
+// static
+void BrowserTaskExecutor::PostFeatureListSetup() {
+  DCHECK(g_browser_task_executor);
+  // TODO(alexclarke): Forward to the BrowserUIThreadScheduler.
+}
+
+// static
+void BrowserTaskExecutor::Shutdown() {
+  if (!g_browser_task_executor)
+    return;
+
+  DCHECK(g_browser_task_executor->message_loop_);
+  // We don't delete either |g_browser_task_executor| or because other threads
+  // may PostTask or call BrowserTaskExecutor::GetTaskRunner while  we're
+  // tearing things down. We don't want to add locks so we just leak instead of
+  // dealing with that.For similar reasons we don't need to call
+  // PostTaskAndroid::SignalNativeSchedulerShutdown on Android. In tests however
+  // we need to clean up, so BrowserTaskExecutor::ResetForTesting should be
+  // called.
+  g_browser_task_executor->message_loop_.reset();
 }
 
 // static
 void BrowserTaskExecutor::ResetForTesting() {
+#if defined(OS_ANDROID)
+  base::PostTaskAndroid::SignalNativeSchedulerShutdown();
+#endif
+
   for (int i = 0; i < BrowserThread::ID_COUNT; ++i) {
     GetAfterStartupTaskRunnerForThreadImpl(static_cast<BrowserThread::ID>(i))
         ->Reset();
@@ -232,6 +292,8 @@
   // policies instead.
   if (traits.priority() == base::TaskPriority::BEST_EFFORT)
     return GetAfterStartupTaskRunnerForThread(thread_id);
+  if (thread_id == BrowserThread::UI)
+    return ui_thread_task_runner_;
   return GetProxyTaskRunnerForThread(thread_id);
 }
 
diff --git a/content/browser/scheduler/browser_task_executor.h b/content/browser/scheduler/browser_task_executor.h
index 29e99387..f56f346 100644
--- a/content/browser/scheduler/browser_task_executor.h
+++ b/content/browser/scheduler/browser_task_executor.h
@@ -5,8 +5,11 @@
 #ifndef CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
 #define CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
 
+#include <memory>
+
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/message_loop/message_loop.h"
 #include "base/task/task_executor.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
@@ -18,10 +21,25 @@
 // browser process.
 class CONTENT_EXPORT BrowserTaskExecutor : public base::TaskExecutor {
  public:
-  // Creates and registers a BrowserTaskExecutor that facilitates posting tasks
-  // to a BrowserThread via //base/task/post_task.h.
+  // Creates and registers a BrowserTaskExecutor on the current thread, which
+  // owns a MessageLoopForUI. This facilitates posting tasks to a BrowserThread
+  // via //base/task/post_task.h.
   static void Create();
 
+  // Creates and registers a BrowserTaskExecutor on the current thread, which
+  // defers to a task runner from a previously created MessageLoopForUI.
+  static void CreateForTesting(
+      scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
+
+  // This must be called after the FeatureList has been initialized in order
+  // for scheduling experiments to function.
+  static void PostFeatureListSetup();
+
+  // Winds down the BrowserTaskExecutor, after this no tasks can be executed
+  // and the base::TaskExecutor APIs are non-functional but won't crash if
+  // called.
+  static void Shutdown();
+
   // Unregister and delete the TaskExecutor after a test.
   static void ResetForTesting();
 
@@ -57,7 +75,10 @@
   FRIEND_TEST_ALL_PREFIXES(BrowserTaskExecutorTest,
                            BestEffortTasksRunAfterStartup);
 
-  BrowserTaskExecutor();
+  // TODO(alexclarke): Replace with a BrowserUIThreadScheduler.
+  BrowserTaskExecutor(
+      std::unique_ptr<base::MessageLoopForUI> message_loop,
+      scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
   ~BrowserTaskExecutor() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
@@ -73,6 +94,9 @@
   static scoped_refptr<base::SingleThreadTaskRunner>
   GetAfterStartupTaskRunnerForThread(BrowserThread::ID id);
 
+  std::unique_ptr<base::MessageLoopForUI> message_loop_;
+  scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;
+
   DISALLOW_COPY_AND_ASSIGN(BrowserTaskExecutor);
 };
 
diff --git a/content/browser/scheduler/browser_task_executor_unittest.cc b/content/browser/scheduler/browser_task_executor_unittest.cc
index a70626b..50e846c 100644
--- a/content/browser/scheduler/browser_task_executor_unittest.cc
+++ b/content/browser/scheduler/browser_task_executor_unittest.cc
@@ -60,9 +60,8 @@
 };
 
 TEST_F(BrowserTaskExecutorTest, EnsureUIThreadTraitPointsToExpectedQueue) {
-  EXPECT_EQ(
-      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}),
-      BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::UI));
+  EXPECT_EQ(base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}),
+            thread_bundle_.GetMainThreadTaskRunner());
 }
 
 TEST_F(BrowserTaskExecutorTest, EnsureIOThreadTraitPointsToExpectedQueue) {
diff --git a/content/browser/scheduler/responsiveness/watcher.cc b/content/browser/scheduler/responsiveness/watcher.cc
index b18527c..1c5e77c 100644
--- a/content/browser/scheduler/responsiveness/watcher.cc
+++ b/content/browser/scheduler/responsiveness/watcher.cc
@@ -13,6 +13,10 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 
+#if defined(OS_CHROMEOS)
+#include "ui/base/ui_base_features.h"
+#endif
+
 namespace content {
 namespace responsiveness {
 
@@ -187,6 +191,16 @@
   if (UNLIKELY(currently_running_metadata->empty() ||
                (task != currently_running_metadata->back().identifier))) {
     *mismatched_task_identifiers += 1;
+#if defined(OS_CHROMEOS)
+    // Mismatches can happen often on ChromeOS with window service when
+    // tab-dragging is involved. Simply ignore the mismatches for now. See
+    // https://crbug.com/929813 for the details of why the mismatch happens.
+    // TODO(mukai): fix the event order issue.
+    if (features::IsUsingWindowService()) {
+      currently_running_metadata_ui_.clear();
+      return;
+    }
+#endif
     DCHECK_LE(*mismatched_task_identifiers, 1);
     return;
   }
@@ -242,6 +256,16 @@
                (opaque_identifier !=
                 currently_running_metadata_ui_.back().identifier))) {
     mismatched_event_identifiers_ui_ += 1;
+#if defined(OS_CHROMEOS)
+    // Mismatches can happen often on ChromeOS with window service when
+    // tab-dragging is involved. Simply ignore the mismatches for now. See
+    // https://crbug.com/929813 for the details of why the mismatch happens.
+    // TODO(mukai): fix the event order issue.
+    if (features::IsUsingWindowService()) {
+      currently_running_metadata_ui_.clear();
+      return;
+    }
+#endif
     DCHECK_LE(mismatched_event_identifiers_ui_, 1);
     return;
   }
diff --git a/content/public/browser/authenticator_request_client_delegate.h b/content/public/browser/authenticator_request_client_delegate.h
index 94f2a17e..c73ae20 100644
--- a/content/public/browser/authenticator_request_client_delegate.h
+++ b/content/public/browser/authenticator_request_client_delegate.h
@@ -31,7 +31,7 @@
 //
 // [1]: See https://www.w3.org/TR/webauthn/.
 class CONTENT_EXPORT AuthenticatorRequestClientDelegate
-    : public device::FidoRequestHandlerBase::TransportAvailabilityObserver {
+    : public device::FidoRequestHandlerBase::Observer {
  public:
   // Failure reasons that might be of interest to the user, so the embedder may
   // decide to inform the user.
@@ -109,7 +109,7 @@
 
   virtual bool IsWebAuthnUIEnabled();
 
-  // device::FidoRequestHandlerBase::TransportAvailabilityObserver:
+  // device::FidoRequestHandlerBase::Observer:
   void OnTransportAvailabilityEnumerated(
       device::FidoRequestHandlerBase::TransportAvailabilityInfo data) override;
   // If true, the request handler will defer dispatch of its request onto the
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 2fff2ecd..07dafe9d 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -751,8 +751,10 @@
 
 std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
 ContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
-    NavigationUIData* navigation_ui_data,
-    int frame_tree_node_id) {
+    content::NavigationUIData* navigation_ui_data,
+    int frame_tree_node_id,
+    const scoped_refptr<network::SharedURLLoaderFactory>&
+        network_loader_factory) {
   return std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>();
 }
 
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index a013031..6999eb05 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1236,8 +1236,11 @@
   // Always called on the IO thread and only when the Network Service is
   // enabled.
   virtual std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
-  WillCreateURLLoaderRequestInterceptors(NavigationUIData* navigation_ui_data,
-                                         int frame_tree_node_id);
+  WillCreateURLLoaderRequestInterceptors(
+      content::NavigationUIData* navigation_ui_data,
+      int frame_tree_node_id,
+      const scoped_refptr<network::SharedURLLoaderFactory>&
+          network_loader_factory);
 
   // Called when the NetworkService, accessible through
   // content::GetNetworkService(), is created. Implementations should avoid
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index d53f9d1..979cd53c 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -340,8 +340,10 @@
   field_trial_list_ = SetUpFieldTrialsAndFeatureList();
   StartBrowserTaskScheduler();
   BrowserTaskExecutor::Create();
+  BrowserTaskExecutor::PostFeatureListSetup();
   // TODO(phajdan.jr): Check return code, http://crbug.com/374738 .
   BrowserMain(params);
+  BrowserTaskExecutor::ResetForTesting();
 #else
   GetContentMainParams()->ui_task = ui_task.release();
   GetContentMainParams()->created_main_parts_closure =
diff --git a/content/public/test/test_browser_thread_bundle.cc b/content/public/test/test_browser_thread_bundle.cc
index 56fa71e..ed09ab1 100644
--- a/content/public/test/test_browser_thread_bundle.cc
+++ b/content/public/test/test_browser_thread_bundle.cc
@@ -84,7 +84,7 @@
   CHECK(com_initializer_->Succeeded());
 #endif
 
-  BrowserTaskExecutor::Create();
+  BrowserTaskExecutor::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
 
   if (HasIOMainLoop()) {
     CHECK(base::MessageLoopCurrentForIO::IsSet());
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 72b2236..90751594 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -2289,10 +2289,11 @@
   DCHECK(main_thread_runner()->BelongsToCurrentThread());
   if (!media_thread_) {
     media_thread_.reset(new base::Thread("Media"));
-    base::Thread::Options options;
 #if defined(OS_FUCHSIA)
     // Start IO thread on Fuchsia to make that thread usable for FIDL.
-    options = base::Thread::Options(base::MessageLoop::TYPE_IO, 0);
+    base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
+#else
+    base::Thread::Options options;
 #endif
     media_thread_->StartWithOptions(options);
   }
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index b2dd0ed..622463d 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -118,8 +118,12 @@
     "public_key_credential_rp_entity.h",
     "public_key_credential_user_entity.cc",
     "public_key_credential_user_entity.h",
+    "reset_request_handler.cc",
+    "reset_request_handler.h",
     "response_data.cc",
     "response_data.h",
+    "set_pin_request_handler.cc",
+    "set_pin_request_handler.h",
     "u2f_command_constructor.cc",
     "u2f_command_constructor.h",
     "u2f_register_operation.cc",
diff --git a/device/fido/ble_adapter_manager_unittest.cc b/device/fido/ble_adapter_manager_unittest.cc
index eb6ef23..f91ba0d 100644
--- a/device/fido/ble_adapter_manager_unittest.cc
+++ b/device/fido/ble_adapter_manager_unittest.cc
@@ -30,11 +30,10 @@
 constexpr char kTestPinCode[] = "1234";
 constexpr char kTestBluetoothDisplayName[] = "device_name";
 
-class MockTransportAvailabilityObserver
-    : public FidoRequestHandlerBase::TransportAvailabilityObserver {
+class MockObserver : public FidoRequestHandlerBase::Observer {
  public:
-  MockTransportAvailabilityObserver() = default;
-  ~MockTransportAvailabilityObserver() override = default;
+  MockObserver() = default;
+  ~MockObserver() override = default;
 
   MOCK_METHOD1(OnTransportAvailabilityEnumerated,
                void(FidoRequestHandlerBase::TransportAvailabilityInfo data));
@@ -51,13 +50,12 @@
                void(base::StringPiece, bool));
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(MockTransportAvailabilityObserver);
+  DISALLOW_COPY_AND_ASSIGN(MockObserver);
 };
 
 class FakeFidoRequestHandlerBase : public FidoRequestHandlerBase {
  public:
-  explicit FakeFidoRequestHandlerBase(
-      MockTransportAvailabilityObserver* observer)
+  explicit FakeFidoRequestHandlerBase(MockObserver* observer)
       : FidoRequestHandlerBase(nullptr, {}) {
     set_observer(observer);
   }
@@ -102,7 +100,7 @@
   }
 
   MockBluetoothAdapter* adapter() { return adapter_.get(); }
-  MockTransportAvailabilityObserver* observer() { return mock_observer_.get(); }
+  MockObserver* observer() { return mock_observer_.get(); }
   bool adapter_powered_on_programmatically(
       const BleAdapterManager& adapter_manager) {
     return adapter_manager.adapter_powered_on_programmatically_;
@@ -126,8 +124,8 @@
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   scoped_refptr<MockBluetoothAdapter> adapter_ =
       base::MakeRefCounted<::testing::NiceMock<MockBluetoothAdapter>>();
-  std::unique_ptr<MockTransportAvailabilityObserver> mock_observer_ =
-      std::make_unique<MockTransportAvailabilityObserver>();
+  std::unique_ptr<MockObserver> mock_observer_ =
+      std::make_unique<MockObserver>();
   std::unique_ptr<FakeFidoRequestHandlerBase> fake_request_handler_ =
       std::make_unique<FakeFidoRequestHandlerBase>(mock_observer_.get());
 };
diff --git a/device/fido/fido_request_handler_base.cc b/device/fido/fido_request_handler_base.cc
index 573fdfeb..58f09110 100644
--- a/device/fido/fido_request_handler_base.cc
+++ b/device/fido/fido_request_handler_base.cc
@@ -48,10 +48,9 @@
 FidoRequestHandlerBase::TransportAvailabilityInfo::
     ~TransportAvailabilityInfo() = default;
 
-// FidoRequestHandlerBase::TransportAvailabilityObserver ----------------------
+// FidoRequestHandlerBase::Observer ----------------------
 
-FidoRequestHandlerBase::TransportAvailabilityObserver::
-    ~TransportAvailabilityObserver() = default;
+FidoRequestHandlerBase::Observer::~Observer() = default;
 
 // FidoRequestHandlerBase -----------------------------------------------------
 
@@ -244,6 +243,11 @@
       std::move(success_callback), std::move(error_callback));
 }
 
+void FidoRequestHandlerBase::ProvidePIN(const std::string& old_pin,
+                                        const std::string& pin) {
+  NOTREACHED();
+}
+
 base::WeakPtr<FidoRequestHandlerBase> FidoRequestHandlerBase::GetWeakPtr() {
   return weak_factory_.GetWeakPtr();
 }
diff --git a/device/fido/fido_request_handler_base.h b/device/fido/fido_request_handler_base.h
index 6530de8..1de5d5e 100644
--- a/device/fido/fido_request_handler_base.h
+++ b/device/fido/fido_request_handler_base.h
@@ -106,13 +106,13 @@
     // If true, dispatch of the request cannot be controlled by
     // the embedder. The embedder must not display a UI for this
     // request and must ignore all subsequent invocations of the
-    // TransportAvailabilityObserver interface methods.
+    // Observer interface methods.
     bool disable_embedder_ui = false;
   };
 
-  class COMPONENT_EXPORT(DEVICE_FIDO) TransportAvailabilityObserver {
+  class COMPONENT_EXPORT(DEVICE_FIDO) Observer {
    public:
-    virtual ~TransportAvailabilityObserver();
+    virtual ~Observer();
 
     // This method will not be invoked until the observer is set.
     virtual void OnTransportAvailabilityEnumerated(
@@ -175,9 +175,11 @@
                                  base::OnceClosure success_callback,
                                  base::OnceClosure error_callback);
 
+  virtual void ProvidePIN(const std::string& old_pin, const std::string& pin);
+
   base::WeakPtr<FidoRequestHandlerBase> GetWeakPtr();
 
-  void set_observer(TransportAvailabilityObserver* observer) {
+  void set_observer(Observer* observer) {
     DCHECK(!observer_) << "Only one observer is supported.";
     observer_ = observer;
 
@@ -218,7 +220,19 @@
   std::vector<std::unique_ptr<FidoDiscoveryBase>>& discoveries() {
     return discoveries_;
   }
-  TransportAvailabilityObserver* observer() const { return observer_; }
+  Observer* observer() const { return observer_; }
+
+  // FidoDiscoveryBase::Observer
+  void AuthenticatorAdded(FidoDiscoveryBase* discovery,
+                          FidoAuthenticator* authenticator) override;
+  void AuthenticatorRemoved(FidoDiscoveryBase* discovery,
+                            FidoAuthenticator* authenticator) override;
+  void AuthenticatorIdChanged(FidoDiscoveryBase* discovery,
+                              const std::string& previous_id,
+                              std::string new_id) override;
+  void AuthenticatorPairingModeChanged(FidoDiscoveryBase* discovery,
+                                       const std::string& device_id,
+                                       bool is_in_pairing_mode) override;
 
  private:
   friend class FidoRequestHandlerTest;
@@ -230,18 +244,6 @@
       const base::flat_set<FidoTransportProtocol>& available_transports);
 #endif
 
-  // FidoDiscoveryBase::Observer
-  void AuthenticatorAdded(FidoDiscoveryBase* discovery,
-                          FidoAuthenticator* authenticator) final;
-  void AuthenticatorRemoved(FidoDiscoveryBase* discovery,
-                            FidoAuthenticator* authenticator) final;
-  void AuthenticatorIdChanged(FidoDiscoveryBase* discovery,
-                              const std::string& previous_id,
-                              std::string new_id) final;
-  void AuthenticatorPairingModeChanged(FidoDiscoveryBase* discovery,
-                                       const std::string& device_id,
-                                       bool is_in_pairing_mode) final;
-
   void AddAuthenticator(FidoAuthenticator* authenticator);
   void NotifyObserverTransportAvailability();
 
@@ -254,7 +256,7 @@
 
   AuthenticatorMap active_authenticators_;
   std::vector<std::unique_ptr<FidoDiscoveryBase>> discoveries_;
-  TransportAvailabilityObserver* observer_ = nullptr;
+  Observer* observer_ = nullptr;
   TransportAvailabilityInfo transport_availability_info_;
   base::RepeatingClosure notify_observer_callback_;
   std::unique_ptr<BleAdapterManager> bluetooth_adapter_manager_;
diff --git a/device/fido/fido_request_handler_unittest.cc b/device/fido/fido_request_handler_unittest.cc
index f198dc5c..32c38b5 100644
--- a/device/fido/fido_request_handler_unittest.cc
+++ b/device/fido/fido_request_handler_unittest.cc
@@ -65,16 +65,15 @@
   void DispatchRequest(FidoAuthenticator* authenticator) override {}
 };
 
-class TestTransportAvailabilityObserver
-    : public FidoRequestHandlerBase::TransportAvailabilityObserver {
+class TestObserver : public FidoRequestHandlerBase::Observer {
  public:
   using TransportAvailabilityNotificationReceiver = test::TestCallbackReceiver<
       FidoRequestHandlerBase::TransportAvailabilityInfo>;
   using AuthenticatorIdChangeNotificationReceiver =
       test::TestCallbackReceiver<std::string>;
 
-  TestTransportAvailabilityObserver() {}
-  ~TestTransportAvailabilityObserver() override {}
+  TestObserver() {}
+  ~TestObserver() override {}
 
   FidoRequestHandlerBase::TransportAvailabilityInfo
   WaitForTransportAvailabilityInfo() {
@@ -104,7 +103,7 @@
   }
 
  protected:
-  // FidoRequestHandlerBase::TransportAvailabilityObserver:
+  // FidoRequestHandlerBase::Observer:
   void OnTransportAvailabilityEnumerated(
       FidoRequestHandlerBase::TransportAvailabilityInfo data) override {
     transport_availability_notification_receiver_.callback().Run(
@@ -133,7 +132,7 @@
   AuthenticatorIdChangeNotificationReceiver
       authenticator_id_change_notification_receiver_;
 
-  DISALLOW_COPY_AND_ASSIGN(TestTransportAvailabilityObserver);
+  DISALLOW_COPY_AND_ASSIGN(TestObserver);
 };
 
 // Fake FidoTask implementation that sends an empty byte array to the device
@@ -530,7 +529,7 @@
   auto authenticator =
       std::make_unique<FidoDeviceAuthenticator>(std::move(device));
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = std::make_unique<FakeFidoRequestHandler>(
       base::flat_set<FidoTransportProtocol>({FidoTransportProtocol::kInternal}),
       callback().callback());
@@ -566,7 +565,7 @@
   auto authenticator =
       std::make_unique<FidoDeviceAuthenticator>(std::move(device));
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = std::make_unique<FakeFidoRequestHandler>(
       base::flat_set<FidoTransportProtocol>({FidoTransportProtocol::kInternal}),
       callback().callback());
@@ -584,7 +583,7 @@
 }
 
 TEST_F(FidoRequestHandlerTest, InternalTransportDisallowedIfMarkedUnavailable) {
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = std::make_unique<FakeFidoRequestHandler>(
       base::flat_set<FidoTransportProtocol>({FidoTransportProtocol::kInternal}),
       callback().callback());
@@ -597,7 +596,7 @@
 TEST_F(FidoRequestHandlerTest, BleTransportAllowedIfBluetoothAdapterPresent) {
   EXPECT_CALL(*adapter(), IsPresent()).WillOnce(::testing::Return(true));
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = CreateFakeHandler();
   request_handler->set_observer(&observer);
 
@@ -610,7 +609,7 @@
        BleTransportDisallowedBluetoothAdapterNotPresent) {
   EXPECT_CALL(*adapter(), IsPresent()).WillOnce(::testing::Return(false));
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = CreateFakeHandler();
   request_handler->set_observer(&observer);
 
@@ -622,7 +621,7 @@
        TransportAvailabilityNotificationOnObserverSetLate) {
   EXPECT_CALL(*adapter(), IsPresent()).WillOnce(::testing::Return(true));
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = CreateFakeHandler();
   scoped_task_environment_.FastForwardUntilNoTasksRemain();
 
@@ -634,7 +633,7 @@
 
 TEST_F(FidoRequestHandlerTest, EmbedderNotifiedWhenAuthenticatorIdChanges) {
   static constexpr char kNewAuthenticatorId[] = "new_authenticator_id";
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   auto request_handler = CreateFakeHandler();
   request_handler->set_observer(&observer);
   ble_discovery()->WaitForCallToStartAndSimulateSuccess();
@@ -653,7 +652,7 @@
   ScopedFakeWinWebAuthnApi scoped_fake_win_webauthn_api;
   scoped_fake_win_webauthn_api.set_available(true);
 
-  TestTransportAvailabilityObserver observer;
+  TestObserver observer;
   ForgeNextHidDiscovery();
   EmptyRequestHandler request_handler(
       {FidoTransportProtocol::kUsbHumanInterfaceDevice});
diff --git a/device/fido/reset_request_handler.cc b/device/fido/reset_request_handler.cc
new file mode 100644
index 0000000..95962060
--- /dev/null
+++ b/device/fido/reset_request_handler.cc
@@ -0,0 +1,75 @@
+// 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 <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "device/fido/fido_authenticator.h"
+#include "device/fido/fido_constants.h"
+#include "device/fido/pin.h"
+#include "device/fido/reset_request_handler.h"
+
+namespace device {
+
+ResetRequestHandler::ResetRequestHandler(
+    service_manager::Connector* connector,
+    const base::flat_set<FidoTransportProtocol>& supported_transports,
+    ResetSentCallback reset_sent_callback,
+    FinishedCallback finished_callback)
+    : FidoRequestHandlerBase(connector, supported_transports),
+      reset_sent_callback_(std::move(reset_sent_callback)),
+      finished_callback_(std::move(finished_callback)),
+      weak_factory_(this) {
+  Start();
+}
+
+ResetRequestHandler::~ResetRequestHandler() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  CancelActiveAuthenticators();
+}
+
+void ResetRequestHandler::DispatchRequest(FidoAuthenticator* authenticator) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+
+  authenticator->GetTouch(base::BindOnce(&ResetRequestHandler::OnTouch,
+                                         weak_factory_.GetWeakPtr(),
+                                         authenticator));
+}
+
+void ResetRequestHandler::OnTouch(FidoAuthenticator* authenticator) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+
+  if (processed_touch_) {
+    return;
+  }
+
+  processed_touch_ = true;
+  CancelActiveAuthenticators();
+
+  if (authenticator->SupportedProtocol() != ProtocolVersion::kCtap) {
+    std::move(finished_callback_)
+        .Run(CtapDeviceResponseCode::kCtap1ErrInvalidCommand);
+    return;
+  }
+
+  authenticator->Reset(base::BindOnce(&ResetRequestHandler::OnResetComplete,
+                                      weak_factory_.GetWeakPtr()));
+  std::move(reset_sent_callback_).Run();
+}
+
+void ResetRequestHandler::OnResetComplete(
+    CtapDeviceResponseCode status,
+    base::Optional<pin::EmptyResponse> response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  DCHECK(processed_touch_);
+
+  if (status == CtapDeviceResponseCode::kSuccess && !response) {
+    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
+  }
+
+  std::move(finished_callback_).Run(status);
+}
+
+}  // namespace device
diff --git a/device/fido/reset_request_handler.h b/device/fido/reset_request_handler.h
new file mode 100644
index 0000000..b6cabbb
--- /dev/null
+++ b/device/fido/reset_request_handler.h
@@ -0,0 +1,73 @@
+// 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 DEVICE_FIDO_RESET_REQUEST_HANDLER_H_
+#define DEVICE_FIDO_RESET_REQUEST_HANDLER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "device/fido/fido_request_handler_base.h"
+#include "device/fido/fido_transport_protocol.h"
+
+namespace service_manager {
+class Connector;
+};  // namespace service_manager
+
+namespace device {
+
+class FidoAuthenticator;
+
+namespace pin {
+struct EmptyResponse;
+}
+
+// ResetRequestHandler is a simple state machine that gets a touch from an
+// authenticator and then sends a CTAP2 reset request. This is expected to be
+// driven by Settings UI for users to manually reset authenticators.
+class COMPONENT_EXPORT(DEVICE_FIDO) ResetRequestHandler
+    : public FidoRequestHandlerBase {
+ public:
+  // ResetSentCallback will be run once an authenticator has been touched and a
+  // reset command has been sent to it. This will always occur before
+  // |FinishedCallback|.
+  using ResetSentCallback = base::OnceCallback<void()>;
+  // FinishedCallback will be called once this process has completed. If the
+  // status is |kCtap1ErrInvalidCommand| then the user may have selected a non-
+  // CTAP2 authenticator, in which case no reset command was ever sent.
+  // Otherwise the status is the result of the reset command.
+  using FinishedCallback = base::OnceCallback<void(CtapDeviceResponseCode)>;
+
+  ResetRequestHandler(
+      service_manager::Connector* connector,
+      const base::flat_set<FidoTransportProtocol>& supported_transports,
+      ResetSentCallback reset_sent_callback,
+      FinishedCallback finished_callback);
+  ~ResetRequestHandler() override;
+
+ private:
+  // FidoRequestHandlerBase:
+  void DispatchRequest(FidoAuthenticator* authenticator) override;
+
+  void OnTouch(FidoAuthenticator* authenticator);
+  void OnResetComplete(CtapDeviceResponseCode status,
+                       base::Optional<pin::EmptyResponse> response);
+
+  ResetSentCallback reset_sent_callback_;
+  FinishedCallback finished_callback_;
+  bool processed_touch_ = false;
+  SEQUENCE_CHECKER(my_sequence_checker_);
+  base::WeakPtrFactory<ResetRequestHandler> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ResetRequestHandler);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_RESET_REQUEST_HANDLER_H_
diff --git a/device/fido/set_pin_request_handler.cc b/device/fido/set_pin_request_handler.cc
new file mode 100644
index 0000000..6b60b30f
--- /dev/null
+++ b/device/fido/set_pin_request_handler.cc
@@ -0,0 +1,174 @@
+// 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 <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "device/fido/fido_authenticator.h"
+#include "device/fido/fido_constants.h"
+#include "device/fido/pin.h"
+#include "device/fido/set_pin_request_handler.h"
+
+namespace device {
+
+SetPINRequestHandler::SetPINRequestHandler(
+    service_manager::Connector* connector,
+    const base::flat_set<FidoTransportProtocol>& supported_transports,
+    GetPINCallback get_pin_callback,
+    FinishedCallback finished_callback)
+    : FidoRequestHandlerBase(connector, supported_transports),
+      get_pin_callback_(std::move(get_pin_callback)),
+      finished_callback_(std::move(finished_callback)),
+      weak_factory_(this) {
+  Start();
+}
+
+SetPINRequestHandler::~SetPINRequestHandler() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  CancelActiveAuthenticators();
+}
+
+void SetPINRequestHandler::ProvidePIN(const std::string& old_pin,
+                                      const std::string& new_pin) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  DCHECK_EQ(State::kWaitingForPIN, state_);
+  DCHECK(pin::IsValid(new_pin));
+
+  if (authenticator_ == nullptr) {
+    // Authenticator was detached.
+    state_ = State::kFinished;
+    finished_callback_.Run(CtapDeviceResponseCode::kCtap1ErrInvalidChannel);
+    return;
+  }
+
+  state_ = State::kGetEphemeralKey;
+  authenticator_->GetEphemeralKey(base::BindOnce(
+      &SetPINRequestHandler::OnHaveEphemeralKey, weak_factory_.GetWeakPtr(),
+      std::move(old_pin), std::move(new_pin)));
+}
+
+void SetPINRequestHandler::DispatchRequest(FidoAuthenticator* authenticator) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+
+  authenticator->GetTouch(base::BindOnce(&SetPINRequestHandler::OnTouch,
+                                         weak_factory_.GetWeakPtr(),
+                                         authenticator));
+}
+
+void SetPINRequestHandler::AuthenticatorRemoved(
+    FidoDiscoveryBase* discovery,
+    FidoAuthenticator* authenticator) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+
+  if (authenticator == authenticator_) {
+    authenticator_ = nullptr;
+  }
+
+  FidoRequestHandlerBase::AuthenticatorRemoved(discovery, authenticator);
+}
+
+void SetPINRequestHandler::OnTouch(FidoAuthenticator* authenticator) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+
+  if (state_ != State::kWaitingForTouch) {
+    return;
+  }
+
+  authenticator_ = authenticator;
+  CancelActiveAuthenticators();
+
+  switch (authenticator_->Options()->client_pin_availability) {
+    case AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported:
+      state_ = State::kFinished;
+      finished_callback_.Run(CtapDeviceResponseCode::kCtap1ErrInvalidCommand);
+      return;
+
+    case AuthenticatorSupportedOptions::ClientPinAvailability::
+        kSupportedAndPinSet:
+      state_ = State::kGettingRetries;
+      authenticator_->GetRetries(
+          base::BindOnce(&SetPINRequestHandler::OnRetriesResponse,
+                         weak_factory_.GetWeakPtr()));
+      break;
+
+    case AuthenticatorSupportedOptions::ClientPinAvailability::
+        kSupportedButPinNotSet:
+      state_ = State::kWaitingForPIN;
+      std::move(get_pin_callback_).Run(base::nullopt);
+      break;
+  }
+}
+
+void SetPINRequestHandler::OnRetriesResponse(
+    CtapDeviceResponseCode status,
+    base::Optional<pin::RetriesResponse> response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  DCHECK_EQ(state_, State::kGettingRetries);
+
+  if (status == CtapDeviceResponseCode::kSuccess && !response) {
+    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
+  }
+
+  if (status != CtapDeviceResponseCode::kSuccess) {
+    state_ = State::kFinished;
+    finished_callback_.Run(status);
+    return;
+  }
+
+  state_ = State::kWaitingForPIN;
+  std::move(get_pin_callback_).Run(response->retries);
+}
+
+void SetPINRequestHandler::OnHaveEphemeralKey(
+    std::string old_pin,
+    std::string new_pin,
+    CtapDeviceResponseCode status,
+    base::Optional<pin::KeyAgreementResponse> response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  DCHECK_EQ(state_, State::kGetEphemeralKey);
+
+  if (status == CtapDeviceResponseCode::kSuccess && !response) {
+    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
+  }
+
+  if (status != CtapDeviceResponseCode::kSuccess) {
+    state_ = State::kFinished;
+    finished_callback_.Run(status);
+    return;
+  }
+
+  state_ = State::kSettingPIN;
+
+  if (old_pin.empty()) {
+    authenticator_->SetPIN(
+        new_pin, *response,
+        base::BindOnce(&SetPINRequestHandler::OnSetPINComplete,
+                       weak_factory_.GetWeakPtr()));
+  } else {
+    authenticator_->ChangePIN(
+        old_pin, new_pin, *response,
+        base::BindOnce(&SetPINRequestHandler::OnSetPINComplete,
+                       weak_factory_.GetWeakPtr()));
+  }
+}
+
+void SetPINRequestHandler::OnSetPINComplete(
+    CtapDeviceResponseCode status,
+    base::Optional<pin::EmptyResponse> response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
+  DCHECK_EQ(state_, State::kSettingPIN);
+
+  if (status == CtapDeviceResponseCode::kCtap2ErrPinInvalid) {
+    // The caller may try again.
+    state_ = State::kWaitingForPIN;
+  } else {
+    state_ = State::kFinished;
+  }
+
+  finished_callback_.Run(status);
+}
+
+}  // namespace device
diff --git a/device/fido/set_pin_request_handler.h b/device/fido/set_pin_request_handler.h
new file mode 100644
index 0000000..0a00ca7b
--- /dev/null
+++ b/device/fido/set_pin_request_handler.h
@@ -0,0 +1,118 @@
+// 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 DEVICE_FIDO_SET_PIN_REQUEST_HANDLER_H_
+#define DEVICE_FIDO_SET_PIN_REQUEST_HANDLER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/component_export.h"
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
+#include "device/fido/fido_request_handler_base.h"
+#include "device/fido/fido_transport_protocol.h"
+
+namespace service_manager {
+class Connector;
+};  // namespace service_manager
+
+namespace device {
+
+class FidoAuthenticator;
+
+namespace pin {
+struct RetriesResponse;
+struct KeyAgreementResponse;
+struct EmptyResponse;
+}  // namespace pin
+
+// SetPINRequestHandler handles the Settings UI-based PIN setting flow. It
+// flashes all authenticators so that the user can indicate which they want to
+// set a PIN on, and then handles (potentially multiple) attempts at setting or
+// changing the PIN.
+class COMPONENT_EXPORT(DEVICE_FIDO) SetPINRequestHandler
+    : public FidoRequestHandlerBase {
+ public:
+  // GetPINCallback is called once, after the user has touched an authenticator,
+  // to request that the user enter a PIN. If the argument is |nullopt| then the
+  // authenticator has no PIN currently set. Otherwise it indicates the number
+  // of attempts remaining.
+  using GetPINCallback = base::OnceCallback<void(base::Optional<int64_t>)>;
+
+  // FinishedCallback is called multiple times once an attempt has completed.
+  // This can be called prior to |GetPINCallback| if the touched authenticator
+  // doesn't support setting a PIN. (In which case the error code will be
+  // |kCtap1ErrInvalidCommand|.) Otherwise it's called after |ProvidePIN| to
+  // report the outcome of an attempt at setting the PIN.
+  //
+  // Interesting status codes:
+  //   |kCtap1ErrInvalidChannel|: authenticator was removed during the process.
+  //   |kCtap1ErrInvalidCommand|: touched authenticator does not support PINs.
+  //   |kCtap2ErrPinInvalid|: when changing a PIN, the old PIN was incorrect.
+  //       In this case only, |ProvidePIN| may be called again to retry.
+  using FinishedCallback =
+      base::RepeatingCallback<void(CtapDeviceResponseCode)>;
+
+  SetPINRequestHandler(
+      service_manager::Connector* connector,
+      const base::flat_set<FidoTransportProtocol>& supported_transports,
+      GetPINCallback get_pin_callback,
+      FinishedCallback finished_callback);
+  ~SetPINRequestHandler() override;
+
+  // ProvidePIN may be called after |get_pin_callback| has been used to indicate
+  // that an attempt at setting the PIN can be made. If the authenticator
+  // doesn't currently have a PIN set, then |old_pin| must be the empty string.
+  // pin::IsValid(new_pin) must be true when calling.
+  void ProvidePIN(const std::string& old_pin,
+                  const std::string& new_pin) override;
+
+ private:
+  enum class State {
+    kWaitingForTouch,
+    kGettingRetries,
+    kWaitingForPIN,
+    kGetEphemeralKey,
+    kSettingPIN,
+    kFinished,
+  };
+
+  // FidoRequestHandlerBase:
+  void DispatchRequest(FidoAuthenticator* authenticator) override;
+  void AuthenticatorRemoved(FidoDiscoveryBase* discovery,
+                            FidoAuthenticator* authenticator) override;
+
+  void OnTouch(FidoAuthenticator* authenticator);
+  void RequestRetries();
+  void OnRetriesResponse(CtapDeviceResponseCode status,
+                         base::Optional<pin::RetriesResponse> response);
+
+  void OnHaveEphemeralKey(std::string old_pin,
+                          std::string new_pin,
+                          CtapDeviceResponseCode status,
+                          base::Optional<pin::KeyAgreementResponse> response);
+
+  void OnSetPINComplete(CtapDeviceResponseCode status,
+                        base::Optional<pin::EmptyResponse> response);
+
+  State state_ = State::kWaitingForTouch;
+  GetPINCallback get_pin_callback_;
+  FinishedCallback finished_callback_;
+  // authenticator_ is the authenticator that was selected by the initial touch.
+  // The pointed-at object is owned by the |FidoRequestHandlerBase| superclass
+  // of this class.
+  FidoAuthenticator* authenticator_ = nullptr;
+  SEQUENCE_CHECKER(my_sequence_checker_);
+  base::WeakPtrFactory<SetPINRequestHandler> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SetPINRequestHandler);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_SET_PIN_REQUEST_HANDLER_H_
diff --git a/device/fido/u2f_register_operation.cc b/device/fido/u2f_register_operation.cc
index e80655a..197cedc 100644
--- a/device/fido/u2f_register_operation.cc
+++ b/device/fido/u2f_register_operation.cc
@@ -58,7 +58,7 @@
 void U2fRegisterOperation::OnRegisterResponseReceived(
     bool is_duplicate_registration,
     base::Optional<std::vector<uint8_t>> device_response) {
-  const auto& apdu_response =
+  const auto apdu_response =
       device_response
           ? apdu::ApduResponse::CreateFromMessage(std::move(*device_response))
           : base::nullopt;
@@ -103,7 +103,7 @@
 void U2fRegisterOperation::OnCheckForExcludedKeyHandle(
     ExcludeListIterator it,
     base::Optional<std::vector<uint8_t>> device_response) {
-  const auto& apdu_response =
+  const auto apdu_response =
       device_response
           ? apdu::ApduResponse::CreateFromMessage(std::move(*device_response))
           : base::nullopt;
diff --git a/device/fido/u2f_sign_operation.cc b/device/fido/u2f_sign_operation.cc
index dba0b6c..115cbdd 100644
--- a/device/fido/u2f_sign_operation.cc
+++ b/device/fido/u2f_sign_operation.cc
@@ -130,7 +130,7 @@
     AllowedListIterator it,
     base::Optional<std::vector<uint8_t>> device_response) {
   DCHECK(request().allow_list());
-  const auto& apdu_response =
+  const auto apdu_response =
       device_response
           ? apdu::ApduResponse::CreateFromMessage(std::move(*device_response))
           : base::nullopt;
diff --git a/device/usb/OWNERS b/device/usb/OWNERS
index a855859..ddbf0e3 100644
--- a/device/usb/OWNERS
+++ b/device/usb/OWNERS
@@ -1,5 +1,5 @@
 pfeldman@chromium.org
-reillyg@chromium.org
-rockot@google.com
+file://chrome/browser/usb/OWNERS
 
 # COMPONENT: IO>USB
+# TEAM: device-dev@chromium.org
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom
index c74949c..43624bf4 100644
--- a/device/vr/public/mojom/vr_service.mojom
+++ b/device/vr/public/mojom/vr_service.mojom
@@ -252,6 +252,18 @@
   // Pass through camera values
   gfx.mojom.Size? buffer_size;
   array<float, 16>? projection_matrix;
+
+  // Eye parameters may be provided per-frame for some runtimes.  If both of
+  // these are null, it indicates that there was no change since the previous
+  // frame.  If either are non-null, it indicates that data has changed. If only
+  // one is null, it indicates that the data has changed and the display is
+  // mono. Some hardware have sliders to adjust the displays for the eyes, so
+  // Oculus, Vive, and Samsung headsets may have differen't eye offsets for each
+  // frame. These need to be synchronized with a frame because the runtimes
+  // distort textures assuming the view matrix they handed out was used for
+  // rendering.
+  VREyeParameters? left_eye;
+  VREyeParameters? right_eye;
 };
 
 enum VRDisplayEventReason {
diff --git a/device/vr/windows/compositor_base.h b/device/vr/windows/compositor_base.h
index 29d8817ef..e47690d4 100644
--- a/device/vr/windows/compositor_base.h
+++ b/device/vr/windows/compositor_base.h
@@ -66,6 +66,9 @@
 #endif
   int16_t next_frame_id_ = 0;
 
+  // Allow derived classes to call methods on the main thread.
+  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
  private:
   // base::Thread overrides:
   void Init() final;
@@ -136,7 +139,6 @@
   gfx::RectF right_webxr_bounds_;
   gfx::Size source_size_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
   mojom::XRPresentationClientPtr submit_client_;
   SubmitOverlayTextureCallback overlay_submit_callback_;
   base::OnceCallback<void()> on_presentation_ended_;
diff --git a/device/vr/windows_mixed_reality/mixed_reality_device.cc b/device/vr/windows_mixed_reality/mixed_reality_device.cc
index 4efa0ff..7f8c7d0 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_device.cc
+++ b/device/vr/windows_mixed_reality/mixed_reality_device.cc
@@ -143,7 +143,10 @@
 }
 
 void MixedRealityDevice::CreateRenderLoop() {
-  render_loop_ = std::make_unique<MixedRealityRenderLoop>();
+  auto on_info_changed = base::BindRepeating(
+      &MixedRealityDevice::SetVRDisplayInfo, weak_ptr_factory_.GetWeakPtr());
+  render_loop_ =
+      std::make_unique<MixedRealityRenderLoop>(std::move(on_info_changed));
 }
 
 void MixedRealityDevice::OnPresentationEnded() {}
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
index d337eb6..3e1de369 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
+++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
@@ -4,6 +4,14 @@
 
 #include "device/vr/windows_mixed_reality/mixed_reality_renderloop.h"
 
+#include <HolographicSpaceInterop.h>
+#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
+#include <windows.graphics.holographic.h>
+#include <windows.perception.h>
+#include <windows.perception.spatial.h>
+
+#include <algorithm>
+#include <utility>
 #include <vector>
 
 #include "base/strings/string_util.h"
@@ -11,20 +19,12 @@
 #include "base/win/com_init_util.h"
 #include "base/win/core_winrt_util.h"
 #include "base/win/scoped_hstring.h"
+#include "device/vr/windows/d3d11_texture_helper.h"
 #include "ui/gfx/geometry/angle_conversions.h"
 #include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/transform.h"
 #include "ui/gfx/transform_util.h"
 
-#if defined(OS_WIN)
-#include "device/vr/windows/d3d11_texture_helper.h"
-#endif
-
-#include <HolographicSpaceInterop.h>
-#include <Windows.Graphics.DirectX.Direct3D11.interop.h>
-#include <windows.graphics.holographic.h>
-#include <windows.perception.h>
-
 namespace device {
 
 using namespace ABI::Windows::Foundation;
@@ -33,6 +33,15 @@
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 
+class MixedRealityWindow : public gfx::WindowImpl {
+  BOOL ProcessWindowMessage(HWND window,
+                            UINT message,
+                            WPARAM w_param,
+                            LPARAM l_param,
+                            LRESULT& result,
+                            DWORD msg_map_id) override;
+};
+
 BOOL MixedRealityWindow::ProcessWindowMessage(HWND window,
                                               UINT message,
                                               WPARAM w_param,
@@ -42,7 +51,60 @@
   return false;  // We don't currently handle any messages ourselves.
 }
 
-MixedRealityRenderLoop::MixedRealityRenderLoop() : XRCompositorCommon() {}
+namespace {
+mojom::VRFieldOfViewPtr ParseProjection(
+    const ABI::Windows::Foundation::Numerics::Matrix4x4& projection) {
+  gfx::Transform proj(
+      projection.M11, projection.M21, projection.M31, projection.M41,
+      projection.M12, projection.M22, projection.M32, projection.M42,
+      projection.M13, projection.M23, projection.M33, projection.M43,
+      projection.M14, projection.M24, projection.M34, projection.M44);
+
+  gfx::Transform projInv;
+  bool invertable = proj.GetInverse(&projInv);
+  DCHECK(invertable);
+
+  // We will convert several points from projection space into view space to
+  // calculate the view frustum angles.  We are assuming some common form for
+  // the projection matrix.
+  gfx::Point3F left_top_far(-1, 1, 1);
+  gfx::Point3F left_top_near(-1, 1, 0);
+  gfx::Point3F right_bottom_far(1, -1, 1);
+  gfx::Point3F right_bottom_near(1, -1, 0);
+
+  projInv.TransformPoint(&left_top_far);
+  projInv.TransformPoint(&left_top_near);
+  projInv.TransformPoint(&right_bottom_far);
+  projInv.TransformPoint(&right_bottom_near);
+
+  float left_on_far_plane = left_top_far.x();
+  float top_on_far_plane = left_top_far.y();
+  float right_on_far_plane = right_bottom_far.x();
+  float bottom_on_far_plane = right_bottom_far.y();
+  float far_plane = left_top_far.z();
+
+  mojom::VRFieldOfViewPtr field_of_view = mojom::VRFieldOfView::New();
+  field_of_view->upDegrees =
+      gfx::RadToDeg(atanf(-top_on_far_plane / far_plane));
+  field_of_view->downDegrees =
+      gfx::RadToDeg(atanf(bottom_on_far_plane / far_plane));
+  field_of_view->leftDegrees =
+      gfx::RadToDeg(atanf(left_on_far_plane / far_plane));
+  field_of_view->rightDegrees =
+      gfx::RadToDeg(atanf(-right_on_far_plane / far_plane));
+
+  // TODO(billorr): Expand the mojo interface to support just sending the
+  // projection matrix directly, instead of decomposing it.
+  return field_of_view;
+}
+
+}  // namespace
+
+MixedRealityRenderLoop::MixedRealityRenderLoop(
+    base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
+        on_display_info_changed)
+    : XRCompositorCommon(),
+      on_display_info_changed_(std::move(on_display_info_changed)) {}
 
 MixedRealityRenderLoop::~MixedRealityRenderLoop() {
   Stop();
@@ -100,16 +162,71 @@
 }
 
 void MixedRealityRenderLoop::StopRuntime() {
-  ShowWindow(window_->hwnd(), SW_HIDE);
+  if (window_)
+    ShowWindow(window_->hwnd(), SW_HIDE);
   holographic_space_ = nullptr;
-  DestroyWindow(window_->hwnd());
+  origin_ = nullptr;
+
+  if (window_)
+    DestroyWindow(window_->hwnd());
   window_ = nullptr;
 
   if (initializer_)
     initializer_ = nullptr;
 }
 
+void MixedRealityRenderLoop::InitializeOrigin() {
+  // Try to use a SpatialStageFrameOfReference.
+  ComPtr<ISpatialStageFrameOfReferenceStatics> spatial_stage_statics;
+  base::win::ScopedHString spatial_stage_string =
+      base::win::ScopedHString::Create(
+          RuntimeClass_Windows_Perception_Spatial_SpatialStageFrameOfReference);
+  HRESULT hr = base::win::RoGetActivationFactory(
+      spatial_stage_string.get(), IID_PPV_ARGS(&spatial_stage_statics));
+  if (SUCCEEDED(hr)) {
+    ComPtr<ISpatialStageFrameOfReference> spatial_stage;
+    hr = spatial_stage_statics->get_Current(&spatial_stage);
+    if (SUCCEEDED(hr) && spatial_stage) {
+      hr = spatial_stage->get_CoordinateSystem(&origin_);
+      if (SUCCEEDED(hr))
+        return;
+    }
+  }
+
+  // Failed to get a Stage frame of reference - try to get a stationary frame.
+  ComPtr<ISpatialLocatorStatics> spatial_locator_statics;
+  base::win::ScopedHString spatial_locator_string =
+      base::win::ScopedHString::Create(
+          RuntimeClass_Windows_Perception_Spatial_SpatialLocator);
+  hr = base::win::RoGetActivationFactory(
+      spatial_locator_string.get(), IID_PPV_ARGS(&spatial_locator_statics));
+  if (FAILED(hr))
+    return;
+
+  ComPtr<ISpatialLocator> locator;
+  hr = spatial_locator_statics->GetDefault(&locator);
+  if (FAILED(hr))
+    return;
+
+  ComPtr<ISpatialStationaryFrameOfReference> stationary_frame;
+  hr = locator->CreateStationaryFrameOfReferenceAtCurrentLocation(
+      &stationary_frame);
+  if (FAILED(hr))
+    return;
+
+  hr = stationary_frame->get_CoordinateSystem(&origin_);
+  if (FAILED(hr))
+    return;
+
+  // TODO(billorr): Consider adding support for using an attached frame for
+  // orientation-only experiences.
+}
+
 void MixedRealityRenderLoop::OnSessionStart() {
+  // Each session should start with a new origin.
+  origin_ = nullptr;
+  InitializeOrigin();
+
   StartPresenting();
 }
 
@@ -143,9 +260,331 @@
   return nullptr;
 }
 
+struct EyeToWorldDecomposed {
+  gfx::Quaternion world_to_eye_rotation;
+  gfx::Point3F eye_in_world_space;
+};
+
+EyeToWorldDecomposed DecomposeViewMatrix(
+    const ABI::Windows::Foundation::Numerics::Matrix4x4& view) {
+  gfx::Transform world_to_view(view.M11, view.M21, view.M31, view.M41, view.M12,
+                               view.M22, view.M32, view.M42, view.M13, view.M23,
+                               view.M33, view.M43, view.M14, view.M24, view.M34,
+                               view.M44);
+
+  gfx::Transform view_to_world;
+  bool invertable = world_to_view.GetInverse(&view_to_world);
+  DCHECK(invertable);
+
+  gfx::Point3F eye_in_world_space(view_to_world.matrix().get(0, 3),
+                                  view_to_world.matrix().get(1, 3),
+                                  view_to_world.matrix().get(2, 3));
+
+  gfx::DecomposedTransform world_to_view_decomposed;
+  bool decomposable =
+      gfx::DecomposeTransform(&world_to_view_decomposed, world_to_view);
+  DCHECK(decomposable);
+
+  gfx::Quaternion world_to_eye_rotation = world_to_view_decomposed.quaternion;
+  return {world_to_eye_rotation, eye_in_world_space};
+}
+
+mojom::VRPosePtr GetMonoViewData(const HolographicStereoTransform& view) {
+  auto eye = DecomposeViewMatrix(view.Left);
+
+  auto pose = mojom::VRPose::New();
+
+  // World to device orientation.
+  pose->orientation =
+      std::vector<float>{static_cast<float>(eye.world_to_eye_rotation.x()),
+                         static_cast<float>(eye.world_to_eye_rotation.y()),
+                         static_cast<float>(eye.world_to_eye_rotation.z()),
+                         static_cast<float>(eye.world_to_eye_rotation.w())};
+
+  // Position in world space.
+  pose->position =
+      std::vector<float>{eye.eye_in_world_space.x(), eye.eye_in_world_space.y(),
+                         eye.eye_in_world_space.z()};
+
+  return pose;
+}
+
+struct PoseAndEyeTransform {
+  mojom::VRPosePtr pose;
+  std::vector<float> left_offset;
+  std::vector<float> right_offset;
+};
+
+PoseAndEyeTransform GetStereoViewData(const HolographicStereoTransform& view) {
+  auto left_eye = DecomposeViewMatrix(view.Left);
+  auto right_eye = DecomposeViewMatrix(view.Right);
+  auto center = gfx::Point3F(
+      (left_eye.eye_in_world_space.x() + right_eye.eye_in_world_space.x()) / 2,
+      (left_eye.eye_in_world_space.y() + right_eye.eye_in_world_space.y()) / 2,
+      (left_eye.eye_in_world_space.z() + right_eye.eye_in_world_space.z()) / 2);
+
+  // We calculate the overal headset pose to be the slerp of per-eye poses as
+  // calculated by the view transform's decompositions.  Although this works, we
+  // should consider using per-eye rotation as well as translation for eye
+  // parameters. See https://crbug.com/928433 for a similar issue.
+  gfx::Quaternion world_to_view_rotation = left_eye.world_to_eye_rotation;
+  world_to_view_rotation.Slerp(right_eye.world_to_eye_rotation, 0.5f);
+
+  // Calculate new eye offsets.
+  gfx::Vector3dF left_offset = left_eye.eye_in_world_space - center;
+  gfx::Vector3dF right_offset = right_eye.eye_in_world_space - center;
+
+  gfx::Transform transform(world_to_view_rotation);  // World to view.
+  transform.Transpose();                             // Now it is view to world.
+
+  transform.TransformVector(&left_offset);  // Offset is now in view space
+  transform.TransformVector(&right_offset);
+
+  PoseAndEyeTransform ret;
+  ret.right_offset =
+      std::vector<float>{right_offset.x(), right_offset.y(), right_offset.z()};
+  ret.left_offset =
+      std::vector<float>{left_offset.x(), left_offset.y(), left_offset.z()};
+
+  // TODO(https://crbug.com/928433): We don't currently support per-eye rotation
+  // in the mojo interface, but we should.
+
+  ret.pose = mojom::VRPose::New();
+
+  // World to device orientation.
+  ret.pose->orientation =
+      std::vector<float>{static_cast<float>(world_to_view_rotation.x()),
+                         static_cast<float>(world_to_view_rotation.y()),
+                         static_cast<float>(world_to_view_rotation.z()),
+                         static_cast<float>(world_to_view_rotation.w())};
+
+  // Position in world space.
+  ret.pose->position = std::vector<float>{center.x(), center.y(), center.z()};
+
+  return ret;
+}
+
+mojom::XRFrameDataPtr CreateDefaultFrameData(
+    ComPtr<IHolographicFramePrediction> prediction,
+    int16_t frame_id) {
+  mojom::XRFrameDataPtr ret = mojom::XRFrameData::New();
+
+  Microsoft::WRL::ComPtr<ABI::Windows::Perception::IPerceptionTimestamp>
+      timestamp;
+  prediction->get_Timestamp(&timestamp);
+  ABI::Windows::Foundation::DateTime date_time;
+  timestamp->get_TargetTime(&date_time);
+
+  ret->time_delta =
+      base::TimeDelta::FromMicroseconds(date_time.UniversalTime / 10);
+  ret->frame_id = frame_id;
+  return ret;
+}
+
+void MixedRealityRenderLoop::UpdateWMRDataForNextFrame() {
+  holographic_frame_ = nullptr;
+  prediction_ = nullptr;
+  poses_ = nullptr;
+  pose_ = nullptr;
+  rendering_params_ = nullptr;
+  camera_ = nullptr;
+
+  // Start populating this frame's data.
+  HRESULT hr = holographic_space_->CreateNextFrame(&holographic_frame_);
+  if (FAILED(hr))
+    return;
+
+  hr = holographic_frame_->get_CurrentPrediction(&prediction_);
+  if (FAILED(hr))
+    return;
+
+  hr = prediction_->get_CameraPoses(&poses_);
+  if (FAILED(hr))
+    return;
+
+  unsigned int num;
+  hr = poses_->get_Size(&num);
+  if (FAILED(hr) || num != 1) {
+    return;
+  }
+
+  // There is only 1 pose.
+  hr = poses_->GetAt(0, &pose_);
+  if (FAILED(hr))
+    return;
+
+  hr = holographic_frame_->GetRenderingParameters(pose_.Get(),
+                                                  &rendering_params_);
+  if (FAILED(hr))
+    return;
+
+  // Make sure we have an origin.
+  if (!origin_) {
+    InitializeOrigin();
+  }
+
+  if (FAILED(pose_->get_HolographicCamera(&camera_)))
+    return;
+}
+
+bool MixedRealityRenderLoop::UpdateDisplayInfo() {
+  if (!pose_)
+    return false;
+  if (!camera_)
+    return false;
+
+  ABI::Windows::Graphics::Holographic::HolographicStereoTransform projection;
+  if (FAILED(pose_->get_ProjectionTransform(&projection)))
+    return false;
+
+  ABI::Windows::Foundation::Size size;
+  if (FAILED(camera_->get_RenderTargetSize(&size)))
+    return false;
+  boolean stereo;
+  if (FAILED(camera_->get_IsStereo(&stereo)))
+    return false;
+
+  bool changed = false;
+
+  if (!current_display_info_) {
+    current_display_info_ = mojom::VRDisplayInfo::New();
+    current_display_info_->id =
+        device::mojom::XRDeviceId::WINDOWS_MIXED_REALITY_ID;
+    current_display_info_->displayName =
+        "Windows Mixed Reality";  // TODO(billorr): share this string.
+    current_display_info_->capabilities = mojom::VRDisplayCapabilities::New(
+        true /* hasPosition */, true /* hasExternalDisplay */,
+        true /* canPresent */, false /* canProvideEnvironmentIntegration */);
+
+    // TODO(billorr): consider scaling framebuffers after rendering support is
+    // added.
+    current_display_info_->webvr_default_framebuffer_scale = 1.0f;
+    current_display_info_->webxr_default_framebuffer_scale = 1.0f;
+
+    changed = true;
+  }
+
+  if (!stereo && current_display_info_->rightEye) {
+    changed = true;
+    current_display_info_->rightEye = nullptr;
+  }
+
+  if (!current_display_info_->leftEye) {
+    current_display_info_->leftEye = mojom::VREyeParameters::New();
+    changed = true;
+  }
+
+  if (current_display_info_->leftEye->renderWidth != size.Width ||
+      current_display_info_->leftEye->renderHeight != size.Height) {
+    changed = true;
+    current_display_info_->leftEye->renderWidth = size.Width;
+    current_display_info_->leftEye->renderHeight = size.Height;
+  }
+
+  auto left_fov = ParseProjection(projection.Left);
+  if (!current_display_info_->leftEye->fieldOfView ||
+      !left_fov->Equals(*current_display_info_->leftEye->fieldOfView)) {
+    current_display_info_->leftEye->fieldOfView = std::move(left_fov);
+    changed = true;
+  }
+
+  if (stereo) {
+    if (!current_display_info_->rightEye) {
+      current_display_info_->rightEye = mojom::VREyeParameters::New();
+      changed = true;
+    }
+
+    if (current_display_info_->rightEye->renderWidth != size.Width ||
+        current_display_info_->rightEye->renderHeight != size.Height) {
+      changed = true;
+      current_display_info_->rightEye->renderWidth = size.Width;
+      current_display_info_->rightEye->renderHeight = size.Height;
+    }
+
+    auto right_fov = ParseProjection(projection.Right);
+    if (!current_display_info_->rightEye->fieldOfView ||
+        !right_fov->Equals(*current_display_info_->rightEye->fieldOfView)) {
+      current_display_info_->rightEye->fieldOfView = std::move(right_fov);
+      changed = true;
+    }
+  }
+
+  // TODO(billorr): Need to set stageParameters.
+  return changed;
+}
+
 mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() {
-  // Not yet implemented.
-  return nullptr;
+  UpdateWMRDataForNextFrame();
+  if (!prediction_)
+    return nullptr;
+
+  // Once we have a prediction, we can generate a frame data.
+  mojom::XRFrameDataPtr ret =
+      CreateDefaultFrameData(prediction_, next_frame_id_);
+
+  if (!origin_ || !pose_) {
+    // If we don't have an origin or pose for this frame, we can still give out
+    // a timestamp and frame to render head-locked content.
+    return ret;
+  }
+
+  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IReference<
+      ABI::Windows::Graphics::Holographic::HolographicStereoTransform>>
+      view_ref;
+  HRESULT hr = pose_->TryGetViewTransform(origin_.Get(), &view_ref);
+  if (FAILED(hr) || !view_ref) {
+    // If we can't locate origin_, throw it away and try to get a new origin
+    // next frame.
+    // TODO(billorr): Try to keep the origin working over multiple frames, doing
+    // some transform work.
+    origin_ = nullptr;
+    return ret;
+  }
+
+  ABI::Windows::Graphics::Holographic::HolographicStereoTransform view;
+  if (FAILED(view_ref->get_Value(&view)))
+    return ret;
+
+  bool send_new_display_info = UpdateDisplayInfo();
+  if (!current_display_info_)
+    return ret;
+
+  if (current_display_info_->rightEye) {
+    // If we have a right eye, we are stereo.
+    PoseAndEyeTransform pose_and_eye_transform = GetStereoViewData(view);
+    ret->pose = std::move(pose_and_eye_transform.pose);
+
+    if (current_display_info_->leftEye->offset !=
+            pose_and_eye_transform.left_offset ||
+        current_display_info_->rightEye->offset !=
+            pose_and_eye_transform.right_offset) {
+      current_display_info_->leftEye->offset =
+          std::move(pose_and_eye_transform.left_offset);
+      current_display_info_->rightEye->offset =
+          std::move(pose_and_eye_transform.right_offset);
+      send_new_display_info = true;
+    }
+  } else {
+    ret->pose = GetMonoViewData(view);
+    std::vector<float> offset = {0, 0, 0};
+    if (current_display_info_->leftEye->offset != offset) {
+      current_display_info_->leftEye->offset = offset;
+      send_new_display_info = true;
+    }
+  }
+
+  if (send_new_display_info) {
+    // Update the eye info for this frame.
+    ret->left_eye = current_display_info_->leftEye.Clone();
+    ret->right_eye = current_display_info_->rightEye.Clone();
+
+    // Notify the device about the display info change.
+    main_thread_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(on_display_info_changed_,
+                                  current_display_info_.Clone()));
+  }
+
+  return ret;
 }
 
 void MixedRealityRenderLoop::GetEnvironmentIntegrationProvider(
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.h b/device/vr/windows_mixed_reality/mixed_reality_renderloop.h
index 3ea5de9..28b0158 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.h
+++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.h
@@ -29,18 +29,13 @@
 
 namespace device {
 
-class MixedRealityWindow : public gfx::WindowImpl {
-  BOOL ProcessWindowMessage(HWND window,
-                            UINT message,
-                            WPARAM w_param,
-                            LPARAM l_param,
-                            LRESULT& result,
-                            DWORD msg_map_id) override;
-};
+class MixedRealityWindow;
 
 class MixedRealityRenderLoop : public XRCompositorCommon {
  public:
-  MixedRealityRenderLoop();
+  explicit MixedRealityRenderLoop(
+      base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
+          on_display_info_changed);
   ~MixedRealityRenderLoop() override;
 
  private:
@@ -60,16 +55,42 @@
 
   // Helpers to implement XRDeviceAbstraction.
   std::vector<mojom::XRInputSourceStatePtr> GetInputState();
-
+  void InitializeOrigin();
   void InitializeSpace();
   void StartPresenting();
+  void UpdateWMRDataForNextFrame();
+  bool UpdateDisplayInfo();  // returns true if display info has changed.
+
+  std::unique_ptr<base::win::ScopedWinrtInitializer> initializer_;
 
   Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Holographic::IHolographicSpace>
       holographic_space_;
-
+  Microsoft::WRL::ComPtr<
+      ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem>
+      origin_;
   std::unique_ptr<MixedRealityWindow> window_;
+  mojom::VRDisplayInfoPtr current_display_info_;
+  base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
+      on_display_info_changed_;
 
-  std::unique_ptr<base::win::ScopedWinrtInitializer> initializer_;
+  // Per frame data:
+  Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Holographic::IHolographicFrame>
+      holographic_frame_;
+  Microsoft::WRL::ComPtr<
+      ABI::Windows::Graphics::Holographic::IHolographicFramePrediction>
+      prediction_;
+  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVectorView<
+      ABI::Windows::Graphics::Holographic::HolographicCameraPose*>>
+      poses_;
+  Microsoft::WRL::ComPtr<
+      ABI::Windows::Graphics::Holographic::IHolographicCameraPose>
+      pose_;
+  Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Holographic::
+                             IHolographicCameraRenderingParameters>
+      rendering_params_;
+  Microsoft::WRL::ComPtr<
+      ABI::Windows::Graphics::Holographic::IHolographicCamera>
+      camera_;
 
   DISALLOW_COPY_AND_ASSIGN(MixedRealityRenderLoop);
 };
diff --git a/device/vr/windows_mixed_reality/mixed_reality_statics.cc b/device/vr/windows_mixed_reality/mixed_reality_statics.cc
index 4d5c211..42172ad 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_statics.cc
+++ b/device/vr/windows_mixed_reality/mixed_reality_statics.cc
@@ -31,9 +31,10 @@
   bool IsApiAvailable() override;
 
  private:
+  base::win::ScopedWinrtInitializer initializer_;
+
   // Adds get_IsAvailable and get_IsSupported to HolographicSpaceStatics.
   ComPtr<IHolographicSpaceStatics2> holographic_space_statics_;
-  base::win::ScopedWinrtInitializer initializer_;
 };
 
 std::unique_ptr<MixedRealityDeviceStatics>
diff --git a/docs/mojo_ipc_conversion.md b/docs/mojo_ipc_conversion.md
index 877af547c..2eb1190b1 100644
--- a/docs/mojo_ipc_conversion.md
+++ b/docs/mojo_ipc_conversion.md
@@ -234,6 +234,12 @@
       [chromium-mojo@chromium.org](https://groups.google.com/a/chromium.org/forum#!forum/chromium-mojo)
       to propose or discuss options.
 
+*** aside
+**NOTE**: If you are converting a sync IPC, see the section on
+[Synchronous Calls](/mojo/public/cpp/bindings/README.md#Synchronous-Calls)
+in the Mojo documentation.
+***
+
 ### Dealing With Replies
 
 If the message is a **reply**, meaning it has a "request ID" which correlates it
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn
index ee63af6e..e103204 100644
--- a/fuchsia/runners/BUILD.gn
+++ b/fuchsia/runners/BUILD.gn
@@ -18,6 +18,7 @@
   deps = [
     "//base",
     "//third_party/fuchsia-sdk/sdk:ui_app",
+    "//third_party/fuchsia-sdk/sdk:ui_viewsv1",
     "//url",
   ]
   public_deps = [
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc
index 03216c0..0142bef 100644
--- a/fuchsia/runners/cast/cast_component.cc
+++ b/fuchsia/runners/cast/cast_component.cc
@@ -20,31 +20,22 @@
 
 CastComponent::CastComponent(
     CastRunner* runner,
-    fuchsia::sys::StartupInfo startup_info,
+    std::unique_ptr<base::fuchsia::StartupContext> context,
     fidl::InterfaceRequest<fuchsia::sys::ComponentController>
         controller_request)
-    : WebComponent(runner,
-                   std::move(startup_info),
-                   std::move(controller_request)),
+    : WebComponent(runner, std::move(context), std::move(controller_request)),
       navigation_observer_binding_(this) {
   base::AutoReset<bool> constructor_active_reset(&constructor_active_, true);
 
-  if (!additional_services() || std::find(additional_service_names().begin(),
-                                          additional_service_names().end(),
-                                          chromium::cast::CastChannel::Name_) ==
-                                    additional_service_names().end()) {
-    LOG(ERROR) << "Component instantiated without required service: "
-               << chromium::cast::CastChannel::Name_;
-    DestroyComponent(1, fuchsia::sys::TerminationReason::UNSUPPORTED);
-    return;
-  }
-
   cast_channel_ = std::make_unique<CastChannelBindings>(
       frame(), &connector_,
-      additional_services()->ConnectToService<chromium::cast::CastChannel>(),
+      startup_context()
+          ->incoming_services()
+          ->ConnectToService<chromium::cast::CastChannel>(),
       base::BindOnce(&CastComponent::DestroyComponent, base::Unretained(this),
                      kBindingsFailureExitCode,
                      fuchsia::sys::TerminationReason::INTERNAL_ERROR));
+
   frame()->SetNavigationEventObserver(
       navigation_observer_binding_.NewBinding());
 }
diff --git a/fuchsia/runners/cast/cast_component.h b/fuchsia/runners/cast/cast_component.h
index fb78584..333d079c 100644
--- a/fuchsia/runners/cast/cast_component.h
+++ b/fuchsia/runners/cast/cast_component.h
@@ -21,7 +21,7 @@
                       public chromium::web::NavigationEventObserver {
  public:
   CastComponent(CastRunner* runner,
-                fuchsia::sys::StartupInfo startup_info,
+                std::unique_ptr<base::fuchsia::StartupContext> startup_context,
                 fidl::InterfaceRequest<fuchsia::sys::ComponentController>
                     controller_request);
   ~CastComponent() override;
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc
index caeb1aa..68c520e3 100644
--- a/fuchsia/runners/cast/cast_runner.cc
+++ b/fuchsia/runners/cast/cast_runner.cc
@@ -48,16 +48,18 @@
   const std::string cast_app_id(cast_url.GetContent());
   app_config_manager_->GetConfig(
       cast_app_id,
-      [this, startup_info = std::move(startup_info),
+      [this,
+       startup_context = std::make_unique<base::fuchsia::StartupContext>(
+           std::move(startup_info)),
        controller_request = std::move(controller_request)](
           chromium::cast::ApplicationConfigPtr app_config) mutable {
-        GetConfigCallback(std::move(startup_info),
+        GetConfigCallback(std::move(startup_context),
                           std::move(controller_request), std::move(app_config));
       });
 }
 
 void CastRunner::GetConfigCallback(
-    fuchsia::sys::StartupInfo startup_info,
+    std::unique_ptr<base::fuchsia::StartupContext> startup_context,
     fidl::InterfaceRequest<fuchsia::sys::ComponentController>
         controller_request,
     chromium::cast::ApplicationConfigPtr app_config) {
@@ -66,6 +68,7 @@
 
     // For test purposes, we need to call RegisterComponent even if there is no
     // URL to launch.
+    // TODO: Replace this hack, e.g. with an test-specific callback.
     RegisterComponent(std::unique_ptr<WebComponent>(nullptr));
     return;
   }
@@ -73,7 +76,7 @@
   // If a config was returned then use it to launch a component.
   GURL cast_app_url(app_config->web_url);
   auto component = std::make_unique<CastComponent>(
-      this, std::move(startup_info), std::move(controller_request));
+      this, std::move(startup_context), std::move(controller_request));
   component->LoadUrl(std::move(cast_app_url));
   RegisterComponent(std::move(component));
 }
diff --git a/fuchsia/runners/cast/cast_runner.h b/fuchsia/runners/cast/cast_runner.h
index b77eccf..f44abc0 100644
--- a/fuchsia/runners/cast/cast_runner.h
+++ b/fuchsia/runners/cast/cast_runner.h
@@ -6,6 +6,7 @@
 #define FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_
 
 #include "base/callback.h"
+#include "base/fuchsia/startup_context.h"
 #include "base/macros.h"
 #include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
 #include "fuchsia/fidl/chromium/web/cpp/fidl.h"
@@ -29,7 +30,7 @@
 
  private:
   void GetConfigCallback(
-      fuchsia::sys::StartupInfo startup_info,
+      std::unique_ptr<base::fuchsia::StartupContext> startup_context,
       fidl::InterfaceRequest<fuchsia::sys::ComponentController>
           controller_request,
       chromium::cast::ApplicationConfigPtr app_config);
diff --git a/fuchsia/runners/cast/test_common.cc b/fuchsia/runners/cast/test_common.cc
index 0e166d7..db08a557 100644
--- a/fuchsia/runners/cast/test_common.cc
+++ b/fuchsia/runners/cast/test_common.cc
@@ -21,7 +21,6 @@
     fidl::Binding<chromium::cast::CastChannel>* cast_channel_binding) {
   // Construct, bind, and populate a ServiceDirectory for publishing
   // the CastChannel service to the CastComponent.
-  auto service_list = std::make_unique<fuchsia::sys::ServiceList>();
   fidl::InterfaceHandle<fuchsia::io::Directory> directory;
   base::fuchsia::ServiceDirectory cast_channel_directory(
       directory.NewRequest());
@@ -35,21 +34,20 @@
       },
       base::Passed(service_connect_runloop.QuitClosure()),
       base::Unretained(cast_channel_binding)));
-  service_list->names.push_back(chromium::cast::CastChannel::Name_);
-  service_list->host_directory = directory.TakeChannel();
 
   // Configure the Runner, including a service directory channel to publish
   // services to.
   fuchsia::sys::StartupInfo startup_info;
   startup_info.launch_info.url = cast_url.as_string();
-  startup_info.launch_info.additional_services = std::move(service_list);
+
   fidl::InterfaceHandle<fuchsia::io::Directory> component_services;
   startup_info.launch_info.directory_request =
       component_services.NewRequest().TakeChannel();
 
-  // The FlatNamespace vectors must be non-null, but may be empty.
-  startup_info.flat_namespace.paths.resize(0);
-  startup_info.flat_namespace.directories.resize(0);
+  // Publish the ServiceDirectory into the FlatNamespace for CastChannel to be
+  // picked up from.
+  startup_info.flat_namespace.paths.emplace_back("/svc");
+  startup_info.flat_namespace.directories.emplace_back(directory.TakeChannel());
 
   fuchsia::sys::Package package;
   package.resolved_url = cast_url.as_string();
diff --git a/fuchsia/runners/common/web_component.cc b/fuchsia/runners/common/web_component.cc
index 9b60945..e72000c9 100644
--- a/fuchsia/runners/common/web_component.cc
+++ b/fuchsia/runners/common/web_component.cc
@@ -37,23 +37,14 @@
 
 WebComponent::WebComponent(
     WebContentRunner* runner,
-    fuchsia::sys::StartupInfo startup_info,
+    std::unique_ptr<base::fuchsia::StartupContext> context,
     fidl::InterfaceRequest<fuchsia::sys::ComponentController>
         controller_request)
-    : runner_(runner), controller_binding_(this) {
+    : runner_(runner),
+      startup_context_(std::move(context)),
+      controller_binding_(this) {
   DCHECK(runner);
 
-  // Handle the incoming services directory for this component.
-  if (startup_info.launch_info.additional_services &&
-      startup_info.launch_info.additional_services->host_directory) {
-    additional_services_ =
-        std::make_unique<base::fuchsia::ServiceDirectoryClient>(
-            fidl::InterfaceHandle<fuchsia::io::Directory>(std::move(
-                startup_info.launch_info.additional_services->host_directory)));
-    additional_service_names_ =
-        std::move(startup_info.launch_info.additional_services->names);
-  }
-
   // If the ComponentController request is valid then bind it, and configure it
   // to destroy this component on error.
   if (controller_request.is_valid()) {
@@ -70,17 +61,15 @@
   // Create the underlying Frame and get its NavigationController.
   runner_->context()->CreateFrame(frame_.NewRequest());
 
-  // Create a ServiceDirectory for this component, and publish a ViewProvider
-  // into it, for the caller to use to create a View for this component.
-  // Note that we must publish ViewProvider before returning control to the
-  // message-loop, to ensure that it is available before the ServiceDirectory
-  // starts processing requests.
-  service_directory_ = std::make_unique<base::fuchsia::ServiceDirectory>(
-      fidl::InterfaceRequest<fuchsia::io::Directory>(
-          std::move(startup_info.launch_info.directory_request)));
+  // Publish ViewProvider before returning control to the message-loop, to
+  // ensure that it is available before the ServiceDirectory starts processing
+  // requests.
   view_provider_binding_ = std::make_unique<
       base::fuchsia::ScopedServiceBinding<fuchsia::ui::app::ViewProvider>>(
-      service_directory_.get(), this);
+      startup_context()->public_services(), this);
+  legacy_view_provider_binding_ = std::make_unique<
+      base::fuchsia::ScopedServiceBinding<fuchsia::ui::viewsv1::ViewProvider>>(
+      startup_context()->public_services(), this);
 }
 
 void WebComponent::Kill() {
@@ -106,6 +95,16 @@
   view_is_bound_ = true;
 }
 
+void WebComponent::CreateView(
+    fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> view_owner,
+    fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) {
+  // Cast the ViewOwner request to view_token. This is temporary hack for
+  // ViewsV2 transition. This version of CreateView() will be removed in the
+  // future.
+  CreateView(zx::eventpair(view_owner.TakeChannel().release()),
+             std::move(services), nullptr);
+}
+
 void WebComponent::DestroyComponent(int termination_exit_code,
                                     fuchsia::sys::TerminationReason reason) {
   termination_reason_ = reason;
diff --git a/fuchsia/runners/common/web_component.h b/fuchsia/runners/common/web_component.h
index 19c7ca82..7341db3d 100644
--- a/fuchsia/runners/common/web_component.h
+++ b/fuchsia/runners/common/web_component.h
@@ -7,6 +7,7 @@
 
 #include <fuchsia/sys/cpp/fidl.h>
 #include <fuchsia/ui/app/cpp/fidl.h>
+#include <fuchsia/ui/viewsv1/cpp/fidl.h>
 #include <lib/fidl/cpp/binding.h>
 #include <lib/fidl/cpp/binding_set.h>
 #include <memory>
@@ -17,6 +18,7 @@
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/service_directory.h"
 #include "base/fuchsia/service_directory_client.h"
+#include "base/fuchsia/startup_context.h"
 #include "base/logging.h"
 #include "fuchsia/fidl/chromium/web/cpp/fidl.h"
 #include "url/gurl.h"
@@ -28,16 +30,19 @@
 // resources and service bindings.  Runners for specialized web-based content
 // (e.g. Cast applications) can extend this class to configure the Frame to
 // their needs, publish additional APIs, etc.
+// TODO(crbug.com/899348): Remove fuchsia::ui::viewsv1::ViewProvider after
+// SCN-1033 is closed.
 class WebComponent : public fuchsia::sys::ComponentController,
-                     public fuchsia::ui::app::ViewProvider {
+                     public fuchsia::ui::app::ViewProvider,
+                     public fuchsia::ui::viewsv1::ViewProvider {
  public:
   // Creates a WebComponent encapsulating a web.Frame. A ViewProvider service
-  // will be published to the service-directory specified in |startup_info|, and
-  // if |controller_request| is valid then it will be bound to this component,
-  // and the component configured to teardown if that channel closes.
+  // will be published to the service-directory specified by |startup_context|,
+  // and if |controller_request| is valid then it will be bound to this
+  // component, and the componentconfigured to teardown if that channel closes.
   // |runner| must outlive this component.
   WebComponent(WebContentRunner* runner,
-               fuchsia::sys::StartupInfo startup_info,
+               std::unique_ptr<base::fuchsia::StartupContext> startup_context,
                fidl::InterfaceRequest<fuchsia::sys::ComponentController>
                    controller_request);
 
@@ -60,28 +65,25 @@
       fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services)
       override;
 
+  // fuchsia::ui::viewsv1::ViewProvider implementation.
+  void CreateView(
+      fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner> view_owner,
+      fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) override;
+
   // Reports the supplied exit-code and reason to the |controller_binding_| and
   // requests that the |runner_| delete this component.
   virtual void DestroyComponent(int termination_exit_code,
                                 fuchsia::sys::TerminationReason reason);
 
-  // Returns the directory of incoming services provided to the component, or
-  // nullptr if none was provided.
-  base::fuchsia::ServiceDirectoryClient* additional_services() const {
-    return additional_services_.get();
-  }
-
-  // Returns the names of services available in additional_services().
-  const std::vector<std::string>& additional_service_names() const {
-    return additional_service_names_;
-  }
-
-  base::fuchsia::ServiceDirectory* service_directory() const {
-    return service_directory_.get();
+  // Returns the component's startup context (e.g. incoming services, public
+  // service directory, etc).
+  base::fuchsia::StartupContext* startup_context() const {
+    return startup_context_.get();
   }
 
  private:
   WebContentRunner* const runner_ = nullptr;
+  const std::unique_ptr<base::fuchsia::StartupContext> startup_context_;
 
   chromium::web::FramePtr frame_;
 
@@ -98,6 +100,9 @@
   std::unique_ptr<
       base::fuchsia::ScopedServiceBinding<fuchsia::ui::app::ViewProvider>>
       view_provider_binding_;
+  std::unique_ptr<
+      base::fuchsia::ScopedServiceBinding<fuchsia::ui::viewsv1::ViewProvider>>
+      legacy_view_provider_binding_;
 
   // Termination reason and exit-code to be reported via the
   // sys::ComponentController::OnTerminated event.
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia/runners/common/web_content_runner.cc
index 281bb07..5ef131f5d 100644
--- a/fuchsia/runners/common/web_content_runner.cc
+++ b/fuchsia/runners/common/web_content_runner.cc
@@ -15,6 +15,7 @@
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/service_directory.h"
 #include "base/fuchsia/service_directory_client.h"
+#include "base/fuchsia/startup_context.h"
 #include "base/logging.h"
 #include "fuchsia/runners/common/web_component.h"
 #include "url/gurl.h"
@@ -74,7 +75,9 @@
   }
 
   std::unique_ptr<WebComponent> component = std::make_unique<WebComponent>(
-      this, std::move(startup_info), std::move(controller_request));
+      this,
+      std::make_unique<base::fuchsia::StartupContext>(std::move(startup_info)),
+      std::move(controller_request));
   component->LoadUrl(url);
   RegisterComponent(std::move(component));
 }
diff --git a/google_apis/drive/auth_service.cc b/google_apis/drive/auth_service.cc
index d53be49..41a7606 100644
--- a/google_apis/drive/auth_service.cc
+++ b/google_apis/drive/auth_service.cc
@@ -137,7 +137,7 @@
   if (HasAccessToken()) {
     // We already have access token. Give it back to the caller asynchronously.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, HTTP_SUCCESS, access_token_));
+        FROM_HERE, base::BindOnce(callback, HTTP_SUCCESS, access_token_));
   } else if (HasRefreshToken()) {
     // We have refresh token, let's get an access token.
     new AuthRequest(identity_manager_, account_id_, url_loader_factory_,
@@ -146,7 +146,7 @@
                     scopes_);
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, DRIVE_NOT_READY, std::string()));
+        FROM_HERE, base::BindOnce(callback, DRIVE_NOT_READY, std::string()));
   }
 }
 
diff --git a/google_apis/drive/base_requests.cc b/google_apis/drive/base_requests.cc
index 55c242d..b855e656 100644
--- a/google_apis/drive/base_requests.cc
+++ b/google_apis/drive/base_requests.cc
@@ -303,8 +303,9 @@
     // asynchronously because client code does not assume result callback is
     // called synchronously.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&UrlFetchRequestBase::CompleteRequestWithError,
-                              weak_ptr_factory_.GetWeakPtr(), error_code));
+        FROM_HERE,
+        base::BindOnce(&UrlFetchRequestBase::CompleteRequestWithError,
+                       weak_ptr_factory_.GetWeakPtr(), error_code));
     return;
   }
 
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc
index 587036bf..c714b814 100644
--- a/google_apis/gaia/oauth2_token_service.cc
+++ b/google_apis/gaia/oauth2_token_service.cc
@@ -446,9 +446,9 @@
   // If we can get refresh token from the delegate, inform cosumer right away.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&RequestImpl::InformConsumer, request.get()->AsWeakPtr(),
-                 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-                 token_response));
+      base::BindOnce(&RequestImpl::InformConsumer, request.get()->AsWeakPtr(),
+                     GoogleServiceAuthError(GoogleServiceAuthError::NONE),
+                     token_response));
   return std::move(request);
 }
 
@@ -515,8 +515,8 @@
 
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&RequestImpl::InformConsumer, request->AsWeakPtr(), error,
-                   OAuth2AccessTokenConsumer::TokenResponse()));
+        base::BindOnce(&RequestImpl::InformConsumer, request->AsWeakPtr(),
+                       error, OAuth2AccessTokenConsumer::TokenResponse()));
     return std::move(request);
   }
 
@@ -580,9 +580,9 @@
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&RequestImpl::InformConsumer, request->AsWeakPtr(),
-                 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
-                 *cache_token_response));
+      base::BindOnce(&RequestImpl::InformConsumer, request->AsWeakPtr(),
+                     GoogleServiceAuthError(GoogleServiceAuthError::NONE),
+                     *cache_token_response));
 }
 
 std::vector<std::string> OAuth2TokenService::GetAccounts() const {
diff --git a/google_apis/gaia/oauth2_token_service_request.cc b/google_apis/gaia/oauth2_token_service_request.cc
index f8098ef8..caae187 100644
--- a/google_apis/gaia/oauth2_token_service_request.cc
+++ b/google_apis/gaia/oauth2_token_service_request.cc
@@ -111,8 +111,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   token_service_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread,
-                 this));
+      base::BindOnce(
+          &OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread, this));
 }
 
 void OAuth2TokenServiceRequest::Core::Stop() {
@@ -127,8 +127,8 @@
   // will be destroyed on the owner thread.
   token_service_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread,
-                 this));
+      base::BindOnce(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread,
+                     this));
 }
 
 bool OAuth2TokenServiceRequest::Core::IsStopped() const {
@@ -227,8 +227,8 @@
   DCHECK(token_service_task_runner()->RunsTasksInCurrentSequence());
   DCHECK_EQ(request_.get(), request);
   owning_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&RequestCore::InformOwnerOnGetTokenSuccess, this,
-                            token_response));
+      FROM_HERE, base::BindOnce(&RequestCore::InformOwnerOnGetTokenSuccess,
+                                this, token_response));
   request_.reset();
 }
 
@@ -238,7 +238,7 @@
   DCHECK_EQ(request_.get(), request);
   owning_task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&RequestCore::InformOwnerOnGetTokenFailure, this, error));
+      base::BindOnce(&RequestCore::InformOwnerOnGetTokenFailure, this, error));
   request_.reset();
 }
 
diff --git a/google_apis/gcm/engine/checkin_request.cc b/google_apis/gcm/engine/checkin_request.cc
index 1238c28..845b6b1 100644
--- a/google_apis/gcm/engine/checkin_request.cc
+++ b/google_apis/gcm/engine/checkin_request.cc
@@ -207,7 +207,7 @@
   DCHECK(!weak_ptr_factory_.HasWeakPtrs());
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&CheckinRequest::Start, weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&CheckinRequest::Start, weak_ptr_factory_.GetWeakPtr()),
       backoff_entry_.GetTimeUntilRelease());
 }
 
diff --git a/google_apis/gcm/engine/connection_factory_impl.cc b/google_apis/gcm/engine/connection_factory_impl.cc
index 8dc63f8..269a1df 100644
--- a/google_apis/gcm/engine/connection_factory_impl.cc
+++ b/google_apis/gcm/engine/connection_factory_impl.cc
@@ -144,8 +144,8 @@
         backoff_entry_->GetTimeUntilRelease().InMilliseconds());
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&ConnectionFactoryImpl::ConnectWithBackoff,
-                   weak_ptr_factory_.GetWeakPtr()),
+        base::BindOnce(&ConnectionFactoryImpl::ConnectWithBackoff,
+                       weak_ptr_factory_.GetWeakPtr()),
         backoff_entry_->GetTimeUntilRelease());
     return;
   }
diff --git a/google_apis/gcm/engine/connection_handler_impl.cc b/google_apis/gcm/engine/connection_handler_impl.cc
index ae1025b..59cf796 100644
--- a/google_apis/gcm/engine/connection_handler_impl.cc
+++ b/google_apis/gcm/engine/connection_handler_impl.cc
@@ -133,9 +133,8 @@
           base::Bind(&ConnectionHandlerImpl::OnMessageSent,
                      weak_ptr_factory_.GetWeakPtr())) != net::ERR_IO_PENDING) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(&ConnectionHandlerImpl::OnMessageSent,
-                   weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&ConnectionHandlerImpl::OnMessageSent,
+                                  weak_ptr_factory_.GetWeakPtr()));
   }
 
   read_timeout_timer_.Start(FROM_HERE,
@@ -262,9 +261,8 @@
              << " more bytes.";
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&ConnectionHandlerImpl::WaitForData,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   MCS_PROTO_BYTES));
+        base::BindOnce(&ConnectionHandlerImpl::WaitForData,
+                       weak_ptr_factory_.GetWeakPtr(), MCS_PROTO_BYTES));
     return;
   }
 
@@ -383,9 +381,8 @@
   // that tag.
   if (protobuf.get() && message_size_ == 0) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(&ConnectionHandlerImpl::GetNextMessage,
-                   weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&ConnectionHandlerImpl::GetNextMessage,
+                                  weak_ptr_factory_.GetWeakPtr()));
     read_callback_.Run(std::move(protobuf));
     return;
   }
@@ -456,9 +453,8 @@
 
   input_stream_->RebuildBuffer();
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&ConnectionHandlerImpl::GetNextMessage,
-                 weak_ptr_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&ConnectionHandlerImpl::GetNextMessage,
+                                weak_ptr_factory_.GetWeakPtr()));
   if (message_tag_ == kLoginResponseTag) {
     if (handshake_complete_) {
       LOG(ERROR) << "Unexpected login response.";
diff --git a/google_apis/gcm/engine/gcm_store_impl.cc b/google_apis/gcm/engine/gcm_store_impl.cc
index 1212715..bbf5300 100644
--- a/google_apis/gcm/engine/gcm_store_impl.cc
+++ b/google_apis/gcm/engine/gcm_store_impl.cc
@@ -343,9 +343,8 @@
   if (load_status != LOADING_SUCCEEDED) {
     result->Reset();
     result->store_does_not_exist = (load_status == STORE_DOES_NOT_EXIST);
-    foreground_task_runner_->PostTask(FROM_HERE,
-                                      base::Bind(callback,
-                                                 base::Passed(&result)));
+    foreground_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(callback, std::move(result)));
     return;
   }
 
@@ -391,9 +390,8 @@
            << result->instance_id_data.size() << " Instance IDs, "
            << instance_id_token_count << " InstanceID tokens.";
   result->success = true;
-  foreground_task_runner_->PostTask(FROM_HERE,
-                                    base::Bind(callback,
-                                               base::Passed(&result)));
+  foreground_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(callback, std::move(result)));
   return;
 }
 
@@ -408,11 +406,12 @@
   const leveldb::Status s =
       leveldb::DestroyDB(path_.AsUTF8Unsafe(), leveldb_env::Options());
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, true));
     return;
   }
   LOG(ERROR) << "Destroy failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+  foreground_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, false));
 }
 
 void GCMStoreImpl::Backend::SetDeviceCredentials(
@@ -422,7 +421,8 @@
   DVLOG(1) << "Saving device credentials with AID " << device_android_id;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -442,11 +442,12 @@
         write_options, MakeSlice(kDeviceTokenKey), MakeSlice(encrypted_token));
   }
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, true));
     return;
   }
   LOG(ERROR) << "LevelDB put failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+  foreground_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, false));
 }
 
 void GCMStoreImpl::Backend::AddRegistration(
@@ -456,7 +457,8 @@
   DVLOG(1) << "Saving registration info for app: " << serialized_key;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
   leveldb::WriteOptions write_options;
@@ -468,8 +470,8 @@
       MakeSlice(serialized_value));
   if (!status.ok())
     LOG(ERROR) << "LevelDB put failed: " << status.ToString();
-  foreground_task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback, status.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, status.ok()));
 }
 
 void GCMStoreImpl::Backend::RemoveRegistration(
@@ -477,7 +479,8 @@
     const UpdateCallback& callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
   leveldb::WriteOptions write_options;
@@ -487,8 +490,8 @@
       write_options, MakeSlice(MakeRegistrationKey(serialized_key)));
   if (!status.ok())
     LOG(ERROR) << "LevelDB remove failed: " << status.ToString();
-  foreground_task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback, status.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, status.ok()));
 }
 
 void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id,
@@ -496,7 +499,8 @@
   DVLOG(1) << "Saving incoming message with id " << persistent_id;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -508,11 +512,12 @@
                                      MakeSlice(key),
                                      MakeSlice(persistent_id));
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, true));
     return;
   }
   LOG(ERROR) << "LevelDB put failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+  foreground_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, false));
 }
 
 void GCMStoreImpl::Backend::RemoveIncomingMessages(
@@ -520,7 +525,8 @@
     const UpdateCallback& callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
   leveldb::WriteOptions write_options;
@@ -537,11 +543,12 @@
       break;
   }
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, true));
     return;
   }
   LOG(ERROR) << "LevelDB remove failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+  foreground_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, false));
 }
 
 void GCMStoreImpl::Backend::AddOutgoingMessage(const std::string& persistent_id,
@@ -550,7 +557,8 @@
   DVLOG(1) << "Saving outgoing message with id " << persistent_id;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
   leveldb::WriteOptions write_options;
@@ -563,11 +571,12 @@
                                      MakeSlice(key),
                                      MakeSlice(data));
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, true));
     return;
   }
   LOG(ERROR) << "LevelDB put failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+  foreground_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, false));
 }
 
 void GCMStoreImpl::Backend::RemoveOutgoingMessages(
@@ -576,10 +585,8 @@
         callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE,
-                                      base::Bind(callback,
-                                                 false,
-                                                 AppIdToMessageCountMap()));
+    foreground_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(callback, false, AppIdToMessageCountMap()));
     return;
   }
   leveldb::ReadOptions read_options;
@@ -615,17 +622,13 @@
       break;
   }
   if (s.ok()) {
-    foreground_task_runner_->PostTask(FROM_HERE,
-                                      base::Bind(callback,
-                                                 true,
-                                                 removed_message_counts));
+    foreground_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(callback, true, removed_message_counts));
     return;
   }
   LOG(ERROR) << "LevelDB remove failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE,
-                                    base::Bind(callback,
-                                               false,
-                                               AppIdToMessageCountMap()));
+  foreground_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(callback, false, AppIdToMessageCountMap()));
 }
 
 void GCMStoreImpl::Backend::SetLastCheckinInfo(
@@ -657,29 +660,23 @@
 
   if (!s.ok())
     LOG(ERROR) << "LevelDB set last checkin info failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::AddInstanceIDData(const std::string& app_id,
                                      const std::string& instance_id_data,
                                      const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddInstanceIDData,
-                 backend_,
-                 app_id,
-                 instance_id_data,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::AddInstanceIDData,
+                                backend_, app_id, instance_id_data, callback));
 }
 
 void GCMStoreImpl::RemoveInstanceIDData(const std::string& app_id,
                                         const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveInstanceIDData,
-                 backend_,
-                 app_id,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::RemoveInstanceIDData,
+                                backend_, app_id, callback));
 }
 
 void GCMStoreImpl::Backend::SetGServicesSettings(
@@ -717,7 +714,8 @@
   leveldb::Status s = db_->Write(write_options, &write_batch);
   if (!s.ok())
     LOG(ERROR) << "LevelDB GService Settings update failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::AddAccountMapping(
@@ -727,7 +725,8 @@
            << account_mapping.email;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -740,7 +739,8 @@
       db_->Put(write_options, MakeSlice(key), MakeSlice(data));
   if (!s.ok())
     LOG(ERROR) << "LevelDB adding account mapping failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::RemoveAccountMapping(
@@ -748,7 +748,8 @@
     const UpdateCallback& callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -760,7 +761,8 @@
 
   if (!s.ok())
     LOG(ERROR) << "LevelDB removal of account mapping failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::SetLastTokenFetchTime(
@@ -769,7 +771,8 @@
   DVLOG(1) << "Setting last token fetching time.";
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -782,7 +785,8 @@
 
   if (!s.ok())
     LOG(ERROR) << "LevelDB setting last token fetching time: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::AddHeartbeatInterval(
@@ -793,7 +797,8 @@
            << " interval: " << interval_ms << "ms.";
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -806,7 +811,8 @@
       db_->Put(write_options, MakeSlice(key), MakeSlice(data));
   if (!s.ok())
     LOG(ERROR) << "LevelDB adding heartbeat interval failed: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::RemoveHeartbeatInterval(
@@ -814,7 +820,8 @@
     const UpdateCallback& callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -828,7 +835,8 @@
     LOG(ERROR) << "LevelDB removal of heartbeat interval failed: "
                << s.ToString();
   }
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 void GCMStoreImpl::Backend::AddInstanceIDData(
@@ -838,7 +846,8 @@
   DVLOG(1) << "Adding Instance ID data.";
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -851,8 +860,8 @@
                                           MakeSlice(instance_id_data));
   if (!status.ok())
     LOG(ERROR) << "LevelDB put failed: " << status.ToString();
-  foreground_task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback, status.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, status.ok()));
 }
 
 void GCMStoreImpl::Backend::RemoveInstanceIDData(
@@ -860,7 +869,8 @@
     const UpdateCallback& callback) {
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
   leveldb::WriteOptions write_options;
@@ -870,8 +880,8 @@
       db_->Delete(write_options, MakeSlice(MakeInstanceIDKey(app_id)));
   if (!status.ok())
     LOG(ERROR) << "LevelDB remove failed: " << status.ToString();
-  foreground_task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback, status.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, status.ok()));
 }
 
 void GCMStoreImpl::Backend::SetValue(const std::string& key,
@@ -881,7 +891,8 @@
            << key << ", Value: " << value;
   if (!db_.get()) {
     LOG(ERROR) << "GCMStore db doesn't exist.";
-    foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+    foreground_task_runner_->PostTask(FROM_HERE,
+                                      base::BindOnce(callback, false));
     return;
   }
 
@@ -893,7 +904,8 @@
 
   if (!s.ok())
     LOG(ERROR) << "LevelDB had problems injecting a value: " << s.ToString();
-  foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+  foreground_task_runner_->PostTask(FROM_HERE,
+                                    base::BindOnce(callback, s.ok()));
 }
 
 bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64_t* android_id,
@@ -1171,26 +1183,22 @@
 void GCMStoreImpl::Load(StoreOpenMode open_mode, const LoadCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::Load,
-                 backend_,
-                 open_mode,
-                 base::Bind(&GCMStoreImpl::LoadContinuation,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            callback)));
+      base::BindOnce(&GCMStoreImpl::Backend::Load, backend_, open_mode,
+                     base::Bind(&GCMStoreImpl::LoadContinuation,
+                                weak_ptr_factory_.GetWeakPtr(), callback)));
 }
 
 void GCMStoreImpl::Close() {
   weak_ptr_factory_.InvalidateWeakPtrs();
   app_message_counts_.clear();
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::Close, backend_));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::Close, backend_));
 }
 
 void GCMStoreImpl::Destroy(const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::Destroy, backend_, callback));
+      base::BindOnce(&GCMStoreImpl::Backend::Destroy, backend_, callback));
 }
 
 void GCMStoreImpl::SetDeviceCredentials(uint64_t device_android_id,
@@ -1198,11 +1206,8 @@
                                         const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::SetDeviceCredentials,
-                 backend_,
-                 device_android_id,
-                 device_security_token,
-                 callback));
+      base::BindOnce(&GCMStoreImpl::Backend::SetDeviceCredentials, backend_,
+                     device_android_id, device_security_token, callback));
 }
 
 void GCMStoreImpl::AddRegistration(
@@ -1211,52 +1216,38 @@
     const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddRegistration,
-                 backend_,
-                 serialized_key,
-                 serialized_value,
-                 callback));
+      base::BindOnce(&GCMStoreImpl::Backend::AddRegistration, backend_,
+                     serialized_key, serialized_value, callback));
 }
 
 void GCMStoreImpl::RemoveRegistration(const std::string& app_id,
                                           const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveRegistration,
-                 backend_,
-                 app_id,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::RemoveRegistration,
+                                backend_, app_id, callback));
 }
 
 void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id,
                                       const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddIncomingMessage,
-                 backend_,
-                 persistent_id,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::AddIncomingMessage,
+                                backend_, persistent_id, callback));
 }
 
 void GCMStoreImpl::RemoveIncomingMessage(const std::string& persistent_id,
                                          const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveIncomingMessages,
-                 backend_,
-                 PersistentIdList(1, persistent_id),
-                 callback));
+      base::BindOnce(&GCMStoreImpl::Backend::RemoveIncomingMessages, backend_,
+                     PersistentIdList(1, persistent_id), callback));
 }
 
 void GCMStoreImpl::RemoveIncomingMessages(
     const PersistentIdList& persistent_ids,
     const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveIncomingMessages,
-                 backend_,
-                 persistent_ids,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::RemoveIncomingMessages,
+                                backend_, persistent_ids, callback));
 }
 
 bool GCMStoreImpl::AddOutgoingMessage(const std::string& persistent_id,
@@ -1273,14 +1264,11 @@
 
     blocking_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&GCMStoreImpl::Backend::AddOutgoingMessage,
-                   backend_,
-                   persistent_id,
-                   message,
-                   base::Bind(&GCMStoreImpl::AddOutgoingMessageContinuation,
-                              weak_ptr_factory_.GetWeakPtr(),
-                              callback,
-                              app_id)));
+        base::BindOnce(
+            &GCMStoreImpl::Backend::AddOutgoingMessage, backend_, persistent_id,
+            message,
+            base::Bind(&GCMStoreImpl::AddOutgoingMessageContinuation,
+                       weak_ptr_factory_.GetWeakPtr(), callback, app_id)));
     return true;
   }
   return false;
@@ -1297,24 +1285,19 @@
   DCHECK(app_message_counts_.count(app_id));
   // TODO(zea): consider verifying the specific message already exists.
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddOutgoingMessage,
-                 backend_,
-                 persistent_id,
-                 message,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::AddOutgoingMessage,
+                                backend_, persistent_id, message, callback));
 }
 
 void GCMStoreImpl::RemoveOutgoingMessage(const std::string& persistent_id,
                                          const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages,
-                 backend_,
-                 PersistentIdList(1, persistent_id),
-                 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            callback)));
+      base::BindOnce(
+          &GCMStoreImpl::Backend::RemoveOutgoingMessages, backend_,
+          PersistentIdList(1, persistent_id),
+          base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation,
+                     weak_ptr_factory_.GetWeakPtr(), callback)));
 }
 
 void GCMStoreImpl::RemoveOutgoingMessages(
@@ -1322,24 +1305,19 @@
     const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveOutgoingMessages,
-                 backend_,
-                 persistent_ids,
-                 base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            callback)));
+      base::BindOnce(
+          &GCMStoreImpl::Backend::RemoveOutgoingMessages, backend_,
+          persistent_ids,
+          base::Bind(&GCMStoreImpl::RemoveOutgoingMessagesContinuation,
+                     weak_ptr_factory_.GetWeakPtr(), callback)));
 }
 
 void GCMStoreImpl::SetLastCheckinInfo(const base::Time& time,
                                       const std::set<std::string>& accounts,
                                       const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::SetLastCheckinInfo,
-                 backend_,
-                 time,
-                 accounts,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::SetLastCheckinInfo,
+                                backend_, time, accounts, callback));
 }
 
 void GCMStoreImpl::SetGServicesSettings(
@@ -1347,76 +1325,52 @@
     const std::string& digest,
     const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::SetGServicesSettings,
-                 backend_,
-                 settings,
-                 digest,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::SetGServicesSettings,
+                                backend_, settings, digest, callback));
 }
 
 void GCMStoreImpl::AddAccountMapping(const AccountMapping& account_mapping,
                                      const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddAccountMapping,
-                 backend_,
-                 account_mapping,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::AddAccountMapping,
+                                backend_, account_mapping, callback));
 }
 
 void GCMStoreImpl::RemoveAccountMapping(const std::string& account_id,
                                         const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveAccountMapping,
-                 backend_,
-                 account_id,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::RemoveAccountMapping,
+                                backend_, account_id, callback));
 }
 
 void GCMStoreImpl::SetLastTokenFetchTime(const base::Time& time,
                                          const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::SetLastTokenFetchTime,
-                 backend_,
-                 time,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::SetLastTokenFetchTime,
+                                backend_, time, callback));
 }
 
 void GCMStoreImpl::AddHeartbeatInterval(const std::string& scope,
                                         int interval_ms,
                                         const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::AddHeartbeatInterval,
-                 backend_,
-                 scope,
-                 interval_ms,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::AddHeartbeatInterval,
+                                backend_, scope, interval_ms, callback));
 }
 
 void GCMStoreImpl::RemoveHeartbeatInterval(const std::string& scope,
                                            const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::RemoveHeartbeatInterval,
-                 backend_,
-                 scope,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::RemoveHeartbeatInterval,
+                                backend_, scope, callback));
 }
 
 void GCMStoreImpl::SetValueForTesting(const std::string& key,
                                       const std::string& value,
                                       const UpdateCallback& callback) {
   blocking_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GCMStoreImpl::Backend::SetValue,
-                 backend_,
-                 key,
-                 value,
-                 callback));
+      FROM_HERE, base::BindOnce(&GCMStoreImpl::Backend::SetValue, backend_, key,
+                                value, callback));
 }
 
 void GCMStoreImpl::LoadContinuation(const LoadCallback& callback,
diff --git a/google_apis/gcm/engine/heartbeat_manager.cc b/google_apis/gcm/engine/heartbeat_manager.cc
index 2ee43fba..dc542967 100644
--- a/google_apis/gcm/engine/heartbeat_manager.cc
+++ b/google_apis/gcm/engine/heartbeat_manager.cc
@@ -194,8 +194,8 @@
   // Linux so we need to poll to check for missed heartbeats.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&HeartbeatManager::CheckForMissedHeartbeat,
-                 weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&HeartbeatManager::CheckForMissedHeartbeat,
+                     weak_ptr_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs));
 #endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
 }
@@ -217,8 +217,8 @@
   // Otherwise check again later.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&HeartbeatManager::CheckForMissedHeartbeat,
-                 weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&HeartbeatManager::CheckForMissedHeartbeat,
+                     weak_ptr_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(kHeartbeatMissedCheckMs));
 #endif  // defined(OS_LINUX) && !defined(OS_CHROMEOS)
 }
diff --git a/google_apis/gcm/engine/mcs_client.cc b/google_apis/gcm/engine/mcs_client.cc
index bbda63ab..b99eaa9 100644
--- a/google_apis/gcm/engine/mcs_client.cc
+++ b/google_apis/gcm/engine/mcs_client.cc
@@ -550,9 +550,8 @@
         base::Bind(&MCSClient::OnGCMUpdateFinished,
                    weak_ptr_factory_.GetWeakPtr()));
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE,
-            base::Bind(&MCSClient::MaybeSendMessage,
-                       weak_ptr_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&MCSClient::MaybeSendMessage,
+                                  weak_ptr_factory_.GetWeakPtr()));
     return;
   }
   DVLOG(1) << "Pending output message found, sending.";
@@ -724,15 +723,14 @@
 
       // Pass the login response on up.
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(message_received_callback_,
-                                MCSMessage(tag, std::move(protobuf))));
+          FROM_HERE, base::BindOnce(message_received_callback_,
+                                    MCSMessage(tag, std::move(protobuf))));
 
       // If there are pending messages, attempt to send one.
       if (!to_send_.empty()) {
         base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE,
-            base::Bind(&MCSClient::MaybeSendMessage,
-                       weak_ptr_factory_.GetWeakPtr()));
+            FROM_HERE, base::BindOnce(&MCSClient::MaybeSendMessage,
+                                      weak_ptr_factory_.GetWeakPtr()));
       }
 
       heartbeat_manager_.Start(
@@ -794,8 +792,8 @@
 
       DCHECK(protobuf.get());
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(message_received_callback_,
-                                MCSMessage(tag, std::move(protobuf))));
+          FROM_HERE, base::BindOnce(message_received_callback_,
+                                    MCSMessage(tag, std::move(protobuf))));
       return;
     }
     default:
@@ -901,9 +899,8 @@
     to_resend_.pop_back();
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&MCSClient::MaybeSendMessage,
-                 weak_ptr_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&MCSClient::MaybeSendMessage,
+                                weak_ptr_factory_.GetWeakPtr()));
 }
 
 void MCSClient::HandleServerConfirmedReceipt(StreamId device_stream_id) {
diff --git a/google_apis/gcm/engine/registration_request.cc b/google_apis/gcm/engine/registration_request.cc
index adece69c..e508560 100644
--- a/google_apis/gcm/engine/registration_request.cc
+++ b/google_apis/gcm/engine/registration_request.cc
@@ -232,7 +232,8 @@
   DCHECK(!weak_ptr_factory_.HasWeakPtrs());
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&RegistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&RegistrationRequest::Start,
+                     weak_ptr_factory_.GetWeakPtr()),
       backoff_entry_.GetTimeUntilRelease());
 }
 
diff --git a/google_apis/gcm/engine/unregistration_request.cc b/google_apis/gcm/engine/unregistration_request.cc
index b9ff85b..ee5d914d 100644
--- a/google_apis/gcm/engine/unregistration_request.cc
+++ b/google_apis/gcm/engine/unregistration_request.cc
@@ -259,7 +259,8 @@
   DCHECK(!weak_ptr_factory_.HasWeakPtrs());
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&UnregistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&UnregistrationRequest::Start,
+                     weak_ptr_factory_.GetWeakPtr()),
       backoff_entry_.GetTimeUntilRelease());
 }
 
diff --git a/ios/chrome/browser/payments/payment_request_util_unittest.mm b/ios/chrome/browser/payments/payment_request_util_unittest.mm
index f9ca218b..72dfeea3 100644
--- a/ios/chrome/browser/payments/payment_request_util_unittest.mm
+++ b/ios/chrome/browser/payments/payment_request_util_unittest.mm
@@ -56,7 +56,6 @@
   billing_address->SetString("dependentLocality", "");
   billing_address->SetString("city", "");
   billing_address->SetString("postalCode", "90210");
-  billing_address->SetString("languageCode", "");
   billing_address->SetString("sortingCode", "");
   billing_address->SetString("organization", "");
   billing_address->SetString("recipient", "");
@@ -72,7 +71,6 @@
   shipping_address->SetString("dependentLocality", "");
   shipping_address->SetString("city", "");
   shipping_address->SetString("postalCode", "94115");
-  shipping_address->SetString("languageCode", "");
   shipping_address->SetString("sortingCode", "");
   shipping_address->SetString("organization", "");
   shipping_address->SetString("recipient", "");
diff --git a/ios/chrome/browser/payments/payment_response_helper_unittest.mm b/ios/chrome/browser/payments/payment_response_helper_unittest.mm
index 2622e1b..0eb5d55 100644
--- a/ios/chrome/browser/payments/payment_response_helper_unittest.mm
+++ b/ios/chrome/browser/payments/payment_response_helper_unittest.mm
@@ -134,7 +134,6 @@
                    response.shipping_address->dependent_locality);
          EXPECT_EQ("91111", response.shipping_address->postal_code);
          EXPECT_EQ(std::string(), response.shipping_address->sorting_code);
-         EXPECT_EQ(std::string(), response.shipping_address->language_code);
          EXPECT_EQ("Underworld", response.shipping_address->organization);
          EXPECT_EQ("John H. Doe", response.shipping_address->recipient);
          EXPECT_EQ("16502111111", response.shipping_address->phone);
diff --git a/ios/chrome/browser/ui/payments/payment_request_payment_response_egtest.mm b/ios/chrome/browser/ui/payments/payment_request_payment_response_egtest.mm
index 1301bd83..0151ef6 100644
--- a/ios/chrome/browser/ui/payments/payment_request_payment_response_egtest.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_payment_response_egtest.mm
@@ -100,7 +100,6 @@
                                      "\"Apt 8\"", "\"city\": \"Elysium\"",
                                      "\"country\": \"US\"",
                                      "\"dependentLocality\": \"\"",
-                                     "\"languageCode\": \"\"",
                                      "\"organization\": \"Underworld\"",
                                      "\"phone\": \"+16502111111\"",
                                      "\"postalCode\": \"91111\"",
@@ -159,7 +158,6 @@
                                        "\"city\": \"Greensdale\"",
                                        "\"country\": \"US\"",
                                        "\"dependentLocality\": \"\"",
-                                       "\"languageCode\": \"\"",
                                        "\"organization\": \"ACME\"",
                                        "\"phone\": \"+13105557889\"",
                                        "\"postalCode\": \"48838\"",
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index b8b51c7b..d10ba1f 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -40,6 +40,7 @@
     "//ios/chrome/app/strings:ios_strings_grit",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/ntp",
     "//ios/chrome/browser/snapshots",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/commands:commands",
@@ -105,7 +106,9 @@
     "//components/search_engines",
     "//components/services/unzip/public/interfaces",
     "//components/strings:components_strings_grit",
+    "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state:test_support",
+    "//ios/chrome/browser/ntp",
     "//ios/chrome/browser/snapshots",
     "//ios/chrome/test:test_support",
     "//ios/net:test_support",
diff --git a/ios/chrome/browser/web/resources/payment_request.js b/ios/chrome/browser/web/resources/payment_request.js
index 85e89de..6e1ecf7a2 100644
--- a/ios/chrome/browser/web/resources/payment_request.js
+++ b/ios/chrome/browser/web/resources/payment_request.js
@@ -1394,7 +1394,6 @@
  *   dependentLocality: string,
  *   postalCode: string,
  *   sortingCode: string,
- *   languageCode: string,
  *   organization: string,
  *   recipient: string,
  *   phone: string
diff --git a/ios/chrome/browser/web/sad_tab_tab_helper.mm b/ios/chrome/browser/web/sad_tab_tab_helper.mm
index c0be4687..3f2d6ba 100644
--- a/ios/chrome/browser/web/sad_tab_tab_helper.mm
+++ b/ios/chrome/browser/web/sad_tab_tab_helper.mm
@@ -14,6 +14,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
+#import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #include "ios/chrome/browser/ui/fullscreen/fullscreen_controller_factory.h"
 #include "ios/chrome/browser/ui/fullscreen/scoped_fullscreen_disabler.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
@@ -102,6 +103,13 @@
 
 void SadTabTabHelper::RenderProcessGone(web::WebState* web_state) {
   DCHECK_EQ(web_state_, web_state);
+
+  // Don't present a sad tab on top of an NTP.
+  NewTabPageTabHelper* NTPHelper = NewTabPageTabHelper::FromWebState(web_state);
+  if (NTPHelper && NTPHelper->IsActive()) {
+    return;
+  }
+
   if (!web_state->IsVisible()) {
     requires_reload_on_becoming_visible_ = true;
     return;
diff --git a/ios/chrome/browser/web/sad_tab_tab_helper_unittest.mm b/ios/chrome/browser/web/sad_tab_tab_helper_unittest.mm
index bd08ef7..ac2a464 100644
--- a/ios/chrome/browser/web/sad_tab_tab_helper_unittest.mm
+++ b/ios/chrome/browser/web/sad_tab_tab_helper_unittest.mm
@@ -8,6 +8,9 @@
 
 #include "base/test/scoped_task_environment.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
+#import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/chrome/browser/web/sad_tab_tab_helper_delegate.h"
 #import "ios/web/public/test/fakes/fake_navigation_context.h"
@@ -142,6 +145,25 @@
   EXPECT_TRUE(navigation_manager_->LoadIfNecessaryWasCalled());
 }
 
+// Tests that SadTab is not presented if app is displaying the NTP.
+TEST_F(SadTabTabHelperTest, AppOnNTP) {
+  web_state_.WasShown();
+
+  web_state_.SetVisibleURL(GURL(kChromeUINewTabURL));
+  id delegate = OCMProtocolMock(@protocol(NewTabPageTabHelperDelegate));
+  NewTabPageTabHelper::CreateForWebState(&web_state_, delegate);
+
+  // Delegate and TabHelper should not present a SadTab.
+  EXPECT_FALSE(tab_helper()->is_showing_sad_tab());
+  EXPECT_FALSE(sad_tab_delegate_.showingSadTab);
+
+  // Helper should get notified of render process failure,
+  // but Sad Tab should not be presented, because application is on the NTP.
+  web_state_.OnRenderProcessGone();
+  EXPECT_FALSE(tab_helper()->is_showing_sad_tab());
+  EXPECT_FALSE(sad_tab_delegate_.showingSadTab);
+}
+
 // Tests that SadTab is not presented if app is in inactive  and navigation
 // item is reloaded once the app became active.
 TEST_F(SadTabTabHelperTest, AppIsInactive) {
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium
index a540d34..336d6db0 100644
--- a/ios/third_party/material_components_ios/README.chromium
+++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@
 Name: Material Components for iOS
 URL: https://github.com/material-components/material-components-ios
 Version: 0
-Revision: eb06a3ba6561b910857100bdedd50eb6167d7eba
+Revision: 63faa33898c3041fcd87ca3abf173b6647e971f3
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/jingle/glue/task_pump.cc b/jingle/glue/task_pump.cc
index 9ee5aee..ff154ce 100644
--- a/jingle/glue/task_pump.cc
+++ b/jingle/glue/task_pump.cc
@@ -25,8 +25,8 @@
   if (!stopped_ && !posted_wake_) {
     // Do the requested wake up.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(&TaskPump::CheckAndRunTasks, weak_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&TaskPump::CheckAndRunTasks,
+                                  weak_factory_.GetWeakPtr()));
     posted_wake_ = true;
   }
 }
diff --git a/jingle/glue/thread_wrapper.cc b/jingle/glue/thread_wrapper.cc
index 4db7bb6..46060b06 100644
--- a/jingle/glue/thread_wrapper.cc
+++ b/jingle/glue/thread_wrapper.cc
@@ -192,10 +192,9 @@
   // Need to signal |pending_send_event_| here in case the thread is
   // sending message to another thread.
   pending_send_event_.Signal();
-  task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&JingleThreadWrapper::ProcessPendingSends,
-                                    weak_ptr_));
-
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&JingleThreadWrapper::ProcessPendingSends, weak_ptr_));
 
   while (!pending_send.done_event.IsSignaled()) {
     base::WaitableEvent* events[] = {&pending_send.done_event,
@@ -247,14 +246,14 @@
   }
 
   if (delay_ms <= 0) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&JingleThreadWrapper::RunTask,
-                                      weak_ptr_, task_id));
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&JingleThreadWrapper::RunTask, weak_ptr_, task_id));
   } else {
-    task_runner_->PostDelayedTask(FROM_HERE,
-                                  base::Bind(&JingleThreadWrapper::RunTask,
-                                             weak_ptr_, task_id),
-                                  base::TimeDelta::FromMilliseconds(delay_ms));
+    task_runner_->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&JingleThreadWrapper::RunTask, weak_ptr_, task_id),
+        base::TimeDelta::FromMilliseconds(delay_ms));
   }
 }
 
diff --git a/jingle/glue/thread_wrapper_unittest.cc b/jingle/glue/thread_wrapper_unittest.cc
index 41d902e75..72ffddf 100644
--- a/jingle/glue/thread_wrapper_unittest.cc
+++ b/jingle/glue/thread_wrapper_unittest.cc
@@ -263,8 +263,8 @@
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   rtc::Thread* target;
   second_thread.task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&InitializeWrapperForNewThread, &target, &initialized_event));
+      FROM_HERE, base::BindOnce(&InitializeWrapperForNewThread, &target,
+                                &initialized_event));
   initialized_event.Wait();
 
   ASSERT_TRUE(target != NULL);
@@ -294,8 +294,8 @@
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   rtc::Thread* target;
   second_thread.task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&InitializeWrapperForNewThread, &target, &initialized_event));
+      FROM_HERE, base::BindOnce(&InitializeWrapperForNewThread, &target,
+                                &initialized_event));
   initialized_event.Wait();
 
   ASSERT_TRUE(target != NULL);
diff --git a/jingle/notifier/listener/non_blocking_push_client.cc b/jingle/notifier/listener/non_blocking_push_client.cc
index 88c59b42..db4a8a7 100644
--- a/jingle/notifier/listener/non_blocking_push_client.cc
+++ b/jingle/notifier/listener/non_blocking_push_client.cc
@@ -125,35 +125,31 @@
 void NonBlockingPushClient::Core::OnNotificationsEnabled() {
   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
   parent_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::OnNotificationsEnabled,
-                 parent_push_client_));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::OnNotificationsEnabled,
+                                parent_push_client_));
 }
 
 void NonBlockingPushClient::Core::OnNotificationsDisabled(
     NotificationsDisabledReason reason) {
   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
   parent_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::OnNotificationsDisabled,
-                 parent_push_client_, reason));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::OnNotificationsDisabled,
+                                parent_push_client_, reason));
 }
 
 void NonBlockingPushClient::Core::OnIncomingNotification(
     const Notification& notification) {
   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
   parent_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::OnIncomingNotification,
-                 parent_push_client_, notification));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::OnIncomingNotification,
+                                parent_push_client_, notification));
 }
 
 void NonBlockingPushClient::Core::OnPingResponse() {
   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
   parent_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::OnPingResponse,
-                 parent_push_client_));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::OnPingResponse,
+                                parent_push_client_));
 }
 
 NonBlockingPushClient::NonBlockingPushClient(
@@ -165,16 +161,16 @@
   core_ = new Core(delegate_task_runner_, weak_ptr_factory_.GetWeakPtr());
   delegate_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&NonBlockingPushClient::Core::CreateOnDelegateThread,
-                 core_, create_blocking_push_client_callback));
+      base::BindOnce(&NonBlockingPushClient::Core::CreateOnDelegateThread,
+                     core_, create_blocking_push_client_callback));
 }
 
 NonBlockingPushClient::~NonBlockingPushClient() {
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&NonBlockingPushClient::Core::DestroyOnDelegateThread,
-                 core_));
+      base::BindOnce(&NonBlockingPushClient::Core::DestroyOnDelegateThread,
+                     core_));
 }
 
 void NonBlockingPushClient::AddObserver(PushClientObserver* observer) {
@@ -192,8 +188,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&NonBlockingPushClient::Core::UpdateSubscriptions,
-                 core_, subscriptions));
+      base::BindOnce(&NonBlockingPushClient::Core::UpdateSubscriptions, core_,
+                     subscriptions));
 }
 
 void NonBlockingPushClient::UpdateCredentials(
@@ -202,24 +198,22 @@
     const net::NetworkTrafficAnnotationTag& traffic_annotation) {
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&NonBlockingPushClient::Core::UpdateCredentials,
-                            core_, email, token, traffic_annotation));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::Core::UpdateCredentials,
+                                core_, email, token, traffic_annotation));
 }
 
 void NonBlockingPushClient::SendNotification(
     const Notification& notification) {
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::Core::SendNotification, core_,
-                 notification));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::Core::SendNotification,
+                                core_, notification));
 }
 
 void NonBlockingPushClient::SendPing() {
   DCHECK(thread_checker_.CalledOnValidThread());
   delegate_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&NonBlockingPushClient::Core::SendPing, core_));
+      FROM_HERE, base::BindOnce(&NonBlockingPushClient::Core::SendPing, core_));
 }
 
 void NonBlockingPushClient::OnNotificationsEnabled() {
diff --git a/jingle/notifier/listener/push_client_unittest.cc b/jingle/notifier/listener/push_client_unittest.cc
index 586abc9..f563028 100644
--- a/jingle/notifier/listener/push_client_unittest.cc
+++ b/jingle/notifier/listener/push_client_unittest.cc
@@ -50,8 +50,8 @@
   base::Thread thread("Non-IO thread");
   EXPECT_TRUE(thread.Start());
   thread.task_runner()->PostTask(
-      FROM_HERE, base::Bind(base::IgnoreResult(&PushClient::CreateDefault),
-                            notifier_options_));
+      FROM_HERE, base::BindOnce(base::IgnoreResult(&PushClient::CreateDefault),
+                                notifier_options_));
   thread.Stop();
 }
 
diff --git a/media/audio/alsa/alsa_output.cc b/media/audio/alsa/alsa_output.cc
index a957846..254fd306 100644
--- a/media/audio/alsa/alsa_output.cc
+++ b/media/audio/alsa/alsa_output.cc
@@ -538,10 +538,10 @@
     next_fill_time = base::TimeDelta::FromMilliseconds(10);
   }
 
-  task_runner_->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&AlsaPcmOutputStream::WriteTask, weak_factory_.GetWeakPtr()),
-      next_fill_time);
+  task_runner_->PostDelayedTask(FROM_HERE,
+                                base::BindOnce(&AlsaPcmOutputStream::WriteTask,
+                                               weak_factory_.GetWeakPtr()),
+                                next_fill_time);
 }
 
 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32_t channels) {
diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc
index f5b2046..4e63f2e6 100644
--- a/media/audio/android/audio_android_unittest.cc
+++ b/media/audio/android/audio_android_unittest.cc
@@ -450,10 +450,8 @@
           base::WaitableEvent::InitialState::NOT_SIGNALED);
       audio_manager()->GetTaskRunner()->PostTask(
           FROM_HERE,
-          base::Bind(&AudioAndroidOutputTest::RunOnAudioThreadImpl,
-                     base::Unretained(this),
-                     closure,
-                     &event));
+          base::BindOnce(&AudioAndroidOutputTest::RunOnAudioThreadImpl,
+                         base::Unretained(this), closure, &event));
       event.Wait();
     } else {
       closure.Run();
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc
index 2728f080..d322bc6 100644
--- a/media/audio/android/audio_manager_android.cc
+++ b/media/audio/android/audio_manager_android.cc
@@ -69,9 +69,9 @@
 
 void AudioManagerAndroid::InitializeIfNeeded() {
   GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(base::IgnoreResult(&AudioManagerAndroid::GetJavaAudioManager),
-                 base::Unretained(this)));
+      FROM_HERE, base::BindOnce(base::IgnoreResult(
+                                    &AudioManagerAndroid::GetJavaAudioManager),
+                                base::Unretained(this)));
 }
 
 void AudioManagerAndroid::ShutdownOnAudioThread() {
@@ -298,20 +298,14 @@
                                   const JavaParamRef<jobject>& obj,
                                   jboolean muted) {
   GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &AudioManagerAndroid::DoSetMuteOnAudioThread,
-          base::Unretained(this),
-          muted));
+      FROM_HERE, base::BindOnce(&AudioManagerAndroid::DoSetMuteOnAudioThread,
+                                base::Unretained(this), muted));
 }
 
 void AudioManagerAndroid::SetOutputVolumeOverride(double volume) {
   GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &AudioManagerAndroid::DoSetVolumeOnAudioThread,
-          base::Unretained(this),
-          volume));
+      FROM_HERE, base::BindOnce(&AudioManagerAndroid::DoSetVolumeOnAudioThread,
+                                base::Unretained(this), volume));
 }
 
 bool AudioManagerAndroid::HasOutputVolumeOverride(double* out_volume) const {
diff --git a/media/audio/audio_debug_recording_helper.cc b/media/audio/audio_debug_recording_helper.cc
index a1d2b7d..b03c77c 100644
--- a/media/audio/audio_debug_recording_helper.cc
+++ b/media/audio/audio_debug_recording_helper.cc
@@ -97,8 +97,8 @@
 
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&AudioDebugRecordingHelper::DoWrite,
-                 weak_factory_.GetWeakPtr(), base::Passed(&audio_bus_copy)));
+      base::BindOnce(&AudioDebugRecordingHelper::DoWrite,
+                     weak_factory_.GetWeakPtr(), std::move(audio_bus_copy)));
 }
 
 void AudioDebugRecordingHelper::DoWrite(std::unique_ptr<media::AudioBus> data) {
diff --git a/media/audio/mac/audio_device_listener_mac_unittest.cc b/media/audio/mac/audio_device_listener_mac_unittest.cc
index cd73209..c300559 100644
--- a/media/audio/mac/audio_device_listener_mac_unittest.cc
+++ b/media/audio/mac/audio_device_listener_mac_unittest.cc
@@ -37,8 +37,8 @@
     // order to ensure we don't end up with unbalanced TaskObserver calls.
     message_loop_.task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(&AudioDeviceListenerMacTest::DestroyDeviceListener,
-                   base::Unretained(this)));
+        base::BindOnce(&AudioDeviceListenerMacTest::DestroyDeviceListener,
+                       base::Unretained(this)));
     base::RunLoop().RunUntilIdle();
   }
 
diff --git a/media/audio/scoped_task_runner_observer.cc b/media/audio/scoped_task_runner_observer.cc
index f275174..1c730366 100644
--- a/media/audio/scoped_task_runner_observer.cc
+++ b/media/audio/scoped_task_runner_observer.cc
@@ -33,9 +33,10 @@
   } else {
     base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                               base::WaitableEvent::InitialState::NOT_SIGNALED);
-    if (task_runner_->PostTask(FROM_HERE,
-            base::Bind(&ScopedTaskRunnerObserver::ObserveLoopDestruction,
-                       base::Unretained(this), enable, &event))) {
+    if (task_runner_->PostTask(
+            FROM_HERE,
+            base::BindOnce(&ScopedTaskRunnerObserver::ObserveLoopDestruction,
+                           base::Unretained(this), enable, &event))) {
       event.Wait();
     } else {
       // The message loop's thread has already terminated, so no need to wait.
diff --git a/media/audio/sounds/audio_stream_handler.cc b/media/audio/sounds/audio_stream_handler.cc
index 41ee3fa6..e49d6b1 100644
--- a/media/audio/sounds/audio_stream_handler.cc
+++ b/media/audio/sounds/audio_stream_handler.cc
@@ -137,7 +137,7 @@
     LOG(ERROR) << "Error during system sound reproduction.";
     audio_manager_->GetTaskRunner()->PostTask(
         FROM_HERE,
-        base::Bind(&AudioStreamContainer::Stop, base::Unretained(this)));
+        base::BindOnce(&AudioStreamContainer::Stop, base::Unretained(this)));
   }
 
   void StopStream() {
@@ -218,9 +218,8 @@
     return false;
 
   AudioManager::Get()->GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(base::IgnoreResult(&AudioStreamContainer::Play),
-                 base::Unretained(stream_.get())));
+      FROM_HERE, base::BindOnce(base::IgnoreResult(&AudioStreamContainer::Play),
+                                base::Unretained(stream_.get())));
   return true;
 }
 
@@ -231,8 +230,8 @@
     return;
 
   AudioManager::Get()->GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get())));
+      FROM_HERE, base::BindOnce(&AudioStreamContainer::Stop,
+                                base::Unretained(stream_.get())));
 }
 
 base::TimeDelta AudioStreamHandler::duration() const {
diff --git a/media/audio/virtual_audio_input_stream_unittest.cc b/media/audio/virtual_audio_input_stream_unittest.cc
index 08753634..0af15f0 100644
--- a/media/audio/virtual_audio_input_stream_unittest.cc
+++ b/media/audio/virtual_audio_input_stream_unittest.cc
@@ -233,7 +233,7 @@
                              base::WaitableEvent::InitialState::NOT_SIGNALED);
     audio_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
+        base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&done)));
     done.Wait();
   }
 
diff --git a/media/base/fake_audio_worker_unittest.cc b/media/base/fake_audio_worker_unittest.cc
index 6f71b281..94d2ee9 100644
--- a/media/base/fake_audio_worker_unittest.cc
+++ b/media/base/fake_audio_worker_unittest.cc
@@ -46,8 +46,8 @@
     // Start() should immediately post a task to run the callback, so we
     // should end up with only a single callback being run.
     message_loop_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&FakeAudioWorkerTest::EndTest, base::Unretained(this), 1));
+        FROM_HERE, base::BindOnce(&FakeAudioWorkerTest::EndTest,
+                                  base::Unretained(this), 1));
   }
 
   void StopStartOnAudioThread() {
@@ -68,8 +68,8 @@
     if (seen_callbacks_ < callbacks) {
       message_loop_.task_runner()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeAudioWorkerTest::TimeCallbacksOnAudioThread,
-                     base::Unretained(this), callbacks),
+          base::BindOnce(&FakeAudioWorkerTest::TimeCallbacksOnAudioThread,
+                         base::Unretained(this), callbacks),
           time_between_callbacks_ / 2);
     } else {
       end_time_ = base::TimeTicks::Now();
@@ -140,8 +140,8 @@
   // chance of catching the worker doing the wrong thing.
   message_loop_.task_runner()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeAudioWorkerTest::StopStartOnAudioThread,
-                 base::Unretained(this)),
+      base::BindOnce(&FakeAudioWorkerTest::StopStartOnAudioThread,
+                     base::Unretained(this)),
       time_between_callbacks_ / 2);
 
   // EndTest() will ensure the proper number of callbacks have occurred.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 4205441..dd61212c 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -366,6 +366,7 @@
 
 #if defined(OS_ANDROID)
 // Enable a gesture to make the media controls expaned into the display cutout.
+// TODO(beccahughes): Remove this.
 const base::Feature kMediaControlsExpandGesture{
     "MediaControlsExpandGesture", base::FEATURE_ENABLED_BY_DEFAULT};
 
@@ -427,10 +428,12 @@
 }
 
 // Adds icons to the overflow menu on the native media controls.
+// TODO(steimel): Remove this.
 const base::Feature kOverflowIconsForMediaControls{
     "OverflowIconsForMediaControls", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables the new redesigned media controls.
+// TODO(steimel): Remove this.
 const base::Feature kUseModernMediaControls{"UseModernMediaControls",
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
diff --git a/media/base/serial_runner.cc b/media/base/serial_runner.cc
index 29ec9d23..affaede 100644
--- a/media/base/serial_runner.cc
+++ b/media/base/serial_runner.cc
@@ -76,10 +76,9 @@
   // Respect both cancellation and calling stack guarantees for |done_cb|
   // when empty.
   if (bound_fns_.empty()) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&SerialRunner::RunNextInSeries,
-                                      weak_factory_.GetWeakPtr(),
-                                      PIPELINE_OK));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&SerialRunner::RunNextInSeries,
+                                  weak_factory_.GetWeakPtr(), PIPELINE_OK));
     return;
   }
 
diff --git a/media/blink/multibuffer_data_source.cc b/media/blink/multibuffer_data_source.cc
index 3e0e784..f02d270 100644
--- a/media/blink/multibuffer_data_source.cc
+++ b/media/blink/multibuffer_data_source.cc
@@ -206,7 +206,7 @@
   if (reader_->Available()) {
     render_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&MultibufferDataSource::StartCallback, weak_ptr_));
+        base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
 
     // When the entire file is already in the cache, we won't get any more
     // progress callbacks, which breaks some expectations. Post a task to
@@ -229,7 +229,7 @@
     if (init_cb_) {
       render_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(&MultibufferDataSource::StartCallback, weak_ptr_));
+          base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
     } else {
       base::AutoLock auto_lock(lock_);
       StopInternal_Locked();
@@ -252,7 +252,7 @@
       if (reader_->Available()) {
         render_task_runner_->PostTask(
             FROM_HERE,
-            base::Bind(&MultibufferDataSource::StartCallback, weak_ptr_));
+            base::BindOnce(&MultibufferDataSource::StartCallback, weak_ptr_));
       } else {
         reader_->Wait(
             1, base::Bind(&MultibufferDataSource::StartCallback, weak_ptr_));
@@ -328,9 +328,9 @@
     }
   }
 
-  render_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(&MultibufferDataSource::StopLoader,
-                                           weak_factory_.GetWeakPtr()));
+  render_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&MultibufferDataSource::StopLoader,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void MultibufferDataSource::Abort() {
@@ -408,8 +408,8 @@
         if (seek_positions_.size() == 1) {
           render_task_runner_->PostDelayedTask(
               FROM_HERE,
-              base::Bind(&MultibufferDataSource::SeekTask,
-                         weak_factory_.GetWeakPtr()),
+              base::BindOnce(&MultibufferDataSource::SeekTask,
+                             weak_factory_.GetWeakPtr()),
               kSeekDelay);
         }
 
@@ -420,9 +420,9 @@
     read_op_.reset(new ReadOperation(position, size, data, read_cb));
   }
 
-  render_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&MultibufferDataSource::ReadTask, weak_factory_.GetWeakPtr()));
+  render_task_runner_->PostTask(FROM_HERE,
+                                base::BindOnce(&MultibufferDataSource::ReadTask,
+                                               weak_factory_.GetWeakPtr()));
 }
 
 bool MultibufferDataSource::GetSize(int64_t* size_out) {
@@ -623,7 +623,7 @@
   }
 
   render_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(std::move(init_cb_), success));
+                                base::BindOnce(std::move(init_cb_), success));
 
   UpdateBufferSizes();
 
diff --git a/media/blink/multibuffer_reader.cc b/media/blink/multibuffer_reader.cc
index e1d52e0..ae7954a 100644
--- a/media/blink/multibuffer_reader.cc
+++ b/media/blink/multibuffer_reader.cc
@@ -181,11 +181,12 @@
   if (!progress_callback_.is_null()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(progress_callback_, static_cast<int64_t>(range.begin)
-                                           << multibuffer_->block_size_shift(),
-                   (static_cast<int64_t>(range.end)
-                    << multibuffer_->block_size_shift()) +
-                       multibuffer_->UncommittedBytesAt(range.end)));
+        base::BindOnce(progress_callback_,
+                       static_cast<int64_t>(range.begin)
+                           << multibuffer_->block_size_shift(),
+                       (static_cast<int64_t>(range.end)
+                        << multibuffer_->block_size_shift()) +
+                           multibuffer_->UncommittedBytesAt(range.end)));
   }
 }
 
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc
index 4653b6cf..5b166702 100644
--- a/media/blink/resource_multibuffer_data_provider.cc
+++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -452,8 +452,8 @@
       retries_++;
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&ResourceMultiBufferDataProvider::Start,
-                     weak_factory_.GetWeakPtr()),
+          base::BindOnce(&ResourceMultiBufferDataProvider::Start,
+                         weak_factory_.GetWeakPtr()),
           base::TimeDelta::FromMilliseconds(kLoaderPartialRetryDelayMs));
       return;
     } else {
@@ -484,8 +484,8 @@
     retries_++;
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&ResourceMultiBufferDataProvider::Start,
-                   weak_factory_.GetWeakPtr()),
+        base::BindOnce(&ResourceMultiBufferDataProvider::Start,
+                       weak_factory_.GetWeakPtr()),
         base::TimeDelta::FromMilliseconds(
             kLoaderFailedRetryDelayMs + kAdditionalDelayPerRetryMs * retries_));
   } else {
diff --git a/media/blink/texttrack_impl.cc b/media/blink/texttrack_impl.cc
index 19397380..d8500cb4 100644
--- a/media/blink/texttrack_impl.cc
+++ b/media/blink/texttrack_impl.cc
@@ -28,8 +28,8 @@
 
 TextTrackImpl::~TextTrackImpl() {
   task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&TextTrackImpl::OnRemoveTrack, client_,
-                                    base::Passed(&text_track_)));
+                         base::BindOnce(&TextTrackImpl::OnRemoveTrack, client_,
+                                        std::move(text_track_)));
 }
 
 void TextTrackImpl::addWebVTTCue(base::TimeDelta start,
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc
index e2782a00..a3fe7783 100644
--- a/media/blink/video_frame_compositor.cc
+++ b/media/blink/video_frame_compositor.cc
@@ -205,8 +205,8 @@
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VideoFrameCompositor::PaintSingleFrame,
-                   base::Unretained(this), frame, repaint_duplicate_frame));
+        base::BindOnce(&VideoFrameCompositor::PaintSingleFrame,
+                       base::Unretained(this), frame, repaint_duplicate_frame));
     return;
   }
   if (ProcessNewFrame(frame, repaint_duplicate_frame) &&
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
index 3a4680f..8ca3677 100644
--- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
+++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
@@ -151,9 +151,9 @@
   // sure |device_context_| outlives |camera_device_delegate_|.
   camera_device_ipc_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&CameraDeviceDelegate::AllocateAndStart,
-                 camera_device_delegate_->GetWeakPtr(), capture_params_,
-                 base::Unretained(device_context_.get())));
+      base::BindOnce(&CameraDeviceDelegate::AllocateAndStart,
+                     camera_device_delegate_->GetWeakPtr(), capture_params_,
+                     base::Unretained(device_context_.get())));
   camera_device_ipc_thread_.task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(&CameraDeviceDelegate::SetRotation,
@@ -239,8 +239,8 @@
   if (camera_device_ipc_thread_.IsRunning()) {
     camera_device_ipc_thread_.task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(&CameraDeviceDelegate::SetRotation,
-                   camera_device_delegate_->GetWeakPtr(), rotation_));
+        base::BindOnce(&CameraDeviceDelegate::SetRotation,
+                       camera_device_delegate_->GetWeakPtr(), rotation_));
   }
 }
 
diff --git a/media/capture/video/fake_video_capture_device.cc b/media/capture/video/fake_video_capture_device.cc
index 678c291c2..e95dcfb 100644
--- a/media/capture/video/fake_video_capture_device.cc
+++ b/media/capture/video/fake_video_capture_device.cc
@@ -695,9 +695,9 @@
   const base::TimeDelta delay = next_execution_time - current_time;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeVideoCaptureDevice::OnNextFrameDue,
-                 weak_factory_.GetWeakPtr(), next_execution_time,
-                 current_session_id_),
+      base::BindOnce(&FakeVideoCaptureDevice::OnNextFrameDue,
+                     weak_factory_.GetWeakPtr(), next_execution_time,
+                     current_session_id_),
       delay);
 }
 
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc
index 7d8acdee..c67c9a2 100644
--- a/media/capture/video/file_video_capture_device.cc
+++ b/media/capture/video/file_video_capture_device.cc
@@ -319,8 +319,8 @@
   capture_thread_.Start();
   capture_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&FileVideoCaptureDevice::OnAllocateAndStart,
-                 base::Unretained(this), params, base::Passed(&client)));
+      base::BindOnce(&FileVideoCaptureDevice::OnAllocateAndStart,
+                     base::Unretained(this), params, std::move(client)));
 }
 
 void FileVideoCaptureDevice::StopAndDeAllocate() {
diff --git a/media/capture/video/linux/video_capture_device_linux.cc b/media/capture/video/linux/video_capture_device_linux.cc
index 51aad2690..d4dd50bc 100644
--- a/media/capture/video/linux/video_capture_device_linux.cc
+++ b/media/capture/video/linux/video_capture_device_linux.cc
@@ -86,11 +86,11 @@
   }
   v4l2_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2CaptureDelegate::AllocateAndStart,
-                 capture_impl_->GetWeakPtr(),
-                 params.requested_format.frame_size.width(),
-                 params.requested_format.frame_size.height(),
-                 params.requested_format.frame_rate, base::Passed(&client)));
+      base::BindOnce(&V4L2CaptureDelegate::AllocateAndStart,
+                     capture_impl_->GetWeakPtr(),
+                     params.requested_format.frame_size.width(),
+                     params.requested_format.frame_size.height(),
+                     params.requested_format.frame_rate, std::move(client)));
 
   for (auto& request : photo_requests_queue_)
     v4l2_thread_.task_runner()->PostTask(FROM_HERE, std::move(request));
@@ -113,7 +113,7 @@
   DCHECK(capture_impl_);
   auto functor =
       base::BindOnce(&V4L2CaptureDelegate::TakePhoto,
-                     capture_impl_->GetWeakPtr(), base::Passed(&callback));
+                     capture_impl_->GetWeakPtr(), std::move(callback));
   if (!v4l2_thread_.IsRunning()) {
     // We have to wait until we get the device AllocateAndStart()ed.
     photo_requests_queue_.push_back(std::move(functor));
@@ -125,7 +125,7 @@
 void VideoCaptureDeviceLinux::GetPhotoState(GetPhotoStateCallback callback) {
   auto functor =
       base::BindOnce(&V4L2CaptureDelegate::GetPhotoState,
-                     capture_impl_->GetWeakPtr(), base::Passed(&callback));
+                     capture_impl_->GetWeakPtr(), std::move(callback));
   if (!v4l2_thread_.IsRunning()) {
     // We have to wait until we get the device AllocateAndStart()ed.
     photo_requests_queue_.push_back(std::move(functor));
@@ -137,9 +137,9 @@
 void VideoCaptureDeviceLinux::SetPhotoOptions(
     mojom::PhotoSettingsPtr settings,
     SetPhotoOptionsCallback callback) {
-  auto functor = base::BindOnce(
-      &V4L2CaptureDelegate::SetPhotoOptions, capture_impl_->GetWeakPtr(),
-      base::Passed(&settings), base::Passed(&callback));
+  auto functor = base::BindOnce(&V4L2CaptureDelegate::SetPhotoOptions,
+                                capture_impl_->GetWeakPtr(),
+                                std::move(settings), std::move(callback));
   if (!v4l2_thread_.IsRunning()) {
     // We have to wait until we get the device AllocateAndStart()ed.
     photo_requests_queue_.push_back(std::move(functor));
diff --git a/media/capture/video/video_frame_receiver_on_task_runner.cc b/media/capture/video/video_frame_receiver_on_task_runner.cc
index 9c7b036..444260f 100644
--- a/media/capture/video/video_frame_receiver_on_task_runner.cc
+++ b/media/capture/video/video_frame_receiver_on_task_runner.cc
@@ -40,8 +40,8 @@
 
 void VideoFrameReceiverOnTaskRunner::OnBufferRetired(int buffer_id) {
   task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&VideoFrameReceiver::OnBufferRetired, receiver_, buffer_id));
+      FROM_HERE, base::BindOnce(&VideoFrameReceiver::OnBufferRetired, receiver_,
+                                buffer_id));
 }
 
 void VideoFrameReceiverOnTaskRunner::OnError(VideoCaptureError error) {
diff --git a/media/cast/net/cast_transport_impl.cc b/media/cast/net/cast_transport_impl.cc
index 7f339bf..83a1321 100644
--- a/media/cast/net/cast_transport_impl.cc
+++ b/media/cast/net/cast_transport_impl.cc
@@ -291,7 +291,8 @@
 
   transport_task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&CastTransportImpl::SendRawEvents, weak_factory_.GetWeakPtr()),
+      base::BindOnce(&CastTransportImpl::SendRawEvents,
+                     weak_factory_.GetWeakPtr()),
       logging_flush_interval_);
 }
 
diff --git a/media/cast/sender/congestion_control_unittest.cc b/media/cast/sender/congestion_control_unittest.cc
index 561ce87..34e35e0 100644
--- a/media/cast/sender/congestion_control_unittest.cc
+++ b/media/cast/sender/congestion_control_unittest.cc
@@ -55,11 +55,11 @@
       congestion_control_->UpdateRtt(rtt);
       congestion_control_->SendFrameToTransport(
           frame_id_, frame_size, testing_clock_.NowTicks());
-      task_runner_->PostDelayedTask(FROM_HERE,
-                                    base::Bind(&CongestionControlTest::AckFrame,
-                                               base::Unretained(this),
-                                               frame_id_),
-                                    ack_time);
+      task_runner_->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(&CongestionControlTest::AckFrame,
+                         base::Unretained(this), frame_id_),
+          ack_time);
       task_runner_->Sleep(frame_delay);
     }
   }
diff --git a/media/cast/sender/external_video_encoder.cc b/media/cast/sender/external_video_encoder.cc
index 30e8ff9..82e9d34 100644
--- a/media/cast/sender/external_video_encoder.cc
+++ b/media/cast/sender/external_video_encoder.cc
@@ -430,16 +430,15 @@
 
   // Note: This method can be called on any thread.
   void OnCreateSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&VEAClientImpl::OnReceivedSharedMemory,
-                                      this,
-                                      base::Passed(&memory)));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&VEAClientImpl::OnReceivedSharedMemory, this,
+                                  std::move(memory)));
   }
 
   void OnCreateInputSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
     task_runner_->PostTask(
         FROM_HERE, base::BindOnce(&VEAClientImpl::OnReceivedInputSharedMemory,
-                                  this, base::Passed(&memory)));
+                                  this, std::move(memory)));
   }
 
   void OnReceivedSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
@@ -663,13 +662,10 @@
   if (!client_ || video_frame->visible_rect().size() != frame_size_)
     return false;
 
-  client_->task_runner()->PostTask(FROM_HERE,
-                                   base::Bind(&VEAClientImpl::EncodeVideoFrame,
-                                              client_,
-                                              video_frame,
-                                              reference_time,
-                                              key_frame_requested_,
-                                              frame_encoded_callback));
+  client_->task_runner()->PostTask(
+      FROM_HERE, base::BindOnce(&VEAClientImpl::EncodeVideoFrame, client_,
+                                video_frame, reference_time,
+                                key_frame_requested_, frame_encoded_callback));
   key_frame_requested_ = false;
   return true;
 }
@@ -762,13 +758,10 @@
                               std::move(vea), video_config.max_frame_rate,
                               std::move(wrapped_status_change_cb),
                               create_video_encode_memory_cb_);
-  client_->task_runner()->PostTask(FROM_HERE,
-                                   base::Bind(&VEAClientImpl::Initialize,
-                                              client_,
-                                              frame_size_,
-                                              codec_profile,
-                                              bit_rate_,
-                                              first_frame_id));
+  client_->task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&VEAClientImpl::Initialize, client_, frame_size_,
+                     codec_profile, bit_rate_, first_frame_id));
 }
 
 SizeAdaptableExternalVideoEncoder::SizeAdaptableExternalVideoEncoder(
diff --git a/media/cast/test/cast_benchmarks.cc b/media/cast/test/cast_benchmarks.cc
index a527ac9..99ab474 100644
--- a/media/cast/test/cast_benchmarks.cc
+++ b/media/cast/test/cast_benchmarks.cc
@@ -651,11 +651,9 @@
       SearchVector ac = a.blend(c, static_cast<double>(x) / max);
       SearchVector v = ab.blend(ac, x == y ? 1.0 : static_cast<double>(y) / x);
       thread_num++;
-      (*threads)[thread_num % threads->size()]
-          ->task_runner()
-          ->PostTask(FROM_HERE,
-                     base::Bind(&CastBenchmark::BinarySearch,
-                                base::Unretained(this), v, accuracy));
+      (*threads)[thread_num % threads->size()]->task_runner()->PostTask(
+          FROM_HERE, base::BindOnce(&CastBenchmark::BinarySearch,
+                                    base::Unretained(this), v, accuracy));
     } else {
       skip *= 2;
       SpanningSearch(max, x, y, skip, a, b, c, accuracy, threads);
diff --git a/media/cast/test/fake_media_source.cc b/media/cast/test/fake_media_source.cc
index 31d5ebe1..7c51ecd6 100644
--- a/media/cast/test/fake_media_source.cc
+++ b/media/cast/test/fake_media_source.cc
@@ -240,10 +240,9 @@
 
   if (!is_transcoding_audio() && !is_transcoding_video()) {
     // Send fake patterns.
-    task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&FakeMediaSource::SendNextFakeFrame,
-                   weak_factory_.GetWeakPtr()));
+    task_runner_->PostTask(FROM_HERE,
+                           base::BindOnce(&FakeMediaSource::SendNextFakeFrame,
+                                          weak_factory_.GetWeakPtr()));
     return;
   }
 
@@ -261,9 +260,9 @@
   audio_converter_.reset(new media::AudioConverter(
       source_audio_params_, output_audio_params_, true));
   audio_converter_->AddInput(this);
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()));
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&FakeMediaSource::SendNextFrame,
+                                        weak_factory_.GetWeakPtr()));
 }
 
 void FakeMediaSource::SendNextFakeFrame() {
@@ -312,8 +311,8 @@
 
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeMediaSource::SendNextFakeFrame,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&FakeMediaSource::SendNextFakeFrame,
+                     weak_factory_.GetWeakPtr()),
       video_time - elapsed_time);
 }
 
@@ -409,7 +408,8 @@
   // Send next send.
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()),
+      base::BindOnce(&FakeMediaSource::SendNextFrame,
+                     weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(kAudioFrameMs));
 }
 
diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc
index 37d4b46..b04d69dd3 100644
--- a/media/cast/test/receiver.cc
+++ b/media/cast/test/receiver.cc
@@ -217,8 +217,8 @@
   void Start() final {
     AudioManager::Get()->GetTaskRunner()->PostTask(
         FROM_HERE,
-        base::Bind(&NaivePlayer::StartAudioOutputOnAudioManagerThread,
-                   base::Unretained(this)));
+        base::BindOnce(&NaivePlayer::StartAudioOutputOnAudioManagerThread,
+                       base::Unretained(this)));
     // Note: No need to wait for audio polling to start since the push-and-pull
     // mechanism is synchronized via the |audio_playout_queue_|.
     InProcessReceiver::Start();
@@ -231,9 +231,8 @@
     DCHECK(!AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
     AudioManager::Get()->GetTaskRunner()->PostTask(
         FROM_HERE,
-        base::Bind(&NaivePlayer::StopAudioOutputOnAudioManagerThread,
-                   base::Unretained(this),
-                   &done));
+        base::BindOnce(&NaivePlayer::StopAudioOutputOnAudioManagerThread,
+                       base::Unretained(this), &done));
     done.Wait();
 
     // Now, stop receiving new frames.
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index 7b2ffe2e..86c3e89 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -315,21 +315,18 @@
   const int logging_duration_seconds = 10;
   io_message_loop.task_runner()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&WriteLogsToFileAndDestroySubscribers,
-                 cast_environment,
-                 base::Passed(&video_event_subscriber),
-                 base::Passed(&audio_event_subscriber),
-                 base::Passed(&video_log_file),
-                 base::Passed(&audio_log_file)),
+      base::BindOnce(&WriteLogsToFileAndDestroySubscribers, cast_environment,
+                     std::move(video_event_subscriber),
+                     std::move(audio_event_subscriber),
+                     std::move(video_log_file), std::move(audio_log_file)),
       base::TimeDelta::FromSeconds(logging_duration_seconds));
 
   io_message_loop.task_runner()->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&WriteStatsAndDestroySubscribers,
-                 cast_environment,
-                 base::Passed(&video_stats_subscriber),
-                 base::Passed(&audio_stats_subscriber),
-                 base::Passed(&offset_estimator)),
+      base::BindOnce(&WriteStatsAndDestroySubscribers, cast_environment,
+                     std::move(video_stats_subscriber),
+                     std::move(audio_stats_subscriber),
+                     std::move(offset_estimator)),
       base::TimeDelta::FromSeconds(logging_duration_seconds));
 
   // CastSender initialization.
@@ -337,12 +334,12 @@
       media::cast::CastSender::Create(cast_environment, transport_sender.get());
   io_message_loop.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&media::cast::CastSender::InitializeVideo,
-                 base::Unretained(cast_sender.get()),
-                 fake_media_source->get_video_config(),
-                 base::Bind(&QuitLoopOnInitializationResult),
-                 media::cast::CreateDefaultVideoEncodeAcceleratorCallback(),
-                 media::cast::CreateDefaultVideoEncodeMemoryCallback()));
+      base::BindOnce(&media::cast::CastSender::InitializeVideo,
+                     base::Unretained(cast_sender.get()),
+                     fake_media_source->get_video_config(),
+                     base::Bind(&QuitLoopOnInitializationResult),
+                     media::cast::CreateDefaultVideoEncodeAcceleratorCallback(),
+                     media::cast::CreateDefaultVideoEncodeMemoryCallback()));
   base::RunLoop().Run();  // Wait for video initialization.
   io_message_loop.task_runner()->PostTask(
       FROM_HERE,
diff --git a/media/cast/test/utility/tap_proxy.cc b/media/cast/test/utility/tap_proxy.cc
index 1adc993..c1f50c7 100644
--- a/media/cast/test/utility/tap_proxy.cc
+++ b/media/cast/test/utility/tap_proxy.cc
@@ -211,8 +211,7 @@
     last_printout = now;
   }
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&CheckByteCounters),
+      FROM_HERE, base::BindOnce(&CheckByteCounters),
       base::TimeDelta::FromMilliseconds(100));
 }
 
diff --git a/media/cast/test/utility/udp_proxy.cc b/media/cast/test/utility/udp_proxy.cc
index 625779c..3021aca 100644
--- a/media/cast/test/utility/udp_proxy.cc
+++ b/media/cast/test/utility/udp_proxy.cc
@@ -82,7 +82,7 @@
     int64_t microseconds = static_cast<int64_t>(seconds * 1E6);
     task_runner_->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&Buffer::ProcessBuffer, weak_factory_.GetWeakPtr()),
+        base::BindOnce(&Buffer::ProcessBuffer, weak_factory_.GetWeakPtr()),
         base::TimeDelta::FromMicroseconds(microseconds));
   }
 
@@ -147,8 +147,8 @@
     double seconds = GetDelay();
     task_runner_->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&SimpleDelayBase::SendInternal, weak_factory_.GetWeakPtr(),
-                   base::Passed(&packet)),
+        base::BindOnce(&SimpleDelayBase::SendInternal,
+                       weak_factory_.GetWeakPtr(), std::move(packet)),
         base::TimeDelta::FromMicroseconds(static_cast<int64_t>(seconds * 1E6)));
   }
  protected:
@@ -248,8 +248,8 @@
     int64_t microseconds = static_cast<int64_t>(seconds * 1E6);
     task_runner_->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&RandomSortedDelay::CauseExtraDelay,
-                   weak_factory_.GetWeakPtr()),
+        base::BindOnce(&RandomSortedDelay::CauseExtraDelay,
+                       weak_factory_.GetWeakPtr()),
         base::TimeDelta::FromMicroseconds(microseconds));
   }
 
@@ -278,8 +278,8 @@
     if (!buffer_.empty()) {
       task_runner_->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&RandomSortedDelay::ProcessBuffer,
-                     weak_factory_.GetWeakPtr()),
+          base::BindOnce(&RandomSortedDelay::ProcessBuffer,
+                         weak_factory_.GetWeakPtr()),
           next_send_ - now);
     }
   }
@@ -330,7 +330,7 @@
     int64_t microseconds = static_cast<int64_t>(seconds * 1E6);
     task_runner_->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()),
+        base::BindOnce(&NetworkGlitchPipe::Flip, weak_factory_.GetWeakPtr()),
         base::TimeDelta::FromMicroseconds(microseconds));
   }
 
@@ -487,8 +487,8 @@
   rate_index_ = (rate_index_ + 1) % average_rates_.size();
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&InterruptedPoissonProcess::UpdateRates,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&InterruptedPoissonProcess::UpdateRates,
+                     weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromSeconds(1));
 }
 
@@ -496,8 +496,8 @@
   on_state_ = false;
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&InterruptedPoissonProcess::SwitchOn,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&InterruptedPoissonProcess::SwitchOn,
+                     weak_factory_.GetWeakPtr()),
       NextEvent(switch_on_rate_));
 }
 
@@ -505,16 +505,16 @@
   on_state_ = true;
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&InterruptedPoissonProcess::SwitchOff,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&InterruptedPoissonProcess::SwitchOff,
+                     weak_factory_.GetWeakPtr()),
       NextEvent(switch_off_rate_));
 }
 
 void InterruptedPoissonProcess::SendPacket() {
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&InterruptedPoissonProcess::SendPacket,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&InterruptedPoissonProcess::SendPacket,
+                     weak_factory_.GetWeakPtr()),
       NextEvent(send_rate_));
 
   // If OFF then don't send.
@@ -702,11 +702,8 @@
         base::WaitableEvent::ResetPolicy::AUTOMATIC,
         base::WaitableEvent::InitialState::NOT_SIGNALED);
     proxy_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&UDPProxyImpl::Start,
-                   base::Unretained(this),
-                   base::Unretained(&start_event),
-                   net_log));
+        FROM_HERE, base::BindOnce(&UDPProxyImpl::Start, base::Unretained(this),
+                                  base::Unretained(&start_event), net_log));
     start_event.Wait();
   }
 
@@ -716,10 +713,8 @@
         base::WaitableEvent::ResetPolicy::AUTOMATIC,
         base::WaitableEvent::InitialState::NOT_SIGNALED);
     proxy_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&UDPProxyImpl::Stop,
-                   base::Unretained(this),
-                   base::Unretained(&stop_event)));
+        FROM_HERE, base::BindOnce(&UDPProxyImpl::Stop, base::Unretained(this),
+                                  base::Unretained(&stop_event)));
     stop_event.Wait();
     proxy_thread_.Stop();
   }
diff --git a/media/cast/test/utility/udp_proxy_main.cc b/media/cast/test/utility/udp_proxy_main.cc
index e60130dc3..9b22a7a 100644
--- a/media/cast/test/utility/udp_proxy_main.cc
+++ b/media/cast/test/utility/udp_proxy_main.cc
@@ -126,8 +126,7 @@
     counter->last_printout = now;
   }
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&CheckByteCounters),
+      FROM_HERE, base::BindOnce(&CheckByteCounters),
       base::TimeDelta::FromMilliseconds(100));
 }
 
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc
index afbedcd..373cd9b 100644
--- a/media/cdm/cdm_adapter.cc
+++ b/media/cdm/cdm_adapter.cc
@@ -687,10 +687,11 @@
   TRACE_EVENT2("media", "CdmAdapter::SetTimer", "delay_ms", delay_ms, "context",
                context);
 
-  task_runner_->PostDelayedTask(FROM_HERE,
-                                base::Bind(&CdmAdapter::TimerExpired,
-                                           weak_factory_.GetWeakPtr(), context),
-                                delay);
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&CdmAdapter::TimerExpired, weak_factory_.GetWeakPtr(),
+                     context),
+      delay);
 }
 
 void CdmAdapter::TimerExpired(void* context) {
diff --git a/media/cdm/cdm_adapter_factory.cc b/media/cdm/cdm_adapter_factory.cc
index 1118ce8f..a49116b7 100644
--- a/media/cdm/cdm_adapter_factory.cc
+++ b/media/cdm/cdm_adapter_factory.cc
@@ -42,8 +42,8 @@
       CdmModule::GetInstance()->GetCreateCdmFunc();
   if (!create_cdm_func) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(cdm_created_cb, nullptr, "CreateCdmFunc not available."));
+        FROM_HERE, base::BindOnce(cdm_created_cb, nullptr,
+                                  "CreateCdmFunc not available."));
     return;
   }
 
@@ -51,7 +51,7 @@
   if (!cdm_helper) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(cdm_created_cb, nullptr, "CDM helper creation failed."));
+        base::BindOnce(cdm_created_cb, nullptr, "CDM helper creation failed."));
     return;
   }
 
diff --git a/media/cdm/default_cdm_factory.cc b/media/cdm/default_cdm_factory.cc
index 8d818cf..440a5d68 100644
--- a/media/cdm/default_cdm_factory.cc
+++ b/media/cdm/default_cdm_factory.cc
@@ -50,7 +50,7 @@
   if (!ShouldCreateAesDecryptor(key_system)) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(cdm_created_cb, nullptr, "Unsupported key system."));
+        base::BindOnce(cdm_created_cb, nullptr, "Unsupported key system."));
     return;
   }
 
diff --git a/media/device_monitors/device_monitor_udev.cc b/media/device_monitors/device_monitor_udev.cc
index cbac9a8..493a060 100644
--- a/media/device_monitors/device_monitor_udev.cc
+++ b/media/device_monitors/device_monitor_udev.cc
@@ -42,7 +42,7 @@
     : io_task_runner_(io_task_runner) {
   io_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&DeviceMonitorLinux::Initialize, base::Unretained(this)));
+      base::BindOnce(&DeviceMonitorLinux::Initialize, base::Unretained(this)));
 }
 
 DeviceMonitorLinux::~DeviceMonitorLinux() = default;
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index e474785..410e5f43 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -1033,7 +1033,7 @@
   // Aborting the read may cause EOF to be marked, undo this.
   blocking_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&UnmarkEndOfStreamAndClearError, glue_->format_context()));
+      base::BindOnce(&UnmarkEndOfStreamAndClearError, glue_->format_context()));
   pending_read_ = false;
 
   // TODO(dalecurtis): We probably should report PIPELINE_ERROR_ABORT here
diff --git a/media/gpu/android/android_video_decode_accelerator.cc b/media/gpu/android/android_video_decode_accelerator.cc
index 64ad14d6..ddb37504 100644
--- a/media/gpu/android/android_video_decode_accelerator.cc
+++ b/media/gpu/android/android_video_decode_accelerator.cc
@@ -723,8 +723,8 @@
   // TODO(dwkang): check if there is a way to remove this workaround.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
-                 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
+      base::BindOnce(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
+                     weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
   bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
 
   if (status != MEDIA_CODEC_OK) {
@@ -827,8 +827,9 @@
           picturebuffers_requested_ = true;
           base::ThreadTaskRunnerHandle::Get()->PostTask(
               FROM_HERE,
-              base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
-                         weak_this_factory_.GetWeakPtr()));
+              base::BindOnce(
+                  &AndroidVideoDecodeAccelerator::RequestPictureBuffers,
+                  weak_this_factory_.GetWeakPtr()));
           return false;
         }
 
@@ -1012,8 +1013,9 @@
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
-                   weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
+        base::BindOnce(
+            &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
+            weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
   }
 }
 
@@ -1298,8 +1300,9 @@
     if (bitstream_buffer_id != -1) {
       base::ThreadTaskRunnerHandle::Get()->PostTask(
           FROM_HERE,
-          base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
-                     weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
+          base::BindOnce(
+              &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
+              weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
     }
   }
   TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
diff --git a/media/gpu/android/android_video_encode_accelerator.cc b/media/gpu/android/android_video_encode_accelerator.cc
index b19e8baf..da452f6 100644
--- a/media/gpu/android/android_video_encode_accelerator.cc
+++ b/media/gpu/android/android_video_encode_accelerator.cc
@@ -208,9 +208,9 @@
       2048;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers,
-                 client_ptr_factory_->GetWeakPtr(), frame_input_count,
-                 config.input_visible_size, output_buffer_capacity));
+      base::BindOnce(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers,
+                     client_ptr_factory_->GetWeakPtr(), frame_input_count,
+                     config.input_visible_size, output_buffer_capacity));
   return true;
 }
 
@@ -443,9 +443,10 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady,
-                 client_ptr_factory_->GetWeakPtr(), bitstream_buffer.id(),
-                 BitstreamBufferMetadata(size, key_frame, frame_timestamp)));
+      base::BindOnce(
+          &VideoEncodeAccelerator::Client::BitstreamBufferReady,
+          client_ptr_factory_->GetWeakPtr(), bitstream_buffer.id(),
+          BitstreamBufferMetadata(size, key_frame, frame_timestamp)));
 }
 
 }  // namespace media
diff --git a/media/gpu/fake_jpeg_decode_accelerator.cc b/media/gpu/fake_jpeg_decode_accelerator.cc
index b12b52f4..4b7c7f4 100644
--- a/media/gpu/fake_jpeg_decode_accelerator.cc
+++ b/media/gpu/fake_jpeg_decode_accelerator.cc
@@ -73,8 +73,8 @@
 
   client_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&FakeJpegDecodeAccelerator::OnDecodeDoneOnClientThread,
-                 weak_factory_.GetWeakPtr(), bitstream_buffer.id()));
+      base::BindOnce(&FakeJpegDecodeAccelerator::OnDecodeDoneOnClientThread,
+                     weak_factory_.GetWeakPtr(), bitstream_buffer.id()));
 }
 
 bool FakeJpegDecodeAccelerator::IsSupported() {
@@ -85,8 +85,8 @@
                                             Error error) {
   client_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&FakeJpegDecodeAccelerator::NotifyErrorOnClientThread,
-                 weak_factory_.GetWeakPtr(), bitstream_buffer_id, error));
+      base::BindOnce(&FakeJpegDecodeAccelerator::NotifyErrorOnClientThread,
+                     weak_factory_.GetWeakPtr(), bitstream_buffer_id, error));
 }
 
 void FakeJpegDecodeAccelerator::NotifyErrorOnClientThread(
diff --git a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc
index 9e52104..7da45b4 100644
--- a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc
+++ b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc
@@ -191,8 +191,8 @@
 
   // The gpu::CommandBufferProxyImpl is going away; error out this VDA.
   media_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&GpuVideoDecodeAcceleratorHost::OnChannelError, weak_this_));
+      FROM_HERE, base::BindOnce(&GpuVideoDecodeAcceleratorHost::OnChannelError,
+                                weak_this_));
 }
 
 void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) {
diff --git a/media/gpu/test/video_decode_accelerator_unittest_helpers.cc b/media/gpu/test/video_decode_accelerator_unittest_helpers.cc
index 7be76e6b..5e05151d 100644
--- a/media/gpu/test/video_decode_accelerator_unittest_helpers.cc
+++ b/media/gpu/test/video_decode_accelerator_unittest_helpers.cc
@@ -43,8 +43,8 @@
   base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
   rendering_thread_.task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&RenderingHelper::InitializeOneOff, use_gl_renderer_, &done));
+      FROM_HERE, base::BindOnce(&RenderingHelper::InitializeOneOff,
+                                use_gl_renderer_, &done));
   done.Wait();
 
 #if defined(OS_CHROMEOS)
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 93e656c..099746f 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -304,8 +304,8 @@
 
   // StartDevicePoll will NotifyError on failure.
   device_thread_.task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&V4L2ImageProcessor::StartDevicePoll, base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&V4L2ImageProcessor::StartDevicePoll,
+                                base::Unretained(this)));
 
   VLOGF(2) << "V4L2ImageProcessor initialized for "
            << "input_layout: " << input_layout_
@@ -464,8 +464,8 @@
         FROM_HERE, base::BindOnce(&V4L2ImageProcessor::StopDevicePoll,
                                   base::Unretained(this)));
     device_thread_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&V4L2ImageProcessor::DestroyBuffersTask,
-                              base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&V4L2ImageProcessor::DestroyBuffersTask,
+                                  base::Unretained(this)));
     // Wait for tasks to finish/early-exit.
     device_thread_.Stop();
   } else {
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
index cee54f6..14a318f 100644
--- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -126,8 +126,9 @@
     DVLOGF(5) << "returning input_id: " << input_id;
     client_task_runner->PostTask(
         FROM_HERE,
-        base::Bind(&VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer,
-                   client, input_id));
+        base::BindOnce(
+            &VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, client,
+            input_id));
   }
 }
 
@@ -540,9 +541,9 @@
 
   child_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VideoDecodeAccelerator::Client::ProvidePictureBuffers,
-                 client_, num_pictures, pixel_format, 1, coded_size_,
-                 device_->GetTextureTarget()));
+      base::BindOnce(&VideoDecodeAccelerator::Client::ProvidePictureBuffers,
+                     client_, num_pictures, pixel_format, 1, coded_size_,
+                     device_->GetTextureTarget()));
 
   // Go into kAwaitingPictureBuffers to prevent us from doing any more decoding
   // or event handling while we are waiting for AssignPictureBuffers(). Not
@@ -1122,8 +1123,8 @@
   if (state_ == kDecoding) {
     decoder_thread_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&V4L2SliceVideoDecodeAccelerator::DecodeBufferTask,
-                   base::Unretained(this)));
+        base::BindOnce(&V4L2SliceVideoDecodeAccelerator::DecodeBufferTask,
+                       base::Unretained(this)));
   }
 }
 
@@ -1322,8 +1323,8 @@
 
   decoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask,
-                 base::Unretained(this), buffers));
+      base::BindOnce(&V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask,
+                     base::Unretained(this), buffers));
 }
 
 void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
@@ -1632,9 +1633,9 @@
 
   decoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2SliceVideoDecodeAccelerator::ReusePictureBufferTask,
-                 base::Unretained(this), picture_buffer_id,
-                 base::Passed(&egl_fence)));
+      base::BindOnce(&V4L2SliceVideoDecodeAccelerator::ReusePictureBufferTask,
+                     base::Unretained(this), picture_buffer_id,
+                     std::move(egl_fence)));
 }
 
 void V4L2SliceVideoDecodeAccelerator::ReusePictureBufferTask(
@@ -1753,8 +1754,8 @@
   decoder_flushing_ = false;
   VLOGF(2) << "Flush finished";
 
-  child_task_runner_->PostTask(FROM_HERE,
-                               base::Bind(&Client::NotifyFlushDone, client_));
+  child_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Client::NotifyFlushDone, client_));
 
   TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2SVDA Flush", this);
   return true;
@@ -1830,8 +1831,8 @@
   decoder_resetting_ = false;
   VLOGF(2) << "Reset finished";
 
-  child_task_runner_->PostTask(FROM_HERE,
-                               base::Bind(&Client::NotifyResetDone, client_));
+  child_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Client::NotifyResetDone, client_));
 
   TRACE_EVENT_ASYNC_END0("media,gpu", "V4L2SVDA Reset", this);
   return true;
@@ -2018,7 +2019,7 @@
       // all pictures are cleared at the beginning.
       decode_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(&Client::PictureReady, decode_client_, picture));
+          base::BindOnce(&Client::PictureReady, decode_client_, picture));
       pending_picture_ready_.pop();
     } else if (!cleared || send_now) {
       DVLOGF(4) << "cleared=" << pending_picture_ready_.front().cleared
diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
index 4ba7f87..48d8fca 100644
--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
@@ -115,7 +115,7 @@
   if (input_id >= 0) {
     client_task_runner->PostTask(
         FROM_HERE,
-        base::Bind(&Client::NotifyEndOfBitstreamBuffer, client, input_id));
+        base::BindOnce(&Client::NotifyEndOfBitstreamBuffer, client, input_id));
   }
 }
 
@@ -344,8 +344,8 @@
 
   decoder_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask,
-                 base::Unretained(this), buffers));
+      base::BindOnce(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask,
+                     base::Unretained(this), buffers));
 }
 
 void V4L2VideoDecodeAccelerator::AssignPictureBuffersTask(
@@ -494,9 +494,9 @@
   }
 
   decoder_thread_.task_runner()->PostTask(
-      FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::AssignEGLImage,
-                            base::Unretained(this), buffer_index,
-                            picture_buffer_id, egl_image));
+      FROM_HERE, base::BindOnce(&V4L2VideoDecodeAccelerator::AssignEGLImage,
+                                base::Unretained(this), buffer_index,
+                                picture_buffer_id, egl_image));
 }
 
 void V4L2VideoDecodeAccelerator::AssignEGLImage(size_t buffer_index,
@@ -601,9 +601,9 @@
 
   decoder_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2VideoDecodeAccelerator::ImportBufferForPictureTask,
-                 base::Unretained(this), picture_buffer_id,
-                 base::Passed(&dmabuf_fds), stride));
+      base::BindOnce(&V4L2VideoDecodeAccelerator::ImportBufferForPictureTask,
+                     base::Unretained(this), picture_buffer_id,
+                     std::move(dmabuf_fds), stride));
 }
 
 void V4L2VideoDecodeAccelerator::ImportBufferForPictureTask(
@@ -680,8 +680,8 @@
     if (iter->egl_image != EGL_NO_IMAGE_KHR) {
       child_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_,
-                     egl_display_, iter->egl_image));
+          base::BindOnce(base::IgnoreResult(&V4L2Device::DestroyEGLImage),
+                         device_, egl_display_, iter->egl_image));
     }
 
     size_t index = iter - output_buffer_map_.begin();
@@ -694,7 +694,7 @@
           FROM_HERE,
           base::BindOnce(&V4L2VideoDecodeAccelerator::CreateEGLImageFor,
                          weak_this_, index, picture_buffer_id,
-                         base::Passed(&dmabuf_fds), iter->texture_id,
+                         std::move(dmabuf_fds), iter->texture_id,
                          egl_image_size_, egl_image_format_fourcc_));
 
       // Early return, AssignEGLImage will make the buffer available for
@@ -741,7 +741,7 @@
       FROM_HERE,
       base::BindOnce(&V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
                      base::Unretained(this), picture_buffer_id,
-                     base::Passed(&egl_fence)));
+                     std::move(egl_fence)));
 }
 
 void V4L2VideoDecodeAccelerator::Flush() {
@@ -1317,8 +1317,8 @@
 
         decoder_thread_.task_runner()->PostDelayedTask(
             FROM_HERE,
-            base::Bind(&V4L2VideoDecodeAccelerator::Enqueue,
-                       base::Unretained(this)),
+            base::BindOnce(&V4L2VideoDecodeAccelerator::Enqueue,
+                           base::Unretained(this)),
             base::TimeDelta::FromMilliseconds(resched_delay));
       }
       break;
@@ -1719,8 +1719,8 @@
   decoder_delay_bitstream_buffer_id_ = -1;
   decoder_flushing_ = false;
   VLOGF(2) << "returning flush";
-  child_task_runner_->PostTask(FROM_HERE,
-                               base::Bind(&Client::NotifyFlushDone, client_));
+  child_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Client::NotifyFlushDone, client_));
 }
 
 bool V4L2VideoDecodeAccelerator::IsDecoderCmdSupported() {
@@ -1859,8 +1859,8 @@
 
   decoder_partial_frame_pending_ = false;
   decoder_delay_bitstream_buffer_id_ = -1;
-  child_task_runner_->PostTask(FROM_HERE,
-                               base::Bind(&Client::NotifyResetDone, client_));
+  child_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Client::NotifyResetDone, client_));
 
   // While we were resetting, we early-outed DecodeBufferTask()s.
   ScheduleDecodeBufferTaskIfNeeded();
@@ -2576,8 +2576,8 @@
     if (output_record.egl_image != EGL_NO_IMAGE_KHR) {
       child_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_,
-                     egl_display_, output_record.egl_image));
+          base::BindOnce(base::IgnoreResult(&V4L2Device::DestroyEGLImage),
+                         device_, egl_display_, output_record.egl_image));
     }
 
     DVLOGF(3) << "dismissing PictureBuffer id=" << output_record.picture_id;
@@ -2638,7 +2638,7 @@
       // all pictures are cleared at the beginning.
       decode_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(&Client::PictureReady, decode_client_, picture));
+          base::BindOnce(&Client::PictureReady, decode_client_, picture));
       pending_picture_ready_.pop();
     } else if (!cleared || send_now) {
       DVLOGF(4) << "cleared=" << pending_picture_ready_.front().cleared
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index 59b22c68..934d36fd 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -294,11 +294,11 @@
 
   child_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Client::RequireBitstreamBuffers, client_, kInputBufferCount,
-                 image_processor_.get()
-                     ? image_processor_->input_layout().coded_size()
-                     : input_allocated_size_,
-                 output_buffer_byte_size_));
+      base::BindOnce(
+          &Client::RequireBitstreamBuffers, client_, kInputBufferCount,
+          image_processor_.get() ? image_processor_->input_layout().coded_size()
+                                 : input_allocated_size_,
+          output_buffer_byte_size_));
   return true;
 }
 
@@ -437,8 +437,8 @@
       new BitstreamBufferRef(buffer.id(), std::move(shm)));
   encoder_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
-                 base::Unretained(this), base::Passed(&buffer_ref)));
+      base::BindOnce(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
+                     base::Unretained(this), std::move(buffer_ref)));
 }
 
 void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange(
@@ -449,7 +449,7 @@
 
   encoder_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask,
           base::Unretained(this), bitrate, framerate));
 }
@@ -494,7 +494,7 @@
   encoder_thread_.task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(&V4L2VideoEncodeAccelerator::FlushTask,
-                     base::Unretained(this), base::Passed(&flush_callback)));
+                     base::Unretained(this), std::move(flush_callback)));
 }
 
 void V4L2VideoEncodeAccelerator::FlushTask(FlushCallback flush_callback) {
@@ -865,13 +865,14 @@
 
     child_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Client::BitstreamBufferReady, client_, bitstream_buffer_id,
-                   BitstreamBufferMetadata(
-                       output_data_size, key_frame,
-                       base::TimeDelta::FromMicroseconds(
-                           dqbuf.timestamp.tv_usec +
-                           dqbuf.timestamp.tv_sec *
-                               base::Time::kMicrosecondsPerSecond))));
+        base::BindOnce(&Client::BitstreamBufferReady, client_,
+                       bitstream_buffer_id,
+                       BitstreamBufferMetadata(
+                           output_data_size, key_frame,
+                           base::TimeDelta::FromMicroseconds(
+                               dqbuf.timestamp.tv_usec +
+                               dqbuf.timestamp.tv_sec *
+                                   base::Time::kMicrosecondsPerSecond))));
     if ((encoder_state_ == kFlushing) && (dqbuf.flags & V4L2_BUF_FLAG_LAST)) {
       // Notify client that flush has finished successfully. The flush callback
       // should be called after notifying the last buffer is ready.
@@ -1128,9 +1129,9 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       encoder_thread_.task_runner();
   if (task_runner && !task_runner->BelongsToCurrentThread()) {
-    task_runner->PostTask(FROM_HERE,
-                          base::Bind(&V4L2VideoEncodeAccelerator::SetErrorState,
-                                     base::Unretained(this), error));
+    task_runner->PostTask(
+        FROM_HERE, base::BindOnce(&V4L2VideoEncodeAccelerator::SetErrorState,
+                                  base::Unretained(this), error));
     return;
   }
 
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
index 6153aed..046b9348 100644
--- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -322,8 +322,8 @@
     VLOGF(1) << "Failed to map output buffer";
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VaapiJpegEncodeAccelerator::NotifyError, weak_this_,
-                   buffer_id, INACCESSIBLE_OUTPUT_BUFFER));
+        base::BindOnce(&VaapiJpegEncodeAccelerator::NotifyError, weak_this_,
+                       buffer_id, INACCESSIBLE_OUTPUT_BUFFER));
     return;
   }
 
@@ -333,8 +333,8 @@
 
   encoder_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VaapiJpegEncodeAccelerator::Encoder::EncodeTask,
-                 base::Unretained(encoder_.get()), base::Passed(&request)));
+      base::BindOnce(&VaapiJpegEncodeAccelerator::Encoder::EncodeTask,
+                     base::Unretained(encoder_.get()), std::move(request)));
 }
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
index 600a196..766bca3a 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -146,9 +146,9 @@
 void VaapiVideoDecodeAccelerator::NotifyError(Error error) {
   if (!task_runner_->BelongsToCurrentThread()) {
     DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&VaapiVideoDecodeAccelerator::NotifyError,
-                                      weak_this_, error));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&VaapiVideoDecodeAccelerator::NotifyError,
+                                  weak_this_, error));
     return;
   }
 
@@ -476,10 +476,10 @@
         VLOGF(2) << "Decoder requesting a new set of surfaces";
         task_runner_->PostTask(
             FROM_HERE,
-            base::Bind(&VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange,
-                       weak_this_, decoder_->GetRequiredNumOfPictures(),
-                       decoder_->GetPicSize(),
-                       decoder_->GetNumReferenceFrames()));
+            base::BindOnce(
+                &VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange,
+                weak_this_, decoder_->GetRequiredNumOfPictures(),
+                decoder_->GetPicSize(), decoder_->GetNumReferenceFrames()));
         // We'll get rescheduled once ProvidePictureBuffers() finishes.
         return;
 
@@ -577,8 +577,8 @@
     DVLOGF(2) << "Awaiting pending output/surface release callbacks to finish";
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange,
-                   weak_this_));
+        base::BindOnce(&VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange,
+                       weak_this_));
     return;
   }
 
@@ -821,7 +821,7 @@
 
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VaapiVideoDecodeAccelerator::FinishFlush, weak_this_));
+      base::BindOnce(&VaapiVideoDecodeAccelerator::FinishFlush, weak_this_));
 }
 
 void VaapiVideoDecodeAccelerator::Flush() {
@@ -860,7 +860,7 @@
   }
 
   task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&Client::NotifyFlushDone, client_));
+                         base::BindOnce(&Client::NotifyFlushDone, client_));
 }
 
 void VaapiVideoDecodeAccelerator::ResetTask() {
@@ -881,7 +881,7 @@
   // And let client know that we are done with reset.
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
+      base::BindOnce(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
 }
 
 void VaapiVideoDecodeAccelerator::Reset() {
@@ -926,14 +926,14 @@
     // Let the surface set change finish first before resetting.
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
+        base::BindOnce(&VaapiVideoDecodeAccelerator::FinishReset, weak_this_));
     return;
   }
 
   state_ = kIdle;
 
   task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&Client::NotifyResetDone, client_));
+                         base::BindOnce(&Client::NotifyResetDone, client_));
 
   // The client might have given us new buffers via Decode() while we were
   // resetting and might be waiting for our move, and not call Decode() anymore
@@ -998,8 +998,8 @@
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VaapiVideoDecodeAccelerator::SurfaceReady, weak_this_,
-                   dec_surface, bitstream_id, visible_rect, color_space));
+        base::BindOnce(&VaapiVideoDecodeAccelerator::SurfaceReady, weak_this_,
+                       dec_surface, bitstream_id, visible_rect, color_space));
     return;
   }
 
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index eb8c68de..7930e98 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -644,8 +644,8 @@
 
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VaapiVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
-                 base::Unretained(this), base::Passed(&buffer_ref)));
+      base::BindOnce(&VaapiVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
+                     base::Unretained(this), std::move(buffer_ref)));
 }
 
 void VaapiVideoEncodeAccelerator::UseOutputBitstreamBufferTask(
@@ -672,7 +672,7 @@
   allocation.SetBitrate(0, 0, bitrate);
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &VaapiVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
           base::Unretained(this), allocation, framerate));
 }
@@ -686,7 +686,7 @@
 
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &VaapiVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
           base::Unretained(this), bitrate_allocation, framerate));
 }
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc
index 15fb11f..396d3f7c 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -893,7 +893,7 @@
   if (config_.decode_calls_per_second > 0) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()),
+        base::BindOnce(&GLRenderingVDAClient::DecodeNextFragment, AsWeakPtr()),
         base::TimeDelta::FromSeconds(1) / config_.decode_calls_per_second);
   } else {
     // Unless DecodeNextFragment() is posted from the above PostDelayedTask(),
@@ -986,17 +986,16 @@
 void VideoDecodeAcceleratorTest::TearDown() {
   // |clients_| must be deleted first because |clients_| use |notes_|.
   g_env->GetRenderingTaskRunner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&Delete<ClientsVector>, base::Passed(&clients_)));
+      FROM_HERE, base::BindOnce(&Delete<ClientsVector>, std::move(clients_)));
 
   g_env->GetRenderingTaskRunner()->PostTask(
-      FROM_HERE, base::BindOnce(&Delete<NotesVector>, base::Passed(&notes_)));
+      FROM_HERE, base::BindOnce(&Delete<NotesVector>, std::move(notes_)));
 
   WaitUntilIdle();
 
   g_env->GetRenderingTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&Delete<TestFilesVector>, base::Passed(&test_video_files_)));
+      base::BindOnce(&Delete<TestFilesVector>, std::move(test_video_files_)));
 
   base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -1083,9 +1082,9 @@
   base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
   g_env->GetRenderingTaskRunner()->PostTask(
-      FROM_HERE,
-      base::Bind(&RenderingHelper::Initialize,
-                 base::Unretained(&rendering_helper_), helper_params, &done));
+      FROM_HERE, base::BindOnce(&RenderingHelper::Initialize,
+                                base::Unretained(&rendering_helper_),
+                                helper_params, &done));
   done.Wait();
 }
 
@@ -1114,7 +1113,7 @@
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
   g_env->GetRenderingTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
+      base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&done)));
   done.Wait();
 }
 
@@ -1389,8 +1388,8 @@
                              base::WaitableEvent::InitialState::NOT_SIGNALED);
     g_env->GetRenderingTaskRunner()->PostTask(
         FROM_HERE,
-        base::Bind(&RenderingHelper::GetThumbnailsAsRGBA,
-                   base::Unretained(&rendering_helper_), &rgba, &done));
+        base::BindOnce(&RenderingHelper::GetThumbnailsAsRGBA,
+                       base::Unretained(&rendering_helper_), &rgba, &done));
     done.Wait();
 
     std::vector<unsigned char> rgb;
diff --git a/media/gpu/vt_video_decode_accelerator_mac.cc b/media/gpu/vt_video_decode_accelerator_mac.cc
index 3ae5854..31759324 100644
--- a/media/gpu/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/vt_video_decode_accelerator_mac.cc
@@ -854,8 +854,8 @@
   // no image.
   if (!frame->has_slice) {
     gpu_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame));
+        FROM_HERE, base::BindOnce(&VTVideoDecodeAccelerator::DecodeDone,
+                                  weak_this_, frame));
     return;
   }
 
@@ -1010,7 +1010,7 @@
   frame->image.reset(image_buffer, base::scoped_policy::RETAIN);
   gpu_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame));
+      base::BindOnce(&VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame));
 }
 
 void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) {
@@ -1057,7 +1057,7 @@
   // Queue a task even if flushing fails, so that destruction always completes.
   gpu_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type));
+      base::BindOnce(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type));
 }
 
 void VTVideoDecodeAccelerator::FlushDone(TaskType type) {
@@ -1121,7 +1121,7 @@
   // future work after that happens.
   gpu_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VTVideoDecodeAccelerator::ProcessWorkQueues, weak_this_));
+      base::BindOnce(&VTVideoDecodeAccelerator::ProcessWorkQueues, weak_this_));
 }
 
 void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
@@ -1357,8 +1357,8 @@
   if (!gpu_task_runner_->BelongsToCurrentThread()) {
     gpu_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&VTVideoDecodeAccelerator::NotifyError, weak_this_,
-                   vda_error_type, session_failure_type));
+        base::BindOnce(&VTVideoDecodeAccelerator::NotifyError, weak_this_,
+                       vda_error_type, session_failure_type));
   } else if (state_ == STATE_DECODING) {
     state_ = STATE_ERROR;
     UMA_HISTOGRAM_ENUMERATION("Media.VTVDA.SessionFailureReason",
diff --git a/media/gpu/vt_video_encode_accelerator_mac.cc b/media/gpu/vt_video_encode_accelerator_mac.cc
index b604b0d0..d3fce17 100644
--- a/media/gpu/vt_video_encode_accelerator_mac.cc
+++ b/media/gpu/vt_video_encode_accelerator_mac.cc
@@ -171,9 +171,9 @@
   }
 
   client_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&Client::RequireBitstreamBuffers, client_, kNumInputBuffers,
-                 input_visible_size_, bitstream_buffer_size_));
+      FROM_HERE, base::BindOnce(&Client::RequireBitstreamBuffers, client_,
+                                kNumInputBuffers, input_visible_size_,
+                                bitstream_buffer_size_));
   return true;
 }
 
@@ -212,8 +212,8 @@
 
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VTVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
-                 base::Unretained(this), base::Passed(&buffer_ref)));
+      base::BindOnce(&VTVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
+                     base::Unretained(this), std::move(buffer_ref)));
 }
 
 void VTVideoEncodeAccelerator::RequestEncodingParametersChange(
@@ -225,8 +225,9 @@
 
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&VTVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
-                 base::Unretained(this), bitrate, framerate));
+      base::BindOnce(
+          &VTVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
+          base::Unretained(this), bitrate, framerate));
 }
 
 void VTVideoEncodeAccelerator::Destroy() {
@@ -398,7 +399,7 @@
       FROM_HERE,
       base::BindOnce(&VTVideoEncodeAccelerator::CompressionCallbackTask,
                      encoder->encoder_weak_ptr_, status,
-                     base::Passed(&encode_output)));
+                     std::move(encode_output)));
 }
 
 void VTVideoEncodeAccelerator::CompressionCallbackTask(
@@ -435,9 +436,9 @@
     DVLOG(2) << " frame dropped";
     client_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id,
-                   BitstreamBufferMetadata(0, false,
-                                           encode_output->capture_timestamp)));
+        base::BindOnce(&Client::BitstreamBufferReady, client_, buffer_ref->id,
+                       BitstreamBufferMetadata(
+                           0, false, encode_output->capture_timestamp)));
     return;
   }
 
@@ -460,9 +461,10 @@
 
   client_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Client::BitstreamBufferReady, client_, buffer_ref->id,
-                 BitstreamBufferMetadata(used_buffer_size, keyframe,
-                                         encode_output->capture_timestamp)));
+      base::BindOnce(
+          &Client::BitstreamBufferReady, client_, buffer_ref->id,
+          BitstreamBufferMetadata(used_buffer_size, keyframe,
+                                  encode_output->capture_timestamp)));
 }
 
 bool VTVideoEncodeAccelerator::ResetCompressionSession() {
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
index b125415..a493a9b 100644
--- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
+++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -290,7 +290,7 @@
       new BitstreamBufferRef(buffer.id(), std::move(shm), buffer.size()));
   encoder_thread_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &MediaFoundationVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
           encoder_task_weak_factory_.GetWeakPtr(), base::Passed(&buffer_ref)));
 }
@@ -303,10 +303,10 @@
   DCHECK(main_client_task_runner_->BelongsToCurrentThread());
 
   encoder_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&MediaFoundationVideoEncodeAccelerator::
-                     RequestEncodingParametersChangeTask,
-                 encoder_task_weak_factory_.GetWeakPtr(), bitrate, framerate));
+      FROM_HERE, base::BindOnce(&MediaFoundationVideoEncodeAccelerator::
+                                    RequestEncodingParametersChangeTask,
+                                encoder_task_weak_factory_.GetWeakPtr(),
+                                bitrate, framerate));
 }
 
 void MediaFoundationVideoEncodeAccelerator::Destroy() {
@@ -319,8 +319,8 @@
   if (encoder_thread_.IsRunning()) {
     encoder_thread_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&MediaFoundationVideoEncodeAccelerator::DestroyTask,
-                   encoder_task_weak_factory_.GetWeakPtr()));
+        base::BindOnce(&MediaFoundationVideoEncodeAccelerator::DestroyTask,
+                       encoder_task_weak_factory_.GetWeakPtr()));
     encoder_thread_.Stop();
   }
 
@@ -666,8 +666,9 @@
 
   main_client_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Client::BitstreamBufferReady, main_client_, buffer_ref->id,
-                 BitstreamBufferMetadata(size, keyframe, timestamp)));
+      base::BindOnce(&Client::BitstreamBufferReady, main_client_,
+                     buffer_ref->id,
+                     BitstreamBufferMetadata(size, keyframe, timestamp)));
 
   // Keep calling ProcessOutput recursively until MF_E_TRANSFORM_NEED_MORE_INPUT
   // is returned to flush out all the output.
@@ -702,10 +703,11 @@
          encode_output->size());
   main_client_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Client::BitstreamBufferReady, main_client_, buffer_ref->id,
-                 BitstreamBufferMetadata(encode_output->size(),
-                                         encode_output->keyframe,
-                                         encode_output->capture_timestamp)));
+      base::BindOnce(&Client::BitstreamBufferReady, main_client_,
+                     buffer_ref->id,
+                     BitstreamBufferMetadata(
+                         encode_output->size(), encode_output->keyframe,
+                         encode_output->capture_timestamp)));
 }
 
 void MediaFoundationVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
diff --git a/media/mojo/clients/mojo_audio_decoder.cc b/media/mojo/clients/mojo_audio_decoder.cc
index c10d8bcd..cbbf36a 100644
--- a/media/mojo/clients/mojo_audio_decoder.cc
+++ b/media/mojo/clients/mojo_audio_decoder.cc
@@ -88,16 +88,16 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   if (remote_decoder_.encountered_error()) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(decode_cb, DecodeStatus::DECODE_ERROR));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(decode_cb, DecodeStatus::DECODE_ERROR));
     return;
   }
 
   mojom::DecoderBufferPtr buffer =
       mojo_decoder_buffer_writer_->WriteDecoderBuffer(std::move(media_buffer));
   if (!buffer) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(decode_cb, DecodeStatus::DECODE_ERROR));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(decode_cb, DecodeStatus::DECODE_ERROR));
     return;
   }
 
diff --git a/media/mojo/clients/mojo_audio_decoder_unittest.cc b/media/mojo/clients/mojo_audio_decoder_unittest.cc
index aa7b71d94..00f2fe3 100644
--- a/media/mojo/clients/mojo_audio_decoder_unittest.cc
+++ b/media/mojo/clients/mojo_audio_decoder_unittest.cc
@@ -60,9 +60,9 @@
     mojom::AudioDecoderPtr remote_audio_decoder;
     service_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&MojoAudioDecoderTest::ConnectToService,
-                   base::Unretained(this),
-                   base::Passed(mojo::MakeRequest(&remote_audio_decoder))));
+        base::BindOnce(&MojoAudioDecoderTest::ConnectToService,
+                       base::Unretained(this),
+                       base::Passed(mojo::MakeRequest(&remote_audio_decoder))));
     mojo_audio_decoder_.reset(new MojoAudioDecoder(
         message_loop_.task_runner(), std::move(remote_audio_decoder)));
   }
diff --git a/media/mojo/clients/mojo_cdm.cc b/media/mojo/clients/mojo_cdm.cc
index cbe9ed3..b883ecc2 100644
--- a/media/mojo/clients/mojo_cdm.cc
+++ b/media/mojo/clients/mojo_cdm.cc
@@ -364,7 +364,7 @@
       DCHECK(decryptor_task_runner_);
       decryptor_task_runner_->PostTask(
           FROM_HERE,
-          base::Bind(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr()));
+          base::BindOnce(&MojoCdm::OnKeyAdded, weak_factory_.GetWeakPtr()));
     }
   }
 
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc
index d9021e22..59696c18 100644
--- a/media/mojo/clients/mojo_video_decoder.cc
+++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -216,7 +216,7 @@
 
   if (has_connection_error_) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(bound_decode_cb, DecodeStatus::DECODE_ERROR));
+        FROM_HERE, base::BindOnce(bound_decode_cb, DecodeStatus::DECODE_ERROR));
     return;
   }
 
@@ -224,7 +224,7 @@
       mojo_decoder_buffer_writer_->WriteDecoderBuffer(std::move(buffer));
   if (!mojo_buffer) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(bound_decode_cb, DecodeStatus::DECODE_ERROR));
+        FROM_HERE, base::BindOnce(bound_decode_cb, DecodeStatus::DECODE_ERROR));
     return;
   }
 
diff --git a/media/remoting/courier_renderer.cc b/media/remoting/courier_renderer.cc
index 7c4a4be..b52a4d2 100644
--- a/media/remoting/courier_renderer.cc
+++ b/media/remoting/courier_renderer.cc
@@ -144,7 +144,7 @@
       FROM_HERE,
       base::BindOnce(
           &RendererController::StartDataPipe, controller_,
-          base::Passed(&audio_data_pipe), base::Passed(&video_data_pipe),
+          std::move(audio_data_pipe), std::move(video_data_pipe),
           base::BindOnce(&CourierRenderer::OnDataPipeCreatedOnMainThread,
                          media_task_runner_, weak_factory_.GetWeakPtr(),
                          rpc_broker_)));
@@ -295,13 +295,13 @@
     mojo::ScopedDataPipeProducerHandle video_handle) {
   media_task_runner->PostTask(
       FROM_HERE,
-      base::Bind(&CourierRenderer::OnDataPipeCreated, self,
-                 base::Passed(&audio), base::Passed(&video),
-                 base::Passed(&audio_handle), base::Passed(&video_handle),
-                 rpc_broker ? rpc_broker->GetUniqueHandle()
-                            : RpcBroker::kInvalidHandle,
-                 rpc_broker ? rpc_broker->GetUniqueHandle()
-                            : RpcBroker::kInvalidHandle));
+      base::BindOnce(&CourierRenderer::OnDataPipeCreated, self,
+                     std::move(audio), std::move(video),
+                     std::move(audio_handle), std::move(video_handle),
+                     rpc_broker ? rpc_broker->GetUniqueHandle()
+                                : RpcBroker::kInvalidHandle,
+                     rpc_broker ? rpc_broker->GetUniqueHandle()
+                                : RpcBroker::kInvalidHandle));
 }
 
 void CourierRenderer::OnDataPipeCreated(
@@ -370,9 +370,9 @@
     scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
     base::WeakPtr<CourierRenderer> self,
     std::unique_ptr<pb::RpcMessage> message) {
-  media_task_runner->PostTask(FROM_HERE,
-                              base::Bind(&CourierRenderer::OnReceivedRpc, self,
-                                         base::Passed(&message)));
+  media_task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&CourierRenderer::OnReceivedRpc, self,
+                                std::move(message)));
 }
 
 void CourierRenderer::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) {
@@ -438,7 +438,7 @@
   DCHECK(main_task_runner_);
   main_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&RpcBroker::SendMessageToRemote, rpc_broker_,
-                                base::Passed(&message)));
+                                std::move(message)));
 }
 
 void CourierRenderer::AcquireRendererDone(
diff --git a/media/remoting/demuxer_stream_adapter.cc b/media/remoting/demuxer_stream_adapter.cc
index 543c836..d685206 100644
--- a/media/remoting/demuxer_stream_adapter.cc
+++ b/media/remoting/demuxer_stream_adapter.cc
@@ -329,9 +329,9 @@
 
   // Contiune to read decoder buffer until reaching |read_until_count_| or
   // end of stream.
-  media_task_runner_->PostTask(FROM_HERE,
-                               base::Bind(&DemuxerStreamAdapter::RequestBuffer,
-                                          weak_factory_.GetWeakPtr()));
+  media_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&DemuxerStreamAdapter::RequestBuffer,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void DemuxerStreamAdapter::SendReadAck() {
diff --git a/media/remoting/fake_remoter.cc b/media/remoting/fake_remoter.cc
index 5e35242..6e9f16a 100644
--- a/media/remoting/fake_remoter.cc
+++ b/media/remoting/fake_remoter.cc
@@ -124,11 +124,11 @@
   if (start_will_fail_) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
+        base::BindOnce(&FakeRemoter::StartFailed, weak_factory_.GetWeakPtr()));
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&FakeRemoter::Started, weak_factory_.GetWeakPtr()));
+        base::BindOnce(&FakeRemoter::Started, weak_factory_.GetWeakPtr()));
   }
 }
 
@@ -152,8 +152,8 @@
 
 void FakeRemoter::Stop(mojom::RemotingStopReason reason) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&FakeRemoter::Stopped, weak_factory_.GetWeakPtr(), reason));
+      FROM_HERE, base::BindOnce(&FakeRemoter::Stopped,
+                                weak_factory_.GetWeakPtr(), reason));
 }
 
 void FakeRemoter::SendMessageToSink(const std::vector<uint8_t>& message) {}
diff --git a/media/test/test_media_source.cc b/media/test/test_media_source.cc
index 4385951..63bdd9f1 100644
--- a/media/test/test_media_source.cc
+++ b/media/test/test_media_source.cc
@@ -213,8 +213,8 @@
 
 void TestMediaSource::DemuxerOpened() {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&TestMediaSource::DemuxerOpenedTask, base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&TestMediaSource::DemuxerOpenedTask,
+                                base::Unretained(this)));
 }
 
 void TestMediaSource::DemuxerOpenedTask() {
diff --git a/media/video/fake_video_encode_accelerator.cc b/media/video/fake_video_encode_accelerator.cc
index cbff69a..1a31113 100644
--- a/media/video/fake_video_encode_accelerator.cc
+++ b/media/video/fake_video_encode_accelerator.cc
@@ -52,9 +52,9 @@
   client_ = client;
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers,
-                 weak_this_factory_.GetWeakPtr(), kMinimumInputCount,
-                 config.input_visible_size, kMinimumOutputBufferSize));
+      base::BindOnce(&FakeVideoEncodeAccelerator::DoRequireBitstreamBuffers,
+                     weak_this_factory_.GetWeakPtr(), kMinimumInputCount,
+                     config.input_visible_size, kMinimumOutputBufferSize));
   return true;
 }
 
@@ -88,12 +88,9 @@
 
 void FakeVideoEncodeAccelerator::SendDummyFrameForTesting(bool key_frame) {
   task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
-                   weak_this_factory_.GetWeakPtr(),
-                   0,
-                   23,
-                   key_frame));
+      FROM_HERE,
+      base::BindOnce(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
+                     weak_this_factory_.GetWeakPtr(), 0, 23, key_frame));
 }
 
 void FakeVideoEncodeAccelerator::SetWillInitializationSucceed(
@@ -119,11 +116,9 @@
     next_frame_is_first_frame_ = false;
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
-                   weak_this_factory_.GetWeakPtr(),
-                   bitstream_buffer_id,
-                   kMinimumOutputBufferSize,
-                   key_frame));
+        base::BindOnce(&FakeVideoEncodeAccelerator::DoBitstreamBufferReady,
+                       weak_this_factory_.GetWeakPtr(), bitstream_buffer_id,
+                       kMinimumOutputBufferSize, key_frame));
   }
 }
 
diff --git a/mojo/public/tools/bindings/README.md b/mojo/public/tools/bindings/README.md
index 070d055..f409714 100644
--- a/mojo/public/tools/bindings/README.md
+++ b/mojo/public/tools/bindings/README.md
@@ -396,8 +396,9 @@
 :   The `Native` attribute may be specified for an empty struct declaration to
     provide a nominal bridge between Mojo IPC and legacy `IPC::ParamTraits` or
     `IPC_STRUCT_TRAITS*` macros.
-    See [Using Legacy IPC Traits](/ipc/README.md#Using-Legacy-IPC-Traits) for
-    more details. Note support for this attribute is strictly limited to C++
+    See
+    [Repurposing Legacy IPC Traits](/docs/mojo_ipc_conversion.md#repurposing-and-invocations)
+    for more details. Note support for this attribute is strictly limited to C++
     bindings generation.
 
 **`[MinVersion=N]`**
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index 0811064..125c60a 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -362,6 +362,12 @@
   }
 }
 
+size_t MockHostResolverBase::last_id() {
+  if (requests_.empty())
+    return 0;
+  return requests_.rbegin()->first;
+}
+
 void MockHostResolverBase::ResolveNow(size_t id) {
   auto it = requests_.find(id);
   if (it == requests_.end())
@@ -841,8 +847,12 @@
     : public HostResolver::Request,
       public HostResolver::ResolveHostRequest {
  public:
-  RequestImpl(base::WeakPtr<HangingHostResolver> resolver, bool is_running)
-      : resolver_(resolver), is_running_(is_running) {}
+  RequestImpl(base::WeakPtr<HangingHostResolver> resolver,
+              bool is_running,
+              bool is_local_only)
+      : resolver_(resolver),
+        is_running_(is_running),
+        is_local_only_(is_local_only) {}
 
   ~RequestImpl() override {
     if (is_running_ && resolver_)
@@ -851,27 +861,41 @@
 
   int Start(CompletionOnceCallback callback) override {
     DCHECK(resolver_);
+    if (is_local_only_)
+      return ERR_DNS_CACHE_MISS;
+
     is_running_ = true;
     return ERR_IO_PENDING;
   }
 
   const base::Optional<AddressList>& GetAddressResults() const override {
-    IMMEDIATE_CRASH();
+    DCHECK(is_local_only_);
+    static const base::NoDestructor<base::Optional<AddressList>> nullopt_result;
+    return *nullopt_result;
   }
 
   const base::Optional<std::vector<std::string>>& GetTextResults()
       const override {
-    IMMEDIATE_CRASH();
+    DCHECK(is_local_only_);
+    static const base::NoDestructor<base::Optional<std::vector<std::string>>>
+        nullopt_result;
+    return *nullopt_result;
   }
 
   const base::Optional<std::vector<HostPortPair>>& GetHostnameResults()
       const override {
-    IMMEDIATE_CRASH();
+    DCHECK(is_local_only_);
+    static const base::NoDestructor<base::Optional<std::vector<HostPortPair>>>
+        nullopt_result;
+    return *nullopt_result;
   }
 
   const base::Optional<HostCache::EntryStaleness>& GetStaleInfo()
       const override {
-    IMMEDIATE_CRASH();
+    DCHECK(is_local_only_);
+    static const base::NoDestructor<base::Optional<HostCache::EntryStaleness>>
+        nullopt_result;
+    return *nullopt_result;
   }
 
   void ChangeRequestPriority(RequestPriority priority) override {}
@@ -881,6 +905,7 @@
   // outstanding request objects.
   base::WeakPtr<HangingHostResolver> resolver_;
   bool is_running_;
+  bool is_local_only_;
 
   DISALLOW_COPY_AND_ASSIGN(RequestImpl);
 };
@@ -894,8 +919,12 @@
     const HostPortPair& host,
     const NetLogWithSource& source_net_log,
     const base::Optional<ResolveHostParameters>& optional_parameters) {
+  bool is_local_only =
+      optional_parameters
+          ? optional_parameters.value().source == HostResolverSource::LOCAL_ONLY
+          : false;
   return std::make_unique<RequestImpl>(weak_ptr_factory_.GetWeakPtr(),
-                                       false /* started */);
+                                       false /* started */, is_local_only);
 }
 
 int HangingHostResolver::Resolve(const RequestInfo& info,
@@ -905,7 +934,8 @@
                                  std::unique_ptr<Request>* request,
                                  const NetLogWithSource& net_log) {
   *request = std::make_unique<RequestImpl>(weak_ptr_factory_.GetWeakPtr(),
-                                           true /* started */);
+                                           true /* started */,
+                                           false /* is_local_only */);
   return ERR_IO_PENDING;
 }
 
diff --git a/net/dns/mock_host_resolver.h b/net/dns/mock_host_resolver.h
index 79c4dcf..6776741 100644
--- a/net/dns/mock_host_resolver.h
+++ b/net/dns/mock_host_resolver.h
@@ -151,6 +151,10 @@
   // for async resolution, starting with 1. IDs are not reused. Once a request
   // completes, it is destroyed, and can no longer be accessed.
 
+  // Returns the ID of the most recently started still-active request. Zero if
+  // no requests are currently active.
+  size_t last_id();
+
   // Resolve request stored in |requests_|. Pass rv to callback.
   void ResolveNow(size_t id);
 
@@ -389,7 +393,9 @@
 // Create rules that map all requests to localhost.
 RuleBasedHostResolverProc* CreateCatchAllHostResolverProc();
 
-// HangingHostResolver never completes its |Resolve| request.
+// HangingHostResolver never completes its |Resolve| request. As LOCAL_ONLY
+// requests are not allowed to complete asynchronously, they will always result
+// in |ERR_DNS_CACHE_MISS|.
 class HangingHostResolver : public HostResolver {
  public:
   HangingHostResolver();
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 1627942..ca9b002 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -524,7 +524,7 @@
       EXPECT_FALSE(test_delegate.has_result());
 
       MockHostResolverBase* host_resolver = session_deps_.host_resolver.get();
-      int request_id = host_resolver->num_resolve();
+      size_t request_id = host_resolver->last_id();
       EXPECT_EQ(initial_priority, host_resolver->request_priority(request_id));
 
       connect_job->ChangePriority(static_cast<RequestPriority>(new_priority));
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index fa0b7db..65056b0 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -67341,6 +67341,20 @@
     { "name": "tnwioa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "toddmissiontx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "townofruthnc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "tnrealid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "cityofmadera.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "jeffersonkyattorney.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "pittmancentertn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "usdoscloud.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "redmondoregon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "widoj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "banningca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "ocwr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "cwr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "sheriffmiamicountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "calcasieuparish.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "ncmedicaidplans.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+    { "name": "ncmedicaidplan.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     { "name": "bmoattachments.org", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
     // END OF ETLD-OWNER REQUESTED ENTRIES
 
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 014d434..5a1ec6a 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/bind.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
@@ -19,6 +20,8 @@
 #include "build/build_config.h"
 #include "net/base/address_list.h"
 #include "net/base/trace_constants.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/host_resolver_source.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_server_properties.h"
 #include "net/http/http_stream_request.h"
@@ -173,18 +176,19 @@
     return base::WeakPtr<SpdySession>();
 
   // Look up IP addresses from resolver cache.
-  HostResolver::RequestInfo resolve_info(key.host_port_pair());
-  AddressList addresses;
-  int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log);
+  HostResolver::ResolveHostParameters parameters;
+  parameters.source = HostResolverSource::LOCAL_ONLY;
+  std::unique_ptr<HostResolver::ResolveHostRequest> request =
+      resolver_->CreateRequest(key.host_port_pair(), net_log, parameters);
+
+  int rv = request->Start(base::BindOnce([](int error) { NOTREACHED(); }));
   DCHECK_NE(rv, ERR_IO_PENDING);
   if (rv != OK)
     return base::WeakPtr<SpdySession>();
 
   // Check if we have a session through a domain alias.
-  for (AddressList::const_iterator address_it = addresses.begin();
-       address_it != addresses.end();
-       ++address_it) {
-    auto range = aliases_.equal_range(*address_it);
+  for (const auto& address : request->GetAddressResults().value().endpoints()) {
+    auto range = aliases_.equal_range(address);
     for (auto alias_it = range.first; alias_it != range.second; ++alias_it) {
       // We found an alias.
       const SpdySessionKey& alias_key = alias_it->second;
diff --git a/net/third_party/quic/platform/impl/batch_writer/quic_batch_writer_test.h b/net/third_party/quic/platform/impl/batch_writer/quic_batch_writer_test.h
index aeb495a2..934df330 100644
--- a/net/third_party/quic/platform/impl/batch_writer/quic_batch_writer_test.h
+++ b/net/third_party/quic/platform/impl/batch_writer/quic_batch_writer_test.h
@@ -116,8 +116,6 @@
         if (packet_size <= data_size && (data_size / packet_size < 200)) {
           params.push_back({QuicMakeUnique<QuicUdpBatchWriterIOTestDelegateT>(),
                             address_family, data_size, packet_size});
-          params.push_back({QuicMakeUnique<QuicUdpBatchWriterIOTestDelegateT>(),
-                            address_family, data_size, packet_size});
         }
       }
     }
diff --git a/remoting/base/auto_thread.cc b/remoting/base/auto_thread.cc
index 0e9a6e5b..743254e 100644
--- a/remoting/base/auto_thread.cc
+++ b/remoting/base/auto_thread.cc
@@ -176,9 +176,9 @@
   was_quit_properly_ = true;
 
   if (joiner_.get()) {
-    joiner_->PostTask(
-        FROM_HERE,
-        base::Bind(&AutoThread::JoinAndDeleteThread, base::Unretained(this)));
+    joiner_->PostTask(FROM_HERE,
+                      base::BindOnce(&AutoThread::JoinAndDeleteThread,
+                                     base::Unretained(this)));
   }
 }
 
diff --git a/remoting/base/auto_thread_task_runner_unittest.cc b/remoting/base/auto_thread_task_runner_unittest.cc
index 2a31eb7..01e2ee35 100644
--- a/remoting/base/auto_thread_task_runner_unittest.cc
+++ b/remoting/base/auto_thread_task_runner_unittest.cc
@@ -30,7 +30,7 @@
   // Post a task to make sure it is executed.
   bool success = false;
   message_loop.task_runner()->PostTask(FROM_HERE,
-                                       base::Bind(&SetFlagTask, &success));
+                                       base::BindOnce(&SetFlagTask, &success));
 
   task_runner = NULL;
   run_loop.Run();
diff --git a/remoting/base/auto_thread_unittest.cc b/remoting/base/auto_thread_unittest.cc
index 595772e..350cc785 100644
--- a/remoting/base/auto_thread_unittest.cc
+++ b/remoting/base/auto_thread_unittest.cc
@@ -28,7 +28,7 @@
 void PostSetFlagTask(
     scoped_refptr<base::TaskRunner> task_runner,
     bool* success) {
-  task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, success));
+  task_runner->PostTask(FROM_HERE, base::BindOnce(&SetFlagTask, success));
 }
 
 #if defined(OS_WIN)
@@ -105,7 +105,7 @@
 
   // Post a task to it.
   bool success = false;
-  task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, &success));
+  task_runner->PostTask(FROM_HERE, base::BindOnce(&SetFlagTask, &success));
 
   task_runner = NULL;
   RunMessageLoop();
@@ -124,8 +124,8 @@
 
   // Post a task to thread 1 that will post a task to thread 2.
   bool success = false;
-  task_runner1->PostTask(FROM_HERE,
-      base::Bind(&PostSetFlagTask, task_runner2, &success));
+  task_runner1->PostTask(
+      FROM_HERE, base::BindOnce(&PostSetFlagTask, task_runner2, &success));
 
   task_runner1 = NULL;
   task_runner2 = NULL;
@@ -146,8 +146,8 @@
   // Post a task to query the COM apartment type.
   HRESULT hresult = E_FAIL;
   APTTYPE apt_type = APTTYPE_NA;
-  task_runner->PostTask(FROM_HERE,
-                        base::Bind(&CheckComAptTypeTask, &apt_type, &hresult));
+  task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&CheckComAptTypeTask, &apt_type, &hresult));
 
   task_runner = NULL;
   RunMessageLoop();
@@ -167,8 +167,8 @@
   // Post a task to query the COM apartment type.
   HRESULT hresult = E_FAIL;
   APTTYPE apt_type = APTTYPE_NA;
-  task_runner->PostTask(FROM_HERE,
-                        base::Bind(&CheckComAptTypeTask, &apt_type, &hresult));
+  task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&CheckComAptTypeTask, &apt_type, &hresult));
 
   task_runner = NULL;
   RunMessageLoop();
diff --git a/remoting/base/fake_oauth_token_getter.cc b/remoting/base/fake_oauth_token_getter.cc
index 225247c0..b1b21c7 100644
--- a/remoting/base/fake_oauth_token_getter.cc
+++ b/remoting/base/fake_oauth_token_getter.cc
@@ -21,7 +21,7 @@
 void FakeOAuthTokenGetter::CallWithToken(const TokenCallback& on_access_token) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(on_access_token, status_, user_email_, access_token_));
+      base::BindOnce(on_access_token, status_, user_email_, access_token_));
 }
 
 void FakeOAuthTokenGetter::InvalidateCache() {
diff --git a/remoting/base/socket_reader.cc b/remoting/base/socket_reader.cc
index 44d6a3d0..6f90b10 100644
--- a/remoting/base/socket_reader.cc
+++ b/remoting/base/socket_reader.cc
@@ -61,8 +61,8 @@
       read_buffer_ = NULL;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&SocketReader::CallCallback, weak_factory_.GetWeakPtr(),
-                   read_buffer_, result));
+        base::BindOnce(&SocketReader::CallCallback, weak_factory_.GetWeakPtr(),
+                       read_buffer_, result));
   }
 }
 
diff --git a/remoting/client/cursor_shape_stub_proxy.cc b/remoting/client/cursor_shape_stub_proxy.cc
index 30580b63..66b1bed 100644
--- a/remoting/client/cursor_shape_stub_proxy.cc
+++ b/remoting/client/cursor_shape_stub_proxy.cc
@@ -19,8 +19,8 @@
 void CursorShapeStubProxy::SetCursorShape(
     const protocol::CursorShapeInfo& cursor_shape) {
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(&protocol::CursorShapeStub::SetCursorShape, stub_,
-                            cursor_shape));
+      FROM_HERE, base::BindOnce(&protocol::CursorShapeStub::SetCursorShape,
+                                stub_, cursor_shape));
 }
 
 }  // namespace remoting
diff --git a/remoting/client/display/gl_renderer.cc b/remoting/client/display/gl_renderer.cc
index e7499a2..3a985944 100644
--- a/remoting/client/display/gl_renderer.cc
+++ b/remoting/client/display/gl_renderer.cc
@@ -147,7 +147,7 @@
     return;
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&GlRenderer::OnRender, weak_ptr_));
+      FROM_HERE, base::BindOnce(&GlRenderer::OnRender, weak_ptr_));
   render_scheduled_ = true;
 }
 
diff --git a/remoting/client/display/gl_renderer_unittest.cc b/remoting/client/display/gl_renderer_unittest.cc
index 2dce491..4a32bdb 100644
--- a/remoting/client/display/gl_renderer_unittest.cc
+++ b/remoting/client/display/gl_renderer_unittest.cc
@@ -161,8 +161,8 @@
                                               int count) {
   for (int i = 0; i < count; i++) {
     message_loop_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&GlRendererTest::SetDesktopFrameWithSize,
-                              base::Unretained(this), size));
+        FROM_HERE, base::BindOnce(&GlRendererTest::SetDesktopFrameWithSize,
+                                  base::Unretained(this), size));
   }
 }
 
diff --git a/remoting/client/dual_buffer_frame_consumer.cc b/remoting/client/dual_buffer_frame_consumer.cc
index 54d6f49..c30f21b8 100644
--- a/remoting/client/dual_buffer_frame_consumer.cc
+++ b/remoting/client/dual_buffer_frame_consumer.cc
@@ -155,9 +155,11 @@
   }
 
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback_, base::Passed(&frame), base::Bind(
-          base::IgnoreResult(&base::TaskRunner::PostTask),
-          base::ThreadTaskRunnerHandle::Get(), FROM_HERE, done)));
+      FROM_HERE,
+      base::BindOnce(
+          callback_, std::move(frame),
+          base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask),
+                     base::ThreadTaskRunnerHandle::Get(), FROM_HERE, done)));
 }
 
 }  // namespace remoting
diff --git a/remoting/client/jni/jni_gl_display_handler.cc b/remoting/client/jni/jni_gl_display_handler.cc
index 6bfb017..d971d127 100644
--- a/remoting/client/jni/jni_gl_display_handler.cc
+++ b/remoting/client/jni/jni_gl_display_handler.cc
@@ -87,8 +87,8 @@
   weak_ptr_ = weak_factory_.GetWeakPtr();
 
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&JniGlDisplayHandler::Core::Initialize,
-                            base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&JniGlDisplayHandler::Core::Initialize,
+                                base::Unretained(this)));
 
   // Do not bind GlRenderer::OnFrameReceived. |renderer_| is not ready yet.
   owned_frame_consumer_.reset(new DualBufferFrameConsumer(
@@ -109,14 +109,14 @@
   DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
   egl_context_->SwapBuffers();
   runtime_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&JniGlDisplayHandler::OnRenderDone, shell_));
+      FROM_HERE, base::BindOnce(&JniGlDisplayHandler::OnRenderDone, shell_));
 }
 
 void JniGlDisplayHandler::Core::OnSizeChanged(int width, int height) {
   DCHECK(runtime_->display_task_runner()->BelongsToCurrentThread());
   runtime_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&JniGlDisplayHandler::OnCanvasSizeChanged, shell_,
-                            width, height));
+      FROM_HERE, base::BindOnce(&JniGlDisplayHandler::OnCanvasSizeChanged,
+                                shell_, width, height));
 }
 
 void JniGlDisplayHandler::Core::SetCursorShape(
@@ -153,8 +153,9 @@
       static_cast<int>(egl_context_->client_version())));
 
   runtime_->network_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&DualBufferFrameConsumer::RequestFullDesktopFrame,
-                            frame_consumer_));
+      FROM_HERE,
+      base::BindOnce(&DualBufferFrameConsumer::RequestFullDesktopFrame,
+                     frame_consumer_));
 }
 
 void JniGlDisplayHandler::Core::SurfaceChanged(int width, int height) {
@@ -249,9 +250,9 @@
     const base::android::JavaParamRef<jobject>& surface) {
   DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&Core::SurfaceCreated, core_->GetWeakPtr(),
-                 base::android::ScopedJavaGlobalRef<jobject>(env, surface)));
+      FROM_HERE, base::BindOnce(&Core::SurfaceCreated, core_->GetWeakPtr(),
+                                base::android::ScopedJavaGlobalRef<jobject>(
+                                    env, surface)));
 }
 
 void JniGlDisplayHandler::OnSurfaceChanged(
@@ -261,8 +262,8 @@
     int height) {
   DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&Core::SurfaceChanged, core_->GetWeakPtr(), width, height));
+      FROM_HERE, base::BindOnce(&Core::SurfaceChanged, core_->GetWeakPtr(),
+                                width, height));
 }
 
 void JniGlDisplayHandler::OnSurfaceDestroyed(
@@ -270,7 +271,7 @@
     const base::android::JavaParamRef<jobject>& caller) {
   DCHECK(runtime_->ui_task_runner()->BelongsToCurrentThread());
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&Core::SurfaceDestroyed, core_->GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&Core::SurfaceDestroyed, core_->GetWeakPtr()));
 }
 
 void JniGlDisplayHandler::OnPixelTransformationChanged(
diff --git a/remoting/client/jni/jni_runtime_delegate.cc b/remoting/client/jni/jni_runtime_delegate.cc
index 1c266e8..f9eb45c0 100644
--- a/remoting/client/jni/jni_runtime_delegate.cc
+++ b/remoting/client/jni/jni_runtime_delegate.cc
@@ -66,12 +66,12 @@
       base::WaitableEvent::ResetPolicy::AUTOMATIC,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
   runtime_->network_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&JniRuntimeDelegate::DetachFromVmAndSignal,
-                            base::Unretained(this), &done_event));
+      FROM_HERE, base::BindOnce(&JniRuntimeDelegate::DetachFromVmAndSignal,
+                                base::Unretained(this), &done_event));
   done_event.Wait();
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&JniRuntimeDelegate::DetachFromVmAndSignal,
-                            base::Unretained(this), &done_event));
+      FROM_HERE, base::BindOnce(&JniRuntimeDelegate::DetachFromVmAndSignal,
+                                base::Unretained(this), &done_event));
   done_event.Wait();
 }
 
diff --git a/remoting/client/plugin/pepper_network_manager.cc b/remoting/client/plugin/pepper_network_manager.cc
index 76813b898..fb95c30e 100644
--- a/remoting/client/plugin/pepper_network_manager.cc
+++ b/remoting/client/plugin/pepper_network_manager.cc
@@ -38,8 +38,9 @@
   if (network_list_received_) {
     // Post a task to avoid reentrancy.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&PepperNetworkManager::SendNetworksChangedSignal,
-                              weak_factory_.GetWeakPtr()));
+        FROM_HERE,
+        base::BindOnce(&PepperNetworkManager::SendNetworksChangedSignal,
+                       weak_factory_.GetWeakPtr()));
   }
   ++start_count_;
 }
diff --git a/remoting/client/queued_task_poster.cc b/remoting/client/queued_task_poster.cc
index 7830791..431fa5a 100644
--- a/remoting/client/queued_task_poster.cc
+++ b/remoting/client/queued_task_poster.cc
@@ -30,8 +30,8 @@
   task_queue_.push(closure);
   if (!transfer_task_scheduled_) {
     source_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&QueuedTaskPoster::TransferTaskQueue,
-                              weak_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&QueuedTaskPoster::TransferTaskQueue,
+                                  weak_factory_.GetWeakPtr()));
     transfer_task_scheduled_ = true;
   }
 }
@@ -50,7 +50,8 @@
       new base::queue<base::Closure>();
   queue_to_transfer->swap(task_queue_);
   target_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&ConsumeTaskQueue, base::Owned(queue_to_transfer)));
+      FROM_HERE,
+      base::BindOnce(&ConsumeTaskQueue, base::Owned(queue_to_transfer)));
 }
 
 }  // namespace remoting
diff --git a/remoting/host/chromeos/clipboard_aura_unittest.cc b/remoting/host/chromeos/clipboard_aura_unittest.cc
index 782f1f5..763a560 100644
--- a/remoting/host/chromeos/clipboard_aura_unittest.cc
+++ b/remoting/host/chromeos/clipboard_aura_unittest.cc
@@ -121,9 +121,10 @@
 
   base::RunLoop run_loop;
   message_loop_.task_runner()->PostDelayedTask(
-      FROM_HERE, base::Bind(&ClipboardAuraTest_MonitorClipboardChanges_Test::
-                                StopAndResetClipboard,
-                            base::Unretained(this)),
+      FROM_HERE,
+      base::BindOnce(&ClipboardAuraTest_MonitorClipboardChanges_Test::
+                         StopAndResetClipboard,
+                     base::Unretained(this)),
       TestTimeouts::tiny_timeout());
   message_loop_.task_runner()->PostDelayedTask(
       FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
diff --git a/remoting/host/chromoting_host_context.cc b/remoting/host/chromoting_host_context.cc
index 5c46220..6606127 100644
--- a/remoting/host/chromoting_host_context.cc
+++ b/remoting/host/chromoting_host_context.cc
@@ -140,7 +140,7 @@
       AutoThread::CreateWithType("ChromotingNetworkThread", ui_task_runner,
                                  base::MessageLoop::TYPE_IO);
   network_task_runner->PostTask(FROM_HERE,
-                                base::Bind(&DisallowBlockingOperations));
+                                base::BindOnce(&DisallowBlockingOperations));
 
   return base::WrapUnique(new ChromotingHostContext(
       ui_task_runner, audio_task_runner, file_task_runner,
diff --git a/remoting/host/config_file_watcher.cc b/remoting/host/config_file_watcher.cc
index 02ee223..376c5c9f 100644
--- a/remoting/host/config_file_watcher.cc
+++ b/remoting/host/config_file_watcher.cc
@@ -125,8 +125,7 @@
   delegate_ = delegate;
 
   io_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&ConfigFileWatcherImpl::WatchOnIoThread, this));
+      FROM_HERE, base::BindOnce(&ConfigFileWatcherImpl::WatchOnIoThread, this));
 }
 
 void ConfigFileWatcherImpl::WatchOnIoThread() {
@@ -147,9 +146,8 @@
           base::Bind(&ConfigFileWatcherImpl::OnConfigUpdated, this))) {
     PLOG(ERROR) << "Couldn't watch file '" << config_path_.value() << "'";
     main_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&ConfigFileWatcherImpl::NotifyError,
-            weak_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&ConfigFileWatcherImpl::NotifyError,
+                                  weak_factory_.GetWeakPtr()));
     return;
   }
 
@@ -162,7 +160,7 @@
 
   weak_factory_.InvalidateWeakPtrs();
   io_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&ConfigFileWatcherImpl::FinishStopping, this));
+      FROM_HERE, base::BindOnce(&ConfigFileWatcherImpl::FinishStopping, this));
 }
 
 ConfigFileWatcherImpl::~ConfigFileWatcherImpl() {
@@ -221,9 +219,8 @@
     PLOG(ERROR) << "Failed to read '" << config_path_.value() << "'";
 
     main_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&ConfigFileWatcherImpl::NotifyError,
-            weak_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&ConfigFileWatcherImpl::NotifyError,
+                                  weak_factory_.GetWeakPtr()));
     return;
   }
 
@@ -233,9 +230,8 @@
   if (config_ != config) {
     config_ = config;
     main_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&ConfigFileWatcherImpl::NotifyUpdate,
-            weak_factory_.GetWeakPtr(), config_));
+        FROM_HERE, base::BindOnce(&ConfigFileWatcherImpl::NotifyUpdate,
+                                  weak_factory_.GetWeakPtr(), config_));
   }
 }
 
diff --git a/remoting/host/curtain_mode_mac.cc b/remoting/host/curtain_mode_mac.cc
index 9dba6ee8..063ccfe 100644
--- a/remoting/host/curtain_mode_mac.cc
+++ b/remoting/host/curtain_mode_mac.cc
@@ -129,7 +129,7 @@
   // unaviodable as long as the curtain enforcement depends on processing of
   // the switch-in notifications.
   ui_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&SessionWatcher::ActivateCurtain, this));
+      FROM_HERE, base::BindOnce(&SessionWatcher::ActivateCurtain, this));
 }
 
 void SessionWatcher::Stop() {
@@ -137,7 +137,7 @@
 
   client_session_control_.reset();
   ui_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&SessionWatcher::RemoveEventHandler, this));
+      FROM_HERE, base::BindOnce(&SessionWatcher::RemoveEventHandler, this));
 }
 
 SessionWatcher::~SessionWatcher() {
@@ -241,7 +241,8 @@
 void SessionWatcher::DisconnectSession(protocol::ErrorCode error) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&SessionWatcher::DisconnectSession, this, error));
+        FROM_HERE,
+        base::BindOnce(&SessionWatcher::DisconnectSession, this, error));
     return;
   }
 
diff --git a/remoting/host/desktop_capturer_proxy.cc b/remoting/host/desktop_capturer_proxy.cc
index af68571a..d30fec6a 100644
--- a/remoting/host/desktop_capturer_proxy.cc
+++ b/remoting/host/desktop_capturer_proxy.cc
@@ -119,8 +119,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   caller_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&DesktopCapturerProxy::OnFrameCaptured, proxy_,
-                            result, base::Passed(&frame)));
+      FROM_HERE, base::BindOnce(&DesktopCapturerProxy::OnFrameCaptured, proxy_,
+                                result, std::move(frame)));
 }
 
 DesktopCapturerProxy::DesktopCapturerProxy(
@@ -137,8 +137,8 @@
     const webrtc::DesktopCaptureOptions& options) {
   DCHECK(thread_checker_.CalledOnValidThread());
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::CreateCapturer,
-                            base::Unretained(core_.get()), options));
+      FROM_HERE, base::BindOnce(&Core::CreateCapturer,
+                                base::Unretained(core_.get()), options));
 }
 
 void DesktopCapturerProxy::set_capturer(
@@ -152,7 +152,7 @@
   callback_ = callback;
 
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get())));
+      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get())));
 }
 
 void DesktopCapturerProxy::SetSharedMemoryFactory(
@@ -161,7 +161,7 @@
 
   capture_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           &Core::SetSharedMemoryFactory, base::Unretained(core_.get()),
           base::Passed(base::WrapUnique(shared_memory_factory.release()))));
 }
@@ -174,7 +174,7 @@
 
   capture_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::CaptureFrame, base::Unretained(core_.get())));
+      base::BindOnce(&Core::CaptureFrame, base::Unretained(core_.get())));
 }
 
 bool DesktopCapturerProxy::GetSourceList(SourceList* sources) {
diff --git a/remoting/host/desktop_process_unittest.cc b/remoting/host/desktop_process_unittest.cc
index 80fa621..2db48ab 100644
--- a/remoting/host/desktop_process_unittest.cc
+++ b/remoting/host/desktop_process_unittest.cc
@@ -227,8 +227,8 @@
 
 void DesktopProcessTest::PostDisconnectChannels() {
   message_loop_.task_runner()->PostTask(
-      FROM_HERE, base::Bind(&DesktopProcessTest::DisconnectChannels,
-                            base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&DesktopProcessTest::DisconnectChannels,
+                                base::Unretained(this)));
 }
 
 void DesktopProcessTest::RunDesktopProcess() {
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc
index be30c098..e66c25e5 100644
--- a/remoting/host/desktop_session_agent.cc
+++ b/remoting/host/desktop_session_agent.cc
@@ -335,7 +335,8 @@
   if (delegate_->desktop_environment_factory().SupportsAudioCapture()) {
     audio_capturer_ = desktop_environment_->CreateAudioCapturer();
     audio_capture_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this));
+        FROM_HERE,
+        base::BindOnce(&DesktopSessionAgent::StartAudioCapturer, this));
   }
 
   // Start the video capturer and mouse cursor monitor.
@@ -499,7 +500,8 @@
 
     // Stop the audio capturer.
     audio_capture_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&DesktopSessionAgent::StopAudioCapturer, this));
+        FROM_HERE,
+        base::BindOnce(&DesktopSessionAgent::StopAudioCapturer, this));
 
     // Stop the video capturer.
     video_capturer_.reset();
@@ -627,8 +629,8 @@
 void DesktopSessionAgent::SendToNetwork(std::unique_ptr<IPC::Message> message) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&DesktopSessionAgent::SendToNetwork, this,
-                              base::Passed(&message)));
+        FROM_HERE, base::BindOnce(&DesktopSessionAgent::SendToNetwork, this,
+                                  std::move(message)));
     return;
   }
 
diff --git a/remoting/host/desktop_session_agent_unittest.cc b/remoting/host/desktop_session_agent_unittest.cc
index 1d2f09b1..d42cf8c 100644
--- a/remoting/host/desktop_session_agent_unittest.cc
+++ b/remoting/host/desktop_session_agent_unittest.cc
@@ -151,17 +151,18 @@
       base::TimeDelta::FromMilliseconds(-1))));
   ASSERT_TRUE(proxy->Send(
       new ChromotingNetworkToAnyMsg_StopProcessStatsReport()));
-  task_runner_->PostDelayedTask(FROM_HERE, base::Bind([](
-          DesktopSessionAgentTest* test,
-          std::unique_ptr<FakeDelegate>* delegate,
-          std::unique_ptr<IPC::ChannelProxy>* proxy) {
-        test->Shutdown();
-        delegate->reset();
-        proxy->reset();
-      },
-      base::Unretained(this),
-      base::Unretained(&delegate),
-      base::Unretained(&proxy)),
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](DesktopSessionAgentTest* test,
+             std::unique_ptr<FakeDelegate>* delegate,
+             std::unique_ptr<IPC::ChannelProxy>* proxy) {
+            test->Shutdown();
+            delegate->reset();
+            proxy->reset();
+          },
+          base::Unretained(this), base::Unretained(&delegate),
+          base::Unretained(&proxy)),
       base::TimeDelta::FromMilliseconds(1));
   run_loop_.Run();
 }
@@ -180,17 +181,18 @@
       base::TimeDelta::FromMilliseconds(1))));
   ASSERT_TRUE(proxy->Send(
       new ChromotingNetworkToAnyMsg_StopProcessStatsReport()));
-  task_runner_->PostDelayedTask(FROM_HERE, base::Bind([](
-          DesktopSessionAgentTest* test,
-          std::unique_ptr<FakeDelegate>* delegate,
-          std::unique_ptr<IPC::ChannelProxy>* proxy) {
-        test->Shutdown();
-        delegate->reset();
-        proxy->reset();
-      },
-      base::Unretained(this),
-      base::Unretained(&delegate),
-      base::Unretained(&proxy)),
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](DesktopSessionAgentTest* test,
+             std::unique_ptr<FakeDelegate>* delegate,
+             std::unique_ptr<IPC::ChannelProxy>* proxy) {
+            test->Shutdown();
+            delegate->reset();
+            proxy->reset();
+          },
+          base::Unretained(this), base::Unretained(&delegate),
+          base::Unretained(&proxy)),
       base::TimeDelta::FromMilliseconds(1));
   run_loop_.Run();
 }
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index d1dd6fac..133bd72 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -492,8 +492,8 @@
 
   // Pass a captured audio packet to |audio_capturer_|.
   audio_capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&IpcAudioCapturer::OnAudioPacket, audio_capturer_,
-                            base::Passed(&packet)));
+      FROM_HERE, base::BindOnce(&IpcAudioCapturer::OnAudioPacket,
+                                audio_capturer_, std::move(packet)));
 }
 
 void DesktopSessionProxy::OnCreateSharedBuffer(
diff --git a/remoting/host/host_change_notification_listener.cc b/remoting/host/host_change_notification_listener.cc
index e616f66..650836a5 100644
--- a/remoting/host/host_change_notification_listener.cc
+++ b/remoting/host/host_change_notification_listener.cc
@@ -69,8 +69,9 @@
       // objects cannot be deleted from a Listener callback, so OnHostDeleted()
       // has to be invoked later.
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(&HostChangeNotificationListener::OnHostDeleted,
-              weak_factory_.GetWeakPtr()));
+          FROM_HERE,
+          base::BindOnce(&HostChangeNotificationListener::OnHostDeleted,
+                         weak_factory_.GetWeakPtr()));
     }
   } else {
     LOG(ERROR) << "Invalid host-changed message received: " << stanza->Str();
diff --git a/remoting/host/host_window_proxy.cc b/remoting/host/host_window_proxy.cc
index 5b62ca1..63df654 100644
--- a/remoting/host/host_window_proxy.cc
+++ b/remoting/host/host_window_proxy.cc
@@ -114,14 +114,15 @@
 
   client_session_control_ = client_session_control;
   ui_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::StartOnUiThread, this,
-                            client_session_control->client_jid()));
+      FROM_HERE, base::BindOnce(&Core::StartOnUiThread, this,
+                                client_session_control->client_jid()));
 }
 
 void HostWindowProxy::Core::Stop() {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
-  ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
+  ui_task_runner_->PostTask(FROM_HERE,
+                            base::BindOnce(&Core::StopOnUiThread, this));
 }
 
 HostWindowProxy::Core::~Core() {
@@ -151,7 +152,7 @@
 void HostWindowProxy::Core::DisconnectSession(protocol::ErrorCode error) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::DisconnectSession, this, error));
+        FROM_HERE, base::BindOnce(&Core::DisconnectSession, this, error));
     return;
   }
 
@@ -163,7 +164,7 @@
     const webrtc::DesktopVector& position) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position));
+        FROM_HERE, base::BindOnce(&Core::OnLocalMouseMoved, this, position));
     return;
   }
 
@@ -174,7 +175,8 @@
 void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::SetDisableInputs, this, disable_inputs));
+        FROM_HERE,
+        base::BindOnce(&Core::SetDisableInputs, this, disable_inputs));
     return;
   }
 
diff --git a/remoting/host/input_injector_chromeos.cc b/remoting/host/input_injector_chromeos.cc
index a41589a0..7d23621 100644
--- a/remoting/host/input_injector_chromeos.cc
+++ b/remoting/host/input_injector_chromeos.cc
@@ -180,26 +180,26 @@
 
 void InputInjectorChromeos::InjectClipboardEvent(const ClipboardEvent& event) {
   input_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::InjectClipboardEvent,
-                            base::Unretained(core_.get()), event));
+      FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent,
+                                base::Unretained(core_.get()), event));
 }
 
 void InputInjectorChromeos::InjectKeyEvent(const KeyEvent& event) {
   input_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&Core::InjectKeyEvent, base::Unretained(core_.get()), event));
+      FROM_HERE, base::BindOnce(&Core::InjectKeyEvent,
+                                base::Unretained(core_.get()), event));
 }
 
 void InputInjectorChromeos::InjectTextEvent(const TextEvent& event) {
   input_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&Core::InjectTextEvent, base::Unretained(core_.get()), event));
+      FROM_HERE, base::BindOnce(&Core::InjectTextEvent,
+                                base::Unretained(core_.get()), event));
 }
 
 void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) {
   input_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::InjectMouseEvent,
-                            base::Unretained(core_.get()), event));
+      FROM_HERE, base::BindOnce(&Core::InjectMouseEvent,
+                                base::Unretained(core_.get()), event));
 }
 
 void InputInjectorChromeos::InjectTouchEvent(const TouchEvent& event) {
@@ -209,8 +209,8 @@
 void InputInjectorChromeos::Start(
     std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
   input_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()),
-                            base::Passed(&client_clipboard)));
+      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()),
+                                std::move(client_clipboard)));
 }
 
 // static
diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc
index 037c27c9..d2d32a9a 100644
--- a/remoting/host/input_injector_mac.cc
+++ b/remoting/host/input_injector_mac.cc
@@ -185,7 +185,7 @@
 void InputInjectorMac::Core::InjectClipboardEvent(const ClipboardEvent& event) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent, this, event));
     return;
   }
 
@@ -346,7 +346,7 @@
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Core::Start, this, base::Passed(&client_clipboard)));
+        base::BindOnce(&Core::Start, this, std::move(client_clipboard)));
     return;
   }
 
@@ -355,7 +355,7 @@
 
 void InputInjectorMac::Core::Stop() {
   if (!task_runner_->BelongsToCurrentThread()) {
-    task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this));
+    task_runner_->PostTask(FROM_HERE, base::BindOnce(&Core::Stop, this));
     return;
   }
 
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc
index 219b85ba..446907b 100644
--- a/remoting/host/input_injector_win.cc
+++ b/remoting/host/input_injector_win.cc
@@ -303,7 +303,7 @@
 void InputInjectorWin::Core::InjectClipboardEvent(const ClipboardEvent& event) {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
     ui_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent, this, event));
     return;
   }
 
@@ -313,8 +313,8 @@
 
 void InputInjectorWin::Core::InjectKeyEvent(const KeyEvent& event) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(&Core::InjectKeyEvent, this, event));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&Core::InjectKeyEvent, this, event));
     return;
   }
 
@@ -324,7 +324,7 @@
 void InputInjectorWin::Core::InjectTextEvent(const TextEvent& event) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
     main_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectTextEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectTextEvent, this, event));
     return;
   }
 
@@ -334,7 +334,7 @@
 void InputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
     main_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectMouseEvent, this, event));
     return;
   }
 
@@ -344,7 +344,7 @@
 void InputInjectorWin::Core::InjectTouchEvent(const TouchEvent& event) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
     main_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectTouchEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectTouchEvent, this, event));
     return;
   }
 
@@ -356,7 +356,7 @@
   if (!ui_task_runner_->BelongsToCurrentThread()) {
     ui_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Core::Start, this, base::Passed(&client_clipboard)));
+        base::BindOnce(&Core::Start, this, std::move(client_clipboard)));
     return;
   }
 
@@ -366,7 +366,7 @@
 
 void InputInjectorWin::Core::Stop() {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
-    ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this));
+    ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(&Core::Stop, this));
     return;
   }
 
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc
index 7e76bd3..ce33e31 100644
--- a/remoting/host/input_injector_x11.cc
+++ b/remoting/host/input_injector_x11.cc
@@ -220,7 +220,8 @@
   CHECK(display_);
 
   if (!task_runner_->BelongsToCurrentThread())
-    task_runner_->PostTask(FROM_HERE, base::Bind(&Core::InitClipboard, this));
+    task_runner_->PostTask(FROM_HERE,
+                           base::BindOnce(&Core::InitClipboard, this));
 
   root_window_ = XRootWindow(display_, DefaultScreen(display_));
   if (root_window_ == BadValue) {
@@ -240,7 +241,7 @@
     const ClipboardEvent& event) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent, this, event));
     return;
   }
 
@@ -255,7 +256,7 @@
 
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&Core::InjectKeyEvent, this, event));
+                           base::BindOnce(&Core::InjectKeyEvent, this, event));
     return;
   }
 
@@ -314,7 +315,7 @@
 void InputInjectorX11::Core::InjectTextEvent(const TextEvent& event) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&Core::InjectTextEvent, this, event));
+                           base::BindOnce(&Core::InjectTextEvent, this, event));
     return;
   }
 
@@ -416,8 +417,8 @@
 
 void InputInjectorX11::Core::InjectMouseEvent(const MouseEvent& event) {
   if (!task_runner_->BelongsToCurrentThread()) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&Core::InjectMouseEvent, this, event));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&Core::InjectMouseEvent, this, event));
     return;
   }
 
@@ -623,7 +624,7 @@
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Core::Start, this, base::Passed(&client_clipboard)));
+        base::BindOnce(&Core::Start, this, std::move(client_clipboard)));
     return;
   }
 
@@ -645,7 +646,7 @@
 
 void InputInjectorX11::Core::Stop() {
   if (!task_runner_->BelongsToCurrentThread()) {
-    task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this));
+    task_runner_->PostTask(FROM_HERE, base::BindOnce(&Core::Stop, this));
     return;
   }
 
diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc
index ff7974d..20ffeb9 100644
--- a/remoting/host/ipc_desktop_environment.cc
+++ b/remoting/host/ipc_desktop_environment.cc
@@ -178,9 +178,9 @@
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached,
-                   base::Unretained(this), terminal_id, session_id,
-                   desktop_pipe));
+        base::BindOnce(
+            &IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached,
+            base::Unretained(this), terminal_id, session_id, desktop_pipe));
     return;
   }
 
@@ -195,9 +195,10 @@
 
 void IpcDesktopEnvironmentFactory::OnTerminalDisconnected(int terminal_id) {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
-    caller_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &IpcDesktopEnvironmentFactory::OnTerminalDisconnected,
-        base::Unretained(this), terminal_id));
+    caller_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&IpcDesktopEnvironmentFactory::OnTerminalDisconnected,
+                       base::Unretained(this), terminal_id));
     return;
   }
 
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc b/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc
index 82a542c..fa858891 100644
--- a/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc
+++ b/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc
@@ -72,8 +72,8 @@
     It2MeConfirmationDialog::Result result) {
   DCHECK(ui_task_runner_->BelongsToCurrentThread());
   caller_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&It2MeConfirmationDialogProxy::ReportResult, parent_, result));
+      FROM_HERE, base::BindOnce(&It2MeConfirmationDialogProxy::ReportResult,
+                                parent_, result));
 }
 
 It2MeConfirmationDialogProxy::It2MeConfirmationDialogProxy(
@@ -98,8 +98,8 @@
 
   callback_ = callback;
   core_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&Core::Show, base::Unretained(core_.get()),
-                            remote_user_email));
+      FROM_HERE, base::BindOnce(&Core::Show, base::Unretained(core_.get()),
+                                remote_user_email));
 }
 
 void It2MeConfirmationDialogProxy::ReportResult(
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc
index 84c60c9..17a4191 100644
--- a/remoting/host/it2me/it2me_host.cc
+++ b/remoting/host/it2me/it2me_host.cc
@@ -100,14 +100,14 @@
 
   // Switch to the network thread to start the actual connection.
   host_context_->network_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::ConnectOnNetworkThread, this, username,
-                            directory_bot_jid, ice_config));
+      FROM_HERE, base::BindOnce(&It2MeHost::ConnectOnNetworkThread, this,
+                                username, directory_bot_jid, ice_config));
 }
 
 void It2MeHost::Disconnect() {
   DCHECK(host_context_->ui_task_runner()->BelongsToCurrentThread());
   host_context_->network_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::DisconnectOnNetworkThread, this));
+      FROM_HERE, base::BindOnce(&It2MeHost::DisconnectOnNetworkThread, this));
 }
 
 void It2MeHost::ConnectOnNetworkThread(const std::string& username,
@@ -241,8 +241,8 @@
 
   // Pass the client user name to the script object before changing state.
   host_context_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated,
-                            observer_, client_username));
+      FROM_HERE, base::BindOnce(&It2MeHost::Observer::OnClientAuthenticated,
+                                observer_, client_username));
 
   SetState(kConnected, ErrorCode::OK);
 }
@@ -264,7 +264,7 @@
   if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
     host_context_->network_task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(&It2MeHost::OnPolicyUpdate, this, base::Passed(&policies)));
+        base::BindOnce(&It2MeHost::OnPolicyUpdate, this, std::move(policies)));
     return;
   }
 
@@ -314,8 +314,8 @@
 
   // Notify the web-app of the policy setting.
   host_context_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnNatPolicyChanged, observer_,
-                            nat_traversal_enabled_));
+      FROM_HERE, base::BindOnce(&It2MeHost::Observer::OnNatPolicyChanged,
+                                observer_, nat_traversal_enabled_));
 }
 
 void It2MeHost::UpdateHostDomainListPolicy(
@@ -409,8 +409,8 @@
 
   // Post a state-change notification to the web-app.
   host_context_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnStateChanged, observer_,
-                            state, error_code));
+      FROM_HERE, base::BindOnce(&It2MeHost::Observer::OnStateChanged, observer_,
+                                state, error_code));
 }
 
 bool It2MeHost::IsRunning() const {
@@ -451,8 +451,8 @@
 
   // Pass the Access Code to the script object before changing state.
   host_context_->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, observer_,
-                            access_code, lifetime));
+      FROM_HERE, base::BindOnce(&It2MeHost::Observer::OnStoreAccessCode,
+                                observer_, access_code, lifetime));
 
   SetState(kReceivedAccessCode, ErrorCode::OK);
 }
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc
index 3b1ed8e3..3ffb131 100644
--- a/remoting/host/it2me/it2me_host_unittest.cc
+++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -95,7 +95,7 @@
   EXPECT_STREQ(remote_user_email_.c_str(), remote_user_email.c_str());
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(callback, dialog_result_));
+      FROM_HERE, base::BindOnce(callback, dialog_result_));
 }
 
 class FakeIt2MeDialogFactory : public It2MeConfirmationDialogFactory {
@@ -258,8 +258,8 @@
   if (last_host_state_ == It2MeHostState::kRequestedAccessCode) {
     network_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&It2MeHost::SetStateForTesting, it2me_host_.get(),
-                   It2MeHostState::kReceivedAccessCode, ErrorCode::OK));
+        base::BindOnce(&It2MeHost::SetStateForTesting, it2me_host_.get(),
+                       It2MeHostState::kReceivedAccessCode, ErrorCode::OK));
   } else if (last_host_state_ != It2MeHostState::kStarting) {
     quit_closure.Run();
     return;
@@ -320,9 +320,10 @@
 
   network_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(it2me_host_->GetValidationCallbackForTesting(), remote_jid,
-                 base::Bind(&It2MeHostTest::OnValidationComplete,
-                            base::Unretained(this), run_loop.QuitClosure())));
+      base::BindOnce(
+          it2me_host_->GetValidationCallbackForTesting(), remote_jid,
+          base::Bind(&It2MeHostTest::OnValidationComplete,
+                     base::Unretained(this), run_loop.QuitClosure())));
 
   run_loop.Run();
 }
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc
index bc54071..ff72e2f 100644
--- a/remoting/host/it2me/it2me_native_messaging_host.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -76,7 +76,7 @@
     std::unique_ptr<base::DictionaryValue> policies) {
   DCHECK(callback);
   task_runner->PostTask(FROM_HERE,
-                        base::Bind(callback, base::Passed(&policies)));
+                        base::BindOnce(callback, std::move(policies)));
 }
 
 void PolicyErrorCallback(
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
index 3f8da5d..e88c885 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -159,15 +159,16 @@
   RunSetState(kRequestedAccessCode);
 
   host_context()->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnStoreAccessCode, observer_,
-                            kTestAccessCode, kTestAccessCodeLifetime));
+      FROM_HERE,
+      base::BindOnce(&It2MeHost::Observer::OnStoreAccessCode, observer_,
+                     kTestAccessCode, kTestAccessCodeLifetime));
 
   RunSetState(kReceivedAccessCode);
   RunSetState(kConnecting);
 
   host_context()->ui_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&It2MeHost::Observer::OnClientAuthenticated,
-                            observer_, kTestClientUsername));
+      FROM_HERE, base::BindOnce(&It2MeHost::Observer::OnClientAuthenticated,
+                                observer_, kTestClientUsername));
 
   RunSetState(kConnected);
 }
@@ -176,7 +177,7 @@
   if (!host_context()->network_task_runner()->BelongsToCurrentThread()) {
     DCHECK(host_context()->ui_task_runner()->BelongsToCurrentThread());
     host_context()->network_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&MockIt2MeHost::Disconnect, this));
+        FROM_HERE, base::BindOnce(&MockIt2MeHost::Disconnect, this));
     return;
   }
 
@@ -186,8 +187,8 @@
 void MockIt2MeHost::RunSetState(It2MeHostState state) {
   if (!host_context()->network_task_runner()->BelongsToCurrentThread()) {
     host_context()->network_task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&It2MeHost::SetStateForTesting, this, state, ErrorCode::OK));
+        FROM_HERE, base::BindOnce(&It2MeHost::SetStateForTesting, this, state,
+                                  ErrorCode::OK));
   } else {
     SetStateForTesting(state, ErrorCode::OK);
   }
@@ -285,9 +286,8 @@
                  base::Unretained(this)));
 
   host_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&It2MeNativeMessagingHostTest::StartHost,
-                 base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&It2MeNativeMessagingHostTest::StartHost,
+                                base::Unretained(this)));
 
   // Wait until the host finishes starting.
   test_run_loop_->Run();
@@ -570,9 +570,8 @@
 void It2MeNativeMessagingHostTest::ExitTest() {
   if (!test_message_loop_->task_runner()->RunsTasksInCurrentSequence()) {
     test_message_loop_->task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&It2MeNativeMessagingHostTest::ExitTest,
-                   base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&It2MeNativeMessagingHostTest::ExitTest,
+                                  base::Unretained(this)));
     return;
   }
   test_run_loop_->Quit();
diff --git a/remoting/host/linux/audio_pipe_reader.cc b/remoting/host/linux/audio_pipe_reader.cc
index 8b2d278..cfe61d9 100644
--- a/remoting/host/linux/audio_pipe_reader.cc
+++ b/remoting/host/linux/audio_pipe_reader.cc
@@ -43,7 +43,8 @@
   scoped_refptr<AudioPipeReader> pipe_reader =
       new AudioPipeReader(task_runner, pipe_path);
   task_runner->PostTask(
-      FROM_HERE, base::Bind(&AudioPipeReader::StartOnAudioThread, pipe_reader));
+      FROM_HERE,
+      base::BindOnce(&AudioPipeReader::StartOnAudioThread, pipe_reader));
   return pipe_reader;
 }
 
diff --git a/remoting/host/linux/certificate_watcher.cc b/remoting/host/linux/certificate_watcher.cc
index 7b3bd3f..39aa54c 100644
--- a/remoting/host/linux/certificate_watcher.cc
+++ b/remoting/host/linux/certificate_watcher.cc
@@ -140,7 +140,8 @@
   if (new_hash != current_hash_) {
     current_hash_ = new_hash;
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&CertificateWatcher::DatabaseChanged, watcher_));
+        FROM_HERE,
+        base::BindOnce(&CertificateWatcher::DatabaseChanged, watcher_));
   } else {
     VLOG(1) << "Directory changed but contents are the same.";
   }
@@ -204,8 +205,8 @@
                                                   cert_watch_path_, delay_));
 
   io_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&CertDbContentWatcher::StartWatching,
-                            base::Unretained(content_watcher_.get())));
+      FROM_HERE, base::BindOnce(&CertDbContentWatcher::StartWatching,
+                                base::Unretained(content_watcher_.get())));
 
   VLOG(1) << "Started watching certificate changes.";
 }
diff --git a/remoting/host/linux/certificate_watcher_unittest.cc b/remoting/host/linux/certificate_watcher_unittest.cc
index 94309293..102e3dd 100644
--- a/remoting/host/linux/certificate_watcher_unittest.cc
+++ b/remoting/host/linux/certificate_watcher_unittest.cc
@@ -66,22 +66,20 @@
 
   void Connect() {
     task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&CertificateWatcher::OnClientConnected,
-                   base::Unretained(watcher_.get()), ""));
+        FROM_HERE, base::BindOnce(&CertificateWatcher::OnClientConnected,
+                                  base::Unretained(watcher_.get()), ""));
   }
 
   void Disconnect() {
     task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&CertificateWatcher::OnClientDisconnected,
-                   base::Unretained(watcher_.get()), ""));
+        FROM_HERE, base::BindOnce(&CertificateWatcher::OnClientDisconnected,
+                                  base::Unretained(watcher_.get()), ""));
   }
 
   void TouchFile(const char* filename) {
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&CertificateWatcherTest::TouchFileTask,
-                                      base::Unretained(this), filename));
+    task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&CertificateWatcherTest::TouchFileTask,
+                                  base::Unretained(this), filename));
   }
 
   void TouchFileTask(const char* filename) {
diff --git a/remoting/host/mouse_cursor_monitor_proxy.cc b/remoting/host/mouse_cursor_monitor_proxy.cc
index 03ce407..355eb30 100644
--- a/remoting/host/mouse_cursor_monitor_proxy.cc
+++ b/remoting/host/mouse_cursor_monitor_proxy.cc
@@ -98,8 +98,8 @@
 
   std::unique_ptr<webrtc::MouseCursor> owned_cursor(cursor);
   caller_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&MouseCursorMonitorProxy::OnMouseCursor, proxy_,
-                            base::Passed(&owned_cursor)));
+      FROM_HERE, base::BindOnce(&MouseCursorMonitorProxy::OnMouseCursor, proxy_,
+                                std::move(owned_cursor)));
 }
 
 void MouseCursorMonitorProxy::Core::OnMouseCursorPosition(
@@ -108,8 +108,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   caller_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&MouseCursorMonitorProxy::OnMouseCursorPosition,
-                            proxy_, state, position));
+      FROM_HERE, base::BindOnce(&MouseCursorMonitorProxy::OnMouseCursorPosition,
+                                proxy_, state, position));
 }
 
 MouseCursorMonitorProxy::MouseCursorMonitorProxy(
@@ -118,8 +118,8 @@
     : capture_task_runner_(capture_task_runner), weak_factory_(this) {
   core_.reset(new Core(weak_factory_.GetWeakPtr()));
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::CreateMouseCursorMonitor,
-                            base::Unretained(core_.get()), options));
+      FROM_HERE, base::BindOnce(&Core::CreateMouseCursorMonitor,
+                                base::Unretained(core_.get()), options));
 }
 
 MouseCursorMonitorProxy::~MouseCursorMonitorProxy() {
@@ -130,21 +130,22 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   callback_ = callback;
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Init, base::Unretained(core_.get()), mode));
+      FROM_HERE,
+      base::BindOnce(&Core::Init, base::Unretained(core_.get()), mode));
 }
 
 void MouseCursorMonitorProxy::Capture() {
   DCHECK(thread_checker_.CalledOnValidThread());
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Capture, base::Unretained(core_.get())));
+      FROM_HERE, base::BindOnce(&Core::Capture, base::Unretained(core_.get())));
 }
 
 void MouseCursorMonitorProxy::SetMouseCursorMonitorForTests(
     std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor) {
   capture_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::SetMouseCursorMonitorForTests,
-                            base::Unretained(core_.get()),
-                            base::Passed(&mouse_cursor_monitor)));
+      FROM_HERE, base::BindOnce(&Core::SetMouseCursorMonitorForTests,
+                                base::Unretained(core_.get()),
+                                std::move(mouse_cursor_monitor)));
 }
 
 void MouseCursorMonitorProxy::OnMouseCursor(
diff --git a/remoting/host/native_messaging/log_message_handler.cc b/remoting/host/native_messaging/log_message_handler.cc
index 47c3478..efaf21af 100644
--- a/remoting/host/native_messaging/log_message_handler.cc
+++ b/remoting/host/native_messaging/log_message_handler.cc
@@ -89,10 +89,9 @@
   // Note that this means that LOG(FATAL) messages will be lost because the
   // process will exit before the message is sent to the client.
   caller_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&LogMessageHandler::SendLogMessageToClient,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 severity, file, line, message_start, str));
+      FROM_HERE, base::BindOnce(&LogMessageHandler::SendLogMessageToClient,
+                                weak_ptr_factory_.GetWeakPtr(), severity, file,
+                                line, message_start, str));
 }
 
 void LogMessageHandler::SendLogMessageToClient(
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc
index ec4e6ea..fca5737 100644
--- a/remoting/host/native_messaging/native_messaging_reader.cc
+++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -130,8 +130,8 @@
 
     // Notify callback of new message.
     caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&NativeMessagingReader::InvokeMessageCallback,
-                              reader_, base::Passed(&message)));
+        FROM_HERE, base::BindOnce(&NativeMessagingReader::InvokeMessageCallback,
+                                  reader_, std::move(message)));
   }
 }
 
@@ -139,7 +139,7 @@
   DCHECK(read_task_runner_->RunsTasksInCurrentSequence());
   caller_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_));
+      base::BindOnce(&NativeMessagingReader::InvokeEofCallback, reader_));
 }
 
 NativeMessagingReader::NativeMessagingReader(base::File file)
@@ -188,8 +188,8 @@
   // base::Unretained is safe since |core_| is only deleted via the
   // DeleteSoon task which is posted from this class's dtor.
   read_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&NativeMessagingReader::Core::ReadMessage,
-                            base::Unretained(core_.get())));
+      FROM_HERE, base::BindOnce(&NativeMessagingReader::Core::ReadMessage,
+                                base::Unretained(core_.get())));
 }
 
 void NativeMessagingReader::InvokeMessageCallback(
diff --git a/remoting/host/process_stats_sender_unittest.cc b/remoting/host/process_stats_sender_unittest.cc
index 1a445f9..a4b28096 100644
--- a/remoting/host/process_stats_sender_unittest.cc
+++ b/remoting/host/process_stats_sender_unittest.cc
@@ -116,7 +116,7 @@
       base::Unretained(&run_loop)));
   message_loop.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           [](std::unique_ptr<ProcessStatsSender>* stats,
              FakeProcessStatsStub* stub, FakeProcessStatsAgent* agent) -> void {
             stats->reset(new ProcessStatsSender(
@@ -155,7 +155,7 @@
       base::ConstRef(agent2), base::Unretained(&run_loop)));
   message_loop.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(
+      base::BindOnce(
           [](std::unique_ptr<ProcessStatsSender>* stats,
              FakeProcessStatsStub* stub, FakeProcessStatsAgent* agent1,
              FakeProcessStatsAgent* agent2) -> void {
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 105fc13..aea20b1a 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -590,8 +590,9 @@
 void HostProcess::OnConfigUpdated(
     const std::string& serialized_config) {
   if (!context_->network_task_runner()->BelongsToCurrentThread()) {
-    context_->network_task_runner()->PostTask(FROM_HERE,
-        base::Bind(&HostProcess::OnConfigUpdated, this, serialized_config));
+    context_->network_task_runner()->PostTask(
+        FROM_HERE,
+        base::BindOnce(&HostProcess::OnConfigUpdated, this, serialized_config));
     return;
   }
 
@@ -824,7 +825,7 @@
   // Shutdown the host if the daemon process disconnects the IPC channel.
   context_->network_task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&HostProcess::ShutdownHost, this, kSuccessExitCode));
+      base::BindOnce(&HostProcess::ShutdownHost, this, kSuccessExitCode));
 }
 
 void HostProcess::StartOnUiThread() {
@@ -839,7 +840,7 @@
   if (!report_offline_reason_.empty()) {
     // Don't need to do any UI initialization.
     context_->network_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&HostProcess::StartOnNetworkThread, this));
+        FROM_HERE, base::BindOnce(&HostProcess::StartOnNetworkThread, this));
     return;
   }
 
@@ -898,8 +899,7 @@
   desktop_environment_factory_.reset(desktop_environment_factory);
 
   context_->network_task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&HostProcess::StartOnNetworkThread, this));
+      FROM_HERE, base::BindOnce(&HostProcess::StartOnNetworkThread, this));
 }
 
 void HostProcess::ShutdownOnUiThread() {
@@ -954,9 +954,9 @@
   DCHECK(context_->ui_task_runner()->BelongsToCurrentThread());
 
 #if defined(OS_WIN)
-  context_->network_task_runner()->PostTask(FROM_HERE, base::Bind(
-      &HostProcess::InitializePairingRegistry,
-      this, privileged_key, unprivileged_key));
+  context_->network_task_runner()->PostTask(
+      FROM_HERE, base::BindOnce(&HostProcess::InitializePairingRegistry, this,
+                                privileged_key, unprivileged_key));
 #else  // !defined(OS_WIN)
   NOTREACHED();
 #endif  // !defined(OS_WIN)
@@ -1064,8 +1064,8 @@
     std::unique_ptr<base::DictionaryValue> policies) {
   if (!context_->network_task_runner()->BelongsToCurrentThread()) {
     context_->network_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&HostProcess::OnPolicyUpdate, this,
-                              base::Passed(&policies)));
+        FROM_HERE, base::BindOnce(&HostProcess::OnPolicyUpdate, this,
+                                  std::move(policies)));
     return;
   }
 
@@ -1096,7 +1096,7 @@
 void HostProcess::OnPolicyError() {
   if (!context_->network_task_runner()->BelongsToCurrentThread()) {
     context_->network_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&HostProcess::OnPolicyError, this));
+        FROM_HERE, base::BindOnce(&HostProcess::OnPolicyError, this));
     return;
   }
 
@@ -1697,7 +1697,7 @@
 
     // Complete the rest of shutdown on the main thread.
     context_->ui_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&HostProcess::ShutdownOnUiThread, this));
+        FROM_HERE, base::BindOnce(&HostProcess::ShutdownOnUiThread, this));
   } else {
     NOTREACHED();
   }
diff --git a/remoting/host/security_key/fake_security_key_ipc_client.cc b/remoting/host/security_key/fake_security_key_ipc_client.cc
index 93fb23f..7c108625 100644
--- a/remoting/host/security_key/fake_security_key_ipc_client.cc
+++ b/remoting/host/security_key/fake_security_key_ipc_client.cc
@@ -52,7 +52,7 @@
   if (send_security_request_should_succeed_) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(response_callback, security_key_response_payload_));
+        base::BindOnce(response_callback, security_key_response_payload_));
   }
 
   return send_security_request_should_succeed_;
diff --git a/remoting/host/security_key/security_key_auth_handler_posix.cc b/remoting/host/security_key/security_key_auth_handler_posix.cc
index ee1866a8..3ecf953a 100644
--- a/remoting/host/security_key/security_key_auth_handler_posix.cc
+++ b/remoting/host/security_key/security_key_auth_handler_posix.cc
@@ -156,9 +156,9 @@
   if (file_task_runner_) {
     // Attempt to clean up the socket before being destroyed.
     file_task_runner_->PostTask(
-        FROM_HERE, base::Bind(base::IgnoreResult(&base::DeleteFile),
-                              g_security_key_socket_name.Get(),
-                              /*recursive=*/false));
+        FROM_HERE, base::BindOnce(base::IgnoreResult(&base::DeleteFile),
+                                  g_security_key_socket_name.Get(),
+                                  /*recursive=*/false));
   }
 }
 
diff --git a/remoting/host/security_key/security_key_ipc_server_impl.cc b/remoting/host/security_key/security_key_ipc_server_impl.cc
index 5119afb..90cdcc37 100644
--- a/remoting/host/security_key/security_key_ipc_server_impl.cc
+++ b/remoting/host/security_key/security_key_ipc_server_impl.cc
@@ -164,8 +164,8 @@
         new ChromotingNetworkToRemoteSecurityKeyMsg_InvalidSession());
 
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&SecurityKeyIpcServerImpl::OnChannelError,
-                              weak_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&SecurityKeyIpcServerImpl::OnChannelError,
+                                  weak_factory_.GetWeakPtr()));
     return;
   }
 #else   // !defined(OS_WIN)
diff --git a/remoting/host/security_key/security_key_message_reader.cc b/remoting/host/security_key/security_key_message_reader.cc
index 1d68f26..77b1e40c 100644
--- a/remoting/host/security_key/security_key_message_reader.cc
+++ b/remoting/host/security_key/security_key_message_reader.cc
@@ -50,9 +50,9 @@
 
   // base::Unretained is safe since this class owns the thread running this task
   // which will be destroyed before this instance is.
-  read_task_runner_->PostTask(FROM_HERE,
-                              base::Bind(&SecurityKeyMessageReader::ReadMessage,
-                                         base::Unretained(this)));
+  read_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&SecurityKeyMessageReader::ReadMessage,
+                                base::Unretained(this)));
 }
 
 void SecurityKeyMessageReader::ReadMessage() {
@@ -106,8 +106,8 @@
     // Notify callback of the new message received.
     main_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&SecurityKeyMessageReader::InvokeMessageCallback,
-                   weak_factory_.GetWeakPtr(), base::Passed(&message)));
+        base::BindOnce(&SecurityKeyMessageReader::InvokeMessageCallback,
+                       weak_factory_.GetWeakPtr(), std::move(message)));
   }
 }
 
@@ -115,8 +115,8 @@
   DCHECK(read_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&SecurityKeyMessageReader::InvokeErrorCallback,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&SecurityKeyMessageReader::InvokeErrorCallback,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void SecurityKeyMessageReader::InvokeMessageCallback(
diff --git a/remoting/host/security_key/security_key_message_reader_impl.cc b/remoting/host/security_key/security_key_message_reader_impl.cc
index 5a70efcb..5c3cd1d 100644
--- a/remoting/host/security_key/security_key_message_reader_impl.cc
+++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -51,8 +51,8 @@
   // base::Unretained is safe since this class owns the thread running this task
   // which will be destroyed before this instance is.
   read_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&SecurityKeyMessageReaderImpl::ReadMessage,
-                            base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&SecurityKeyMessageReaderImpl::ReadMessage,
+                                base::Unretained(this)));
 }
 
 void SecurityKeyMessageReaderImpl::ReadMessage() {
@@ -93,8 +93,8 @@
     // Notify callback of the new message received.
     main_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&SecurityKeyMessageReaderImpl::InvokeMessageCallback,
-                   weak_factory_.GetWeakPtr(), base::Passed(&message)));
+        base::BindOnce(&SecurityKeyMessageReaderImpl::InvokeMessageCallback,
+                       weak_factory_.GetWeakPtr(), std::move(message)));
   }
 }
 
@@ -126,8 +126,9 @@
   DCHECK(read_task_runner_->RunsTasksInCurrentSequence());
 
   main_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&SecurityKeyMessageReaderImpl::InvokeErrorCallback,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE,
+      base::BindOnce(&SecurityKeyMessageReaderImpl::InvokeErrorCallback,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void SecurityKeyMessageReaderImpl::InvokeMessageCallback(
diff --git a/remoting/host/setup/daemon_controller.cc b/remoting/host/setup/daemon_controller.cc
index 67201a2..e654fd2 100644
--- a/remoting/host/setup/daemon_controller.cc
+++ b/remoting/host/setup/daemon_controller.cc
@@ -113,7 +113,7 @@
 
   std::unique_ptr<base::DictionaryValue> config = delegate_->GetConfig();
   caller_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(done, base::Passed(&config)));
+                                base::BindOnce(done, std::move(config)));
 }
 
 void DaemonController::DoSetConfigAndStart(
@@ -145,7 +145,7 @@
 
   DaemonController::UsageStatsConsent consent =
       delegate_->GetUsageStatsConsent();
-  caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, consent));
+  caller_task_runner_->PostTask(FROM_HERE, base::BindOnce(done, consent));
 }
 
 void DaemonController::InvokeCompletionCallbackAndScheduleNext(
@@ -154,8 +154,9 @@
   if (!caller_task_runner_->BelongsToCurrentThread()) {
     caller_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext,
-                   this, done, result));
+        base::BindOnce(
+            &DaemonController::InvokeCompletionCallbackAndScheduleNext, this,
+            done, result));
     return;
   }
 
diff --git a/remoting/host/setup/host_starter.cc b/remoting/host/setup/host_starter.cc
index 4472d1e..2769d9f 100644
--- a/remoting/host/setup/host_starter.cc
+++ b/remoting/host/setup/host_starter.cc
@@ -80,9 +80,10 @@
     const std::string& access_token,
     int expires_in_seconds) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnGetTokensResponse, weak_ptr_,
-        refresh_token, access_token, expires_in_seconds));
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&HostStarter::OnGetTokensResponse, weak_ptr_,
+                       refresh_token, access_token, expires_in_seconds));
     return;
   }
   refresh_token_ = refresh_token;
@@ -102,8 +103,9 @@
 // with the service account credentials.
 void HostStarter::OnGetUserEmailResponse(const std::string& user_email) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnGetUserEmailResponse, weak_ptr_, user_email));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&HostStarter::OnGetUserEmailResponse,
+                                  weak_ptr_, user_email));
     return;
   }
 
@@ -131,8 +133,9 @@
 
 void HostStarter::OnHostRegistered(const std::string& authorization_code) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnHostRegistered, weak_ptr_, authorization_code));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&HostStarter::OnHostRegistered, weak_ptr_,
+                                  authorization_code));
     return;
   }
 
@@ -176,8 +179,9 @@
 
 void HostStarter::OnHostStarted(DaemonController::AsyncResult result) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnHostStarted, weak_ptr_, result));
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&HostStarter::OnHostStarted, weak_ptr_, result));
     return;
   }
   if (result != DaemonController::RESULT_OK) {
@@ -190,8 +194,8 @@
 
 void HostStarter::OnOAuthError() {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnOAuthError, weak_ptr_));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&HostStarter::OnOAuthError, weak_ptr_));
     return;
   }
   if (unregistering_host_) {
@@ -204,8 +208,9 @@
 
 void HostStarter::OnNetworkError(int response_code) {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnNetworkError, weak_ptr_, response_code));
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&HostStarter::OnNetworkError, weak_ptr_, response_code));
     return;
   }
   if (unregistering_host_) {
@@ -218,8 +223,8 @@
 
 void HostStarter::OnHostUnregistered() {
   if (!main_task_runner_->BelongsToCurrentThread()) {
-    main_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &HostStarter::OnHostUnregistered, weak_ptr_));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&HostStarter::OnHostUnregistered, weak_ptr_));
     return;
   }
   base::ResetAndReturn(&on_done_).Run(START_ERROR);
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
index 4c2b4d16a..3166b27 100644
--- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -313,9 +313,8 @@
                  base::Unretained(this)));
 
   host_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&Me2MeNativeMessagingHostTest::StartHost,
-                 base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&Me2MeNativeMessagingHostTest::StartHost,
+                                base::Unretained(this)));
 
   // Wait until the host finishes starting.
   test_run_loop_->Run();
@@ -380,9 +379,8 @@
 void Me2MeNativeMessagingHostTest::ExitTest() {
   if (!test_message_loop_->task_runner()->RunsTasksInCurrentSequence()) {
     test_message_loop_->task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&Me2MeNativeMessagingHostTest::ExitTest,
-                   base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&Me2MeNativeMessagingHostTest::ExitTest,
+                                  base::Unretained(this)));
     return;
   }
   test_run_loop_->Quit();
diff --git a/remoting/host/setup/start_host_main.cc b/remoting/host/setup/start_host_main.cc
index 8a7898b1..ded0027 100644
--- a/remoting/host/setup/start_host_main.cc
+++ b/remoting/host/setup/start_host_main.cc
@@ -98,7 +98,7 @@
 void OnDone(HostStarter::Result result) {
   if (!g_message_loop->task_runner()->BelongsToCurrentThread()) {
     g_message_loop->task_runner()->PostTask(FROM_HERE,
-                                            base::Bind(&OnDone, result));
+                                            base::BindOnce(&OnDone, result));
     return;
   }
   switch (result) {
diff --git a/remoting/host/win/host_service.cc b/remoting/host/win/host_service.cc
index 7fc475b..461a55a 100644
--- a/remoting/host/win/host_service.cc
+++ b/remoting/host/win/host_service.cc
@@ -382,8 +382,8 @@
     case CTRL_LOGOFF_EVENT:
     case CTRL_SHUTDOWN_EVENT:
       self->main_task_runner_->PostTask(
-          FROM_HERE, base::Bind(&HostService::StopDaemonProcess,
-                                self->weak_ptr_));
+          FROM_HERE,
+          base::BindOnce(&HostService::StopDaemonProcess, self->weak_ptr_));
       return TRUE;
 
     default:
@@ -404,14 +404,17 @@
     case SERVICE_CONTROL_SHUTDOWN:
     case SERVICE_CONTROL_STOP:
       self->main_task_runner_->PostTask(
-          FROM_HERE, base::Bind(&HostService::StopDaemonProcess,
-                                self->weak_ptr_));
+          FROM_HERE,
+          base::BindOnce(&HostService::StopDaemonProcess, self->weak_ptr_));
       return NO_ERROR;
 
     case SERVICE_CONTROL_SESSIONCHANGE:
-      self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
-          &HostService::OnSessionChange, self->weak_ptr_, event_type,
-          reinterpret_cast<WTSSESSION_NOTIFICATION*>(event_data)->dwSessionId));
+      self->main_task_runner_->PostTask(
+          FROM_HERE,
+          base::BindOnce(&HostService::OnSessionChange, self->weak_ptr_,
+                         event_type,
+                         reinterpret_cast<WTSSESSION_NOTIFICATION*>(event_data)
+                             ->dwSessionId));
       return NO_ERROR;
 
     default:
diff --git a/remoting/host/win/rdp_client.cc b/remoting/host/win/rdp_client.cc
index 01a7caf2..a29f5b4 100644
--- a/remoting/host/win/rdp_client.cc
+++ b/remoting/host/win/rdp_client.cc
@@ -134,8 +134,8 @@
                               DWORD port_number) {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
     ui_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&Core::Connect, this, resolution, terminal_id, port_number));
+        FROM_HERE, base::BindOnce(&Core::Connect, this, resolution, terminal_id,
+                                  port_number));
     return;
   }
 
@@ -159,7 +159,8 @@
 
 void RdpClient::Core::Disconnect() {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
-    ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Disconnect, this));
+    ui_task_runner_->PostTask(FROM_HERE,
+                              base::BindOnce(&Core::Disconnect, this));
     return;
   }
 
@@ -176,7 +177,8 @@
 
 void RdpClient::Core::InjectSas() {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
-    ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::InjectSas, this));
+    ui_task_runner_->PostTask(FROM_HERE,
+                              base::BindOnce(&Core::InjectSas, this));
     return;
   }
 
@@ -188,7 +190,7 @@
 void RdpClient::Core::ChangeResolution(const ScreenResolution& resolution) {
   if (!ui_task_runner_->BelongsToCurrentThread()) {
     ui_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::ChangeResolution, this, resolution));
+        FROM_HERE, base::BindOnce(&Core::ChangeResolution, this, resolution));
     return;
   }
 
@@ -222,8 +224,8 @@
 
 void RdpClient::Core::NotifyConnected() {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
-    caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::NotifyConnected, this));
+    caller_task_runner_->PostTask(FROM_HERE,
+                                  base::BindOnce(&Core::NotifyConnected, this));
     return;
   }
 
@@ -233,8 +235,8 @@
 
 void RdpClient::Core::NotifyClosed() {
   if (!caller_task_runner_->BelongsToCurrentThread()) {
-    caller_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::NotifyClosed, this));
+    caller_task_runner_->PostTask(FROM_HERE,
+                                  base::BindOnce(&Core::NotifyClosed, this));
     return;
   }
 
diff --git a/remoting/host/win/rdp_client_unittest.cc b/remoting/host/win/rdp_client_unittest.cc
index 10a6b03b..3167e155 100644
--- a/remoting/host/win/rdp_client_unittest.cc
+++ b/remoting/host/win/rdp_client_unittest.cc
@@ -143,7 +143,7 @@
 
   message_loop_.task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&RdpClientTest::CloseRdpClient, base::Unretained(this)));
+      base::BindOnce(&RdpClientTest::CloseRdpClient, base::Unretained(this)));
 }
 
 void RdpClientTest::CloseRdpClient() {
diff --git a/remoting/host/win/session_input_injector.cc b/remoting/host/win/session_input_injector.cc
index a52725e..57d8dde 100644
--- a/remoting/host/win/session_input_injector.cc
+++ b/remoting/host/win/session_input_injector.cc
@@ -117,7 +117,7 @@
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&Core::Start, this, base::Passed(&client_clipboard)));
+        base::BindOnce(&Core::Start, this, std::move(client_clipboard)));
     return;
   }
 
@@ -128,7 +128,7 @@
     const ClipboardEvent& event) {
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent, this, event));
     return;
   }
 
@@ -138,7 +138,7 @@
 void SessionInputInjectorWin::Core::InjectKeyEvent(const KeyEvent& event) {
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectKeyEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectKeyEvent, this, event));
     return;
   }
 
@@ -171,7 +171,7 @@
 void SessionInputInjectorWin::Core::InjectTextEvent(const TextEvent& event) {
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectTextEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectTextEvent, this, event));
     return;
   }
 
@@ -182,7 +182,7 @@
 void SessionInputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) {
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectMouseEvent, this, event));
     return;
   }
 
@@ -193,7 +193,7 @@
 void SessionInputInjectorWin::Core::InjectTouchEvent(const TouchEvent& event) {
   if (!input_task_runner_->BelongsToCurrentThread()) {
     input_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InjectTouchEvent, this, event));
+        FROM_HERE, base::BindOnce(&Core::InjectTouchEvent, this, event));
     return;
   }
 
diff --git a/remoting/host/win/worker_process_launcher_unittest.cc b/remoting/host/win/worker_process_launcher_unittest.cc
index db01caed..6d71286 100644
--- a/remoting/host/win/worker_process_launcher_unittest.cc
+++ b/remoting/host/win/worker_process_launcher_unittest.cc
@@ -248,9 +248,8 @@
   DoLaunchProcess();
 
   task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&WorkerProcessLauncherTest::ConnectClient,
-                 base::Unretained(this)));
+      FROM_HERE, base::BindOnce(&WorkerProcessLauncherTest::ConnectClient,
+                                base::Unretained(this)));
 }
 
 void WorkerProcessLauncherTest::FailLaunchAndStopWorker(
@@ -259,10 +258,9 @@
 
   event_handler->OnFatalError();
 
-  task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&WorkerProcessLauncherTest::StopWorker,
-                 base::Unretained(this)));
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&WorkerProcessLauncherTest::StopWorker,
+                                        base::Unretained(this)));
 }
 
 void WorkerProcessLauncherTest::KillProcess() {
diff --git a/remoting/host/win/wts_session_process_delegate.cc b/remoting/host/win/wts_session_process_delegate.cc
index 9a3092f..1599721 100644
--- a/remoting/host/win/wts_session_process_delegate.cc
+++ b/remoting/host/win/wts_session_process_delegate.cc
@@ -212,7 +212,7 @@
     // MessageLoopForIO::RegisterJobObject() can only be called via
     // MessageLoopCurrentForIO::Get().
     io_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&Core::InitializeJob, this, base::Passed(&job)));
+        FROM_HERE, base::BindOnce(&Core::InitializeJob, this, std::move(job)));
   }
 
   // Create a session token for the launched process.
@@ -301,7 +301,7 @@
   switch (bytes_transferred) {
     case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
       caller_task_runner_->PostTask(
-          FROM_HERE, base::Bind(&Core::OnActiveProcessZero, this));
+          FROM_HERE, base::BindOnce(&Core::OnActiveProcessZero, this));
       break;
     }
     case JOB_OBJECT_MSG_NEW_PROCESS: {
@@ -334,8 +334,8 @@
         }
 
         caller_task_runner_->PostTask(
-            FROM_HERE, base::Bind(&Core::OnProcessLaunchDetected, this,
-                                  worker_process_pid_));
+            FROM_HERE, base::BindOnce(&Core::OnProcessLaunchDetected, this,
+                                      worker_process_pid_));
       }
       break;
     }
@@ -464,8 +464,8 @@
   // DrainJobNotifications() is posted after the job object is destroyed, so
   // by this time all notifications from the job object have been processed
   // already. Let the main thread know that the queue has been drained.
-  caller_task_runner_->PostTask(FROM_HERE, base::Bind(
-      &Core::DrainJobNotificationsCompleted, this));
+  caller_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&Core::DrainJobNotificationsCompleted, this));
 }
 
 void WtsSessionProcessDelegate::Core::DrainJobNotificationsCompleted() {
@@ -476,8 +476,8 @@
 
     // Drain the completion queue to make sure all job object notification have
     // been received.
-    io_task_runner_->PostTask(FROM_HERE, base::Bind(
-        &Core::DrainJobNotifications, this));
+    io_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&Core::DrainJobNotifications, this));
   }
 }
 
@@ -492,8 +492,9 @@
   }
 
   // Let the main thread know that initialization is complete.
-  caller_task_runner_->PostTask(FROM_HERE, base::Bind(
-      &Core::InitializeJobCompleted, this, base::Passed(&job)));
+  caller_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&Core::InitializeJobCompleted, this, std::move(job)));
 }
 
 void WtsSessionProcessDelegate::Core::InitializeJobCompleted(ScopedHandle job) {
diff --git a/remoting/ios/display/gl_display_handler.mm b/remoting/ios/display/gl_display_handler.mm
index eed2696..c631ae71 100644
--- a/remoting/ios/display/gl_display_handler.mm
+++ b/remoting/ios/display/gl_display_handler.mm
@@ -107,7 +107,7 @@
       std::make_unique<RendererProxy>(runtime_->display_task_runner());
 
   runtime_->display_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&Core::Initialize, GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&Core::Initialize, GetWeakPtr()));
 }
 
 Core::~Core() {
@@ -211,8 +211,9 @@
   renderer_->RequestCanvasSize();
 
   runtime_->network_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&DualBufferFrameConsumer::RequestFullDesktopFrame,
-                            frame_consumer_));
+      FROM_HERE,
+      base::BindOnce(&DualBufferFrameConsumer::RequestFullDesktopFrame,
+                     frame_consumer_));
 }
 
 void Core::DestroyRendererContext() {
@@ -305,8 +306,8 @@
 - (void)setDelegate:(id<GlDisplayHandlerDelegate>)delegate {
   _runtime->display_task_runner()->PostTask(
       FROM_HERE,
-      base::Bind(&remoting::GlDisplayHandler::Core::SetHandlerDelegate,
-                 _core->GetWeakPtr(), delegate));
+      base::BindOnce(&remoting::GlDisplayHandler::Core::SetHandlerDelegate,
+                     _core->GetWeakPtr(), delegate));
 }
 
 - (id<GlDisplayHandlerDelegate>)delegate {
diff --git a/remoting/protocol/audio_pump.cc b/remoting/protocol/audio_pump.cc
index eaaabc6..76f8786 100644
--- a/remoting/protocol/audio_pump.cc
+++ b/remoting/protocol/audio_pump.cc
@@ -189,8 +189,8 @@
   bytes_pending_ += packet_size;
 
   pump_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AudioPump::SendAudioPacket, pump_,
-                            base::Passed(&encoded_packet), packet_size));
+      FROM_HERE, base::BindOnce(&AudioPump::SendAudioPacket, pump_,
+                                std::move(encoded_packet), packet_size));
 }
 
 std::unique_ptr<AudioPacket> AudioPump::Core::Downmix(
@@ -236,7 +236,7 @@
                        std::move(audio_encoder)));
 
   audio_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get())));
+      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get())));
 }
 
 AudioPump::~AudioPump() {
@@ -250,7 +250,7 @@
 
   audio_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::Pause, base::Unretained(core_.get()), pause));
+      base::BindOnce(&Core::Pause, base::Unretained(core_.get()), pause));
 }
 
 void AudioPump::SendAudioPacket(std::unique_ptr<AudioPacket> packet, int size) {
@@ -265,7 +265,7 @@
 void AudioPump::OnPacketSent(int size) {
   audio_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::OnPacketSent, base::Unretained(core_.get()), size));
+      base::BindOnce(&Core::OnPacketSent, base::Unretained(core_.get()), size));
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/channel_multiplexer.cc b/remoting/protocol/channel_multiplexer.cc
index 313b351..1872bbd 100644
--- a/remoting/protocol/channel_multiplexer.cc
+++ b/remoting/protocol/channel_multiplexer.cc
@@ -387,8 +387,8 @@
   // callback may destroy the multiplexer or somehow else modify
   // |pending_channels_| list (e.g. call CancelChannelCreation()).
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&ChannelMultiplexer::DoCreatePendingChannels,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&ChannelMultiplexer::DoCreatePendingChannels,
+                                weak_factory_.GetWeakPtr()));
 
   PendingChannel c = pending_channels_.front();
   pending_channels_.erase(pending_channels_.begin());
@@ -415,8 +415,8 @@
   for (auto it = channels_.begin(); it != channels_.end(); ++it) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&ChannelMultiplexer::NotifyBaseChannelError,
-                   weak_factory_.GetWeakPtr(), it->second->name(), error));
+        base::BindOnce(&ChannelMultiplexer::NotifyBaseChannelError,
+                       weak_factory_.GetWeakPtr(), it->second->name(), error));
   }
 }
 
diff --git a/remoting/protocol/clipboard_thread_proxy.cc b/remoting/protocol/clipboard_thread_proxy.cc
index b401241..077cb91 100644
--- a/remoting/protocol/clipboard_thread_proxy.cc
+++ b/remoting/protocol/clipboard_thread_proxy.cc
@@ -20,10 +20,10 @@
 }
 
 void ClipboardThreadProxy::InjectClipboardEvent(const ClipboardEvent& event) {
-  clipboard_stub_task_runner_->PostTask(FROM_HERE, base::Bind(
-      &ClipboardThreadProxy::InjectClipboardEventStatic,
-      clipboard_stub_,
-      event));
+  clipboard_stub_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&ClipboardThreadProxy::InjectClipboardEventStatic,
+                     clipboard_stub_, event));
 }
 
 void ClipboardThreadProxy::InjectClipboardEventStatic(
diff --git a/remoting/protocol/connection_tester.cc b/remoting/protocol/connection_tester.cc
index a8b65f1..01b66ef2 100644
--- a/remoting/protocol/connection_tester.cc
+++ b/remoting/protocol/connection_tester.cc
@@ -212,7 +212,8 @@
     packets_sent_++;
     task_runner_->PostDelayedTask(
         FROM_HERE,
-        base::Bind(&DatagramConnectionTester::DoWrite, base::Unretained(this)),
+        base::BindOnce(&DatagramConnectionTester::DoWrite,
+                       base::Unretained(this)),
         base::TimeDelta::FromMilliseconds(delay_ms_));
   }
 }
diff --git a/remoting/protocol/fake_datagram_socket.cc b/remoting/protocol/fake_datagram_socket.cc
index 1b06864..fddd67a 100644
--- a/remoting/protocol/fake_datagram_socket.cc
+++ b/remoting/protocol/fake_datagram_socket.cc
@@ -77,8 +77,8 @@
     send_pending_ = true;
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&FakeDatagramSocket::DoAsyncSend, weak_factory_.GetWeakPtr(),
-                   buf, buf_len, callback));
+        base::BindOnce(&FakeDatagramSocket::DoAsyncSend,
+                       weak_factory_.GetWeakPtr(), buf, buf_len, callback));
     return net::ERR_IO_PENDING;
   } else {
     return DoSend(buf, buf_len);
@@ -111,8 +111,8 @@
   if (peer_socket_.get()) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&FakeDatagramSocket::AppendInputPacket, peer_socket_,
-                   std::string(buf->data(), buf->data() + buf_len)));
+        base::BindOnce(&FakeDatagramSocket::AppendInputPacket, peer_socket_,
+                       std::string(buf->data(), buf->data() + buf_len)));
   }
 
   return buf_len;
@@ -171,9 +171,9 @@
   if (asynchronous_create_) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&FakeDatagramChannelFactory::NotifyChannelCreated,
-                   weak_factory_.GetWeakPtr(), base::Passed(&channel),
-                   name, callback));
+        base::BindOnce(&FakeDatagramChannelFactory::NotifyChannelCreated,
+                       weak_factory_.GetWeakPtr(), std::move(channel), name,
+                       callback));
   } else {
     NotifyChannelCreated(std::move(channel), name, callback);
   }
diff --git a/remoting/protocol/fake_message_pipe.cc b/remoting/protocol/fake_message_pipe.cc
index 3537235..8ca852162 100644
--- a/remoting/protocol/fake_message_pipe.cc
+++ b/remoting/protocol/fake_message_pipe.cc
@@ -33,15 +33,12 @@
 void FakeMessagePipe::Send(google::protobuf::MessageLite* message,
                            const base::Closure& done) {
   if (asynchronous_) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-        base::Bind([](FakeMessagePipe* me,
-                      google::protobuf::MessageLite* message,
-                      const base::Closure& done) {
-                     me->SendImpl(message, done);
-                   },
-                   base::Unretained(this),
-                   base::Unretained(message),
-                   done));
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            [](FakeMessagePipe* me, google::protobuf::MessageLite* message,
+               const base::Closure& done) { me->SendImpl(message, done); },
+            base::Unretained(this), base::Unretained(message), done));
     return;
   }
   SendImpl(message, done);
@@ -49,13 +46,13 @@
 
 void FakeMessagePipe::Receive(std::unique_ptr<CompoundBuffer> message) {
   if (asynchronous_) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-        base::Bind([](FakeMessagePipe* me,
-                      std::unique_ptr<CompoundBuffer> message) {
-                     me->ReceiveImpl(std::move(message));
-                   },
-                   base::Unretained(this),
-                   base::Passed(std::move(message))));
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            [](FakeMessagePipe* me, std::unique_ptr<CompoundBuffer> message) {
+              me->ReceiveImpl(std::move(message));
+            },
+            base::Unretained(this), base::Passed(std::move(message))));
     return;
   }
 
@@ -64,11 +61,10 @@
 
 void FakeMessagePipe::OpenPipe() {
   if (asynchronous_) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(
-        [](FakeMessagePipe* me) {
-          me->OpenPipeImpl();
-        },
-        base::Unretained(this)));
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce([](FakeMessagePipe* me) { me->OpenPipeImpl(); },
+                       base::Unretained(this)));
     return;
   }
 
@@ -77,11 +73,10 @@
 
 void FakeMessagePipe::ClosePipe() {
   if (asynchronous_) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(
-        [](FakeMessagePipe* me) {
-          me->ClosePipeImpl();
-        },
-        base::Unretained(this)));
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce([](FakeMessagePipe* me) { me->ClosePipeImpl(); },
+                       base::Unretained(this)));
     return;
   }
 
diff --git a/remoting/protocol/fake_session.cc b/remoting/protocol/fake_session.cc
index 68e6551..6c59aae 100644
--- a/remoting/protocol/fake_session.cc
+++ b/remoting/protocol/fake_session.cc
@@ -84,7 +84,7 @@
       peer->Close(error);
     } else {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::Bind(&FakeSession::Close, peer, error),
+          FROM_HERE, base::BindOnce(&FakeSession::Close, peer, error),
           signaling_delay_);
     }
   }
@@ -99,8 +99,9 @@
     peer_->ProcessTransportInfo(std::move(transport_info));
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE, base::Bind(&FakeSession::ProcessTransportInfo, peer_,
-                              base::Passed(&transport_info)),
+        FROM_HERE,
+        base::BindOnce(&FakeSession::ProcessTransportInfo, peer_,
+                       std::move(transport_info)),
         signaling_delay_);
   }
 }
diff --git a/remoting/protocol/fake_stream_socket.cc b/remoting/protocol/fake_stream_socket.cc
index c8561af2..f9bbc0f 100644
--- a/remoting/protocol/fake_stream_socket.cc
+++ b/remoting/protocol/fake_stream_socket.cc
@@ -27,8 +27,8 @@
   EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
   if (peer_socket_) {
     task_runner_->PostTask(
-        FROM_HERE, base::Bind(&FakeStreamSocket::SetReadError, peer_socket_,
-                              net::ERR_CONNECTION_CLOSED));
+        FROM_HERE, base::BindOnce(&FakeStreamSocket::SetReadError, peer_socket_,
+                                  net::ERR_CONNECTION_CLOSED));
   }
 }
 
@@ -147,9 +147,8 @@
   if (peer_socket_) {
     task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&FakeStreamSocket::AppendInputData,
-                   peer_socket_,
-                   std::string(buf->data(), buf->data() + buf_len)));
+        base::BindOnce(&FakeStreamSocket::AppendInputData, peer_socket_,
+                       std::string(buf->data(), buf->data() + buf_len)));
   }
 }
 
@@ -188,9 +187,11 @@
     channel.reset();
 
   if (asynchronous_create_) {
-    task_runner_->PostTask(FROM_HERE, base::Bind(
-        &FakeStreamChannelFactory::NotifyChannelCreated,
-        weak_factory_.GetWeakPtr(), base::Passed(&channel), name, callback));
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&FakeStreamChannelFactory::NotifyChannelCreated,
+                       weak_factory_.GetWeakPtr(), std::move(channel), name,
+                       callback));
   } else {
     NotifyChannelCreated(std::move(channel), name, callback);
   }
diff --git a/remoting/protocol/ice_transport_channel.cc b/remoting/protocol/ice_transport_channel.cc
index a50328a..2870699 100644
--- a/remoting/protocol/ice_transport_channel.cc
+++ b/remoting/protocol/ice_transport_channel.cc
@@ -132,8 +132,8 @@
                          this, &IceTransportChannel::TryReconnect);
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&IceTransportChannel::NotifyConnected,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&IceTransportChannel::NotifyConnected,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void IceTransportChannel::NotifyConnected() {
diff --git a/remoting/protocol/ice_transport_unittest.cc b/remoting/protocol/ice_transport_unittest.cc
index 3ed180d..98698cd 100644
--- a/remoting/protocol/ice_transport_unittest.cc
+++ b/remoting/protocol/ice_transport_unittest.cc
@@ -97,9 +97,10 @@
   void ProcessTransportInfo(std::unique_ptr<IceTransport>* target_transport,
                             std::unique_ptr<jingle_xmpp::XmlElement> transport_info) {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE, base::Bind(&IceTransportTest::DeliverTransportInfo,
-                              base::Unretained(this), target_transport,
-                              base::Passed(&transport_info)),
+        FROM_HERE,
+        base::BindOnce(&IceTransportTest::DeliverTransportInfo,
+                       base::Unretained(this), target_transport,
+                       std::move(transport_info)),
         transport_info_delay_);
   }
 
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index 2928677d..fbf0641 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -230,9 +230,9 @@
 
   // Delay sending session-initiate message to ensure SessionPlugin can be
   // attached before the message.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-      base::Bind(&JingleSession::SendSessionInitiateMessage,
-                 weak_factory_.GetWeakPtr()));
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(&JingleSession::SendSessionInitiateMessage,
+                                weak_factory_.GetWeakPtr()));
 
   SetState(CONNECTING);
 }
diff --git a/remoting/protocol/message_reader.cc b/remoting/protocol/message_reader.cc
index 3c92c01..1378ffb3 100644
--- a/remoting/protocol/message_reader.cc
+++ b/remoting/protocol/message_reader.cc
@@ -108,8 +108,8 @@
       break;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&MessageReader::RunCallback, weak_factory_.GetWeakPtr(),
-                   base::Passed(base::WrapUnique(buffer))));
+        base::BindOnce(&MessageReader::RunCallback, weak_factory_.GetWeakPtr(),
+                       base::Passed(base::WrapUnique(buffer))));
   }
 }
 
diff --git a/remoting/protocol/pseudotcp_adapter_unittest.cc b/remoting/protocol/pseudotcp_adapter_unittest.cc
index c60d1238..f8cfa1a 100644
--- a/remoting/protocol/pseudotcp_adapter_unittest.cc
+++ b/remoting/protocol/pseudotcp_adapter_unittest.cc
@@ -138,9 +138,9 @@
     if (peer_socket_) {
       base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
           FROM_HERE,
-          base::Bind(&FakeSocket::AppendInputPacket,
-                     base::Unretained(peer_socket_),
-                     std::vector<char>(buf->data(), buf->data() + buf_len)),
+          base::BindOnce(&FakeSocket::AppendInputPacket,
+                         base::Unretained(peer_socket_),
+                         std::vector<char>(buf->data(), buf->data() + buf_len)),
           base::TimeDelta::FromMilliseconds(latency_ms_));
     }
 
@@ -173,7 +173,7 @@
 
   void Start() {
     task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&TCPChannelTester::DoStart, this));
+                           base::BindOnce(&TCPChannelTester::DoStart, this));
   }
 
   void CheckResults() {
diff --git a/remoting/protocol/video_frame_pump.cc b/remoting/protocol/video_frame_pump.cc
index 91a812c8..91dbe14 100644
--- a/remoting/protocol/video_frame_pump.cc
+++ b/remoting/protocol/video_frame_pump.cc
@@ -85,16 +85,18 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   encode_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&VideoEncoder::SetLosslessEncode,
-                            base::Unretained(encoder_.get()), want_lossless));
+      FROM_HERE,
+      base::BindOnce(&VideoEncoder::SetLosslessEncode,
+                     base::Unretained(encoder_.get()), want_lossless));
 }
 
 void VideoFramePump::SetLosslessColor(bool want_lossless) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   encode_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&VideoEncoder::SetLosslessColor,
-                            base::Unretained(encoder_.get()), want_lossless));
+      FROM_HERE,
+      base::BindOnce(&VideoEncoder::SetLosslessColor,
+                     base::Unretained(encoder_.get()), want_lossless));
 }
 
 void VideoFramePump::SetObserver(Observer* observer) {
diff --git a/remoting/protocol/webrtc_audio_sink_adapter.cc b/remoting/protocol/webrtc_audio_sink_adapter.cc
index 651d4eec..4b1f6d58 100644
--- a/remoting/protocol/webrtc_audio_sink_adapter.cc
+++ b/remoting/protocol/webrtc_audio_sink_adapter.cc
@@ -70,8 +70,8 @@
   audio_packet->add_data(reinterpret_cast<const char*>(audio_data), data_size);
 
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AudioStub::ProcessAudioPacket, audio_stub_,
-                            base::Passed(&audio_packet), base::Closure()));
+      FROM_HERE, base::BindOnce(&AudioStub::ProcessAudioPacket, audio_stub_,
+                                std::move(audio_packet), base::Closure()));
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/webrtc_audio_source_adapter.cc b/remoting/protocol/webrtc_audio_source_adapter.cc
index f6eda6e3..559a076f 100644
--- a/remoting/protocol/webrtc_audio_source_adapter.cc
+++ b/remoting/protocol/webrtc_audio_source_adapter.cc
@@ -157,14 +157,14 @@
 void WebrtcAudioSourceAdapter::Start(
     std::unique_ptr<AudioSource> audio_source) {
   audio_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()),
-                            base::Passed(&audio_source)));
+      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()),
+                                std::move(audio_source)));
 }
 
 void WebrtcAudioSourceAdapter::Pause(bool pause) {
   audio_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::Pause, base::Unretained(core_.get()), pause));
+      base::BindOnce(&Core::Pause, base::Unretained(core_.get()), pause));
 }
 
 WebrtcAudioSourceAdapter::SourceState WebrtcAudioSourceAdapter::state() const {
diff --git a/remoting/protocol/webrtc_dummy_video_encoder.cc b/remoting/protocol/webrtc_dummy_video_encoder.cc
index 562fa3eb..6261e73 100644
--- a/remoting/protocol/webrtc_dummy_video_encoder.cc
+++ b/remoting/protocol/webrtc_dummy_video_encoder.cc
@@ -110,16 +110,17 @@
   // be called only from VCMGenericEncoder::RequestFrame() to request a key
   // frame.
   main_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&VideoChannelStateObserver::OnKeyFrameRequested,
-                            video_channel_state_observer_));
+      FROM_HERE, base::BindOnce(&VideoChannelStateObserver::OnKeyFrameRequested,
+                                video_channel_state_observer_));
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 int32_t WebrtcDummyVideoEncoder::SetRates(uint32_t bitrate,
                                           uint32_t framerate) {
   main_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&VideoChannelStateObserver::OnTargetBitrateChanged,
-                            video_channel_state_observer_, bitrate));
+      FROM_HERE,
+      base::BindOnce(&VideoChannelStateObserver::OnTargetBitrateChanged,
+                     video_channel_state_observer_, bitrate));
   // framerate is not expected to be valid given we never report captured
   // frames.
   return WEBRTC_VIDEO_CODEC_OK;
@@ -248,8 +249,8 @@
   base::AutoLock lock(lock_);
   encoders_.push_back(encoder.get());
   if (encoder_created_callback_) {
-    main_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(encoder_created_callback_, type));
+    main_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(encoder_created_callback_, type));
   }
   return encoder;
 }
diff --git a/remoting/protocol/webrtc_video_renderer_adapter.cc b/remoting/protocol/webrtc_video_renderer_adapter.cc
index 50f1fbd..54e752ad 100644
--- a/remoting/protocol/webrtc_video_renderer_adapter.cc
+++ b/remoting/protocol/webrtc_video_renderer_adapter.cc
@@ -105,11 +105,11 @@
 
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&WebrtcVideoRendererAdapter::HandleFrameOnMainThread,
-                 weak_factory_.GetWeakPtr(), frame.transport_frame_id(),
-                 base::TimeTicks::Now(),
-                 scoped_refptr<webrtc::VideoFrameBuffer>(
-                     frame.video_frame_buffer().get())));
+      base::BindOnce(&WebrtcVideoRendererAdapter::HandleFrameOnMainThread,
+                     weak_factory_.GetWeakPtr(), frame.transport_frame_id(),
+                     base::TimeTicks::Now(),
+                     scoped_refptr<webrtc::VideoFrameBuffer>(
+                         frame.video_frame_buffer().get())));
 }
 
 void WebrtcVideoRendererAdapter::OnVideoFrameStats(
diff --git a/remoting/signaling/delegating_signal_strategy.cc b/remoting/signaling/delegating_signal_strategy.cc
index 0e58fdf4..9ac290c3 100644
--- a/remoting/signaling/delegating_signal_strategy.cc
+++ b/remoting/signaling/delegating_signal_strategy.cc
@@ -46,8 +46,8 @@
   }
 
   client_task_runner->PostTask(
-      FROM_HERE, base::Bind(&DelegatingSignalStrategy::OnIncomingMessage,
-                            weak_ptr, message));
+      FROM_HERE, base::BindOnce(&DelegatingSignalStrategy::OnIncomingMessage,
+                                weak_ptr, message));
 }
 
 void DelegatingSignalStrategy::OnIncomingMessage(const std::string& message) {
@@ -103,8 +103,8 @@
     std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
   DCHECK(client_task_runner_->BelongsToCurrentThread());
   GetLocalAddress().SetInMessage(stanza.get(), SignalingAddress::FROM);
-  delegate_task_runner_->PostTask(FROM_HERE,
-                                  base::Bind(send_iq_callback_, stanza->Str()));
+  delegate_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(send_iq_callback_, stanza->Str()));
   return true;
 }
 
diff --git a/remoting/signaling/fake_signal_strategy.cc b/remoting/signaling/fake_signal_strategy.cc
index 91c4304..2b23ded8 100644
--- a/remoting/signaling/fake_signal_strategy.cc
+++ b/remoting/signaling/fake_signal_strategy.cc
@@ -49,8 +49,8 @@
     peer->SetPeerCallback(peer_callback);
   } else {
     peer->main_thread_->PostTask(
-        FROM_HERE, base::Bind(&FakeSignalStrategy::SetPeerCallback,
-                              base::Unretained(peer), peer_callback));
+        FROM_HERE, base::BindOnce(&FakeSignalStrategy::SetPeerCallback,
+                                  base::Unretained(peer), peer_callback));
   }
 }
 
@@ -113,7 +113,7 @@
     peer_callback_.Run(std::move(stanza));
   } else {
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-        FROM_HERE, base::Bind(peer_callback_, base::Passed(&stanza)),
+        FROM_HERE, base::BindOnce(peer_callback_, std::move(stanza)),
         send_delay_);
   }
   return true;
@@ -129,9 +129,9 @@
     scoped_refptr<base::SingleThreadTaskRunner> thread,
     base::WeakPtr<FakeSignalStrategy> target,
     std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
-  thread->PostTask(FROM_HERE,
-                   base::Bind(&FakeSignalStrategy::OnIncomingMessage,
-                              target, base::Passed(&stanza)));
+  thread->PostTask(
+      FROM_HERE, base::BindOnce(&FakeSignalStrategy::OnIncomingMessage, target,
+                                std::move(stanza)));
 }
 
 void FakeSignalStrategy::OnIncomingMessage(
diff --git a/remoting/signaling/iq_sender.cc b/remoting/signaling/iq_sender.cc
index 9a96bf9..37c2ee6 100644
--- a/remoting/signaling/iq_sender.cc
+++ b/remoting/signaling/iq_sender.cc
@@ -144,7 +144,8 @@
 
 void IqRequest::SetTimeout(base::TimeDelta timeout) {
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::Bind(&IqRequest::OnTimeout, weak_factory_.GetWeakPtr()),
+      FROM_HERE,
+      base::BindOnce(&IqRequest::OnTimeout, weak_factory_.GetWeakPtr()),
       timeout);
 }
 
@@ -163,8 +164,8 @@
   std::unique_ptr<jingle_xmpp::XmlElement> stanza_copy(new jingle_xmpp::XmlElement(*stanza));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&IqRequest::DeliverResponse, weak_factory_.GetWeakPtr(),
-                 base::Passed(&stanza_copy)));
+      base::BindOnce(&IqRequest::DeliverResponse, weak_factory_.GetWeakPtr(),
+                     std::move(stanza_copy)));
 }
 
 void IqRequest::DeliverResponse(std::unique_ptr<jingle_xmpp::XmlElement> stanza) {
diff --git a/remoting/test/fake_network_dispatcher.cc b/remoting/test/fake_network_dispatcher.cc
index 0c96e07..c547bca 100644
--- a/remoting/test/fake_network_dispatcher.cc
+++ b/remoting/test/fake_network_dispatcher.cc
@@ -75,9 +75,9 @@
     // case.
     scoped_refptr<base::SingleThreadTaskRunner> task_runner = node->GetThread();
     if (!task_runner->BelongsToCurrentThread()) {
-      task_runner->PostTask(FROM_HERE,
-                            base::Bind(&FakeNetworkDispatcher::DeliverPacket,
-                                       this, from, to, data, data_size));
+      task_runner->PostTask(
+          FROM_HERE, base::BindOnce(&FakeNetworkDispatcher::DeliverPacket, this,
+                                    from, to, data, data_size));
       return;
     }
   }
diff --git a/remoting/test/fake_network_manager.cc b/remoting/test/fake_network_manager.cc
index 2c74b6d..7a29d8a5 100644
--- a/remoting/test/fake_network_manager.cc
+++ b/remoting/test/fake_network_manager.cc
@@ -26,8 +26,8 @@
 void FakeNetworkManager::StartUpdating() {
   started_ = true;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&FakeNetworkManager::SendNetworksChangedSignal,
-                            weak_factory_.GetWeakPtr()));
+      FROM_HERE, base::BindOnce(&FakeNetworkManager::SendNetworksChangedSignal,
+                                weak_factory_.GetWeakPtr()));
 }
 
 void FakeNetworkManager::StopUpdating() {
diff --git a/remoting/test/fake_socket_factory.cc b/remoting/test/fake_socket_factory.cc
index 07d13d28..7c8e37c 100644
--- a/remoting/test/fake_socket_factory.cc
+++ b/remoting/test/fake_socket_factory.cc
@@ -325,8 +325,8 @@
   pending_packets_.push_back(packet);
   task_runner_->PostDelayedTask(
       FROM_HERE,
-      base::Bind(&FakePacketSocketFactory::DoReceivePacket,
-                 weak_factory_.GetWeakPtr()),
+      base::BindOnce(&FakePacketSocketFactory::DoReceivePacket,
+                     weak_factory_.GetWeakPtr()),
       delay);
 }
 
diff --git a/remoting/test/it2me_standalone_host.cc b/remoting/test/it2me_standalone_host.cc
index 6e16ea0..944172a1 100644
--- a/remoting/test/it2me_standalone_host.cc
+++ b/remoting/test/it2me_standalone_host.cc
@@ -74,7 +74,7 @@
 void It2MeStandaloneHost::Run() {
   main_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&It2MeStandaloneHost::Connect, base::Unretained(this)));
+      base::BindOnce(&It2MeStandaloneHost::Connect, base::Unretained(this)));
   run_loop_.Run();
 }
 
diff --git a/remoting/test/protocol_perftest.cc b/remoting/test/protocol_perftest.cc
index 171661d..ed80305c 100644
--- a/remoting/test/protocol_perftest.cc
+++ b/remoting/test/protocol_perftest.cc
@@ -196,8 +196,8 @@
 
   void OnClientConnected(const std::string& jid) override {
     message_loop_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&ProtocolPerfTest::OnHostConnectedMainThread,
-                              base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&ProtocolPerfTest::OnHostConnectedMainThread,
+                                  base::Unretained(this)));
   }
 
  protected:
@@ -258,7 +258,7 @@
 
     host_thread_.task_runner()->PostTask(
         FROM_HERE,
-        base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this)));
+        base::BindOnce(&ProtocolPerfTest::StartHost, base::Unretained(this)));
   }
 
   void StartHost() {
@@ -323,8 +323,8 @@
     host_->Start(kHostOwner);
 
     message_loop_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&ProtocolPerfTest::StartClientAfterHost,
-                              base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&ProtocolPerfTest::StartClientAfterHost,
+                                  base::Unretained(this)));
   }
 
   void StartClientAfterHost() {
diff --git a/remoting/test/test_video_renderer.cc b/remoting/test/test_video_renderer.cc
index 3f9b26f..a5ebfc2 100644
--- a/remoting/test/test_video_renderer.cc
+++ b/remoting/test/test_video_renderer.cc
@@ -280,8 +280,9 @@
     LOG(ERROR) << "Cannot start TestVideoRenderer";
   } else {
     video_decode_task_runner_ = video_decode_thread_->task_runner();
-    video_decode_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Initialize,
-                                        base::Unretained(core_.get())));
+    video_decode_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&Core::Initialize, base::Unretained(core_.get())));
   }
 }
 
@@ -352,9 +353,8 @@
 
   VLOG(2) << "TestVideoRenderer::SetDecoder() Called";
   video_decode_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&Core::SetCodecForDecoding,
-                            base::Unretained(core_.get()),
-                            codec));
+      FROM_HERE, base::BindOnce(&Core::SetCodecForDecoding,
+                                base::Unretained(core_.get()), codec));
 }
 
 std::unique_ptr<webrtc::DesktopFrame>
@@ -374,9 +374,9 @@
   DVLOG(2) << "TestVideoRenderer::SetImagePatternAndMatchedCallback() Called";
   video_decode_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::ExpectAverageColorInRect, base::Unretained(core_.get()),
-                 expected_rect, expected_avg_color,
-                 image_pattern_matched_callback));
+      base::BindOnce(&Core::ExpectAverageColorInRect,
+                     base::Unretained(core_.get()), expected_rect,
+                     expected_avg_color, image_pattern_matched_callback));
 }
 
 void TestVideoRenderer::SaveFrameDataToDisk(bool save_frame_data_to_disk) {
@@ -384,8 +384,8 @@
 
   video_decode_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&Core::save_frame_data_to_disk, base::Unretained(core_.get()),
-                 save_frame_data_to_disk));
+      base::BindOnce(&Core::save_frame_data_to_disk,
+                     base::Unretained(core_.get()), save_frame_data_to_disk));
 }
 
 }  // namespace test
diff --git a/services/media_session/audio_focus_manager.cc b/services/media_session/audio_focus_manager.cc
index 09b8b7b..aeddd8a 100644
--- a/services/media_session/audio_focus_manager.cc
+++ b/services/media_session/audio_focus_manager.cc
@@ -462,6 +462,8 @@
         if (!session->IsSuspended())
           state.should_duck = true;
         break;
+      case mojom::AudioFocusType::kAmbient:
+        break;
     }
   }
 }
diff --git a/services/media_session/audio_focus_manager_metrics_helper.cc b/services/media_session/audio_focus_manager_metrics_helper.cc
index bbf5e44..6363c0b5 100644
--- a/services/media_session/audio_focus_manager_metrics_helper.cc
+++ b/services/media_session/audio_focus_manager_metrics_helper.cc
@@ -88,6 +88,8 @@
       return AudioFocusType::kGainTransientMayDuck;
     case mojom::AudioFocusType::kGainTransient:
       return AudioFocusType::kGainTransient;
+    case mojom::AudioFocusType::kAmbient:
+      return AudioFocusType::kAmbient;
   }
 
   NOTREACHED();
diff --git a/services/media_session/audio_focus_manager_metrics_helper.h b/services/media_session/audio_focus_manager_metrics_helper.h
index c5892eff..9c4993f 100644
--- a/services/media_session/audio_focus_manager_metrics_helper.h
+++ b/services/media_session/audio_focus_manager_metrics_helper.h
@@ -52,7 +52,8 @@
     kGain = 1,
     kGainTransientMayDuck = 2,
     kGainTransient = 3,
-    kMaxValue = kGainTransient  // Leave at the end.
+    kAmbient = 4,
+    kMaxValue = kAmbient  // Leave at the end.
   };
 
   void OnRequestAudioFocus(AudioFocusRequestSource, mojom::AudioFocusType);
diff --git a/services/media_session/audio_focus_manager_unittest.cc b/services/media_session/audio_focus_manager_unittest.cc
index 8fbe988..029188f 100644
--- a/services/media_session/audio_focus_manager_unittest.cc
+++ b/services/media_session/audio_focus_manager_unittest.cc
@@ -78,6 +78,10 @@
     return GetCountForType(mojom::AudioFocusType::kGainTransientMayDuck);
   }
 
+  int GetAmbientCount() {
+    return GetCountForType(mojom::AudioFocusType::kAmbient);
+  }
+
   void AbandonAudioFocusNoReset(test::MockMediaSession* session) {
     session->audio_focus_request()->AbandonAudioFocus();
     session->FlushForTesting();
@@ -1457,4 +1461,30 @@
   }
 }
 
+TEST_P(AudioFocusManagerTest, AmbientFocusHasNoEffect) {
+  test::MockMediaSession media_session_1;
+  test::MockMediaSession media_session_2;
+
+  AudioFocusManager::RequestId request_id_1 =
+      RequestAudioFocus(&media_session_1, mojom::AudioFocusType::kGain);
+  EXPECT_EQ(request_id_1, GetAudioFocusedSession());
+  EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
+            GetState(&media_session_1));
+
+  EXPECT_EQ(0, GetAmbientCount());
+  RequestAudioFocus(&media_session_2, mojom::AudioFocusType::kAmbient);
+
+  EXPECT_EQ(1, GetAmbientCount());
+  EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
+            GetState(&media_session_1));
+  EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
+            GetState(&media_session_2));
+
+  media_session_2.AbandonAudioFocusFromClient();
+
+  EXPECT_EQ(0, GetAmbientCount());
+  EXPECT_EQ(mojom::MediaSessionInfo::SessionState::kActive,
+            GetState(&media_session_1));
+}
+
 }  // namespace media_session
diff --git a/services/media_session/public/mojom/audio_focus.mojom b/services/media_session/public/mojom/audio_focus.mojom
index 8c64774..f5e5c94 100644
--- a/services/media_session/public/mojom/audio_focus.mojom
+++ b/services/media_session/public/mojom/audio_focus.mojom
@@ -47,6 +47,10 @@
   // Request transient focus when you expect to play audio for only a short
   // time and you expect the previous holder to pause playing.
   kGainTransient,
+
+  // Request audio focus for playback can be mixed with other types of audio.
+  // It has no effect on other holders of audio focus.
+  kAmbient,
 };
 
 // Contains information about |MediaSessions| that have requested audio focus
diff --git a/services/ws/client_root.cc b/services/ws/client_root.cc
index 394392b..22d34d9f 100644
--- a/services/ws/client_root.cc
+++ b/services/ws/client_root.cc
@@ -59,8 +59,8 @@
   window_->AddObserver(this);
   if (window_->GetHost())
     window->GetHost()->AddObserver(this);
-  client_surface_embedder_ = std::make_unique<aura::ClientSurfaceEmbedder>(
-      window_, is_top_level, gfx::Insets());
+  client_surface_embedder_ =
+      std::make_unique<aura::ClientSurfaceEmbedder>(window_);
   if (ShouldAssignLocalSurfaceIdImpl(window, is_top_level_))
     parent_local_surface_id_allocator_.emplace();
   // Ensure there is a valid LocalSurfaceId (if necessary).
@@ -84,13 +84,6 @@
   host_frame_sink_manager->InvalidateFrameSinkId(proxy_window->frame_sink_id());
 }
 
-void ClientRoot::SetClientAreaInsets(const gfx::Insets& client_area_insets) {
-  if (!is_top_level_)
-    return;
-
-  client_surface_embedder_->SetClientAreaInsets(client_area_insets);
-}
-
 void ClientRoot::RegisterVizEmbeddingSupport() {
   // This function should only be called once.
   viz::HostFrameSinkManager* host_frame_sink_manager =
@@ -257,12 +250,6 @@
   // ensures smooth resizes.
   if (ShouldAssignLocalSurfaceId() && window_->GetHost())
     window_->GetHost()->compositor()->OnChildResizing();
-
-  if (fallback_surface_info_) {
-    client_surface_embedder_->SetFallbackSurfaceInfo(*fallback_surface_info_);
-    fallback_surface_info_.reset();
-  }
-  client_surface_embedder_->UpdateSizeAndGutters();
 }
 
 void ClientRoot::CheckForScaleFactorChange() {
@@ -414,24 +401,15 @@
 
 void ClientRoot::OnFirstSurfaceActivation(
     const viz::SurfaceInfo& surface_info) {
-  // TODO(sky): saman says the SetFallbackSurfaceInfo() should not be needed
-  // anymore.
+  if (window_tree_->client_name().empty())
+    return;
+
   ProxyWindow* proxy_window = ProxyWindow::GetMayBeNull(window_);
-  if (proxy_window->local_surface_id_allocation().has_value()) {
-    DCHECK(!fallback_surface_info_);
-    if (!client_surface_embedder_->HasPrimarySurfaceId())
-      UpdateLocalSurfaceIdAndClientSurfaceEmbedder();
-    client_surface_embedder_->SetFallbackSurfaceInfo(surface_info);
-  } else {
-    fallback_surface_info_ = std::make_unique<viz::SurfaceInfo>(surface_info);
-  }
-  if (!window_tree_->client_name().empty()) {
-    // OnFirstSurfaceActivation() should only be called after
-    // AttachCompositorFrameSink().
-    DCHECK(proxy_window->attached_compositor_frame_sink());
-    window_tree_->window_service()->OnFirstSurfaceActivation(
-        window_tree_->client_name());
-  }
+  // OnFirstSurfaceActivation() should only be called after
+  // AttachCompositorFrameSink().
+  DCHECK(proxy_window->attached_compositor_frame_sink());
+  window_tree_->window_service()->OnFirstSurfaceActivation(
+      window_tree_->client_name());
 }
 
 void ClientRoot::OnFrameTokenChanged(uint32_t frame_token) {
diff --git a/services/ws/client_root.h b/services/ws/client_root.h
index 84df5d8..6fcf350 100644
--- a/services/ws/client_root.h
+++ b/services/ws/client_root.h
@@ -27,10 +27,6 @@
 class WindowPositionInRootMonitor;
 }
 
-namespace gfx {
-class Insets;
-}
-
 namespace viz {
 class LocalSurfaceIdAllocation;
 class SurfaceInfo;
@@ -54,11 +50,6 @@
   ClientRoot(WindowTree* window_tree, aura::Window* window, bool is_top_level);
   ~ClientRoot() override;
 
-  // Called when the client area of the window changes. If the window is a
-  // top-level window, then this propagates the insets to the
-  // ClientSurfaceEmbedder.
-  void SetClientAreaInsets(const gfx::Insets& client_area_insets);
-
   // Registers the necessary state needed for embedding in viz.
   void RegisterVizEmbeddingSupport();
 
@@ -167,11 +158,6 @@
   bool is_moving_across_displays_ = false;
   base::Optional<gfx::Rect> scheduled_change_old_bounds_;
 
-  // If non-null then the fallback SurfaceInfo was supplied before the primary
-  // surface. This will be pushed to the Layer once the primary surface is
-  // supplied.
-  std::unique_ptr<viz::SurfaceInfo> fallback_surface_info_;
-
   // Used for non-top-levels to watch for changes in screen coordinates.
   std::unique_ptr<aura_extra::WindowPositionInRootMonitor>
       root_position_monitor_;
diff --git a/services/ws/proxy_window.cc b/services/ws/proxy_window.cc
index d3c15735..c33feee 100644
--- a/services/ws/proxy_window.cc
+++ b/services/ws/proxy_window.cc
@@ -465,11 +465,6 @@
 
   additional_client_areas_ = additional_client_areas;
   client_area_ = insets;
-  ClientRoot* client_root =
-      owning_window_tree_ ? owning_window_tree_->GetClientRootForWindow(window_)
-                          : nullptr;
-  if (client_root)
-    client_root->SetClientAreaInsets(insets);
 }
 
 void ProxyWindow::SetHitTestInsets(const gfx::Insets& mouse,
diff --git a/services/ws/proxy_window_unittest.cc b/services/ws/proxy_window_unittest.cc
index aa819d3..c5992cf4 100644
--- a/services/ws/proxy_window_unittest.cc
+++ b/services/ws/proxy_window_unittest.cc
@@ -88,23 +88,4 @@
   EXPECT_EQ(top_level, setup.root()->targeter()->FindTargetForEvent(
                            setup.root(), &mouse_event_2));
 }
-
-TEST(ProxyWindow, SetClientAreaPropagatesToClientSurfaceEmbedder) {
-  WindowServiceTestSetup setup;
-
-  aura::Window* top_level =
-      setup.window_tree_test_helper()->NewTopLevelWindow();
-  ASSERT_TRUE(top_level);
-  const gfx::Rect top_level_bounds(100, 200, 200, 200);
-  top_level->SetBounds(top_level_bounds);
-  const gfx::Insets top_level_insets(1, 2, 11, 12);
-  setup.window_tree_test_helper()->SetClientArea(top_level, top_level_insets);
-  aura::ClientSurfaceEmbedder* client_surface_embedder =
-      ClientRootTestHelper(
-          setup.window_tree()->GetClientRootForWindow(top_level))
-          .GetClientSurfaceEmbedder();
-  ASSERT_TRUE(client_surface_embedder);
-  EXPECT_EQ(top_level_insets, client_surface_embedder->client_area_insets());
-}
-
 }  // namespace ws
diff --git a/storage/browser/blob/blob_reader.cc b/storage/browser/blob/blob_reader.cc
index ecc8f7a..5100695 100644
--- a/storage/browser/blob/blob_reader.cc
+++ b/storage/browser/blob/blob_reader.cc
@@ -698,10 +698,9 @@
             item.offset() + additional_offset,
             item.expected_modification_time());
       }
-      return base::WrapUnique(FileStreamReader::CreateForLocalFile(
+      return FileStreamReader::CreateForLocalFile(
           file_task_runner_.get(), item.path(),
-          item.offset() + additional_offset,
-          item.expected_modification_time()));
+          item.offset() + additional_offset, item.expected_modification_time());
     case BlobDataItem::Type::kFileFilesystem: {
       int64_t max_bytes_to_read =
           item.length() == std::numeric_limits<uint64_t>::max()
diff --git a/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
index 8929c32..698a36e9d 100644
--- a/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
+++ b/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
@@ -747,12 +747,13 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       file_thread.task_runner();
 
-  std::unique_ptr<storage::FileStreamReader> reader(
+  std::unique_ptr<storage::FileStreamReader> reader =
       storage::FileStreamReader::CreateForLocalFile(
-          task_runner.get(), source_path, 0, base::Time()));
+          task_runner.get(), source_path, 0, base::Time());
 
-  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
-      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
+  std::unique_ptr<FileStreamWriter> writer =
+      FileStreamWriter::CreateForLocalFile(task_runner.get(), dest_path, 0,
+                                           FileStreamWriter::CREATE_NEW_FILE);
 
   std::vector<int64_t> progress;
   CopyOrMoveOperationDelegate::StreamCopyHelper helper(
@@ -803,12 +804,13 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       file_thread.task_runner();
 
-  std::unique_ptr<storage::FileStreamReader> reader(
+  std::unique_ptr<storage::FileStreamReader> reader =
       storage::FileStreamReader::CreateForLocalFile(
-          task_runner.get(), source_path, 0, base::Time()));
+          task_runner.get(), source_path, 0, base::Time());
 
-  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
-      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
+  std::unique_ptr<FileStreamWriter> writer =
+      FileStreamWriter::CreateForLocalFile(task_runner.get(), dest_path, 0,
+                                           FileStreamWriter::CREATE_NEW_FILE);
 
   std::vector<int64_t> progress;
   CopyOrMoveOperationDelegate::StreamCopyHelper helper(
@@ -855,12 +857,13 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       file_thread.task_runner();
 
-  std::unique_ptr<storage::FileStreamReader> reader(
+  std::unique_ptr<storage::FileStreamReader> reader =
       storage::FileStreamReader::CreateForLocalFile(
-          task_runner.get(), source_path, 0, base::Time()));
+          task_runner.get(), source_path, 0, base::Time());
 
-  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
-      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
+  std::unique_ptr<FileStreamWriter> writer =
+      FileStreamWriter::CreateForLocalFile(task_runner.get(), dest_path, 0,
+                                           FileStreamWriter::CREATE_NEW_FILE);
 
   std::vector<int64_t> progress;
   CopyOrMoveOperationDelegate::StreamCopyHelper helper(
diff --git a/storage/browser/fileapi/file_stream_reader.h b/storage/browser/fileapi/file_stream_reader.h
index d5bd883..1d62775 100644
--- a/storage/browser/fileapi/file_stream_reader.h
+++ b/storage/browser/fileapi/file_stream_reader.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/files/file.h"
@@ -44,7 +46,7 @@
   // it does any succeeding read operations should fail with
   // ERR_UPLOAD_FILE_CHANGED error.
   COMPONENT_EXPORT(STORAGE_BROWSER)
-  static FileStreamReader* CreateForLocalFile(
+  static std::unique_ptr<FileStreamReader> CreateForLocalFile(
       base::TaskRunner* task_runner,
       const base::FilePath& file_path,
       int64_t initial_offset,
@@ -60,7 +62,7 @@
   // it does any succeeding read operations should fail with
   // ERR_UPLOAD_FILE_CHANGED error.
   COMPONENT_EXPORT(STORAGE_BROWSER)
-  static FileStreamReader* CreateForMemoryFile(
+  static std::unique_ptr<FileStreamReader> CreateForMemoryFile(
       base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
       const base::FilePath& file_path,
       int64_t initial_offset,
diff --git a/storage/browser/fileapi/file_stream_writer.h b/storage/browser/fileapi/file_stream_writer.h
index 921e1837..0e976db 100644
--- a/storage/browser/fileapi/file_stream_writer.h
+++ b/storage/browser/fileapi/file_stream_writer.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
 #include "net/base/completion_once_callback.h"
@@ -34,15 +36,16 @@
   // Creates a writer for the existing file in the path |file_path| starting
   // from |initial_offset|. Uses |task_runner| for async file operations.
   COMPONENT_EXPORT(STORAGE_BROWSER)
-  static FileStreamWriter* CreateForLocalFile(base::TaskRunner* task_runner,
-                                              const base::FilePath& file_path,
-                                              int64_t initial_offset,
-                                              OpenOrCreate open_or_create);
+  static std::unique_ptr<FileStreamWriter> CreateForLocalFile(
+      base::TaskRunner* task_runner,
+      const base::FilePath& file_path,
+      int64_t initial_offset,
+      OpenOrCreate open_or_create);
 
   // Creates a writer for the existing memory file in the path |file_path|
   // starting from |initial_offset|.
   COMPONENT_EXPORT(STORAGE_BROWSER)
-  static FileStreamWriter* CreateForMemoryFile(
+  static std::unique_ptr<FileStreamWriter> CreateForMemoryFile(
       base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
       const base::FilePath& file_path,
       int64_t initial_offset,
diff --git a/storage/browser/fileapi/file_system_file_stream_reader.cc b/storage/browser/fileapi/file_system_file_stream_reader.cc
index 0d0bd7b..df504693 100644
--- a/storage/browser/fileapi/file_system_file_stream_reader.cc
+++ b/storage/browser/fileapi/file_system_file_stream_reader.cc
@@ -101,13 +101,13 @@
 
   if (file_system_context_->is_incognito() &&
       base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
-    file_reader_.reset(FileStreamReader::CreateForMemoryFile(
+    file_reader_ = FileStreamReader::CreateForMemoryFile(
         file_system_context_->sandbox_delegate()->memory_file_util_delegate(),
-        platform_path, initial_offset_, expected_modification_time_));
+        platform_path, initial_offset_, expected_modification_time_);
   } else {
-    file_reader_.reset(FileStreamReader::CreateForLocalFile(
+    file_reader_ = FileStreamReader::CreateForLocalFile(
         file_system_context_->default_file_task_runner(), platform_path,
-        initial_offset_, expected_modification_time_));
+        initial_offset_, expected_modification_time_);
   }
 
   if (read_callback_) {
diff --git a/storage/browser/fileapi/isolated_file_system_backend.cc b/storage/browser/fileapi/isolated_file_system_backend.cc
index 13eb8a3..f884769 100644
--- a/storage/browser/fileapi/isolated_file_system_backend.cc
+++ b/storage/browser/fileapi/isolated_file_system_backend.cc
@@ -125,10 +125,9 @@
     int64_t max_bytes_to_read,
     const base::Time& expected_modification_time,
     FileSystemContext* context) const {
-  return std::unique_ptr<storage::FileStreamReader>(
-      storage::FileStreamReader::CreateForLocalFile(
-          context->default_file_task_runner(), url.path(), offset,
-          expected_modification_time));
+  return storage::FileStreamReader::CreateForLocalFile(
+      context->default_file_task_runner(), url.path(), offset,
+      expected_modification_time);
 }
 
 std::unique_ptr<FileStreamWriter>
@@ -136,9 +135,9 @@
     const FileSystemURL& url,
     int64_t offset,
     FileSystemContext* context) const {
-  return std::unique_ptr<FileStreamWriter>(FileStreamWriter::CreateForLocalFile(
+  return FileStreamWriter::CreateForLocalFile(
       context->default_file_task_runner(), url.path(), offset,
-      FileStreamWriter::OPEN_EXISTING_FILE));
+      FileStreamWriter::OPEN_EXISTING_FILE);
 }
 
 FileSystemQuotaUtil* IsolatedFileSystemBackend::GetQuotaUtil() {
diff --git a/storage/browser/fileapi/local_file_stream_reader.cc b/storage/browser/fileapi/local_file_stream_reader.cc
index 67eb2ce..4073f0b 100644
--- a/storage/browser/fileapi/local_file_stream_reader.cc
+++ b/storage/browser/fileapi/local_file_stream_reader.cc
@@ -12,6 +12,7 @@
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/task_runner.h"
 #include "base/task_runner_util.h"
 #include "net/base/file_stream.h"
@@ -53,13 +54,13 @@
 
 }  // namespace
 
-FileStreamReader* FileStreamReader::CreateForLocalFile(
+std::unique_ptr<FileStreamReader> FileStreamReader::CreateForLocalFile(
     base::TaskRunner* task_runner,
     const base::FilePath& file_path,
     int64_t initial_offset,
     const base::Time& expected_modification_time) {
-  return new LocalFileStreamReader(task_runner, file_path, initial_offset,
-                                   expected_modification_time);
+  return base::WrapUnique(new LocalFileStreamReader(
+      task_runner, file_path, initial_offset, expected_modification_time));
 }
 
 LocalFileStreamReader::~LocalFileStreamReader() = default;
diff --git a/storage/browser/fileapi/local_file_stream_writer.cc b/storage/browser/fileapi/local_file_stream_writer.cc
index 7832ec1..f3ceffd 100644
--- a/storage/browser/fileapi/local_file_stream_writer.cc
+++ b/storage/browser/fileapi/local_file_stream_writer.cc
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include "base/bind.h"
+#include "base/memory/ptr_util.h"
 #include "net/base/file_stream.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -24,13 +25,13 @@
 
 }  // namespace
 
-FileStreamWriter* FileStreamWriter::CreateForLocalFile(
+std::unique_ptr<FileStreamWriter> FileStreamWriter::CreateForLocalFile(
     base::TaskRunner* task_runner,
     const base::FilePath& file_path,
     int64_t initial_offset,
     OpenOrCreate open_or_create) {
-  return new LocalFileStreamWriter(
-      task_runner, file_path, initial_offset, open_or_create);
+  return base::WrapUnique(new LocalFileStreamWriter(
+      task_runner, file_path, initial_offset, open_or_create));
 }
 
 LocalFileStreamWriter::~LocalFileStreamWriter() {
diff --git a/storage/browser/fileapi/memory_file_stream_reader.cc b/storage/browser/fileapi/memory_file_stream_reader.cc
index ada3541..c0408bb3 100644
--- a/storage/browser/fileapi/memory_file_stream_reader.cc
+++ b/storage/browser/fileapi/memory_file_stream_reader.cc
@@ -4,15 +4,20 @@
 
 #include "storage/browser/fileapi/memory_file_stream_reader.h"
 
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+
 namespace storage {
 
-FileStreamReader* FileStreamReader::CreateForMemoryFile(
+std::unique_ptr<FileStreamReader> FileStreamReader::CreateForMemoryFile(
     base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
     const base::FilePath& file_path,
     int64_t initial_offset,
     const base::Time& expected_modification_time) {
-  return new MemoryFileStreamReader(std::move(memory_file_util), file_path,
-                                    initial_offset, expected_modification_time);
+  return base::WrapUnique(
+      new MemoryFileStreamReader(std::move(memory_file_util), file_path,
+                                 initial_offset, expected_modification_time));
 }
 
 MemoryFileStreamReader::~MemoryFileStreamReader() = default;
diff --git a/storage/browser/fileapi/memory_file_stream_writer.cc b/storage/browser/fileapi/memory_file_stream_writer.cc
index 7089e371..c9dcdd8 100644
--- a/storage/browser/fileapi/memory_file_stream_writer.cc
+++ b/storage/browser/fileapi/memory_file_stream_writer.cc
@@ -4,15 +4,19 @@
 
 #include "storage/browser/fileapi/memory_file_stream_writer.h"
 
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+
 namespace storage {
 
-FileStreamWriter* FileStreamWriter::CreateForMemoryFile(
+std::unique_ptr<FileStreamWriter> FileStreamWriter::CreateForMemoryFile(
     base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util,
     const base::FilePath& file_path,
     int64_t initial_offset,
     OpenOrCreate open_or_create) {
-  return new MemoryFileStreamWriter(std::move(memory_file_util), file_path,
-                                    initial_offset, open_or_create);
+  return base::WrapUnique(new MemoryFileStreamWriter(
+      std::move(memory_file_util), file_path, initial_offset, open_or_create));
 }
 
 MemoryFileStreamWriter::~MemoryFileStreamWriter() = default;
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.cc b/storage/browser/fileapi/sandbox_file_stream_writer.cc
index 857d307..9cf34451 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.cc
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.cc
@@ -145,13 +145,13 @@
 
   if (file_system_context_->is_incognito() &&
       base::FeatureList::IsEnabled(features::kEnableFilesystemInIncognito)) {
-    file_writer_.reset(FileStreamWriter::CreateForMemoryFile(
+    file_writer_ = FileStreamWriter::CreateForMemoryFile(
         file_system_context_->sandbox_delegate()->memory_file_util_delegate(),
-        platform_path, initial_offset_, FileStreamWriter::OPEN_EXISTING_FILE));
+        platform_path, initial_offset_, FileStreamWriter::OPEN_EXISTING_FILE);
   } else {
-    file_writer_.reset(FileStreamWriter::CreateForLocalFile(
+    file_writer_ = FileStreamWriter::CreateForLocalFile(
         file_system_context_->default_file_task_runner(), platform_path,
-        initial_offset_, FileStreamWriter::OPEN_EXISTING_FILE));
+        initial_offset_, FileStreamWriter::OPEN_EXISTING_FILE);
   }
   storage::QuotaManagerProxy* quota_manager_proxy =
       file_system_context_->quota_manager_proxy();
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index a98b36ef..b43c5eb 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4382,8 +4382,6 @@
     "ServiceWorkerForegroundPriority": [
         {
             "platforms": [
-                "android",
-                "android_webview",
                 "chromeos",
                 "linux",
                 "mac",
@@ -4399,6 +4397,22 @@
             ]
         }
     ],
+    "ServiceWorkerForegroundPriorityAndroid": [
+        {
+            "platforms": [
+                "android",
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ServiceWorkerForegroundPriority"
+                    ]
+                }
+            ]
+        }
+    ],
     "ServiceWorkerServicification": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
index 7e639bd..60fa0e3 100644
--- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
+++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -365,6 +365,12 @@
               int64 object_store_id,
               IDBKeyRange key_range,
               associated IDBCallbacks callbacks);
+  // Gets the current number of an IndexedDB ObjectStore's key generator. It
+  // is implemented in the browser (more priviledged) and handles requests in
+  // the renderer process: WebIDBDatabaseImpl::GetKeyGeneratorCurrentNumber()
+  GetKeyGeneratorCurrentNumber(int64 transaction_id,
+                               int64 object_store_id,
+                               associated IDBCallbacks callbacks);
   Clear(int64 transaction_id,
         int64 object_store_id,
         associated IDBCallbacks callbacks);
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index 7986125..15f6b8e 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -2964,6 +2964,21 @@
       # If true, there are more entries to fetch in the given range.
       boolean hasMore
 
+  # Gets the auto increment number of an object store. Only meaningful
+  # when objectStore.autoIncrement is true.
+  command getKeyGeneratorCurrentNumber
+    parameters
+      # Security origin.
+      string securityOrigin
+      # Database name.
+      string databaseName
+      # Object store name.
+      string objectStoreName
+    returns
+      # the current value of key generator, to become the next inserted
+      # key into the object store.
+      number currentNumber
+
   # Requests database with given name in given frame.
   command requestDatabase
     parameters
diff --git a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
index be6165b..6ed7e71b 100644
--- a/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
+++ b/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -48,7 +48,7 @@
             },
             {
                 "domain": "IndexedDB",
-                "async": ["requestDatabaseNames", "requestDatabase", "requestData", "deleteObjectStoreEntries", "clearObjectStore", "deleteDatabase"]
+                "async": ["requestDatabaseNames", "requestDatabase", "requestData", "getKeyGeneratorCurrentNumber", "deleteObjectStoreEntries", "clearObjectStore", "deleteDatabase"]
             },
             {
                 "domain": "LayerTree"
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn
index 1d09ecb..a42f874 100644
--- a/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -31,6 +31,7 @@
     "bidi_run.h",
     "bidi_run_for_line.cc",
     "bidi_run_for_line.h",
+    "box_layout_extra_input.h",
     "collapsed_border_value.cc",
     "collapsed_border_value.h",
     "column_balancer.cc",
diff --git a/third_party/blink/renderer/core/layout/box_layout_extra_input.h b/third_party/blink/renderer/core/layout/box_layout_extra_input.h
new file mode 100644
index 0000000..02ee264bf
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/box_layout_extra_input.h
@@ -0,0 +1,44 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BOX_LAYOUT_EXTRA_INPUT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BOX_LAYOUT_EXTRA_INPUT_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+
+namespace blink {
+
+class LayoutBox;
+
+// Extra input data for laying out a LayoutBox. The object will automatically
+// associate itself with the specified LayoutBox upon creation, and dissociate
+// itself upon destruction.
+struct BoxLayoutExtraInput {
+  BoxLayoutExtraInput(LayoutBox&);
+  ~BoxLayoutExtraInput();
+
+  LayoutBox& box;
+
+  // When set, no attempt should be be made to resolve the inline size. Use this
+  // one instead.
+  base::Optional<LayoutUnit> override_inline_size;
+
+  // When set, no attempt should be be made to resolve the block size. Use this
+  // one instead.
+  base::Optional<LayoutUnit> override_block_size;
+
+  // Available inline size. https://drafts.csswg.org/css-sizing/#available
+  LayoutUnit available_inline_size;
+
+  // The content size of the containing block. These are somewhat vague legacy
+  // layout values, that typically either mean available size or percentage
+  // resolution size.
+  LayoutUnit containing_block_content_inline_size;
+  LayoutUnit containing_block_content_block_size;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_BOX_LAYOUT_EXTRA_INPUT_H_
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 3e0a94e..a5fbded 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/core/input/event_handler.h"
 #include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/api/line_layout_box.h"
+#include "third_party/blink/renderer/core/layout/box_layout_extra_input.h"
 #include "third_party/blink/renderer/core/layout/custom/layout_custom.h"
 #include "third_party/blink/renderer/core/layout/custom/layout_worklet.h"
 #include "third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h"
@@ -96,12 +97,20 @@
   LayoutUnit intrinsic_content_logical_height;
   LayoutRectOutsets margin_box_outsets;
   LayoutUnit preferred_logical_width[2];
-  void* pointers[3];
+  void* pointers[4];
 };
 
 static_assert(sizeof(LayoutBox) == sizeof(SameSizeAsLayoutBox),
               "LayoutBox should stay small");
 
+BoxLayoutExtraInput::BoxLayoutExtraInput(LayoutBox& box) : box(box) {
+  box.SetBoxLayoutExtraInput(this);
+}
+
+BoxLayoutExtraInput::~BoxLayoutExtraInput() {
+  box.SetBoxLayoutExtraInput(nullptr);
+}
+
 LayoutBox::LayoutBox(ContainerNode* node)
     : LayoutBoxModelObject(node),
       intrinsic_content_logical_height_(-1),
@@ -1334,38 +1343,50 @@
 
 LayoutUnit LayoutBox::OverrideLogicalWidth() const {
   DCHECK(HasOverrideLogicalWidth());
+  if (extra_input_ && extra_input_->override_inline_size)
+    return *extra_input_->override_inline_size;
   return rare_data_->override_logical_width_;
 }
 
 LayoutUnit LayoutBox::OverrideLogicalHeight() const {
   DCHECK(HasOverrideLogicalHeight());
+  if (extra_input_ && extra_input_->override_block_size)
+    return *extra_input_->override_block_size;
   return rare_data_->override_logical_height_;
 }
 
 bool LayoutBox::HasOverrideLogicalHeight() const {
+  if (extra_input_ && extra_input_->override_block_size)
+    return true;
   return rare_data_ && rare_data_->override_logical_height_ != -1;
 }
 
 bool LayoutBox::HasOverrideLogicalWidth() const {
+  if (extra_input_ && extra_input_->override_inline_size)
+    return true;
   return rare_data_ && rare_data_->override_logical_width_ != -1;
 }
 
 void LayoutBox::SetOverrideLogicalHeight(LayoutUnit height) {
+  DCHECK(!extra_input_);
   DCHECK_GE(height, 0);
   EnsureRareData().override_logical_height_ = height;
 }
 
 void LayoutBox::SetOverrideLogicalWidth(LayoutUnit width) {
+  DCHECK(!extra_input_);
   DCHECK_GE(width, 0);
   EnsureRareData().override_logical_width_ = width;
 }
 
 void LayoutBox::ClearOverrideLogicalHeight() {
+  DCHECK(!extra_input_);
   if (rare_data_)
     rare_data_->override_logical_height_ = LayoutUnit(-1);
 }
 
 void LayoutBox::ClearOverrideLogicalWidth() {
+  DCHECK(!extra_input_);
   if (rare_data_)
     rare_data_->override_logical_width_ = LayoutUnit(-1);
 }
@@ -1390,40 +1411,41 @@
 LayoutUnit LayoutBox::OverrideContainingBlockContentWidth() const {
   DCHECK(HasOverrideContainingBlockContentWidth());
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
-             ? rare_data_->override_containing_block_content_logical_width_
-             : rare_data_->override_containing_block_content_logical_height_;
+             ? OverrideContainingBlockContentLogicalWidth()
+             : OverrideContainingBlockContentLogicalHeight();
 }
 
 LayoutUnit LayoutBox::OverrideContainingBlockContentHeight() const {
   DCHECK(HasOverrideContainingBlockContentHeight());
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
-             ? rare_data_->override_containing_block_content_logical_height_
-             : rare_data_->override_containing_block_content_logical_width_;
+             ? OverrideContainingBlockContentLogicalHeight()
+             : OverrideContainingBlockContentLogicalWidth();
 }
 
 bool LayoutBox::HasOverrideContainingBlockContentWidth() const {
-  if (!rare_data_ || !ContainingBlock())
+  if (!ContainingBlock())
     return false;
 
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
-             ? rare_data_->has_override_containing_block_content_logical_width_
-             : rare_data_
-                   ->has_override_containing_block_content_logical_height_;
+             ? HasOverrideContainingBlockContentLogicalWidth()
+             : HasOverrideContainingBlockContentLogicalHeight();
 }
 
 bool LayoutBox::HasOverrideContainingBlockContentHeight() const {
-  if (!rare_data_ || !ContainingBlock())
+  if (!ContainingBlock())
     return false;
 
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
-             ? rare_data_->has_override_containing_block_content_logical_height_
-             : rare_data_->has_override_containing_block_content_logical_width_;
+             ? HasOverrideContainingBlockContentLogicalHeight()
+             : HasOverrideContainingBlockContentLogicalWidth();
 }
 
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalWidth() const {
   DCHECK(HasOverrideContainingBlockContentLogicalWidth());
+  if (extra_input_)
+    return extra_input_->containing_block_content_inline_size;
   return rare_data_->override_containing_block_content_logical_width_;
 }
 
@@ -1431,12 +1453,16 @@
 // direction ?.
 LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalHeight() const {
   DCHECK(HasOverrideContainingBlockContentLogicalHeight());
+  if (extra_input_)
+    return extra_input_->containing_block_content_block_size;
   return rare_data_->override_containing_block_content_logical_height_;
 }
 
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 bool LayoutBox::HasOverrideContainingBlockContentLogicalWidth() const {
+  if (extra_input_)
+    return true;
   return rare_data_ &&
          rare_data_->has_override_containing_block_content_logical_width_;
 }
@@ -1444,6 +1470,8 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 bool LayoutBox::HasOverrideContainingBlockContentLogicalHeight() const {
+  if (extra_input_)
+    return true;
   return rare_data_ &&
          rare_data_->has_override_containing_block_content_logical_height_;
 }
@@ -1452,6 +1480,7 @@
 // direction ?.
 void LayoutBox::SetOverrideContainingBlockContentLogicalWidth(
     LayoutUnit logical_width) {
+  DCHECK(!extra_input_);
   DCHECK_GE(logical_width, LayoutUnit(-1));
   EnsureRareData().override_containing_block_content_logical_width_ =
       logical_width;
@@ -1462,6 +1491,7 @@
 // direction ?.
 void LayoutBox::SetOverrideContainingBlockContentLogicalHeight(
     LayoutUnit logical_height) {
+  DCHECK(!extra_input_);
   DCHECK_GE(logical_height, LayoutUnit(-1));
   EnsureRareData().override_containing_block_content_logical_height_ =
       logical_height;
@@ -1471,6 +1501,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 void LayoutBox::ClearOverrideContainingBlockContentSize() {
+  DCHECK(!extra_input_);
   if (!rare_data_)
     return;
   EnsureRareData().has_override_containing_block_content_logical_width_ = false;
@@ -1492,11 +1523,6 @@
     LayoutUnit logical_height) {
   DCHECK_GE(logical_height, LayoutUnit(-1));
   auto& rare_data = EnsureRareData();
-
-  // The actual data field is shared with override available inline size. They
-  // cannot be in use at the same time.
-  DCHECK(!rare_data.has_override_available_inline_size_);
-
   rare_data.override_percentage_resolution_block_size_ = logical_height;
   rare_data.has_override_percentage_resolution_block_size_ = true;
 }
@@ -1509,29 +1535,9 @@
 
 LayoutUnit LayoutBox::OverrideAvailableInlineSize() const {
   DCHECK(HasOverrideAvailableInlineSize());
-  return rare_data_->override_percentage_resolution_block_size_;
-}
-
-bool LayoutBox::HasOverrideAvailableInlineSize() const {
-  return rare_data_ && rare_data_->has_override_available_inline_size_;
-}
-
-void LayoutBox::SetOverrideAvailableInlineSize(LayoutUnit inline_size) {
-  DCHECK_GE(inline_size, LayoutUnit());
-  auto& rare_data = EnsureRareData();
-
-  // The actual data field is shared with override block percentage resolution
-  // size. They cannot be in use at the same time.
-  DCHECK(!rare_data.has_override_percentage_resolution_block_size_);
-
-  rare_data.override_available_inline_size_ = inline_size;
-  rare_data.has_override_available_inline_size_ = true;
-}
-
-void LayoutBox::ClearOverrideAvailableInlineSize() {
-  if (!rare_data_)
-    return;
-  EnsureRareData().has_override_available_inline_size_ = false;
+  if (extra_input_)
+    return extra_input_->available_inline_size;
+  return LayoutUnit();
 }
 
 LayoutUnit LayoutBox::AdjustBorderBoxLogicalWidthForBoxSizing(
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 086749e..0d3f161 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -39,6 +39,7 @@
 class EventHandler;
 class LayoutBlockFlow;
 class LayoutMultiColumnSpannerPlaceholder;
+struct BoxLayoutExtraInput;
 struct NGPhysicalBoxStrut;
 class ShapeOutsideInfo;
 
@@ -72,7 +73,6 @@
         has_override_containing_block_content_logical_width_(false),
         has_override_containing_block_content_logical_height_(false),
         has_override_percentage_resolution_block_size_(false),
-        has_override_available_inline_size_(false),
         has_previous_content_box_rect_and_layout_overflow_rect_(false),
         percent_height_container_(nullptr),
         snap_container_(nullptr),
@@ -88,22 +88,11 @@
   bool has_override_containing_block_content_logical_width_ : 1;
   bool has_override_containing_block_content_logical_height_ : 1;
   bool has_override_percentage_resolution_block_size_ : 1;
-  bool has_override_available_inline_size_ : 1;
   bool has_previous_content_box_rect_and_layout_overflow_rect_ : 1;
 
   LayoutUnit override_containing_block_content_logical_width_;
   LayoutUnit override_containing_block_content_logical_height_;
-
-  // Put two members that aren't used at the same time inside a union, to save
-  // space. There are DCHECKs to make sure that they aren't actually used at the
-  // same time. Currently, the percentage resolution block size is only used by
-  // custom layout children, while the available inline size is only used by
-  // LayoutNG. So, since custom layout containers are laid out by legacy, this
-  // should be safe.
-  union {
-    LayoutUnit override_percentage_resolution_block_size_;
-    LayoutUnit override_available_inline_size_;
-  };
+  LayoutUnit override_percentage_resolution_block_size_;
 
   LayoutUnit offset_to_next_page_;
 
@@ -746,6 +735,10 @@
                      MapCoordinatesFlags mode = 0) const override;
   FloatRect LocalBoundingBoxRectForAccessibility() const final;
 
+  void SetBoxLayoutExtraInput(const BoxLayoutExtraInput* input) {
+    extra_input_ = input;
+  }
+
   void UpdateLayout() override;
   void Paint(const PaintInfo&) const override;
 
@@ -802,9 +795,7 @@
   // available inline size, rather than deducing it from the containing block
   // (and then subtract space taken up by adjacent floats).
   LayoutUnit OverrideAvailableInlineSize() const;
-  bool HasOverrideAvailableInlineSize() const;
-  void SetOverrideAvailableInlineSize(LayoutUnit);
-  void ClearOverrideAvailableInlineSize();
+  bool HasOverrideAvailableInlineSize() const { return extra_input_; }
 
   LayoutUnit AdjustBorderBoxLogicalWidthForBoxSizing(float width) const;
   LayoutUnit AdjustBorderBoxLogicalHeightForBoxSizing(float height) const;
@@ -1829,6 +1820,11 @@
 
   std::unique_ptr<BoxOverflowModel> overflow_;
 
+  // Extra layout input data. This one may be set during layout, and cleared
+  // afterwards. Always nullptr when this object isn't in the process of being
+  // laid out.
+  const BoxLayoutExtraInput* extra_input_ = nullptr;
+
   union {
     // The inline box containing this LayoutBox, for atomic inline elements.
     // Valid only when !IsInLayoutNGInlineFormattingContext().
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index 49193ed..ecdd0d9e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -253,6 +253,7 @@
     <style>
     html { font-size: 10px; }
     img { vertical-align: bottom; }
+    #container { display: flow-root; }
     </style>
     <div id=container><img src="#" width="96" height="96"></div>
   )HTML");
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
index cab1194..1b8d087f 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
@@ -34,11 +34,6 @@
 void LayoutNGBlockFlow::UpdateBlockLayout(bool relayout_children) {
   LayoutAnalyzer::BlockScope analyzer(*this);
 
-  // This block is an entry-point from the legacy engine to LayoutNG. This means
-  // that we need to be at a formatting context boundary, since NG and legacy
-  // don't cooperate on e.g. margin collapsing.
-  DCHECK(CreatesNewFormattingContext());
-
   if (IsOutOfFlowPositioned()) {
     UpdateOutOfFlowBlockLayout();
     return;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index ad5b990..c2756c8 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1242,6 +1242,22 @@
   scoped_refptr<NGLayoutResult> layout_result = child.Layout(
       child_space, child_break_token, &inline_child_layout_context_);
 
+  // To save space of the stack when we recurse into |NGBlockNode::Layout|
+  // above, the rest of this function is continued within |FinishInflow|.
+  // However it should be read as one function.
+  return FinishInflow(child, child_break_token, child_space, layout_result,
+                      &child_data, previous_inflow_position,
+                      previous_inline_break_token);
+}
+
+bool NGBlockLayoutAlgorithm::FinishInflow(
+    NGLayoutInputNode child,
+    const NGBreakToken* child_break_token,
+    const NGConstraintSpace& child_space,
+    scoped_refptr<NGLayoutResult> layout_result,
+    NGInflowChildData* child_data,
+    NGPreviousInflowPosition* previous_inflow_position,
+    scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) {
   base::Optional<LayoutUnit> child_bfc_block_offset =
       layout_result->BfcBlockOffset();
   // TODO(layout-dev): A more optimal version of this is to set
@@ -1312,7 +1328,7 @@
       // Since we know our own BFC block offset, though, we can calculate that
       // of the child as well.
       child_bfc_block_offset = PositionEmptyChildWithParentBfc(
-          child, child_space, child_data, *layout_result);
+          child, child_space, *child_data, *layout_result);
     }
   } else if (!has_clearance) {
     // We shouldn't have any pending floats here, since an in-flow child found
@@ -1346,13 +1362,13 @@
   bool empty_block_affected_by_clearance_needs_relayout = false;
   if (empty_block_affected_by_clearance) {
     NGMarginStrut margin_strut;
-    margin_strut.Append(child_data.margins.block_start,
+    margin_strut.Append(child_data->margins.block_start,
                         child.Style().HasMarginBeforeQuirk());
 
     // We only need to relayout if the new margin strut is different to the
     // previous one.
-    if (child_data.margin_strut != margin_strut) {
-      child_data.margin_strut = margin_strut;
+    if (child_data->margin_strut != margin_strut) {
+      child_data->margin_strut = margin_strut;
       empty_block_affected_by_clearance_needs_relayout = true;
     }
   }
@@ -1366,7 +1382,7 @@
        empty_block_affected_by_clearance_needs_relayout) &&
       child_bfc_block_offset) {
     NGConstraintSpace new_child_space = CreateConstraintSpaceForChild(
-        child, child_data, child_available_size_, child_bfc_block_offset);
+        child, *child_data, child_available_size_, child_bfc_block_offset);
     layout_result = child.Layout(new_child_space, child_break_token,
                                  &inline_child_layout_context_);
 
@@ -1379,7 +1395,7 @@
       child_bfc_block_offset = layout_result->BfcBlockOffset();
       DCHECK(child_bfc_block_offset);
       new_child_space = CreateConstraintSpaceForChild(
-          child, child_data, child_available_size_, child_bfc_block_offset);
+          child, *child_data, child_available_size_, child_bfc_block_offset);
       layout_result = child.Layout(new_child_space, child_break_token,
                                    &inline_child_layout_context_);
     }
@@ -1446,18 +1462,18 @@
     // also required to calculate line-left offset (due to block alignment)
     // before layout. Do so now, so that we store the correct values (which is
     // required by e.g. getComputedStyle()).
-    if (!child_data.margins_fully_resolved) {
+    if (!child_data->margins_fully_resolved) {
       ResolveInlineMargins(child.Style(), Style(),
                            child_available_size_.inline_size,
-                           fragment.InlineSize(), &child_data.margins);
-      child_data.margins_fully_resolved = true;
+                           fragment.InlineSize(), &child_data->margins);
+      child_data->margins_fully_resolved = true;
     }
 
-    ToNGBlockNode(child).StoreMargins(ConstraintSpace(), child_data.margins);
+    ToNGBlockNode(child).StoreMargins(ConstraintSpace(), child_data->margins);
   }
 
   *previous_inflow_position = ComputeInflowPosition(
-      *previous_inflow_position, child, child_data, child_bfc_block_offset,
+      *previous_inflow_position, child, *child_data, child_bfc_block_offset,
       logical_offset, *layout_result, fragment,
       empty_block_affected_by_clearance);
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
index 160edc1..e8f83948 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -185,6 +185,15 @@
       NGPreviousInflowPosition*,
       scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
 
+  bool FinishInflow(
+      NGLayoutInputNode child,
+      const NGBreakToken* child_break_token,
+      const NGConstraintSpace&,
+      scoped_refptr<NGLayoutResult>,
+      NGInflowChildData*,
+      NGPreviousInflowPosition*,
+      scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
+
   // Return the amount of block space available in the current fragmentainer
   // for the node being laid out by this algorithm.
   LayoutUnit FragmentainerSpaceAvailable() const;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 88b1411b..3c92c18c 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -8,6 +8,7 @@
 
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/html/html_marquee_element.h"
+#include "third_party/blink/renderer/core/layout/box_layout_extra_input.h"
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/layout_fieldset.h"
 #include "third_party/blink/renderer/core/layout/layout_inline.h"
@@ -858,42 +859,26 @@
   const NGConstraintSpace* old_space =
       block ? block->CachedConstraintSpace() : nullptr;
   if (!old_space || box_->NeedsLayout() || *old_space != constraint_space) {
-    LayoutUnit inline_size =
+    BoxLayoutExtraInput input(*box_);
+    input.containing_block_content_inline_size =
         CalculateAvailableInlineSizeForLegacy(*box_, constraint_space);
-    LayoutUnit block_size =
+    input.containing_block_content_block_size =
         CalculateAvailableBlockSizeForLegacy(*box_, constraint_space);
 
-    LayoutObject* containing_block = box_->ContainingBlock();
-    bool parallel_writing_mode;
-    if (!containing_block) {
-      parallel_writing_mode = true;
-    } else {
-      parallel_writing_mode = IsParallelWritingMode(
-          containing_block->StyleRef().GetWritingMode(), writing_mode);
+    if (LayoutObject* containing_block = box_->ContainingBlock()) {
+      if (!IsParallelWritingMode(containing_block->StyleRef().GetWritingMode(),
+                                 writing_mode)) {
+        // The sizes should be in the containing block writing mode.
+        std::swap(input.containing_block_content_block_size,
+                  input.containing_block_content_inline_size);
+      }
     }
-    if (parallel_writing_mode) {
-      box_->SetOverrideContainingBlockContentLogicalWidth(inline_size);
-      box_->SetOverrideContainingBlockContentLogicalHeight(block_size);
-    } else {
-      // OverrideContainingBlock should be in containing block writing mode.
-      box_->SetOverrideContainingBlockContentLogicalWidth(block_size);
-      box_->SetOverrideContainingBlockContentLogicalHeight(inline_size);
-    }
+    input.available_inline_size = constraint_space.AvailableSize().inline_size;
 
-    if (constraint_space.IsFixedSizeInline()) {
-      box_->SetOverrideLogicalWidth(
-          constraint_space.AvailableSize().inline_size);
-    } else {
-      box_->ClearOverrideLogicalWidth();
-    }
-    if (constraint_space.IsFixedSizeBlock()) {
-      box_->SetOverrideLogicalHeight(
-          constraint_space.AvailableSize().block_size);
-    } else {
-      box_->ClearOverrideLogicalHeight();
-    }
-    box_->SetOverrideAvailableInlineSize(
-        constraint_space.AvailableSize().inline_size);
+    if (constraint_space.IsFixedSizeInline())
+      input.override_inline_size = constraint_space.AvailableSize().inline_size;
+    if (constraint_space.IsFixedSizeBlock())
+      input.override_block_size = constraint_space.AvailableSize().block_size;
     box_->ComputeAndSetBlockDirectionMargins(box_->ContainingBlock());
 
     // Using |LayoutObject::LayoutIfNeeded| save us a little bit of overhead,
@@ -904,11 +889,6 @@
     else
       box_->ForceChildLayout();
 
-    // Reset the containing block size override size, now that we're done with
-    // subtree layout. Min/max calculation that depends on the block size of the
-    // container (e.g. objects with intrinsic ratio and percentage block size)
-    // in a subsequent layout pass might otherwise become wrong.
-    box_->ClearOverrideContainingBlockContentSize();
     if (block)
       block->SetCachedConstraintSpace(constraint_space);
   }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
index daabe5f3..3f91f64 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
@@ -34,58 +34,52 @@
 }  // namespace
 
 NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
-    const LayoutBox& box) {
-  const LayoutBlock* cb = box.ContainingBlock();
+    const LayoutBlock& block) {
+  // We should only ever create a constraint space from legacy layout if the
+  // object is a new formatting context.
+  DCHECK(block.CreatesNewFormattingContext());
 
+  const LayoutBlock* cb = block.ContainingBlock();
   LayoutUnit available_logical_width =
-      LayoutBoxUtils::AvailableLogicalWidth(box, cb);
+      LayoutBoxUtils::AvailableLogicalWidth(block, cb);
   LayoutUnit available_logical_height =
-      LayoutBoxUtils::AvailableLogicalHeight(box, cb);
+      LayoutBoxUtils::AvailableLogicalHeight(block, cb);
   NGLogicalSize percentage_size = {available_logical_width,
                                    available_logical_height};
   NGLogicalSize available_size = percentage_size;
 
   bool fixed_inline = false, fixed_block = false;
   bool fixed_block_is_definite = true;
-  if (box.HasOverrideLogicalWidth()) {
-    available_size.inline_size = box.OverrideLogicalWidth();
+  if (block.HasOverrideLogicalWidth()) {
+    available_size.inline_size = block.OverrideLogicalWidth();
     fixed_inline = true;
   }
-  if (box.HasOverrideLogicalHeight()) {
-    available_size.block_size = box.OverrideLogicalHeight();
+  if (block.HasOverrideLogicalHeight()) {
+    available_size.block_size = block.OverrideLogicalHeight();
     fixed_block = true;
   }
-  if (box.IsFlexItem() && fixed_block) {
+  if (block.IsFlexItem() && fixed_block) {
     // The flexbox-specific behavior is in addition to regular definite-ness, so
     // if the flex item would normally have a definite height it should keep it.
     fixed_block_is_definite =
-        ToLayoutFlexibleBox(box.Parent())
-            ->UseOverrideLogicalHeightForPerentageResolution(box) ||
-        (box.IsLayoutBlock() && ToLayoutBlock(box).HasDefiniteLogicalHeight());
+        ToLayoutFlexibleBox(block.Parent())
+            ->UseOverrideLogicalHeightForPerentageResolution(block) ||
+        block.HasDefiniteLogicalHeight();
   }
 
-  bool is_new_fc = true;
-  // TODO(ikilpatrick): This DCHECK needs to be enabled once we've switched
-  // LayoutTableCell, etc over to LayoutNG.
-  //
-  // We currently need to "force" LayoutNG roots to be formatting contexts so
-  // that floats have layout performed on them.
-  //
-  // DCHECK(is_new_fc,
-  //  box.IsLayoutBlock() && ToLayoutBlock(box).CreatesNewFormattingContext());
-
-  auto writing_mode = box.StyleRef().GetWritingMode();
+  const ComputedStyle& style = block.StyleRef();
+  auto writing_mode = style.GetWritingMode();
   bool parallel_containing_block = IsParallelWritingMode(
       cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
-  NGConstraintSpaceBuilder builder(writing_mode, writing_mode, is_new_fc,
+  NGConstraintSpaceBuilder builder(writing_mode, writing_mode,
+                                   /* is_new_fc */ true,
                                    !parallel_containing_block);
 
-  if (!box.IsWritingModeRoot() || box.IsGridItem()) {
+  if (!block.IsWritingModeRoot() || block.IsGridItem()) {
     // Add all types because we don't know which baselines will be requested.
-    FontBaseline baseline_type = box.StyleRef().GetFontBaseline();
+    FontBaseline baseline_type = style.GetFontBaseline();
     bool synthesize_inline_block_baseline =
-        box.IsLayoutBlock() &&
-        ToLayoutBlock(box).UseLogicalBottomMarginEdgeForInlineBlockBaseline();
+        block.UseLogicalBottomMarginEdgeForInlineBlockBaseline();
     if (!synthesize_inline_block_baseline) {
       builder.AddBaselineRequest(
           {NGBaselineAlgorithmType::kAtomicInline, baseline_type});
@@ -100,8 +94,8 @@
       .SetIsFixedSizeBlock(fixed_block)
       .SetFixedSizeBlockIsDefinite(fixed_block_is_definite)
       .SetIsShrinkToFit(
-          box.SizesLogicalWidthToFitContent(box.StyleRef().LogicalWidth()))
-      .SetTextDirection(box.StyleRef().Direction())
+          block.SizesLogicalWidthToFitContent(style.LogicalWidth()))
+      .SetTextDirection(style.Direction())
       .ToConstraintSpace();
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
index 800f0ad..621d6769 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -21,7 +21,7 @@
 
 namespace blink {
 
-class LayoutBox;
+class LayoutBlock;
 class NGConstraintSpaceBuilder;
 
 enum NGFragmentationType {
@@ -136,7 +136,7 @@
   // Creates NGConstraintSpace representing LayoutObject's containing block.
   // This should live on NGBlockNode or another layout bridge and probably take
   // a root NGConstraintSpace.
-  static NGConstraintSpace CreateFromLayoutObject(const LayoutBox&);
+  static NGConstraintSpace CreateFromLayoutObject(const LayoutBlock&);
 
   const NGExclusionSpace& ExclusionSpace() const { return exclusion_space_; }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index 9403761d..6110de7e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -136,21 +136,11 @@
     return;
   }
 
+  HashSet<const LayoutObject*> placed_objects;
   while (descendant_candidates.size() > 0) {
     ComputeInlineContainingBlocks(descendant_candidates);
-    for (auto& candidate : descendant_candidates) {
-      if (IsContainingBlockForDescendant(candidate) &&
-          (!only_layout || candidate.node.GetLayoutBox() == only_layout)) {
-        NGLogicalOffset offset;
-        scoped_refptr<NGLayoutResult> result =
-            LayoutDescendant(candidate, &offset, only_layout);
-        container_builder_->AddChild(*result, offset);
-        if (candidate.node.GetLayoutBox() != only_layout)
-          candidate.node.UseOldOutOfFlowPositioning();
-      } else {
-        container_builder_->AddOutOfFlowDescendant(candidate);
-      }
-    }
+    LayoutDescendantCandidates(descendant_candidates, only_layout,
+                               &placed_objects);
     // Sweep any descendants that might have been added.
     // This happens when an absolute container has a fixed child.
     descendant_candidates.Shrink(0);
@@ -326,10 +316,30 @@
   }
 }
 
+void NGOutOfFlowLayoutPart::LayoutDescendantCandidates(
+    const Vector<NGOutOfFlowPositionedDescendant> descendant_candidates,
+    const LayoutBox* only_layout,
+    HashSet<const LayoutObject*>* placed_objects) {
+  for (auto& candidate : descendant_candidates) {
+    if (IsContainingBlockForDescendant(candidate) &&
+        (!only_layout || candidate.node.GetLayoutBox() == only_layout)) {
+      NGLogicalOffset offset;
+      scoped_refptr<NGLayoutResult> result =
+          LayoutDescendant(candidate, only_layout, &offset);
+      container_builder_->AddChild(*result, offset);
+      placed_objects->insert(candidate.node.GetLayoutBox());
+      if (candidate.node.GetLayoutBox() != only_layout)
+        candidate.node.UseOldOutOfFlowPositioning();
+    } else {
+      container_builder_->AddOutOfFlowDescendant(candidate);
+    }
+  }
+}
+
 scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant(
     const NGOutOfFlowPositionedDescendant& descendant,
-    NGLogicalOffset* offset,
-    LayoutBox* only_layout) {
+    const LayoutBox* only_layout,
+    NGLogicalOffset* offset) {
   ContainingBlockInfo container_info = GetContainingBlockInfo(descendant);
   const ComputedStyle& descendant_style = descendant.node.Style();
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
index fa22a3d..8178215 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
 #include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
 namespace blink {
 
@@ -94,10 +95,15 @@
 
   void ComputeInlineContainingBlocks(Vector<NGOutOfFlowPositionedDescendant>);
 
+  void LayoutDescendantCandidates(
+      const Vector<NGOutOfFlowPositionedDescendant> descendant_candidates,
+      const LayoutBox* only_layout,
+      HashSet<const LayoutObject*>* placed_objects);
+
   scoped_refptr<NGLayoutResult> LayoutDescendant(
       const NGOutOfFlowPositionedDescendant&,
-      NGLogicalOffset* offset,
-      LayoutBox* only_layout);
+      const LayoutBox* only_layout,
+      NGLogicalOffset* offset);
 
   bool IsContainingBlockForDescendant(
       const NGOutOfFlowPositionedDescendant& descendant);
diff --git a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
index 017e155c..c64bd35 100644
--- a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
@@ -41,7 +41,7 @@
 
   ModuleScriptCreationParams params(
       script_resource->GetResponse().CurrentRequestUrl(),
-      script_resource->SourceText(),
+      script_resource->SourceText(), script_resource->CacheHandler(),
       script_resource->GetResourceRequest().GetFetchCredentialsMode());
   client_->NotifyFetchFinished(params, error_messages);
 }
@@ -72,8 +72,10 @@
     return true;
   }
 
+  // TODO(hiroshige): Support V8 Code Cache for Layered API.
   ModuleScriptCreationParams params(
       layered_api_url, ParkableString(source_text.ReleaseImpl()),
+      nullptr /* cache_handler */,
       fetch_params.GetResourceRequest().GetFetchCredentialsMode());
   client_->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
   return true;
diff --git a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
index e3b3bb5..6cc54cdc 100644
--- a/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc
@@ -41,6 +41,7 @@
 
   ModuleScriptCreationParams params(
       fetch_params.Url(), ParkableString(script->TakeSourceText().Impl()),
+      nullptr /* cache_handler */,
       fetch_params.GetResourceRequest().GetFetchCredentialsMode());
   client->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
 }
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
index bd4849d..232efe3 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
@@ -9,6 +9,8 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/platform/bindings/parkable_string.h"
 #include "third_party/blink/renderer/platform/cross_thread_copier.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -20,11 +22,13 @@
   ModuleScriptCreationParams(
       const KURL& response_url,
       const ParkableString& source_text,
+      SingleCachedMetadataHandler* cache_handler,
       network::mojom::FetchCredentialsMode fetch_credentials_mode)
       : response_url_(response_url),
         is_isolated_(false),
         source_text_(source_text),
         isolated_source_text_(),
+        cache_handler_(cache_handler),
         fetch_credentials_mode_(fetch_credentials_mode) {}
 
   ~ModuleScriptCreationParams() = default;
@@ -47,6 +51,7 @@
     }
     return source_text_;
   }
+  SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; }
   network::mojom::FetchCredentialsMode GetFetchCredentialsMode() const {
     return fetch_credentials_mode_;
   }
@@ -75,6 +80,9 @@
   mutable ParkableString source_text_;
   mutable String isolated_source_text_;
 
+  // |cache_handler_| is cleared when crossing thread boundaries.
+  Persistent<SingleCachedMetadataHandler> cache_handler_;
+
   const network::mojom::FetchCredentialsMode fetch_credentials_mode_;
 };
 
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
index 6d55a6e..3286d9e 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -349,7 +349,7 @@
     // specifier must have been previously successful with these same two
     // arguments.
     CHECK(url.IsValid()) << "ModuleScript::ResolveModuleSpecifier() impl must "
-                            "return either a valid url or null.";
+                            "return a valid url.";
 
     // [FD] Step 5.3. If visited set does not contain url, then:
     if (!visited_set_.Contains(url)) {
@@ -522,7 +522,7 @@
     // moduleScript would have been marked as itself having a parse error.)
     CHECK(child_url.IsValid())
         << "ModuleScript::ResolveModuleSpecifier() impl must "
-           "return either a valid url or null.";
+           "return a valid url.";
 
     // [FFPE] Step 7. Let childModules be the list obtained by getting each
     // value in moduleMap whose key is given by an item of childURLs.
diff --git a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
index 4ed3653..e286ce62 100644
--- a/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc
@@ -102,7 +102,7 @@
 
   ModuleScriptCreationParams params(
       script_resource->GetResponse().CurrentRequestUrl(),
-      script_resource->SourceText(),
+      script_resource->SourceText(), script_resource->CacheHandler(),
       script_resource->GetResourceRequest().GetFetchCredentialsMode());
 
   // Step 13.7. "Asynchronously complete the perform the fetch steps with
diff --git a/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
index 51d9da8..23a533a 100644
--- a/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
@@ -47,7 +47,7 @@
   if (WasModuleLoadSuccessful(script_resource, &error_messages)) {
     params.emplace(
         script_resource->GetResponse().CurrentRequestUrl(),
-        script_resource->SourceText(),
+        script_resource->SourceText(), script_resource->CacheHandler(),
         script_resource->GetResourceRequest().GetFetchCredentialsMode());
   }
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index b2b85d45..8f72d7a 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -319,7 +319,13 @@
     // FIXME: This isn't right. We need to know the thickness of custom
     // scrollbars even when they don't exist in order to set the resizer square
     // size properly.
-    horizontal_thickness = GetPageScrollbarTheme().ScrollbarThickness();
+    horizontal_thickness =
+        GetLayoutBox()
+            ->GetDocument()
+            .GetPage()
+            ->GetChromeClient()
+            .WindowToViewportScalar(
+                GetPageScrollbarTheme().ScrollbarThickness());
     vertical_thickness = horizontal_thickness;
   } else if (VerticalScrollbar() && !HorizontalScrollbar()) {
     horizontal_thickness = VerticalScrollbar()->ScrollbarThickness();
diff --git a/third_party/blink/renderer/core/script/document_modulator_impl.cc b/third_party/blink/renderer/core/script/document_modulator_impl.cc
index 42c7286..624aff3 100644
--- a/third_party/blink/renderer/core/script/document_modulator_impl.cc
+++ b/third_party/blink/renderer/core/script/document_modulator_impl.cc
@@ -4,6 +4,9 @@
 
 #include "third_party/blink/renderer/core/script/document_modulator_impl.h"
 
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 
@@ -26,4 +29,12 @@
   return false;
 }
 
+V8CacheOptions DocumentModulatorImpl::GetV8CacheOptions() const {
+  Document* document = To<Document>(GetExecutionContext());
+  const Settings* settings = document->GetFrame()->GetSettings();
+  if (settings)
+    return settings->GetV8CacheOptions();
+  return kV8CacheOptionsDefault;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/document_modulator_impl.h b/third_party/blink/renderer/core/script/document_modulator_impl.h
index a090c5d6..2f9053b 100644
--- a/third_party/blink/renderer/core/script/document_modulator_impl.h
+++ b/third_party/blink/renderer/core/script/document_modulator_impl.h
@@ -31,6 +31,7 @@
  private:
   // Implements ModulatorImplBase.
   bool IsDynamicImportForbidden(String* reason) override;
+  V8CacheOptions GetV8CacheOptions() const override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/modulator.h b/third_party/blink/renderer/core/script/modulator.h
index 2172280..b1d6a5dc 100644
--- a/third_party/blink/renderer/core/script/modulator.h
+++ b/third_party/blink/renderer/core/script/modulator.h
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_module.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/script/module_import_meta.h"
 #include "third_party/blink/renderer/platform/bindings/name_client.h"
@@ -113,6 +114,8 @@
 
   virtual ScriptState* GetScriptState() = 0;
 
+  virtual V8CacheOptions GetV8CacheOptions() const = 0;
+
   // https://html.spec.whatwg.org/C/#concept-bc-noscript
   // "scripting is disabled for settings's responsible browsing context"
   virtual bool IsScriptingDisabled() const = 0;
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc
index 411a570..9311745 100644
--- a/third_party/blink/renderer/core/script/module_map_test.cc
+++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -115,7 +115,7 @@
                ModuleScriptFetcher::Client* client) override {
       TestRequest* test_request = MakeGarbageCollected<TestRequest>(
           ModuleScriptCreationParams(
-              request.Url(), ParkableString(String("").ReleaseImpl()),
+              request.Url(), ParkableString(String("").ReleaseImpl()), nullptr,
               request.GetResourceRequest().GetFetchCredentialsMode()),
           client);
       modulator_->test_requests_.push_back(test_request);
@@ -148,13 +148,13 @@
                 ModuleScriptFetcher::Client* client)
         : params_(params), client_(client) {}
     void NotifyFetchFinished() {
-      client_->NotifyFetchFinished(params_,
+      client_->NotifyFetchFinished(*params_,
                                    HeapVector<Member<ConsoleMessage>>());
     }
     void Trace(blink::Visitor* visitor) { visitor->Trace(client_); }
 
    private:
-    ModuleScriptCreationParams params_;
+    base::Optional<ModuleScriptCreationParams> params_;
     Member<ModuleScriptFetcher::Client> client_;
   };
   HeapVector<Member<TestRequest>> test_requests_;
diff --git a/third_party/blink/renderer/core/script/worker_modulator_impl.cc b/third_party/blink/renderer/core/script/worker_modulator_impl.cc
index 78135bd..09b73ce 100644
--- a/third_party/blink/renderer/core/script/worker_modulator_impl.cc
+++ b/third_party/blink/renderer/core/script/worker_modulator_impl.cc
@@ -55,4 +55,9 @@
   return true;
 }
 
+V8CacheOptions WorkerModulatorImpl::GetV8CacheOptions() const {
+  auto* scope = To<WorkerGlobalScope>(GetExecutionContext());
+  return scope->GetV8CacheOptions();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/worker_modulator_impl.h b/third_party/blink/renderer/core/script/worker_modulator_impl.h
index 3d5c5ea6..7123b0b7 100644
--- a/third_party/blink/renderer/core/script/worker_modulator_impl.h
+++ b/third_party/blink/renderer/core/script/worker_modulator_impl.h
@@ -28,6 +28,7 @@
  private:
   // Implements ModulatorImplBase.
   bool IsDynamicImportForbidden(String* reason) override;
+  V8CacheOptions GetV8CacheOptions() const override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/worklet_modulator_impl.cc b/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
index 932fc41..90ca676 100644
--- a/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
+++ b/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
@@ -30,4 +30,8 @@
   return true;
 }
 
+V8CacheOptions WorkletModulatorImpl::GetV8CacheOptions() const {
+  return kV8CacheOptionsDefault;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/worklet_modulator_impl.h b/third_party/blink/renderer/core/script/worklet_modulator_impl.h
index 3996eaf..d658f4b 100644
--- a/third_party/blink/renderer/core/script/worklet_modulator_impl.h
+++ b/third_party/blink/renderer/core/script/worklet_modulator_impl.h
@@ -30,6 +30,7 @@
  private:
   // Implements ModulatorImplBase.
   bool IsDynamicImportForbidden(String* reason) override;
+  V8CacheOptions GetV8CacheOptions() const override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.cc b/third_party/blink/renderer/core/testing/dummy_modulator.cc
index 1a9b6eb..ce5f4e84 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.cc
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -50,6 +50,10 @@
   return nullptr;
 }
 
+V8CacheOptions DummyModulator::GetV8CacheOptions() const {
+  return kV8CacheOptionsDefault;
+}
+
 bool DummyModulator::IsScriptingDisabled() const {
   return false;
 }
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.h b/third_party/blink/renderer/core/testing/dummy_modulator.h
index 63d30fe..0813123 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.h
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -32,6 +32,7 @@
   ScriptModuleResolver* GetScriptModuleResolver() override;
   base::SingleThreadTaskRunner* TaskRunner() override;
   ScriptState* GetScriptState() override;
+  V8CacheOptions GetV8CacheOptions() const override;
   bool IsScriptingDisabled() const override;
 
   void FetchTree(const KURL&,
diff --git a/third_party/blink/renderer/core/workers/README.md b/third_party/blink/renderer/core/workers/README.md
index f17260a..34d0442 100644
--- a/third_party/blink/renderer/core/workers/README.md
+++ b/third_party/blink/renderer/core/workers/README.md
@@ -25,6 +25,60 @@
 - `MessagingProxy` is the main (parent) thread side proxy that communicates to the worker thread.
 - `ObjectProxy` is the worker thread side proxy that communicates to the main (parent) thread. `Object` indicates a worker/worklet JavaScript object on the parent execution context.
 
+# Off-the-main-thread fetch
+
+All worker subresources, and some of worker/worklet top-level scripts,
+are fetched off-the-main-thread (i.e. on the worker/worklet thread).
+See following docs for more details.
+
+- [off-the-main-thread subresource fetch](https://docs.google.com/document/d/1829D6zllR1qfwvwDXHb9pjhIcbM4EZ70EiaFAaPj9YQ/edit?usp=sharing), Done.
+- [off-the-main-thread top-level script fetch](https://docs.google.com/document/d/1cI6UJGdeWvlavCzfxGh3hfWy7N62Yfsu_A98RxsCyys/edit?usp=sharing), ongoing.
+
+There are two types of network fetch on the worker/worklet thread:
+insideSettings and outsideSettings fetch.
+The terms insideSettings and outsideSettings are originated from
+[HTML spec](https://html.spec.whatwg.org/C/#worker-processing-model) and
+[Worklet spec](https://drafts.css-houdini.org/worklets/).
+
+## insideSettings fetch
+
+insideSettings fetch is subresource fetch.
+
+In the spec, insideSettings corresponds to the
+[worker environment settings object](https://html.spec.whatwg.org/multipage/workers.html#set-up-a-worker-environment-settings-object)
+of `WorkerOrWorkletGlobalScope`.
+
+In the implementation, insideSettings roughly corresponds to
+`WorkerOrWorkletGlobalScope`.
+`WorkerOrWorkletGlobalScope::Fetcher()`,
+its corresponding `WorkerFetchContext`, and
+`WorkerOrWorkletGlobalScope::GetContentSecurityPolicy()` are used.
+
+Currently, all subresource fetches are already off-the-main-thread.
+
+## outsideSettings fetch
+
+outsideSettings fetch is off-the-main-thread top-level worker/worklet
+script fetch.
+
+In the spec, an outsideSettings is the environment settings object of
+worker's parent context.
+
+In the implementation, outsideSettings should correspond to
+`Document` (or `WorkerOrWorkletGlobalScope` for nested workers), but
+the worker thread can't access these objects due to threading restriction.
+Therefore, we pass `FetchClientSettingsObjectSnapshot` that contains
+information of these objects across threads, and create
+`ResourceFetcher`, `WorkerFetchContext` and `ContentSecurityPolicy`
+(separate objects from those used for insideSettings fetch)
+on the worker thread.
+They work as if the parent context, and are used via
+`WorkerOrWorkletGlobalScope::CreateOutsideSettingsFetcher()`.
+
+Note that, where off-the-main-thread top-level fetch is NOT enabled
+(e.g. classic workers), the worker scripts are fetched on the main thread and
+thus WorkerOrWorkletGlobalScope and the worker thread are not involved.
+
 # References
 
 - [Worker / Worklet Internals](https://docs.google.com/presentation/d/1GZJ3VnLIO_Pw0jr9nRw6_-trg68ol-AkliMxJ6jo6Bo/edit?usp=sharing) (April 19, 2018)
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index 4ef4088e..def09af 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -180,6 +180,8 @@
 
   TrustedTypePolicyFactory* trustedTypes();
 
+  V8CacheOptions GetV8CacheOptions() const { return v8_cache_options_; }
+
  protected:
   WorkerGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
                     WorkerThread*,
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 9a3066e..13fad22 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -1557,12 +1557,33 @@
   return AtomicString("text/xml");
 }
 
-String XMLHttpRequest::FinalResponseCharset() const {
+// https://xhr.spec.whatwg.org/#final-charset
+WTF::TextEncoding XMLHttpRequest::FinalResponseCharset() const {
+  // 1. Let label be null. [spec text]
+  //
+  // 2. If response MIME type's parameters["charset"] exists, then set label to
+  // it. [spec text]
+  String label = response_.TextEncodingName();
+
+  // 3. If override MIME type's parameters["charset"] exists, then set label to
+  // it. [spec text]
   String override_response_charset =
       ExtractCharsetFromMediaType(mime_type_override_);
   if (!override_response_charset.IsEmpty())
-    return override_response_charset;
-  return response_.TextEncodingName();
+    label = override_response_charset;
+
+  // 4. If label is null, then return null. [spec text]
+  //
+  // 5. Let encoding be the result of getting an encoding from label. [spec
+  // text]
+  //
+  // 6. If encoding is failure, then return null. [spec text]
+  //
+  // 7. Return encoding. [spec text]
+  //
+  // We rely on WTF::TextEncoding() to return invalid TextEncoding for
+  // null, empty, or invalid/unsupported |label|.
+  return WTF::TextEncoding(label);
 }
 
 void XMLHttpRequest::UpdateContentTypeAndCharset(
@@ -1812,15 +1833,12 @@
   if (response_type_code_ == kResponseTypeJSON)
     return TextResourceDecoder::Create(decoder_options_for_utf8_plain_text);
 
-  String final_response_charset = FinalResponseCharset();
-  if (!final_response_charset.IsEmpty()) {
-    // If the final charset is given, use the charset without sniffing the
-    // content.
-    // TODO(crbug/905968): If WTF::TextEncoding::IsValid() is false, this
-    // currently falls back to Latin1Encoding(). Fallback to UTF-8 instead.
+  WTF::TextEncoding final_response_charset = FinalResponseCharset();
+  if (final_response_charset.IsValid()) {
+    // If the final charset is given and valid, use the charset without
+    // sniffing the content.
     return TextResourceDecoder::Create(TextResourceDecoderOptions(
-        TextResourceDecoderOptions::kPlainTextContent,
-        WTF::TextEncoding(final_response_charset)));
+        TextResourceDecoderOptions::kPlainTextContent, final_response_charset));
   }
 
   TextResourceDecoderOptions decoder_options_for_xml(
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index 9922e85c..d682ec4 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -217,7 +217,7 @@
   AtomicString FinalResponseMIMETypeWithFallback() const;
   // Returns the "final charset" defined in
   // https://xhr.spec.whatwg.org/#final-charset.
-  String FinalResponseCharset() const;
+  WTF::TextEncoding FinalResponseCharset() const;
   bool ResponseIsXML() const;
   bool ResponseIsHTML() const;
 
diff --git a/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js b/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
index 14e36e1..0a3f7f1 100644
--- a/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
+++ b/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
@@ -619,6 +619,10 @@
         hintText.appendChild(UI.formatLocalized('Record (%s) to display network activity.', [recordNode]));
       }
     }
+    hintText.createChild('br');
+    hintText.appendChild(UI.XLink.create(
+        'https://developers.google.com/web/tools/chrome-devtools/network/?utm_source=devtools&utm_campaign=2019Q1',
+        'Learn more'));
   }
 
   _hideRecordingHint() {
diff --git a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js
index 534c56d..8121a619 100644
--- a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js
+++ b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBModel.js
@@ -428,6 +428,27 @@
   }
 
   /**
+   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
+   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
+   * @return {!Promise<?number>}
+   */
+  async getKeyGeneratorValue(databaseId, objectStore) {
+    if (!objectStore.autoIncrement)
+      return null;
+    const databaseOrigin = databaseId.securityOrigin;
+    const databaseName = databaseId.name;
+    const objectStoreName = objectStore.name;
+    const response = await this._indexedDBAgent.invoke_getKeyGeneratorCurrentNumber(
+        {securityOrigin: databaseOrigin, databaseName, objectStoreName});
+
+    if (response[Protocol.Error]) {
+      console.error('IndexedDBAgent error: ' + response[Protocol.Error]);
+      return null;
+    }
+    return response.currentNumber;
+  }
+
+  /**
    * @param {string} securityOrigin
    */
   async _refreshDatabaseList(securityOrigin) {
diff --git a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js
index 63382fb..37ddf40 100644
--- a/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js
+++ b/third_party/blink/renderer/devtools/front_end/resources/IndexedDBViews.js
@@ -133,6 +133,8 @@
 
     this._pageSize = 50;
     this._skipCount = 0;
+    /** @type {?number} */
+    this._keyGeneratorValue = null;
 
     this.update(objectStore, index);
     this._entries = [];
@@ -336,6 +338,15 @@
       this._updatedDataForTests();
     }
 
+    /**
+     * @param {?number} number
+     * @this {Resources.IDBDataView}
+     */
+    function callbackKeyGeneratorValue(number) {
+      this._keyGeneratorValue = number;
+      this._updateSummaryBar();
+    }
+
     const idbKeyRange = key ? window.IDBKeyRange.lowerBound(key) : null;
     if (this._isIndex) {
       this._model.loadIndexData(
@@ -345,6 +356,18 @@
       this._model.loadObjectStoreData(
           this._databaseId, this._objectStore.name, idbKeyRange, skipCount, pageSize, callback.bind(this));
     }
+    this._model.getKeyGeneratorValue(this._databaseId, this._objectStore).then(callbackKeyGeneratorValue.bind(this));
+    this._updateSummaryBar();
+  }
+
+  _updateSummaryBar() {
+    if (this._keyGeneratorValue === null)
+      return;
+    if (!this._summaryBarElement)
+      this._summaryBarElement = this.element.createChild('div', 'object-store-summary-bar');
+    this._summaryBarElement.removeChildren();
+    const span = this._summaryBarElement.createChild('span');
+    span.textContent = ls`key generator value: ` + String(this._keyGeneratorValue);
   }
 
   _updatedDataForTests() {
diff --git a/third_party/blink/renderer/devtools/front_end/resources/indexedDBViews.css b/third_party/blink/renderer/devtools/front_end/resources/indexedDBViews.css
index 58de433..d19972cc 100644
--- a/third_party/blink/renderer/devtools/front_end/resources/indexedDBViews.css
+++ b/third_party/blink/renderer/devtools/front_end/resources/indexedDBViews.css
@@ -91,3 +91,14 @@
 .resources-toolbar {
     padding-right: 10px;
 }
+
+.object-store-summary-bar {
+    flex: 0 0 27px;
+    line-height: 27px;
+    padding-left: 5px;
+    background-color: #eee;
+    border-top: 1px solid #ccc;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+}
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
index 0fe51333..fee49ea 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -640,6 +640,17 @@
   return request;
 }
 
+IDBRequest* IDBObjectStore::getKeyGeneratorCurrentNumber(
+    ScriptState* script_state,
+    IDBRequest::AsyncTraceState metrics) {
+  IDBRequest* request = IDBRequest::Create(
+      script_state, this, transaction_.Get(), std::move(metrics));
+
+  BackendDB()->GetKeyGeneratorCurrentNumber(
+      transaction_->Id(), Id(), request->CreateWebCallbacks().release());
+  return request;
+}
+
 IDBRequest* IDBObjectStore::clear(ScriptState* script_state,
                                   ExceptionState& exception_state) {
   IDB_TRACE("IDBObjectStore::clearRequestSetup");
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.h b/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
index 9a59516..0f833244 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
@@ -139,6 +139,9 @@
       ScriptState*,
       IDBKeyRange*,
       IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState());
+  IDBRequest* getKeyGeneratorCurrentNumber(
+      ScriptState*,
+      IDBRequest::AsyncTraceState = IDBRequest::AsyncTraceState());
 
   void MarkDeleted();
   bool IsDeleted() const { return deleted_; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
index 2eeb014..48948d7f 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
@@ -144,6 +144,10 @@
       int64_t object_store_id,
       mojom::blink::IDBKeyRangePtr key_range,
       mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override {}
+  void GetKeyGeneratorCurrentNumber(
+      int64_t transaction_id,
+      int64_t object_store_id,
+      mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override {}
   void Clear(int64_t transaction_id,
              int64_t object_store_id,
              mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override {}
diff --git a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
index 8458374..a4edbc6 100644
--- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
+++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
@@ -86,6 +86,8 @@
     DeleteObjectStoreEntriesCallback;
 typedef blink::protocol::IndexedDB::Backend::ClearObjectStoreCallback
     ClearObjectStoreCallback;
+typedef blink::protocol::IndexedDB::Backend::
+    GetKeyGeneratorCurrentNumberCallback GetKeyGeneratorCurrentNumberCallback;
 typedef blink::protocol::IndexedDB::Backend::DeleteDatabaseCallback
     DeleteDatabaseCallback;
 
@@ -828,6 +830,107 @@
       database_name);
 }
 
+class GetKeyGeneratorCurrentNumberListener final : public NativeEventListener {
+ public:
+  static GetKeyGeneratorCurrentNumberListener* Create(
+      std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback) {
+    return MakeGarbageCollected<GetKeyGeneratorCurrentNumberListener>(
+        std::move(request_callback));
+  }
+
+  GetKeyGeneratorCurrentNumberListener(
+      std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback)
+      : request_callback_(std::move(request_callback)) {}
+  ~GetKeyGeneratorCurrentNumberListener() override = default;
+
+  void Invoke(ExecutionContext*, Event* event) override {
+    if (event->type() != event_type_names::kSuccess) {
+      request_callback_->sendFailure(
+          Response::Error("Failed to get current number of key generator."));
+      return;
+    }
+
+    IDBRequest* idb_request = static_cast<IDBRequest*>(event->target());
+    IDBAny* request_result = idb_request->ResultAsAny();
+    if (request_result->GetType() != IDBAny::kIntegerType) {
+      request_callback_->sendFailure(
+          Response::Error("Unexpected result type."));
+      return;
+    }
+    request_callback_->sendSuccess(request_result->Integer());
+  }
+
+ private:
+  std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback_;
+};
+
+class GetKeyGeneratorCurrentNumber final
+    : public ExecutableWithDatabase<GetKeyGeneratorCurrentNumberCallback> {
+ public:
+  static scoped_refptr<GetKeyGeneratorCurrentNumber> Create(
+      const String& object_store_name,
+      std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback) {
+    return AdoptRef(new GetKeyGeneratorCurrentNumber(
+        object_store_name, std::move(request_callback)));
+  }
+
+ private:
+  GetKeyGeneratorCurrentNumber(
+      const String& object_store_name,
+      std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback)
+      : object_store_name_(object_store_name),
+        request_callback_(std::move(request_callback)) {}
+
+  void Execute(IDBDatabase* idb_database, ScriptState* script_state) override {
+    IDBTransaction* idb_transaction =
+        TransactionForDatabase(script_state, idb_database, object_store_name_,
+                               indexed_db_names::kReadonly);
+    if (!idb_transaction) {
+      request_callback_->sendFailure(
+          Response::Error("Could not get transaction"));
+      return;
+    }
+    IDBObjectStore* idb_object_store =
+        ObjectStoreForTransaction(idb_transaction, object_store_name_);
+    if (!idb_object_store) {
+      request_callback_->sendFailure(
+          Response::Error("Could not get object store"));
+      return;
+    }
+    IDBRequest* idb_request =
+        idb_object_store->getKeyGeneratorCurrentNumber(script_state);
+    idb_request->addEventListener(event_type_names::kSuccess,
+                                  GetKeyGeneratorCurrentNumberListener::Create(
+                                      std::move(request_callback_)),
+                                  false);
+    idb_request->addEventListener(event_type_names::kError,
+                                  GetKeyGeneratorCurrentNumberListener::Create(
+                                      std::move(request_callback_)),
+                                  false);
+  }
+
+  GetKeyGeneratorCurrentNumberCallback* GetRequestCallback() override {
+    return request_callback_.get();
+  }
+
+ private:
+  const String object_store_name_;
+  std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback_;
+};
+
+void InspectorIndexedDBAgent::getKeyGeneratorCurrentNumber(
+    const String& security_origin,
+    const String& database_name,
+    const String& object_store_name,
+    std::unique_ptr<GetKeyGeneratorCurrentNumberCallback> request_callback) {
+  scoped_refptr<GetKeyGeneratorCurrentNumber> get_auto_increment_number =
+      GetKeyGeneratorCurrentNumber::Create(object_store_name,
+                                           std::move(request_callback));
+  get_auto_increment_number->Start(
+      inspected_frames_->FrameWithSecurityOrigin(security_origin),
+      database_name);
+}
+
 class DeleteObjectStoreEntriesListener final : public NativeEventListener {
  public:
   static DeleteObjectStoreEntriesListener* Create(
diff --git a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
index 5c101559..071b11c 100644
--- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
+++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h
@@ -69,6 +69,11 @@
                    int page_size,
                    protocol::Maybe<protocol::IndexedDB::KeyRange>,
                    std::unique_ptr<RequestDataCallback>) override;
+  void getKeyGeneratorCurrentNumber(
+      const String& security_origin,
+      const String& database_name,
+      const String& object_store_name,
+      std::unique_ptr<GetKeyGeneratorCurrentNumberCallback>) override;
   void deleteObjectStoreEntries(
       const String& security_origin,
       const String& database_name,
diff --git a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
index 0ed42f3..2a0fadc 100644
--- a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
+++ b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h
@@ -127,6 +127,10 @@
                     long long object_store_id,
                     const IDBKeyRange*,
                     WebIDBCallbacks*));
+  MOCK_METHOD3(GetKeyGeneratorCurrentNumber,
+               void(long long transaction_id,
+                    long long object_store_id,
+                    WebIDBCallbacks*));
   MOCK_METHOD3(Clear,
                void(long long transaction_id,
                     long long object_store_id,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database.h
index f2b7089..ed1696d 100644
--- a/third_party/blink/renderer/modules/indexeddb/web_idb_database.h
+++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database.h
@@ -137,6 +137,9 @@
                            long long object_store_id,
                            const IDBKeyRange*,
                            WebIDBCallbacks*) = 0;
+  virtual void GetKeyGeneratorCurrentNumber(long long transaction_id,
+                                            long long object_store_id,
+                                            WebIDBCallbacks*) = 0;
   virtual void Clear(long long transaction_id,
                      long long object_store_id,
                      WebIDBCallbacks*) = 0;
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
index c8f5339..00fda1ec 100644
--- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
+++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
@@ -221,6 +221,16 @@
                          GetCallbacksProxy(base::WrapUnique(callbacks)));
 }
 
+void WebIDBDatabaseImpl::GetKeyGeneratorCurrentNumber(
+    long long transaction_id,
+    long long object_store_id,
+    WebIDBCallbacks* callbacks) {
+  callbacks->SetState(nullptr, transaction_id);
+  database_->GetKeyGeneratorCurrentNumber(
+      transaction_id, object_store_id,
+      GetCallbacksProxy(base::WrapUnique(callbacks)));
+}
+
 void WebIDBDatabaseImpl::Clear(long long transaction_id,
                                long long object_store_id,
                                WebIDBCallbacks* callbacks) {
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h
index a69c90e..f9b1107 100644
--- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h
+++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h
@@ -100,6 +100,9 @@
                    long long object_store_id,
                    const IDBKeyRange*,
                    WebIDBCallbacks*) override;
+  void GetKeyGeneratorCurrentNumber(long long transaction_id,
+                                    long long object_store_id,
+                                    WebIDBCallbacks*) override;
   void Clear(long long transaction_id,
              long long object_store_id,
              WebIDBCallbacks*) override;
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index 73045f9..0feebbf 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -459,6 +459,7 @@
           "xr/xr_input_source.idl",
           "xr/xr_input_source_event.idl",
           "xr/xr_layer.idl",
+          "xr/xr_pose.idl",
           "xr/xr_presentation_context.idl",
           "xr/xr_ray.idl",
           "xr/xr_reference_space.idl",
diff --git a/third_party/blink/renderer/modules/payments/address_errors.idl b/third_party/blink/renderer/modules/payments/address_errors.idl
index 71f9b30..b85bff8 100644
--- a/third_party/blink/renderer/modules/payments/address_errors.idl
+++ b/third_party/blink/renderer/modules/payments/address_errors.idl
@@ -9,7 +9,6 @@
     DOMString city;
     DOMString country;
     DOMString dependentLocality;
-    DOMString languageCode;
     DOMString organization;
     DOMString phone;
     DOMString postalCode;
diff --git a/third_party/blink/renderer/modules/payments/on_payment_response_test.cc b/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
index 49a42630..5ea4e91 100644
--- a/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
+++ b/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
@@ -32,8 +32,6 @@
       BuildPaymentResponseForTest();
   response->shipping_address = payments::mojom::blink::PaymentAddress::New();
   response->shipping_address->country = "US";
-  response->shipping_address->language_code = "en";
-  response->shipping_address->script_code = "Latn";
 
   request->show(scope.GetScriptState())
       .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -148,8 +146,6 @@
   response->shipping_option = "";
   response->shipping_address = payments::mojom::blink::PaymentAddress::New();
   response->shipping_address->country = "US";
-  response->shipping_address->language_code = "en";
-  response->shipping_address->script_code = "Latn";
 
   request->show(scope.GetScriptState())
       .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -267,8 +263,6 @@
       BuildPaymentResponseForTest();
   response->shipping_address = payments::mojom::blink::PaymentAddress::New();
   response->shipping_address->country = "US";
-  response->shipping_address->language_code = "en";
-  response->shipping_address->script_code = "Latn";
 
   request->show(scope.GetScriptState())
       .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
@@ -435,8 +429,6 @@
   response->shipping_option = "standardShipping";
   response->shipping_address = payments::mojom::blink::PaymentAddress::New();
   response->shipping_address->country = "US";
-  response->shipping_address->language_code = "en";
-  response->shipping_address->script_code = "Latn";
   ScriptValue out_value;
   request->show(scope.GetScriptState())
       .Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
@@ -449,8 +441,6 @@
   PaymentResponse* resp = V8PaymentResponse::ToImplWithTypeCheck(
       scope.GetIsolate(), out_value.V8Value());
   EXPECT_EQ("standardShipping", resp->shippingOption());
-  EXPECT_EQ("US", resp->shippingAddress()->country());
-  EXPECT_EQ("en-Latn", resp->shippingAddress()->languageCode());
 }
 
 // If the merchant requests a payer name, the resolved show() promise should
diff --git a/third_party/blink/renderer/modules/payments/payment_address.cc b/third_party/blink/renderer/modules/payments/payment_address.cc
index 62f765a..192be382 100644
--- a/third_party/blink/renderer/modules/payments/payment_address.cc
+++ b/third_party/blink/renderer/modules/payments/payment_address.cc
@@ -18,18 +18,9 @@
       dependent_locality_(address->dependent_locality),
       postal_code_(address->postal_code),
       sorting_code_(address->sorting_code),
-      language_code_(address->language_code),
       organization_(address->organization),
       recipient_(address->recipient),
-      phone_(address->phone) {
-  if (!language_code_.IsEmpty() && !address->script_code.IsEmpty()) {
-    StringBuilder builder;
-    builder.Append(language_code_);
-    builder.Append('-');
-    builder.Append(address->script_code);
-    language_code_ = builder.ToString();
-  }
-}
+      phone_(address->phone) {}
 
 PaymentAddress::~PaymentAddress() = default;
 
@@ -42,7 +33,6 @@
   result.AddString("dependentLocality", dependentLocality());
   result.AddString("postalCode", postalCode());
   result.AddString("sortingCode", sortingCode());
-  result.AddString("languageCode", languageCode());
   result.AddString("organization", organization());
   result.AddString("recipient", recipient());
   result.AddString("phone", phone());
diff --git a/third_party/blink/renderer/modules/payments/payment_address.h b/third_party/blink/renderer/modules/payments/payment_address.h
index f993e0f..a27d82ae 100644
--- a/third_party/blink/renderer/modules/payments/payment_address.h
+++ b/third_party/blink/renderer/modules/payments/payment_address.h
@@ -33,7 +33,6 @@
   const String& dependentLocality() const { return dependent_locality_; }
   const String& postalCode() const { return postal_code_; }
   const String& sortingCode() const { return sorting_code_; }
-  const String& languageCode() const { return language_code_; }
   const String& organization() const { return organization_; }
   const String& recipient() const { return recipient_; }
   const String& phone() const { return phone_; }
@@ -46,7 +45,6 @@
   String dependent_locality_;
   String postal_code_;
   String sorting_code_;
-  String language_code_;
   String organization_;
   String recipient_;
   String phone_;
diff --git a/third_party/blink/renderer/modules/payments/payment_address.idl b/third_party/blink/renderer/modules/payments/payment_address.idl
index 01e2a3e..ec6ae165 100644
--- a/third_party/blink/renderer/modules/payments/payment_address.idl
+++ b/third_party/blink/renderer/modules/payments/payment_address.idl
@@ -13,7 +13,6 @@
     readonly attribute DOMString city;
     readonly attribute DOMString country;
     readonly attribute DOMString dependentLocality;
-    [MeasureAs=PaymentAddressLanguageCode] readonly attribute DOMString languageCode;
     readonly attribute DOMString organization;
     readonly attribute DOMString phone;
     readonly attribute DOMString postalCode;
diff --git a/third_party/blink/renderer/modules/payments/payment_address_test.cc b/third_party/blink/renderer/modules/payments/payment_address_test.cc
index 80f5b65..d2472e06 100644
--- a/third_party/blink/renderer/modules/payments/payment_address_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_address_test.cc
@@ -4,9 +4,10 @@
 
 #include "third_party/blink/renderer/modules/payments/payment_address.h"
 
-#include "testing/gtest/include/gtest/gtest.h"
 #include <utility>
 
+#include "testing/gtest/include/gtest/gtest.h"
+
 namespace blink {
 namespace {
 
@@ -22,8 +23,6 @@
   input->dependent_locality = "Venice";
   input->postal_code = "90291";
   input->sorting_code = "CEDEX";
-  input->language_code = "en";
-  input->script_code = "Latn";
   input->organization = "Google";
   input->recipient = "Jon Doe";
   input->phone = "Phone Number";
@@ -41,33 +40,10 @@
   EXPECT_EQ("Venice", output->dependentLocality());
   EXPECT_EQ("90291", output->postalCode());
   EXPECT_EQ("CEDEX", output->sortingCode());
-  EXPECT_EQ("en-Latn", output->languageCode());
   EXPECT_EQ("Google", output->organization());
   EXPECT_EQ("Jon Doe", output->recipient());
   EXPECT_EQ("Phone Number", output->phone());
 }
 
-TEST(PaymentAddressTest, IgnoreScriptCodeWithEmptyLanguageCode) {
-  payments::mojom::blink::PaymentAddressPtr input =
-      payments::mojom::blink::PaymentAddress::New();
-  input->script_code = "Latn";
-
-  PaymentAddress* output =
-      MakeGarbageCollected<PaymentAddress>(std::move(input));
-
-  EXPECT_TRUE(output->languageCode().IsEmpty());
-}
-
-TEST(PaymentAddressTest, NoHyphenWithEmptyScriptCode) {
-  payments::mojom::blink::PaymentAddressPtr input =
-      payments::mojom::blink::PaymentAddress::New();
-  input->language_code = "en";
-
-  PaymentAddress* output =
-      MakeGarbageCollected<PaymentAddress>(std::move(input));
-
-  EXPECT_EQ("en", output->languageCode());
-}
-
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index 791c248..1b85f3c7 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -191,8 +191,6 @@
     output->dependent_locality = input->hasDependentLocality()
                                      ? input->dependentLocality()
                                      : g_empty_string;
-    output->language_code =
-        input->hasLanguageCode() ? input->languageCode() : g_empty_string;
     output->organization =
         input->hasOrganization() ? input->organization() : g_empty_string;
     output->phone = input->hasPhone() ? input->phone() : g_empty_string;
diff --git a/third_party/blink/renderer/modules/payments/payment_response_test.cc b/third_party/blink/renderer/modules/payments/payment_response_test.cc
index 4cb8af68..c78ab7a0 100644
--- a/third_party/blink/renderer/modules/payments/payment_response_test.cc
+++ b/third_party/blink/renderer/modules/payments/payment_response_test.cc
@@ -175,8 +175,6 @@
   input->payer->name = "Jon Doe";
   input->shipping_address = payments::mojom::blink::PaymentAddress::New();
   input->shipping_address->country = "US";
-  input->shipping_address->language_code = "en";
-  input->shipping_address->script_code = "Latn";
   input->shipping_address->address_line.push_back("340 Main St");
   input->shipping_address->address_line.push_back("BIN1");
   input->shipping_address->address_line.push_back("First floor");
@@ -201,8 +199,7 @@
       "St\","
       "\"BIN1\",\"First "
       "floor\"],\"region\":\"\",\"city\":\"\",\"dependentLocality\":"
-      "\"\",\"postalCode\":\"\",\"sortingCode\":\"\",\"languageCode\":\"en-"
-      "Latn\","
+      "\"\",\"postalCode\":\"\",\"sortingCode\":\"\","
       "\"organization\":\"\",\"recipient\":\"\",\"phone\":\"\"},"
       "\"shippingOption\":"
       "\"standardShippingOption\",\"payerName\":\"Jon Doe\","
diff --git a/third_party/blink/renderer/modules/payments/payments_validators.cc b/third_party/blink/renderer/modules/payments/payments_validators.cc
index 4dec988..4a31613 100644
--- a/third_party/blink/renderer/modules/payments/payments_validators.cc
+++ b/third_party/blink/renderer/modules/payments/payments_validators.cc
@@ -60,59 +60,10 @@
   return false;
 }
 
-bool PaymentsValidators::IsValidLanguageCodeFormat(
-    const String& code,
-    String* optional_error_message) {
-  if (ScriptRegexp("^([a-z]{2,3})?$", kTextCaseSensitive).Match(code) == 0)
-    return true;
-
-  if (optional_error_message)
-    *optional_error_message =
-        "'" + code +
-        "' is not a valid BCP-47 language code, should be "
-        "2-3 lower case letters [a-z]";
-
-  return false;
-}
-
-bool PaymentsValidators::IsValidScriptCodeFormat(
-    const String& code,
-    String* optional_error_message) {
-  if (ScriptRegexp("^([A-Z][a-z]{3})?$", kTextCaseSensitive).Match(code) == 0)
-    return true;
-
-  if (optional_error_message)
-    *optional_error_message =
-        "'" + code +
-        "' is not a valid ISO 15924 script code, should be "
-        "an upper case letter [A-Z] followed by 3 lower "
-        "case letters [a-z]";
-
-  return false;
-}
-
 bool PaymentsValidators::IsValidShippingAddress(
     const payments::mojom::blink::PaymentAddressPtr& address,
     String* optional_error_message) {
-  if (!IsValidCountryCodeFormat(address->country, optional_error_message))
-    return false;
-
-  if (!IsValidLanguageCodeFormat(address->language_code,
-                                 optional_error_message))
-    return false;
-
-  if (!IsValidScriptCodeFormat(address->script_code, optional_error_message))
-    return false;
-
-  if (address->language_code.IsEmpty() && !address->script_code.IsEmpty()) {
-    if (optional_error_message)
-      *optional_error_message =
-          "If language code is empty, then script code should also be empty";
-
-    return false;
-  }
-
-  return true;
+  return IsValidCountryCodeFormat(address->country, optional_error_message);
 }
 
 bool PaymentsValidators::IsValidErrorMsgFormat(const String& error,
@@ -141,9 +92,6 @@
          (!errors->hasDependentLocality() ||
           IsValidErrorMsgFormat(errors->dependentLocality(),
                                 optional_error_message)) &&
-         (!errors->hasLanguageCode() ||
-          IsValidErrorMsgFormat(errors->languageCode(),
-                                optional_error_message)) &&
          (!errors->hasOrganization() ||
           IsValidErrorMsgFormat(errors->organization(),
                                 optional_error_message)) &&
diff --git a/third_party/blink/renderer/modules/payments/payments_validators.h b/third_party/blink/renderer/modules/payments/payments_validators.h
index dafd439..ac1e5d2 100644
--- a/third_party/blink/renderer/modules/payments/payments_validators.h
+++ b/third_party/blink/renderer/modules/payments/payments_validators.h
@@ -35,19 +35,8 @@
   static bool IsValidCountryCodeFormat(const String& code,
                                        String* optional_error_message);
 
-  // Returns true if |code| is a valid ISO 639 language code.
-  static bool IsValidLanguageCodeFormat(const String& code,
-                                        String* optional_error_message);
-
-  // Returns true if |code| is a valid ISO 15924 script code.
-  static bool IsValidScriptCodeFormat(const String& code,
-                                      String* optional_error_message);
-
   // Returns true if the payment address is valid:
   //  - Has a valid region code
-  //  - Has a valid language code, if any.
-  //  - Has a valid script code, if any.
-  // A script code should be present only if language code is present.
   static bool IsValidShippingAddress(
       const payments::mojom::blink::PaymentAddressPtr&,
       String* optional_error_message);
diff --git a/third_party/blink/renderer/modules/payments/payments_validators_test.cc b/third_party/blink/renderer/modules/payments/payments_validators_test.cc
index 9440130..0b5c3bf 100644
--- a/third_party/blink/renderer/modules/payments/payments_validators_test.cc
+++ b/third_party/blink/renderer/modules/payments/payments_validators_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/payments/payments_validators.h"
 
 #include <ostream>  // NOLINT
+
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -154,77 +155,12 @@
                                          TestCase("USA", false),
                                          TestCase("", false)));
 
-class PaymentsLanguageValidatorTest : public testing::TestWithParam<TestCase> {
-};
-
-TEST_P(PaymentsLanguageValidatorTest, IsValidLanguageCodeFormat) {
-  String error_message;
-  EXPECT_EQ(GetParam().expected_valid,
-            PaymentsValidators::IsValidLanguageCodeFormat(GetParam().input,
-                                                          &error_message))
-      << error_message;
-  EXPECT_EQ(GetParam().expected_valid, error_message.IsEmpty())
-      << error_message;
-
-  EXPECT_EQ(
-      GetParam().expected_valid,
-      PaymentsValidators::IsValidLanguageCodeFormat(GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(LanguageCodes,
-                         PaymentsLanguageValidatorTest,
-                         testing::Values(TestCase("", true),
-                                         TestCase("en", true),
-                                         TestCase("eng", true),
-                                         // Invalid language code formats
-                                         TestCase("e1", false),
-                                         TestCase("en1", false),
-                                         TestCase("e", false),
-                                         TestCase("engl", false),
-                                         TestCase("EN", false)));
-
-class PaymentsScriptValidatorTest : public testing::TestWithParam<TestCase> {};
-
-TEST_P(PaymentsScriptValidatorTest, IsValidScriptCodeFormat) {
-  String error_message;
-  EXPECT_EQ(GetParam().expected_valid,
-            PaymentsValidators::IsValidScriptCodeFormat(GetParam().input,
-                                                        &error_message))
-      << error_message;
-  EXPECT_EQ(GetParam().expected_valid, error_message.IsEmpty())
-      << error_message;
-
-  EXPECT_EQ(
-      GetParam().expected_valid,
-      PaymentsValidators::IsValidScriptCodeFormat(GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_SUITE_P(ScriptCodes,
-                         PaymentsScriptValidatorTest,
-                         testing::Values(TestCase("", true),
-                                         TestCase("Latn", true),
-                                         // Invalid script code formats
-                                         TestCase("Lat1", false),
-                                         TestCase("1lat", false),
-                                         TestCase("Latin", false),
-                                         TestCase("Lat", false),
-                                         TestCase("latn", false),
-                                         TestCase("LATN", false)));
-
 struct ShippingAddressTestCase {
-  ShippingAddressTestCase(const char* country_code,
-                          const char* language_code,
-                          const char* script_code,
-                          bool expected_valid)
-      : country_code(country_code),
-        language_code(language_code),
-        script_code(script_code),
-        expected_valid(expected_valid) {}
+  ShippingAddressTestCase(const char* country_code, bool expected_valid)
+      : country_code(country_code), expected_valid(expected_valid) {}
   ~ShippingAddressTestCase() = default;
 
   const char* country_code;
-  const char* language_code;
-  const char* script_code;
   bool expected_valid;
 };
 
@@ -235,8 +171,6 @@
   payments::mojom::blink::PaymentAddressPtr address =
       payments::mojom::blink::PaymentAddress::New();
   address->country = GetParam().country_code;
-  address->language_code = GetParam().language_code;
-  address->script_code = GetParam().script_code;
 
   String error_message;
   EXPECT_EQ(GetParam().expected_valid,
@@ -252,16 +186,12 @@
 INSTANTIATE_TEST_SUITE_P(
     ShippingAddresses,
     PaymentsShippingAddressValidatorTest,
-    testing::Values(
-        ShippingAddressTestCase("US", "en", "Latn", true),
-        ShippingAddressTestCase("US", "en", "", true),
-        ShippingAddressTestCase("US", "", "", true),
-        // Invalid shipping addresses
-        ShippingAddressTestCase("", "", "", false),
-        ShippingAddressTestCase("InvalidCountryCode", "", "", false),
-        ShippingAddressTestCase("US", "InvalidLanguageCode", "", false),
-        ShippingAddressTestCase("US", "en", "InvalidScriptCode", false),
-        ShippingAddressTestCase("US", "", "Latn", false)));
+    testing::Values(ShippingAddressTestCase("US", true),
+                    ShippingAddressTestCase("US", true),
+                    ShippingAddressTestCase("US", true),
+                    // Invalid shipping addresses
+                    ShippingAddressTestCase("", false),
+                    ShippingAddressTestCase("InvalidCountryCode", false)));
 
 struct ValidationErrorsTestCase {
   ValidationErrorsTestCase(bool expected_valid)
@@ -274,7 +204,6 @@
   const char* m_shipping_address_city = "";
   const char* m_shipping_address_country = "";
   const char* m_shipping_address_dependent_locality = "";
-  const char* m_shipping_address_language_code = "";
   const char* m_shipping_address_organization = "";
   const char* m_shipping_address_phone = "";
   const char* m_shipping_address_postal_code = "";
@@ -306,7 +235,6 @@
   shipping_address->setCountry(test_case.m_shipping_address_country);
   shipping_address->setDependentLocality(
       test_case.m_shipping_address_dependent_locality);
-  shipping_address->setLanguageCode(test_case.m_shipping_address_language_code);
   shipping_address->setOrganization(test_case.m_shipping_address_organization);
   shipping_address->setPhone(test_case.m_shipping_address_phone);
   shipping_address->setPostalCode(test_case.m_shipping_address_postal_code);
@@ -350,9 +278,6 @@
         VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
                                     "test",
                                     true),
-        VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
-                                    "test",
-                                    true),
         VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
                                     "test",
                                     true),
@@ -381,9 +306,6 @@
         VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
                                     LongString2049(),
                                     false),
-        VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
-                                    LongString2049(),
-                                    false),
         VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
                                     LongString2049(),
                                     false),
diff --git a/third_party/blink/renderer/modules/vr/vr_display.cc b/third_party/blink/renderer/modules/vr/vr_display.cc
index 94e7e987..1fda46f 100644
--- a/third_party/blink/renderer/modules/vr/vr_display.cc
+++ b/third_party/blink/renderer/modules/vr/vr_display.cc
@@ -1063,6 +1063,16 @@
   if (!doc)
     return;
 
+  if (frame_data->left_eye) {
+    eye_parameters_left_ =
+        MakeGarbageCollected<VREyeParameters>(frame_data->left_eye, 1);
+  }
+
+  if (frame_data->right_eye) {
+    eye_parameters_right_ =
+        MakeGarbageCollected<VREyeParameters>(frame_data->right_eye, 1);
+  }
+
   // Post a task to handle scheduled animations after the current
   // execution context finishes, so that we yield to non-mojo tasks in
   // between frames. Executing mojo tasks back to back within the same
diff --git a/third_party/blink/renderer/modules/webusb/OWNERS b/third_party/blink/renderer/modules/webusb/OWNERS
index 2caff2f..8dc3166 100644
--- a/third_party/blink/renderer/modules/webusb/OWNERS
+++ b/third_party/blink/renderer/modules/webusb/OWNERS
@@ -1,4 +1,4 @@
-reillyg@chromium.org
-rockot@google.com
+file://chrome/browser/usb/OWNERS
 
-# COMPONENT: Blink>USB
\ No newline at end of file
+# COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
diff --git a/third_party/blink/renderer/modules/xr/BUILD.gn b/third_party/blink/renderer/modules/xr/BUILD.gn
index 2fb81d3..b7c970c1 100644
--- a/third_party/blink/renderer/modules/xr/BUILD.gn
+++ b/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -28,6 +28,8 @@
     "xr_input_source_event.h",
     "xr_layer.cc",
     "xr_layer.h",
+    "xr_pose.cc",
+    "xr_pose.h",
     "xr_presentation_context.cc",
     "xr_presentation_context.h",
     "xr_ray.cc",
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
index d6727c8..7e2ac0e 100644
--- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
+++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -291,9 +291,9 @@
   // Used kInternalMedia since 1) this is not spec-ed and 2) this is media
   // related then tasks should not be throttled or frozen in background tabs.
   frame->GetTaskRunner(blink::TaskType::kInternalMedia)
-      ->PostTask(FROM_HERE,
-                 WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
-                           WrapWeakPersistent(this), nullptr, high_res_now_ms));
+      ->PostTask(FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
+                                      WrapWeakPersistent(this), std::move(data),
+                                      high_res_now_ms));
 }
 
 void XRFrameProvider::OnNonImmersiveVSync(double high_res_now_ms) {
@@ -404,6 +404,10 @@
       DCHECK(buffer_mailbox_holder_);
     }
 #endif
+    if (frame_data && (frame_data->left_eye || frame_data->right_eye)) {
+      immersive_session_->UpdateDisplayInfo(frame_data->left_eye,
+                                            frame_data->right_eye);
+    }
     immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix),
                                 buffer_mailbox_holder_, base::nullopt,
                                 base::nullopt);
diff --git a/third_party/blink/renderer/modules/xr/xr_pose.cc b/third_party/blink/renderer/modules/xr/xr_pose.cc
new file mode 100644
index 0000000..e4de76e
--- /dev/null
+++ b/third_party/blink/renderer/modules/xr/xr_pose.cc
@@ -0,0 +1,22 @@
+// 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 "third_party/blink/renderer/modules/xr/xr_pose.h"
+
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
+
+namespace blink {
+
+XRPose::XRPose(std::unique_ptr<TransformationMatrix> pose_model_matrix,
+               bool emulated_position)
+    : transform_(
+          MakeGarbageCollected<XRRigidTransform>(std::move(pose_model_matrix))),
+      emulated_position_(emulated_position) {}
+
+void XRPose::Trace(blink::Visitor* visitor) {
+  visitor->Trace(transform_);
+  ScriptWrappable::Trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_pose.h b/third_party/blink/renderer/modules/xr/xr_pose.h
new file mode 100644
index 0000000..8003b42
--- /dev/null
+++ b/third_party/blink/renderer/modules/xr/xr_pose.h
@@ -0,0 +1,39 @@
+// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_POSE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_POSE_H_
+
+#include <utility>
+
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
+
+namespace blink {
+
+class XRRigidTransform;
+
+class XRPose : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  XRPose(std::unique_ptr<TransformationMatrix>, bool);
+  ~XRPose() override = default;
+
+  XRRigidTransform* transform() const { return transform_; }
+  bool emulatedPosition() const { return emulated_position_; }
+
+  void Trace(blink::Visitor*) override;
+
+ protected:
+  Member<XRRigidTransform> transform_;
+
+ private:
+  bool emulated_position_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_POSE_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_pose.idl b/third_party/blink/renderer/modules/xr/xr_pose.idl
new file mode 100644
index 0000000..3827098
--- /dev/null
+++ b/third_party/blink/renderer/modules/xr/xr_pose.idl
@@ -0,0 +1,13 @@
+// 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.
+
+// https://immersive-web.github.io/webxr/#xrpose-interface
+[
+    SecureContext,
+    Exposed=Window,
+    OriginTrialEnabled=WebXR
+] interface XRPose {
+  readonly attribute XRRigidTransform transform;
+  readonly attribute boolean emulatedPosition;
+};
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index a1f03418..a7f7d75 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -241,6 +241,15 @@
   pending_render_state_.push_back(init);
 }
 
+void XRSession::UpdateDisplayInfo(
+    const device::mojom::blink::VREyeParametersPtr& left_eye,
+    const device::mojom::blink::VREyeParametersPtr& right_eye) {
+  auto display_info = display_info_.Clone();
+  display_info->leftEye = left_eye.Clone();
+  display_info->rightEye = right_eye.Clone();
+  SetXRDisplayInfo(std::move(display_info));
+}
+
 ScriptPromise XRSession::requestReferenceSpace(
     ScriptState* script_state,
     const XRReferenceSpaceOptions* options) {
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h
index 5d28777..0f6bdfd 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -149,9 +149,18 @@
 
   void OnPoseReset();
 
-  const device::mojom::blink::VRDisplayInfoPtr& GetVRDisplayInfo() {
+  const device::mojom::blink::VRDisplayInfoPtr& GetVRDisplayInfo() const {
     return display_info_;
   }
+
+  // TODO(jacde): Update the mojom to deliver this per-frame.
+  bool EmulatedPosition() const {
+    return !display_info_->capabilities->hasPosition;
+  }
+
+  void UpdateDisplayInfo(
+      const device::mojom::blink::VREyeParametersPtr& left_eye,
+      const device::mojom::blink::VREyeParametersPtr& right_eye);
   bool External() const { return is_external_; }
   // Incremented every time display_info_ is changed, so that other objects that
   // depend on it can know when they need to update.
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc b/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
index 8543bd85..85ab8a53 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
@@ -6,7 +6,6 @@
 
 #include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
 #include "third_party/blink/renderer/modules/xr/xr_session.h"
-#include "third_party/blink/renderer/modules/xr/xr_utils.h"
 #include "third_party/blink/renderer/modules/xr/xr_view.h"
 
 namespace blink {
@@ -14,9 +13,7 @@
 XRViewerPose::XRViewerPose(
     XRSession* session,
     std::unique_ptr<TransformationMatrix> pose_model_matrix)
-    : session_(session),
-      transform_(MakeGarbageCollected<XRRigidTransform>(
-          std::move(pose_model_matrix))) {
+    : XRPose(std::move(pose_model_matrix), session->EmulatedPosition()) {
   // Can only update views with an invertible matrix.
   TransformationMatrix inv_pose_matrix = transform_->InverseMatrix();
 
@@ -30,10 +27,8 @@
 }
 
 void XRViewerPose::Trace(blink::Visitor* visitor) {
-  visitor->Trace(session_);
-  visitor->Trace(transform_);
   visitor->Trace(views_);
-  ScriptWrappable::Trace(visitor);
+  XRPose::Trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.h b/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
index 321bfc2..1a27fc6 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
@@ -5,33 +5,27 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_VIEWER_POSE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_VIEWER_POSE_H_
 
-#include <utility>
+#include "third_party/blink/renderer/modules/xr/xr_pose.h"
 
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
 
 namespace blink {
 
-class XRRigidTransform;
 class XRSession;
 class XRView;
 
-class XRViewerPose final : public ScriptWrappable {
+class XRViewerPose final : public XRPose {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
   XRViewerPose(XRSession*, std::unique_ptr<TransformationMatrix>);
+  ~XRViewerPose() override = default;
 
-  XRRigidTransform* transform() const { return transform_; }
   const HeapVector<Member<XRView>>& views() const { return views_; }
 
   void Trace(blink::Visitor*) override;
 
  private:
-  const Member<XRSession> session_;
-  Member<XRRigidTransform> transform_;
   HeapVector<Member<XRView>> views_;
 };
 
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl b/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
index 9ebc6443..15fad3a 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
@@ -8,7 +8,6 @@
     SecureContext,
     Exposed=Window,
     OriginTrialEnabled=WebXR
-] interface XRViewerPose {
-  readonly attribute XRRigidTransform transform;
+] interface XRViewerPose : XRPose {
   readonly attribute FrozenArray<XRView> views;
 };
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 d2b161c7..86db6a1 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
@@ -650,8 +650,9 @@
       synthetic_effect.clip_id =
           EnsureCompositorClipNode(*pending_clip.clip->Parent());
     }
-    synthetic_effect.transform_id =
-        EnsureCompositorTransformNode(pending_clip.clip->LocalTransformSpace());
+    const auto& transform = pending_clip.clip->LocalTransformSpace();
+    synthetic_effect.transform_id = EnsureCompositorTransformNode(transform);
+    synthetic_effect.double_sided = !transform.IsBackfaceHidden();
     synthetic_effect.has_render_surface = true;
     // Clip and kDstIn do not commute. This shall never be reached because
     // kDstIn is only used internally to implement CSS clip-path and mask,
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
index 9b1a1dc..6e41f59 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
@@ -187,9 +187,7 @@
   EXPECT_EQ(fresh200, fetched);
 }
 
-// The strong validator causes a revalidation to be launched, and the proxy and
-// original resources leak because of their reference loop.
-TEST_F(MemoryCacheCorrectnessTest, DISABLED_ExpiredFromLastModified) {
+TEST_F(MemoryCacheCorrectnessTest, ExpiredFromLastModified) {
   ResourceResponse expired200_response;
   expired200_response.SetHTTPStatusCode(200);
   expired200_response.SetHTTPHeaderField("Date", kOriginalRequestDateAsString);
@@ -201,8 +199,13 @@
   // Advance the clock beyond the implicit freshness period.
   AdvanceClock(24. * 60. * 60. * 0.2);
 
+  EXPECT_FALSE(expired200->ErrorOccurred());
   MockResource* fetched = FetchMockResource();
-  EXPECT_NE(expired200, fetched);
+  // We want to make sure that revalidation happens, and we are checking the
+  // ResourceStatus because in this case the revalidation request fails
+  // synchronously.
+  EXPECT_EQ(expired200, fetched);
+  EXPECT_TRUE(expired200->ErrorOccurred());
 }
 
 TEST_F(MemoryCacheCorrectnessTest, ExpiredFromExpires) {
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index e6375a5..1604974 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -148,6 +148,8 @@
 crbug.com/591099 external/wpt/css/css-masking/clip-path/clip-path-ellipse-007.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-masking/clip-path/clip-path-polygon-010.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-multicol/multicol-span-all-005.html [ Failure ]
+crbug.com/921396 external/wpt/css/css-position/position-absolute-container-dynamic.html [ Failure ]
+crbug.com/907911 external/wpt/css/css-position/position-absolute-percentage-height.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-table-tbody-top-absolute-child.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-table-tr-left-absolute-child.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/static-position/htb-ltr-rtl.tentative.html [ Pass ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index 6d49fe4..4f17a39a 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2018,8 +2018,6 @@
 external/wpt/payment-request/change-shipping-option-manual.https.html [ WontFix ]
 external/wpt/payment-request/change-shipping-option-select-last-manual.https.html [ WontFix ]
 external/wpt/payment-request/payment-request-hasenrolledinstrument-method-manual.https.html [ WontFix ]
-external/wpt/payment-request/payment-request-multiple-show-manual.https.html [ WontFix ]
-external/wpt/payment-request/payment-request-show-method-manual.https.html [ WontFix ]
 external/wpt/payment-request/payment-response/complete-method-manual.https.html [ WontFix ]
 external/wpt/payment-request/payment-response/methodName-attribute-manual.https.html [ WontFix ]
 external/wpt/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0d11d7e8..5d10a20 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5740,8 +5740,6 @@
 
 # Sheriff 2018-11-23
 crbug.com/874162 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-event-fired.html [ Skip ]
-crbug.com/906320 virtual/not-site-per-process/http/tests/devtools/isolated-code-cache/same-origin-test.js [ Failure Pass ]
-crbug.com/906320 [ Mac10.13 ] virtual/site-isolated-code-cache/http/tests/devtools/isolated-code-cache/same-origin-test.js [ Failure Pass ]
 
 # Sheriff 2018-11-26
 crbug.com/908276 [ Mac ] external/wpt/webstorage/storage_setitem.html [ Pass Timeout ]
@@ -5914,7 +5912,6 @@
 crbug.com/922951 fast/text/international/inline-plaintext-relayout-with-leading-neutrals.html [ Skip ]
 crbug.com/922951 http/tests/cache/subresource-fragment-identifier.html [ Skip ]
 crbug.com/922951 http/tests/devtools/audits2/audits2-successful-run.js [ Skip ]
-crbug.com/922951 http/tests/devtools/isolated-code-cache/same-origin-test.js [ Skip ]
 crbug.com/922951 http/tests/devtools/tracing-session-id.js [ Skip ]
 crbug.com/922951 http/tests/devtools/tracing/console-timeline.js [ Skip ]
 crbug.com/922951 http/tests/devtools/tracing/timeline-network-received-data.js [ Skip ]
@@ -6028,8 +6025,6 @@
 crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.html [ Pass Failure ]
 crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.worker.html [ Pass Failure ]
 
-crbug.com/927296 virtual/wasm-site-isolated-code-cache/http/tests/devtools/wasm-isolated-code-cache/wasm-cache-test.js [ Pass Failure ]
-
 # Disabled until FreezeFramesOnVisiblity feature enabled by default.
 crbug.com/907125 external/wpt/lifecycle/child-display-none.tentative.html [ Skip ]
 
@@ -6072,7 +6067,3 @@
 
 # Sheriff 2019-02-13
 crbug.com/931646 [ Win7 ] http/tests/preload/meta-viewport-link-headers-imagesrcset.html [ Failure Pass ]
-
-# Temporarily disabling tests for RtpReceiver::GetParameters until new version is rolled into chromium.
-crbug.com/webrtc/10299 external/wpt/webrtc/RTCRtpReceiver-getParameters.html [ Pass Failure ]
-crbug.com/webrtc/10299 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpReceiver-getParameters.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property-expected.txt b/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property-expected.txt
deleted file mode 100644
index 666acc37..0000000
--- a/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-CONSOLE MESSAGE: line 62: background-color for the first target is: rgb(0, 128, 128)
-CONSOLE MESSAGE: line 64: box-shadow for the second target is: rgb(0, 128, 128) 4px 4px 25px 0px
-
diff --git a/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property.html b/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property.html
deleted file mode 100644
index c7f947410a..0000000
--- a/third_party/blink/web_tests/animations/animationworklet/animate-non-accelerated-property.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE html>
-<style>
-#target {
-  width: 100px;
-  height: 100px;
-  background-color: #0f0;
-}
-#target2 {
-  width: 100px;
-  height: 100px;
-  background-color: #0f0;
-  box-shadow: 4px 4px 25px #00f;
-}
-</style>
-
-<div id="target"></div>
-<div id="target2"></div>
-
-<script id="simple_animate" type="text/worklet">
-registerAnimator("test_animator", class {
-  animate(currentTime, effect) {
-    effect.localTime = 1000;
-  }
-});
-</script>
-
-<script src="resources/animation-worklet-tests.js"></script>
-<script>
-if (window.testRunner) {
-  testRunner.dumpAsText();
-  testRunner.waitUntilDone();
-}
-
-runInAnimationWorklet(
-  document.getElementById('simple_animate').textContent
-).then(_ => {
-  const effect = new KeyframeEffect(
-      document.getElementById("target"),
-      [
-        { background: '#0f0' },
-        { background: '#00f' },
-      ],
-      { duration: 2000 }
-  );
-
-  const effect2 = new KeyframeEffect(
-      document.getElementById("target2"),
-      [
-        { boxShadow: '4px 4px 25px #00f' },
-        { boxShadow: '4px 4px 25px #0f0' }
-      ],
-      { duration: 2000 }
-  );
-
-  const animation = new WorkletAnimation('test_animator', effect);
-  animation.play();
-  const animation2 = new WorkletAnimation('test_animator', effect2);
-  animation2.play();
-
-  if (window.testRunner) {
-    waitTwoAnimationFrames( _ => {
-      console.log('background-color for the first target is: ' +
-          getComputedStyle(document.getElementById('target')).backgroundColor);
-      console.log('box-shadow for the second target is: ' +
-          getComputedStyle(document.getElementById('target2')).boxShadow);
-      testRunner.notifyDone();
-    });
-  }
-});
-</script>
diff --git a/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property-expected.txt b/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property-expected.txt
deleted file mode 100644
index 387ba2d..0000000
--- a/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CONSOLE MESSAGE: line 49: background-color for the first target is: rgb(0, 255, 0)
-
diff --git a/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property.html b/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property.html
deleted file mode 100644
index cbf3b33a..0000000
--- a/third_party/blink/web_tests/animations/animationworklet/cancel-non-accelerated-property.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<style>
-#target {
-  width: 100px;
-  height: 100px;
-  background-color: #0f0;
-}
-</style>
-
-<div id="target"></div>
-
-<script id="simple_animate" type="text/worklet">
-registerAnimator("test_animator", class {
-  animate(currentTime, effect) {
-    effect.localTime = 1000;
-  }
-});
-</script>
-
-<script src="resources/animation-worklet-tests.js"></script>
-<script>
-if (window.testRunner) {
-  testRunner.dumpAsText();
-  testRunner.waitUntilDone();
-}
-
-runInAnimationWorklet(
-  document.getElementById('simple_animate').textContent
-).then(_ => {
-  const effect = new KeyframeEffect(
-      document.getElementById("target"),
-      [
-        { background: '#0f0' },
-        { background: '#00f' },
-      ],
-      {
-        duration: 2000,
-        iteration: Infinity
-      }
-  );
-
-  const animation = new WorkletAnimation('test_animator', effect);
-  animation.play();
-
-  waitTwoAnimationFrames( _ => {
-    animation.cancel();
-    if (window.testRunner) {
-      waitTwoAnimationFrames( _ => {
-        console.log('background-color for the first target is: ' +
-            getComputedStyle(document.getElementById('target')).backgroundColor);
-        testRunner.notifyDone();
-      });
-    }
-  });
-});
-</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 37af55d52..b3281a0 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
@@ -251506,6 +251506,12 @@
      {}
     ]
    ],
+   "kv-storage/backingstore.https.html": [
+    [
+     "/kv-storage/backingstore.https.html",
+     {}
+    ]
+   ],
    "kv-storage/cause-errors-via-idb.https.html": [
     [
      "/kv-storage/cause-errors-via-idb.https.html",
@@ -422719,6 +422725,10 @@
    "90e705862d599f2920ebdf5fa07cc3e4ba1f6d46",
    "testharness"
   ],
+  "kv-storage/backingstore.https.html": [
+   "44e634d85bbc34621450c4029a63c5e9114075b3",
+   "testharness"
+  ],
   "kv-storage/cause-errors-via-idb.https.html": [
    "21fe36b36cb1dbedca5383abb526b9b4f6c8ce3e",
    "testharness"
@@ -422764,7 +422774,7 @@
    "testharness"
   ],
   "kv-storage/storage-smoke-test.https.html": [
-   "df6fd8c8181f579df03972d25fe9a91b2354380f",
+   "da48dc7cf13cb31fd5f5a3b4b7fa086100197bd9",
    "testharness"
   ],
   "kv-storage/undefined-value.https.html": [
@@ -446280,7 +446290,7 @@
    "support"
   ],
   "resources/testdriver.js": [
-   "09a15e1bbb93880688f3216415711c7fd295355f",
+   "e328302e4f345114654eda323dbd09a5f650d419",
    "support"
   ],
   "resources/testdriver.js.headers": [
diff --git a/third_party/blink/web_tests/external/wpt/animation-worklet/animate-non-accelerated-property.https.html b/third_party/blink/web_tests/external/wpt/animation-worklet/animate-non-accelerated-property.https.html
new file mode 100644
index 0000000..8e30387
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/animation-worklet/animate-non-accelerated-property.https.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Animate non-accelerated property using worklet animation</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+
+<div id="target"></div>
+<div id="target2"></div>
+
+<script>
+  promise_test(async t => {
+    await registerConstantLocalTimeAnimator(1000);
+    const target = document.getElementById("target");
+    const effect = new KeyframeEffect(
+        target,
+        [
+          { background: 'green' },
+          { background: 'blue' },
+        ],
+        { duration: 2000 }
+    );
+
+    const target2 = document.getElementById("target2");
+    const effect2 = new KeyframeEffect(
+        target2,
+        [
+          { boxShadow: '4px 4px 25px blue' },
+          { boxShadow: '4px 4px 25px green' }
+        ],
+        { duration: 2000 }
+    );
+    const animation = new WorkletAnimation('constant_time', effect);
+    animation.play();
+    const animation2 = new WorkletAnimation('constant_time', effect2);
+    animation2.play();
+
+    await waitForAsyncAnimationFrames(1);
+    assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 64, 128)");
+    assert_equals(getComputedStyle(target2).boxShadow, "rgb(0, 64, 128) 4px 4px 25px 0px");
+  }, "Individual worklet animation should output values at specified local time for corresponding targets and effects");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/animation-worklet/cancel-non-accelerated-property.https.html b/third_party/blink/web_tests/external/wpt/animation-worklet/cancel-non-accelerated-property.https.html
new file mode 100644
index 0000000..594da4c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/animation-worklet/cancel-non-accelerated-property.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Cancel non accelerated property using worklet animation</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+
+<style>
+#target {
+  background-color: red;
+}
+</style>
+
+<div id="target"></div>
+
+<script>
+  promise_test(async t => {
+    await registerConstantLocalTimeAnimator(1000);
+    const target = document.getElementById('target');
+    const effect = new KeyframeEffect(
+        target,
+        [
+          { background: 'green' },
+          { background: 'blue' },
+        ],
+        {
+          duration: 2000,
+          iteration: Infinity
+        }
+    );
+    const animation = new WorkletAnimation('constant_time', effect);
+    animation.play();
+
+    await waitForAsyncAnimationFrames(1);
+    // establish that the animation started
+    assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 64, 128)");
+    animation.cancel();
+
+    await waitForAsyncAnimationFrames(1);
+    // confirm the animation is cancelled
+    assert_equals(getComputedStyle(target).backgroundColor, "rgb(255, 0, 0)");
+  }, "Animation should update the outputs after starting and then return to pre-animated values after being cancelled");
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-container-dynamic.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-container-dynamic.html
new file mode 100644
index 0000000..711d3176
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-container-dynamic.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>CSS Position Absolute: dynamic changes to containing block width</title>
+<link rel="author" href="mailto:atotic@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#abs-non-replaced-width">
+<meta name="assert" content="abspos descendant responds to containing block size change">
+<style>
+
+#container {
+  position: relative;
+  width: 50px;
+  height: 100px;
+  background: red;
+}
+#target {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: green;
+}
+</style>
+<div id="container">
+  <div style="display:flex;">
+    <div id="target"></div>
+  </div>
+</div>
+<script>
+document.body.offsetTop;
+test(() => {
+  document.getElementById("container").style.width = "100px";
+  assert_equals(document.querySelector("#target").offsetWidth, 100);
+}, '#target used container width when computing size');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-percentage-height.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-percentage-height.html
new file mode 100644
index 0000000..8b2e5c0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-percentage-height.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<title>CSS Position Absolute: css-position-3</title>
+<link rel="author" href="mailto:atotic@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://www.w3.org/TR/css-position-3/">
+<meta name="assert" content="abspos resolves %-ge sizes correctly.">
+<style>
+
+#container {
+  position: relative;
+}
+
+#image-wrapper {
+  display: flex;
+  position: absolute;
+  height: 100%;
+  background: green;
+}
+
+#content-wrapper {
+  margin-left: 30%;
+}
+
+#target {
+  display: block;
+  min-height: 100%;
+  opacity: 0.5;
+}
+</style>
+<!-- IMG height is 100% of image wrapper height.
+  IMG width is 100% of image wrapper width.
+  IMG width equals IMG height -->
+<div id="container">
+  <div id="image-wrapper">
+    <!-- 1x1 green pixel -->
+    <img id="target" src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==">
+  </div>
+  <div id="content-wrapper">
+    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+  </div>
+</div>
+<script>
+document.body.offsetTop;
+test(() => {
+  let target = document.querySelector("#target");
+  assert_equals(target.offsetWidth, target.offsetHeight);
+  assert_equals(target.offsetWidth, document.querySelector("#image-wrapper").offsetWidth);
+  assert_equals(target.offsetHeight, document.querySelector("#content-wrapper").offsetHeight);
+}, '#target height matches containing block height, and target parent width matches #target width' );
+
+test(() => {
+  document.body.style.marginLeft = "300px";
+  let target = document.querySelector("#target");
+  assert_equals(target.offsetWidth, target.offsetHeight);
+  assert_equals(target.offsetWidth, document.querySelector("#image-wrapper").offsetWidth);
+  assert_equals(target.offsetHeight, document.querySelector("#content-wrapper").offsetHeight);
+}, '#target height matches containing block height, and target parent width matches #target width after resize');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html
new file mode 100644
index 0000000..ebd2d86
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background: green"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html
new file mode 100644
index 0000000..6381ee7f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>CSS Test (Transforms): composited under rotateY(180deg) with overflow clip under perspective</title>
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2">
+<meta name="assert" content="This tests that a composited element with default
+  backface-visibility is visible under rotateY(180deg) with overflow clip under
+  perspective.">
+<link rel="match" href="composited-under-rotateY-180deg-clip-perspective-ref.html">
+<div style="perspective: 1px">
+  <div style="transform: rotateY(180deg); overflow: hidden; width: 100px">
+    <div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
+  </div>
+  <div style="transform: rotateY(180deg); overflow: hidden; width: 100px; backface-visibility: hidden">
+    <div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any-expected.txt b/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any-expected.txt
deleted file mode 100644
index 1ddd0815..0000000
--- a/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS UTF-7 should not be supported
-PASS utf-7 should not be supported
-PASS UTF-32 with BOM should decode as UTF-16LE
-FAIL UTF-32 with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32 expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS utf-32 with BOM should decode as UTF-16LE
-FAIL utf-32 with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32 expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS UTF-32LE with BOM should decode as UTF-16LE
-FAIL UTF-32LE with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32LE expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS utf-32le with BOM should decode as UTF-16LE
-FAIL utf-32le with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32le expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-FAIL UTF-32be with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32be expected "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+0080" but got "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+00C2/U+20AC"
-FAIL UTF-32be with BOM should decode as UTF-8 assert_equals: Decoding with UTF-32be expected "U+0000/U+0000/U+FFFD/U+FFFD/U+0000/U+0000/U+0000/U+0041/U+0000/U+0080/U+0042" but got "U+0000/U+0000/U+00FE/U+00FF/U+0000/U+0000/U+0000/U+0041/U+0000/U+00C2/U+20AC/U+0042"
-FAIL utf-32be with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32be expected "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+0080" but got "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+00C2/U+20AC"
-FAIL utf-32be with BOM should decode as UTF-8 assert_equals: Decoding with utf-32be expected "U+0000/U+0000/U+FFFD/U+FFFD/U+0000/U+0000/U+0000/U+0041/U+0000/U+0080/U+0042" but got "U+0000/U+0000/U+00FE/U+00FF/U+0000/U+0000/U+0000/U+0041/U+0000/U+00C2/U+20AC/U+0042"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any.worker-expected.txt
deleted file mode 100644
index 1ddd0815..0000000
--- a/third_party/blink/web_tests/external/wpt/encoding/unsupported-encodings.any.worker-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a testharness.js-based test.
-PASS UTF-7 should not be supported
-PASS utf-7 should not be supported
-PASS UTF-32 with BOM should decode as UTF-16LE
-FAIL UTF-32 with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32 expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS utf-32 with BOM should decode as UTF-16LE
-FAIL utf-32 with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32 expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS UTF-32LE with BOM should decode as UTF-16LE
-FAIL UTF-32LE with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32LE expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-PASS utf-32le with BOM should decode as UTF-16LE
-FAIL utf-32le with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32le expected "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+0080" but got "U+0041/U+0000/U+0000/U+0000/U+0042/U+0000/U+0000/U+00C2/U+20AC"
-FAIL UTF-32be with no BOM should decode as UTF-8 assert_equals: Decoding with UTF-32be expected "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+0080" but got "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+00C2/U+20AC"
-FAIL UTF-32be with BOM should decode as UTF-8 assert_equals: Decoding with UTF-32be expected "U+0000/U+0000/U+FFFD/U+FFFD/U+0000/U+0000/U+0000/U+0041/U+0000/U+0080/U+0042" but got "U+0000/U+0000/U+00FE/U+00FF/U+0000/U+0000/U+0000/U+0041/U+0000/U+00C2/U+20AC/U+0042"
-FAIL utf-32be with no BOM should decode as UTF-8 assert_equals: Decoding with utf-32be expected "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+0080" but got "U+0000/U+0000/U+0000/U+0041/U+0000/U+0000/U+0000/U+0042/U+00C2/U+20AC"
-FAIL utf-32be with BOM should decode as UTF-8 assert_equals: Decoding with utf-32be expected "U+0000/U+0000/U+FFFD/U+FFFD/U+0000/U+0000/U+0000/U+0041/U+0000/U+0080/U+0042" but got "U+0000/U+0000/U+00FE/U+00FF/U+0000/U+0000/U+0000/U+0041/U+0000/U+00C2/U+20AC/U+0042"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/historical.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/historical.https-expected.txt
deleted file mode 100644
index 34cd171..0000000
--- a/third_party/blink/web_tests/external/wpt/payment-request/historical.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-PASS paymentRequestID in PaymentRequest
-PASS paymentRequestID in PaymentResponse
-PASS careOf in PaymentAddress
-PASS totalAmount in PaymentResponse
-PASS paymentRequestId in PaymentRequest
-PASS paymentRequestId in PaymentResponse
-FAIL languageCode in PaymentAddress assert_false: expected false got true
-PASS regionCode in PaymentAddress
-PASS supportedMethods must not support sequence<DOMString>
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html
deleted file mode 100644
index cc412171..0000000
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-multiple-show-manual.https.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Manual test for multiple PaymentRequest.show()</title>
-<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-"use strict";
-setup({
-  allow_uncaught_exception: true,
-});
-const defaultMethods = Object.freeze([
-  { supportedMethods: "basic-card" },
-  {
-    supportedMethods: "https://apple.com/apple-pay",
-    data: {
-      version: 3,
-      merchantIdentifier: "merchant.com.example",
-      countryCode: "US",
-      merchantCapabilities: ["supports3DS"],
-      supportedNetworks: ["visa"],
-    }
-  },
-]);
-
-const defaultDetails = Object.freeze({
-  total: {
-    label: "Total",
-    amount: {
-      currency: "USD",
-      value: "1.00",
-    },
-  },
-});
-
-function testCallingShowMultipleTimes() {
-  promise_test(async t => {
-    const request = new PaymentRequest(defaultMethods, defaultDetails);
-    const p1 = request.show();
-    const p2 = request.show();
-    const p3 = request.show();
-    const promises = new Set([p1, p2, p3]);
-    await request.abort();
-    assert_equals(promises.size, 3, "Must have three unique objects");
-    await promise_rejects(t, "AbortError", p1);
-    await promise_rejects(t, "InvalidStateError", p2);
-    await promise_rejects(t, "InvalidStateError", p3);
-  }, "Calling show() multiple times is always a new object.");
-}
-</script>
-<h2>Manual test for multiple PaymentRequest.show()</h2>
-<p>
-  Click on the button to bring up the Payment Request UI window and then will
-  close it automatically. (If a payment sheet stays open, the test has failed.)
-</p>
-<ul>
-  <li>
-    <button onclick="testCallingShowMultipleTimes()">
-      Calling show() multiple times is always a new object.
-    </button>
-  </li>
-</ul>
-<small>
-  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
-  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
-</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html
deleted file mode 100644
index 6ef98e8..0000000
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method-manual.https.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Manual tests for PaymentRequest.show() method</title>
-<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-"use strict";
-setup({
-  explicit_done: true,
-  explicit_timeout: true,
-});
-const defaultMethods = Object.freeze([
-  { supportedMethods: "basic-card" },
-  {
-    supportedMethods: "https://apple.com/apple-pay",
-    data: {
-      version: 3,
-      merchantIdentifier: "merchant.com.example",
-      countryCode: "US",
-      merchantCapabilities: ["supports3DS"],
-      supportedNetworks: ["visa"],
-    }
-  },
-]);
-
-const defaultDetails = Object.freeze({
-  total: {
-    label: "Total",
-    amount: {
-      currency: "USD",
-      value: "1.00",
-    },
-  },
-});
-
-function testThrowsIfStateIsNotCreated() {
-  promise_test(async t => {
-    const request = new PaymentRequest(defaultMethods, defaultDetails);
-    const acceptPromise = request.show(); // Sets state to "interactive"
-    await promise_rejects(t, "InvalidStateError", request.show());
-    await request.abort();
-    await promise_rejects(t, "AbortError", acceptPromise);
-  }, "Throws if the promise [[state]] is not 'created'.");
-}
-
-function testPaymentRequestIsShowingBoolean() {
-  promise_test(async t => {
-    const request1 = new PaymentRequest(defaultMethods, defaultDetails);
-    const request2 = new PaymentRequest(defaultMethods, defaultDetails);
-    const acceptPromise1 = request1.show();
-    const acceptPromise2 = request2.show();
-    await promise_rejects(t, "AbortError", acceptPromise2);
-    await request1.abort();
-    await promise_rejects(t, "AbortError", acceptPromise1);
-  }, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
-}
-
-function testNotSupportedError() {
-  promise_test(async t => {
-    const request = new PaymentRequest(
-      [{ supportedMethods: "this-is-not-supported" }],
-      defaultDetails
-    );
-    const acceptPromise = request.show();
-    await promise_rejects(t, "NotSupportedError", acceptPromise);
-  }, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
-}
-</script>
-<h2>Manual tests for PaymentRequest.show() method</h2>
-<p>
-  Click on each button in sequence from top to bottom without refreshing the
-  page. Each button will bring up the Payment Request UI window and then will
-  close it automatically. (If a payment sheet stays open, the test has failed.)
-</p>
-<ol>
-  <li>
-    <button onclick="testThrowsIfStateIsNotCreated()">
-      Throws if the promise [[state]] is not 'created'.
-    </button>
-  </li>
-  <li>
-    <button onclick="testPaymentRequestIsShowingBoolean()">
-      If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.
-    </button>
-  </li>
-  <li>
-    <button onclick="testNotSupportedError()">
-      If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.
-    </button>
-  </li>
-  <li><button onclick="done()">Done!</button></li>
-</ol>
-<small>
-  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
-  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
-</small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt
index cfe2e93..bebd7e8 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt
@@ -1,4 +1,9 @@
 This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once
 FAIL Calling show() without being triggered by user interaction throws assert_throws: function "function() { throw e }" threw object "UnknownError: Request failed" that is not a DOMException SecurityError: property "code" is equal to 0, expected 18
+FAIL Throws if the promise [[state]] is not 'created'. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
+FAIL If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. assert_throws: function "function() { throw e }" threw object "InvalidStateError: Already called show() once" that is not a DOMException AbortError: property "code" is equal to 11, expected 20
+FAIL If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException. assert_throws: function "function() { throw e }" threw object "InvalidStateError: Already called show() once" that is not a DOMException NotSupportedError: property "code" is equal to 11, expected 9
+FAIL Calling show() multiple times always returns a new promise. 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/payment-request/payment-request-show-method.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html
index dd049870..cc8c881 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https.html
@@ -4,6 +4,8 @@
 <link rel="help" href="https://w3c.github.io/payment-request/#show-method">
 <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>
 "use strict";
 const defaultMethods = Object.freeze([
@@ -33,8 +35,80 @@
 promise_test(async t => {
   const request = new PaymentRequest(defaultMethods, defaultDetails);
   const acceptPromise = request.show();
+  // Abort the request after 2 seconds if it has not rejected. This allows the
+  // other tests in this file to run even if a non-compliant browser shows the
+  // payment sheet without user activation.
+  t.step_timeout(() => {
+    t.force_timeout();
+    request.abort();
+  }, 2000);
+
   await promise_rejects(t, "SecurityError", acceptPromise);
 }, `Calling show() without being triggered by user interaction throws`);
+
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const [acceptPromise] = await test_driver.bless(
+    "test: throws if the promise [[state]] is not 'created'",
+    () => {
+      const acceptPromise = request.show(); // Sets state to "interactive"
+      return [acceptPromise];
+    });
+  await promise_rejects(t, "InvalidStateError", request.show());
+  await request.abort();
+  await promise_rejects(t, "AbortError", acceptPromise);
+}, "Throws if the promise [[state]] is not 'created'.");
+
+promise_test(async t => {
+  const request1 = new PaymentRequest(defaultMethods, defaultDetails);
+  const request2 = new PaymentRequest(defaultMethods, defaultDetails);
+  const [acceptPromise1] = await test_driver.bless(
+    `test: reject promise with "AbortedError" if payment request is already showing`,
+    async () => {
+      const acceptPromise1 = request1.show();
+      const acceptPromise2 = request2.show();
+      await promise_rejects(t, "AbortError", acceptPromise2);
+      return [acceptPromise1];
+    });
+
+  await request1.abort();
+  await promise_rejects(t, "AbortError", acceptPromise1);
+}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
+
+promise_test(async t => {
+  const request = new PaymentRequest(
+    [{ supportedMethods: "this-is-not-supported" }],
+    defaultDetails
+  );
+  const [acceptPromise] = await test_driver.bless(
+    `test: reject promise with "NotSupportedError"`,
+    () => {
+      const acceptPromise = request.show();
+      return [acceptPromise];
+    });
+  await promise_rejects(t, "NotSupportedError", acceptPromise);
+}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
+
+promise_test(async t => {
+  const request = new PaymentRequest(defaultMethods, defaultDetails);
+  const [p1, p2, p3] = await test_driver.bless(
+    `test: calling show() multiple times always returns a new promise`,
+    () => {
+      const p1 = request.show();
+      const p2 = request.show();
+      const p3 = request.show();
+      return [p1, p2, p3];
+    });
+  const promises = new Set([p1, p2, p3]);
+  assert_equals(promises.size, 3, "Must have three unique objects");
+
+  await promise_rejects(t, "InvalidStateError", p2);
+  await promise_rejects(t, "InvalidStateError", p3);
+
+  await request.abort();
+  await promise_rejects(t, "AbortError", p1);
+}, "Calling show() multiple times always returns a new promise.");
+
 </script>
 <small>
   If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
diff --git a/third_party/blink/web_tests/external/wpt/resources/testdriver.js b/third_party/blink/web_tests/external/wpt/resources/testdriver.js
index 09a15e1..e328302e 100644
--- a/third_party/blink/web_tests/external/wpt/resources/testdriver.js
+++ b/third_party/blink/web_tests/external/wpt/resources/testdriver.js
@@ -197,7 +197,7 @@
         }
     };
 
-    var manual = {
+    window.test_driver_internal = {
         /**
          * This flag should be set to `true` by any code which implements the
          * internal methods defined below for automation purposes. Doing so
@@ -283,7 +283,4 @@
             return Promise.reject(new Error("unimplemented"));
         }
     };
-
-    window.test_driver_internal = Object.create(manual);
-
 })();
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getParameters-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getParameters-expected.txt
index 4f8f48aa..69215e4e 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getParameters-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-getParameters-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS getParameters() with audio receiver
 PASS getParameters() with video receiver
-FAIL getParameters() with simulcast video receiver promise_test: Unhandled rejection with value: object "OperationError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': Attempted to create an encoder with more than 1 encoding parameter."
+FAIL getParameters() with simulcast video receiver assert_greater_than: expected a number greater than 0 but got 0
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webusb/OWNERS b/third_party/blink/web_tests/external/wpt/webusb/OWNERS
index 7cabb58..8dc3166 100644
--- a/third_party/blink/web_tests/external/wpt/webusb/OWNERS
+++ b/third_party/blink/web_tests/external/wpt/webusb/OWNERS
@@ -1,2 +1,4 @@
+file://chrome/browser/usb/OWNERS
+
 # COMPONENT: Blink>USB
-# TEAM: device-dev@chromium.org
+# TEAM: webusb@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
index cb0fa2a..0ddbaadb 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 214 tests; 188 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 214 tests; 198 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Partial interface Navigator: original interface defined
 PASS Partial dictionary WebGLContextAttributes: original dictionary defined
@@ -133,18 +133,18 @@
 PASS XRRay interface: attribute origin
 PASS XRRay interface: attribute direction
 PASS XRRay interface: attribute matrix
-FAIL XRPose interface: existence and properties of interface object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface object length assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface object name assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface: attribute transform assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRPose interface: attribute emulatedPosition assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
-FAIL XRViewerPose interface: existence and properties of interface object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+PASS XRPose interface: existence and properties of interface object
+PASS XRPose interface object length
+PASS XRPose interface object name
+PASS XRPose interface: existence and properties of interface prototype object
+PASS XRPose interface: existence and properties of interface prototype object's "constructor" property
+PASS XRPose interface: existence and properties of interface prototype object's @@unscopables property
+PASS XRPose interface: attribute transform
+PASS XRPose interface: attribute emulatedPosition
+PASS XRViewerPose interface: existence and properties of interface object
 PASS XRViewerPose interface object length
 PASS XRViewerPose interface object name
-FAIL XRViewerPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+PASS XRViewerPose interface: existence and properties of interface prototype object
 PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property
 PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRViewerPose interface: attribute views
diff --git a/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-edge-cases.window-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-edge-cases.window-expected.txt
deleted file mode 100644
index 8e3a758e..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/overridemimetype-edge-cases.window-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS overrideMimeType() is not reset by open(), basic
-PASS overrideMimeType() is not reset by open()
-PASS If charset is not overridden by overrideMimeType() the original continues to be used
-FAIL Charset can be overridden by overrideMimeType() with a bogus charset assert_equals: expected "\ufffd\ufffd" but got "Âð"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/xhr/responsetext-decoding-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/responsetext-decoding-expected.txt
deleted file mode 100644
index 7460930..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/responsetext-decoding-expected.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-This is a testharness.js-based test.
-PASS XMLHttpRequest: responseText decoding (application/xml %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (text/html %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (application/xml;charset=utf-8 %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (application/xml;charset=windows-1252 %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (text/html;charset=utf-8 %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (text/html;charset=windows-1252 %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E empty)
-PASS XMLHttpRequest: responseText decoding (text/plain;charset=windows-1252 %FF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %FF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %FE%FF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %FE%FF%FE%FF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %EF%BB%BF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %EF%BB%BF%EF%BB%BF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %C2 empty)
-PASS XMLHttpRequest: responseText decoding (text/xml %FE%FF empty)
-PASS XMLHttpRequest: responseText decoding (text/xml %FE%FF%FE%FF empty)
-PASS XMLHttpRequest: responseText decoding (text/xml %EF%BB%BF empty)
-PASS XMLHttpRequest: responseText decoding (text/xml %EF%BB%BF%EF%BB%BF empty)
-PASS XMLHttpRequest: responseText decoding (text/plain %E3%81%B2 empty)
-PASS XMLHttpRequest: responseText decoding (application/xml %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (text/html %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (application/xml;charset=utf-8 %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (application/xml;charset=windows-1252 %3C%3Fxml%20version%3D'1.0'%20encoding%3D'windows-1252'%3F%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (text/html;charset=utf-8 %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (text/html;charset=windows-1252 %3C!doctype%20html%3E%3Cmeta%20charset%3Dwindows-1252%3E%3Cx%3E%e6%a9%9f%3C%2Fx%3E  text)
-PASS XMLHttpRequest: responseText decoding (text/plain;charset=windows-1252 %FF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %FF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %FE%FF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %FE%FF%FE%FF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %EF%BB%BF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %EF%BB%BF%EF%BB%BF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %C2  text)
-FAIL XMLHttpRequest: responseText decoding (text/plain;charset=bogus %C2  text) assert_equals: expected "\ufffd" but got "Â"
-PASS XMLHttpRequest: responseText decoding (text/xml %FE%FF  text)
-PASS XMLHttpRequest: responseText decoding (text/xml %FE%FF%FE%FF  text)
-PASS XMLHttpRequest: responseText decoding (text/xml %EF%BB%BF  text)
-PASS XMLHttpRequest: responseText decoding (text/xml %EF%BB%BF%EF%BB%BF  text)
-PASS XMLHttpRequest: responseText decoding (text/plain %E3%81%B2  text)
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data-expected.txt b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data-expected.txt
index 9504723..359ea99 100644
--- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data-expected.txt
@@ -1,5 +1,7 @@
 Tests that data is correctly loaded by IndexedDBModel from IndexedDB object store and index.
 
+key generator value: 1
+key generator value: 7
 Dumping values, fromIndex = false, skipCount = 0, pageSize = 2, idbKeyRange = null
     Key = key_01, primaryKey = key_01, value = {"key":"key_01","value":"value_01"}
     Key = key_02, primaryKey = key_02, value = {"key":"key_02","value":"value_02"}
@@ -64,4 +66,12 @@
 VM:3 InspectorTest.IndexedDB_callback10
 VM:3 InspectorTest.IndexedDB_callback11
 VM:3 InspectorTest.IndexedDB_callback12
+VM:3 InspectorTest.IndexedDB_callback13
+VM:3 InspectorTest.IndexedDB_callback14
+VM:3 InspectorTest.IndexedDB_callback15
+VM:3 InspectorTest.IndexedDB_callback16
+VM:3 InspectorTest.IndexedDB_callback17
+VM:3 InspectorTest.IndexedDB_callback18
+VM:3 InspectorTest.IndexedDB_callback19
+VM:3 InspectorTest.IndexedDB_callback20
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data.js b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data.js
index b911abbd..51ddaa8b 100644
--- a/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data.js
+++ b/third_party/blink/web_tests/http/tests/devtools/indexeddb/database-data.js
@@ -13,11 +13,17 @@
   var mainFrameId = TestRunner.resourceTreeModel.mainFrame.id;
   var securityOrigin = 'http://127.0.0.1:8000';
   var databaseName = 'testDatabase';
-  var objectStoreName = 'testObjectStore';
+  var objectStoreName1 = 'testObjectStore1';
+  var objectStoreName2 = 'testObjectStore2';
   var indexName = 'testIndexName';
   var databaseId = new Resources.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
 
-  function addIDBValues(count, callback) {
+  /**
+   * @param {number} count
+   * @param {boolean} specifyKey
+   * @param {*} callback
+   */
+  function addIDBValues(count, objectStoreName, specifyKey, callback) {
     var i = 0;
     addValues();
 
@@ -30,8 +36,13 @@
       var id = i < 10 ? '0' + i : i;
       var key = 'key_' + id;
       var value = 'value_' + id;
+      let insertedObject;
+      if (specifyKey)
+        insertedObject = {key: key, value: value};
+      else
+        insertedObject = {value: value};
       ApplicationTestRunner.addIDBValue(
-          mainFrameId, databaseName, objectStoreName, {key: key, value: value}, '', addValues);
+          mainFrameId, databaseName, objectStoreName, insertedObject, '', addValues);
     }
   }
 
@@ -44,9 +55,9 @@
         ', idbKeyRange = ' + idbKeyRangeString);
     if (fromIndex)
       indexedDBModel.loadIndexData(
-          databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, innerCallback);
+          databaseId, objectStoreName1, indexName, idbKeyRange, skipCount, pageSize, innerCallback);
     else
-      indexedDBModel.loadObjectStoreData(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, innerCallback);
+      indexedDBModel.loadObjectStoreData(databaseId, objectStoreName1, idbKeyRange, skipCount, pageSize, innerCallback);
 
     function innerCallback(entries, hasMore) {
       var index = 0;
@@ -82,22 +93,38 @@
     ApplicationTestRunner.createDatabase(mainFrameId, databaseName, step2);
 
     function step2() {
-      ApplicationTestRunner.createObjectStore(mainFrameId, databaseName, objectStoreName, 'key', true, step3);
+      ApplicationTestRunner.createObjectStore(
+        mainFrameId, databaseName, objectStoreName1, 'key', true, () => {
+          ApplicationTestRunner.createObjectStore(mainFrameId, databaseName, objectStoreName2, 'key', true, step3);
+        });
     }
 
     function step3() {
       ApplicationTestRunner.createObjectStoreIndex(
-          mainFrameId, databaseName, objectStoreName, indexName, 'value', false, true, step4);
+          mainFrameId, databaseName, objectStoreName1, indexName, 'value', false, true, step4);
     }
 
     function step4() {
-      addIDBValues(6, refreshDatabaseNames);
+      addIDBValues(6, objectStoreName1, true, () => {
+        addIDBValues(6, objectStoreName2, false, postFillingActions);
+      });
     }
-  }
 
-  function refreshDatabaseNames() {
-    TestRunner.addSniffer(Resources.IndexedDBModel.prototype, '_updateOriginDatabaseNames', refreshDatabase, false);
-    indexedDBModel.refreshDatabaseNames();
+    async function postFillingActions() {
+      await new Promise(resolve => {
+        indexedDBModel.getKeyGeneratorValue(
+          databaseId, {name: objectStoreName1, autoIncrement: true}).then(printKeyGeneratorValue);
+        indexedDBModel.getKeyGeneratorValue(
+          databaseId, {name: objectStoreName2, autoIncrement: true}).then(printKeyGeneratorValue);
+        resolve();
+      });
+      TestRunner.addSniffer(Resources.IndexedDBModel.prototype, '_updateOriginDatabaseNames', refreshDatabase, false);
+      indexedDBModel.refreshDatabaseNames();
+
+      function printKeyGeneratorValue(number) {
+        TestRunner.addResult('key generator value: ' + (number ? String(number) : 'null'));
+      }
+    }
   }
 
   function refreshDatabase() {
@@ -167,7 +194,7 @@
   }
 
   function runClearTests() {
-    indexedDBModel.clearObjectStore(databaseId, objectStoreName).then(step1);
+    indexedDBModel.clearObjectStore(databaseId, objectStoreName1).then(step1);
     TestRunner.addResult('Cleared data from objectStore');
 
     function step1() {
@@ -185,10 +212,12 @@
   }
 
   function deleteDatabase() {
-    ApplicationTestRunner.deleteObjectStoreIndex(mainFrameId, databaseName, objectStoreName, indexName, step2);
+    ApplicationTestRunner.deleteObjectStoreIndex(mainFrameId, databaseName, objectStoreName1, indexName, step2);
 
     function step2() {
-      ApplicationTestRunner.deleteObjectStore(mainFrameId, databaseName, objectStoreName, step3);
+      ApplicationTestRunner.deleteObjectStore(mainFrameId, databaseName, objectStoreName1, () => {
+        ApplicationTestRunner.deleteObjectStore(mainFrameId, databaseName, objectStoreName2, step3);
+      });
     }
 
     function step3() {
diff --git a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/cross-origin-script.html b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/cross-origin-script.html
new file mode 100644
index 0000000..6a6823d
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/cross-origin-script.html
@@ -0,0 +1 @@
+<script charset="UTF-8" src="http://localhost:8000/devtools/resources/v8-cache-script.cgi"></script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/same-origin-script.html b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/same-origin-script.html
new file mode 100644
index 0000000..a100263
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/resources/same-origin-script.html
@@ -0,0 +1 @@
+<script charset="UTF-8" src="/devtools/resources/v8-cache-script.cgi"></script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt
index a67a62c..51e1ab3 100644
--- a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test-expected.txt
@@ -8,13 +8,13 @@
         lineNumber : 0
         notStreamedReason : "script too small"
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
 v8.compile Properties:
 {
     data : {
@@ -22,13 +22,13 @@
         lineNumber : 0
         notStreamedReason : "already used streamed data"
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
 v8.compile Properties:
 {
     data : {
@@ -38,13 +38,13 @@
         notStreamedReason : "already used streamed data"
         producedCacheSize : <number>
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
 v8.compile Properties:
 {
     data : {
@@ -55,13 +55,13 @@
         lineNumber : 0
         notStreamedReason : "already used streamed data"
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
 v8.compile Properties:
 {
     data : {
@@ -69,13 +69,13 @@
         lineNumber : 0
         notStreamedReason : "script too small"
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
 v8.compile Properties:
 {
     data : {
@@ -86,12 +86,29 @@
         lineNumber : 0
         notStreamedReason : "already used streamed data"
         streamed : <boolean>
-        url : .../devtools/resources/v8-cache-script.js
+        url : .../devtools/resources/v8-cache-script.cgi
     }
     endTime : <number>
     startTime : <number>
     type : "v8.compile"
 }
-Text details for v8.compile: v8-cache-script.js:1
+Text details for v8.compile: v8-cache-script.cgi:1
+v8.compile Properties:
+{
+    data : {
+        cacheConsumeOptions : "code"
+        cacheRejected : false
+        columnNumber : 0
+        consumedCacheSize : <number>
+        lineNumber : 0
+        notStreamedReason : "script too small"
+        streamed : <boolean>
+        url : .../devtools/resources/v8-cache-script.cgi
+    }
+    endTime : <number>
+    startTime : <number>
+    type : "v8.compile"
+}
+Text details for v8.compile: v8-cache-script.cgi:1
 -----------------------------------------------
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test.js b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test.js
index c3dacc1..777f181e 100644
--- a/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/isolated-code-cache/same-origin-test.js
@@ -11,51 +11,48 @@
   // scripts in the cache.
   SDK.multitargetNetworkManager.clearBrowserCache();
 
-  await TestRunner.evaluateInPagePromise(`
-      function loadScript() {
-        const url = 'http://localhost:8000/devtools/resources/v8-cache-script.js';
-        const frameId = 'frame_id';
-        let iframeWindow = document.getElementById(frameId).contentWindow;
-        return iframeWindow.loadScript(url)
-            .then(() => iframeWindow.loadScript(url))
-            .then(() => iframeWindow.loadScript(url));
-      }
-      function differentURLLoadScript() {
-        const url = 'http://127.0.0.1:8000/devtools/resources/v8-cache-script.js';
-        const frameId = 'diff_url_frame';
-        let iframeWindow = document.getElementById(frameId).contentWindow;
-        return iframeWindow.loadScript(url);
-      }
-      function sameURLLoadScript() {
-        const url = 'http://localhost:8000/devtools/resources/v8-cache-script.js';
-        const frameId = 'same_url_frame';
-        let iframeWindow = document.getElementById(frameId).contentWindow;
-        return iframeWindow.loadScript(url);
-      }
-  `);
+  // There are two scripts:
+  // [A] http://127.0.0.1:8000/devtools/resources/v8-cache-script.cgi
+  // [B] http://localhost:8000/devtools/resources/v8-cache-script.cgi
 
-  const scope = 'http://127.0.0.1:8000/devtools/service-workers/resources/v8-cache-iframe.html';
-  const frameId = 'frame_id';
-  const different_url_frameId = 'diff_url_frame';
-  const same_url_frameId = 'same_url_frame';
-
-  await TestRunner.addIframe(scope, {id: frameId});
-  await TestRunner.addIframe(scope, {id: different_url_frameId});
-  await TestRunner.addIframe(scope, {id: same_url_frameId});
+  // An iframe that loads [A].
+  // The script is executed as a parser-inserted script,
+  // to keep the ScriptResource on the MemoryCache.
+  // ScriptResources for dynamically-inserted <script>s can be
+  // garbage-collected and thus removed from MemoryCache after its execution.
+  const scope = 'resources/same-origin-script.html';
+  // An iframe that loads [B].
+  const scopeCrossOrigin = 'resources/cross-origin-script.html';
 
   TestRunner.addResult('--- Trace events related to code caches ------');
   await PerformanceTestRunner.startTimeline();
-  // This loads the same script thrice. With the current V8 heuristics (defined
+
+  // Load [A] thrice. With the current V8 heuristics (defined
   // in third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc) we produce
   // cache on second fetch and consume it in the third fetch. This tests these
   // heuristics.
-  await TestRunner.callFunctionInPageAsync('loadScript');
+  // Note that addIframe() waits for iframe's load event, which waits for the
+  // <script> loading.
+  await TestRunner.addIframe(scope);
+  await TestRunner.addIframe(scope);
+  await TestRunner.addIframe(scope);
 
-  // Load from a different origin should not use the cached code
-  await TestRunner.callFunctionInPageAsync('differentURLLoadScript');
+  // Load [B]. Should not use the cached code.
+  await TestRunner.addIframe(scopeCrossOrigin);
 
-  // Loading from the same origin should use cached code
-  await TestRunner.callFunctionInPageAsync('sameURLLoadScript');
+  // Load [A] again from MemoryCache. Should use cached code.
+  await TestRunner.addIframe(scope);
+
+  // Clear [A] from MemoryCache. Blink evicts previous Resource when a
+  // new request to the same URL but with different resource type is started.
+  // We fetch() to the URL of [A], and thus evicts the previous ScriptResource
+  // of [A].
+  await TestRunner.evaluateInPageAsync(
+      `fetch('/devtools/resources/v8-cache-script.cgi')`);
+
+  // Load [A] from Disk Cache. As we cleared [A] from MemoryCache, this
+  // doesn't hit MemoryCache, but still hits Disk Cache.
+  await TestRunner.addIframe(scope);
 
   await PerformanceTestRunner.stopTimeline();
   PerformanceTestRunner.printTimelineRecordsWithDetails(
diff --git a/third_party/blink/web_tests/http/tests/devtools/resources/v8-cache-script.cgi b/third_party/blink/web_tests/http/tests/devtools/resources/v8-cache-script.cgi
new file mode 100755
index 0000000..685dacb3
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/resources/v8-cache-script.cgi
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -wT
+
+print <<EOM;
+Content-Type: text/javascript
+Access-Control-Allow-Origin: *
+Cache-Control: private, max-age=1000
+
+// So sorry about this waste of bytes:
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+// Filler comment, to trigger code caching heuristic (script > 1K.)
+EOM
diff --git a/third_party/blink/web_tests/http/tests/usb/OWNERS b/third_party/blink/web_tests/http/tests/usb/OWNERS
index 2a5357e..8dc3166 100644
--- a/third_party/blink/web_tests/http/tests/usb/OWNERS
+++ b/third_party/blink/web_tests/http/tests/usb/OWNERS
@@ -1,2 +1,4 @@
-# TEAM: device-dev@chromium.org
+file://chrome/browser/usb/OWNERS
+
 # COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
diff --git a/third_party/blink/web_tests/platform/linux/fast/hidpi/resize-corner-hidpi-expected.png b/third_party/blink/web_tests/platform/linux/fast/hidpi/resize-corner-hidpi-expected.png
index b79d157..d2c7ebd1 100644
--- a/third_party/blink/web_tests/platform/linux/fast/hidpi/resize-corner-hidpi-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/hidpi/resize-corner-hidpi-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/hidpi/resize-corner-hidpi-expected.png b/third_party/blink/web_tests/platform/win/fast/hidpi/resize-corner-hidpi-expected.png
index a52861d..bd408a56 100644
--- a/third_party/blink/web_tests/platform/win/fast/hidpi/resize-corner-hidpi-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/hidpi/resize-corner-hidpi-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/usb/OWNERS b/third_party/blink/web_tests/usb/OWNERS
index 2a5357e..8dc3166 100644
--- a/third_party/blink/web_tests/usb/OWNERS
+++ b/third_party/blink/web_tests/usb/OWNERS
@@ -1,2 +1,4 @@
-# TEAM: device-dev@chromium.org
+file://chrome/browser/usb/OWNERS
+
 # COMPONENT: Blink>USB
+# TEAM: webusb@chromium.org
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 d57c9c3..fbc7e2d 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
@@ -4465,7 +4465,6 @@
     getter city
     getter country
     getter dependentLocality
-    getter languageCode
     getter organization
     getter phone
     getter postalCode
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 56108888..f0e6d703 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
@@ -5166,7 +5166,6 @@
     getter city
     getter country
     getter dependentLocality
-    getter languageCode
     getter organization
     getter phone
     getter postalCode
@@ -10469,6 +10468,11 @@
 interface XRLayer
     attribute @@toStringTag
     method constructor
+interface XRPose
+    attribute @@toStringTag
+    getter emulatedPosition
+    getter transform
+    method constructor
 interface XRPresentationContext
     attribute @@toStringTag
     getter canvas
@@ -10546,9 +10550,8 @@
     getter transform
     getter viewMatrix
     method constructor
-interface XRViewerPose
+interface XRViewerPose : XRPose
     attribute @@toStringTag
-    getter transform
     getter views
     method constructor
 interface XRViewport
diff --git a/third_party/libFuzzer/BUILD.gn b/third_party/libFuzzer/BUILD.gn
index 25d54402..273604dd 100644
--- a/third_party/libFuzzer/BUILD.gn
+++ b/third_party/libFuzzer/BUILD.gn
@@ -4,23 +4,35 @@
 
 import("///build/config/sanitizers/sanitizers.gni")
 
+config("ignore_unused_result_warning") {
+  if (is_clang) {
+    cflags = [
+      # See crbug.com/932188, libFuzzer does not check the result of write()
+      # when it does raw printing.
+      "-Wno-unused-result",
+    ]
+  }
+}
+
 # Engine should be compiled without coverage (infinite loop in trace_cmp).
 fuzzing_engine_remove_configs = [
   "//build/config/coverage:default_coverage",
   "//build/config/sanitizers:default_sanitizer_flags",
 ]
 
-# Add any sanitizer flags back.  In MSAN builds, instrumenting libfuzzer with
+# Add any sanitizer flags back. In MSAN builds, instrumenting libfuzzer with
 # MSAN is necessary since all parts of the binary need to be instrumented for it
-# to work.  ASAN builds are more subtle: libfuzzer depends on features from the
-# C++ STL.  If it were not instrumented, templates would be insantiated without
-# ASAN from libfuzzer and with ASAN in other TUs.  The linker might merge
+# to work. ASAN builds are more subtle: libfuzzer depends on features from the
+# C++ STL. If it were not instrumented, templates would be insantiated without
+# ASAN from libfuzzer and with ASAN in other TUs. The linker might merge
 # instrumented template instantiations with non-instrumented ones (which could
 # have a different ABI) in the final binary, which is problematic for TUs
-# expecting one particular ABI (https://crbug.com/915422).  The other sanitizers
+# expecting one particular ABI (https://crbug.com/915422). The other sanitizers
 # are added back for the same reason.
-fuzzing_engine_add_configs =
-    [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ]
+fuzzing_engine_add_configs = [
+  "//build/config/sanitizers:default_sanitizer_flags_but_coverage",
+  ":ignore_unused_result_warning",
+]
 
 source_set("libfuzzer") {
   sources = [
diff --git a/third_party/libudev/OWNERS b/third_party/libudev/OWNERS
index 528326c..dbeb6f2 100644
--- a/third_party/libudev/OWNERS
+++ b/third_party/libudev/OWNERS
@@ -1,4 +1,5 @@
-reillyg@chromium.org
+file://chrome/browser/usb/OWNERS
 thestig@chromium.org
 
-# COMPONENT: IO>USB
\ No newline at end of file
+# COMPONENT: IO>USB
+# TEAM: device-dev@chromium.org
diff --git a/third_party/usb_ids/OWNERS b/third_party/usb_ids/OWNERS
index a011e5d..e841f9b 100644
--- a/third_party/usb_ids/OWNERS
+++ b/third_party/usb_ids/OWNERS
@@ -1,3 +1,4 @@
-reillyg@chromium.org
+file://chrome/browser/usb/OWNERS
 
-# COMPONENT: IO>USB
\ No newline at end of file
+# COMPONENT: IO>USB
+# TEAM: device-dev@chromium.org
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8831644..e375c783 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -2365,6 +2365,7 @@
   <int value="1" label="Gain"/>
   <int value="2" label="Gain transient may duck"/>
   <int value="3" label="Gain transient"/>
+  <int value="4" label="Ambient"/>
 </enum>
 
 <enum name="AudioFramesPerBuffer">
@@ -28178,6 +28179,19 @@
   <int value="4" label="Number of events"/>
 </enum>
 
+<enum name="InspectionResultsCacheReadResult">
+  <int value="0" label="Success"/>
+  <int value="1" label="Failed to read the file"/>
+  <int value="2" label="Failed to deserialize the version number"/>
+  <int value="3" label="Invalid cache version"/>
+  <int value="4"
+      label="Failed to deserialize the number of inspection results"/>
+  <int value="5" label="The number of inspection results is negative"/>
+  <int value="6" label="Failed to deserialize an inspection result"/>
+  <int value="7" label="Failed to deserialize the MD5 digest"/>
+  <int value="8" label="Invalid MD5 digest"/>
+</enum>
+
 <enum name="InstallabilityCheckStatus">
   <int value="0" label="Check not started"/>
   <int value="1" label="Check terminated before it could finish"/>
@@ -31439,6 +31453,7 @@
   <int value="-864205629" label="enable-offline-load-stale-cache"/>
   <int value="-861678473" label="disable-offer-upload-credit-cards"/>
   <int value="-861343291" label="ChromeHome:disabled"/>
+  <int value="-860578793" label="TabGridLayoutAndroid:disabled"/>
   <int value="-860534647" label="SiteDetails:enabled"/>
   <int value="-856915246" label="enable-new-audio-rendering-mixing-strategy"/>
   <int value="-856016114" label="NTPOfflinePages:disabled"/>
@@ -32564,6 +32579,7 @@
   <int value="1116593018" label="CaptureThumbnailOnLoadFinished:disabled"/>
   <int value="1117795262" label="BloatedRendererDetection:disabled"/>
   <int value="1118109174" label="enable-launcher-search-provider-api"/>
+  <int value="1120428727" label="TabGridLayoutAndroid:enabled"/>
   <int value="1126061778" label="CaptureThumbnailOnLoadFinished:enabled"/>
   <int value="1127183523" label="PassiveEventListenersDueToFling:enabled"/>
   <int value="1127427821" label="OmniboxEntitySuggestions:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index dee9ecb..9b2da27 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -26456,23 +26456,26 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.MetadataDBInitResult" enum="DriveMetadataDBInitStatus">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.MetadataDBInitResult" enum="DriveMetadataDBInitStatus"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>Result of drive resource metadata database initialization.</summary>
 </histogram>
 
 <histogram name="Drive.MetadataDBOpenExistingResult"
-    enum="DriveMetadataDBInitStatus">
-  <owner>joshwoodward@google.com</owner>
+    enum="DriveMetadataDBInitStatus" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Result of attempt to open existing drive resource metadata database.
   </summary>
 </histogram>
 
 <histogram name="Drive.MetadataDBValidityCheckFailureReason"
-    enum="DriveMetadataDBValidityCheckFailureReason">
-  <owner>bengold@chromium.org</owner>
-  <owner>hashimoto@chromium.org</owner>
+    enum="DriveMetadataDBValidityCheckFailureReason" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Reason of drive resource metadata database validity check failure. Recorded
     when the validity check fails during Drive metadata initialization triggered
@@ -26480,8 +26483,9 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.MetadataDBVersionBeforeUpgradeCheck">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.MetadataDBVersionBeforeUpgradeCheck" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Version number of drive resource metadata DB found on the disk before
     checking whether it should be upgraded. Recorded during Drive metadata
@@ -26498,8 +26502,10 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.NumberOfCacheFilesRecoveredAfterDBCorruption">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.NumberOfCacheFilesRecoveredAfterDBCorruption"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Number of files recovered from Drive cache directory. Recorded when file
     recovery takes place after metadata DB corruption is found during metadata
@@ -26507,31 +26513,36 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.NumberOfHostedDocuments">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.NumberOfHostedDocuments" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Number of hosted documents (spreadsheets etc.) on Drive. Logged when Drive
     is first accessed.
   </summary>
 </histogram>
 
-<histogram name="Drive.NumberOfRegularFiles">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.NumberOfRegularFiles" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Number of regualr files on Drive. Logged when Drive is first accessed.
   </summary>
 </histogram>
 
-<histogram name="Drive.NumberOfTotalFiles">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.NumberOfTotalFiles" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Number of total files (regualr files + hosted documents) on Drive. Logged
     when Drive is first accessed.
   </summary>
 </histogram>
 
-<histogram name="Drive.PushNotificationInitiallyEnabled" enum="BooleanEnabled">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.PushNotificationInitiallyEnabled" enum="BooleanEnabled"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Tracks whether the push notification is initially enabled for Drive.
     Recorded when the first notification is processed. Notification is emulated
@@ -26539,16 +26550,20 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.PushNotificationRegistered" enum="BooleanRegistered">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.PushNotificationRegistered" enum="BooleanRegistered"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Tracks whether the push notification request is registered correctly for
     Drive. Recorded when the push notification manager is initialized.
   </summary>
 </histogram>
 
-<histogram name="Drive.SearchMetadataTime" units="microseconds">
-  <owner>joshwoodward@google.com</owner>
+<histogram name="Drive.SearchMetadataTime" units="microseconds"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Time spent to perform an incremental search for auto completion of files on
     Drive. This time is collected for every partial query the user types for
@@ -26564,13 +26579,16 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.TotalFileCountInBatchUpload">
-  <owner>hirono@chromium.org</owner>
+<histogram name="Drive.TotalFileCountInBatchUpload" expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>Total file count contained in a drive batch upload request.</summary>
 </histogram>
 
-<histogram name="Drive.TotalFileSizeInBatchUpload" units="KB">
-  <owner>hirono@chromium.org</owner>
+<histogram name="Drive.TotalFileSizeInBatchUpload" units="KB"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>Total file size contained in a drive batch upload request.</summary>
 </histogram>
 
@@ -26587,8 +26605,10 @@
   </summary>
 </histogram>
 
-<histogram name="Drive.UploadProtocol" enum="DriveUploadProtocol">
-  <owner>hirono@chromium.org</owner>
+<histogram name="Drive.UploadProtocol" enum="DriveUploadProtocol"
+    expires_after="M75">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Upload protocol for each file. e.g. Batch upload including 5 files triggers
     the metric 5 times.
@@ -26677,8 +26697,9 @@
 </histogram>
 
 <histogram name="DriveOffline.CrosAutoEnableOutcome"
-    enum="CrosEnableDriveOfflineOutcome">
-  <owner>joshwoodward@google.com</owner>
+    enum="CrosEnableDriveOfflineOutcome" expires_after="M79">
+  <owner>slangley@chromium.org</owner>
+  <owner>weifangsun@chromium.org</owner>
   <summary>
     Outcome of enabling Google Drive offline mode automatically when a user
     first logs into a Chrome OS device. This process involves opening a hidden
@@ -56420,6 +56441,21 @@
   </summary>
 </histogram>
 
+<histogram name="Navigation.NavigationURLLoaderImplIOPostTime"
+    units="microseconds" expires_after="M79">
+  <owner>jam@chromium.org</owner>
+  <owner>kinuko@chromium.org</owner>
+  <summary>
+    The sum of all the times spent posting tasks between the UI and IO threads
+    inside NavigationURLLoaderImpl. Recorded when each frame navigation gets the
+    response.
+
+    Note: This metric drops reports on clients with low-resolution clocks, which
+    means these reports will be biased against a portion of the population on
+    Windows. See Windows.HasHighResolutionTimeTicks for the affected sample.
+  </summary>
+</histogram>
+
 <histogram name="Navigation.OnBeforeUnloadOverheadTime" units="ms">
   <owner>carlosk@chromium.org</owner>
   <summary>
@@ -125381,9 +125417,10 @@
 </histogram>
 
 <histogram name="VR.EnterVrBrowserWithoutFeatureModule" enum="BooleanSuccess"
-    expires_after="M74">
+    expires_after="2020-01-01">
+  <owner>cassew@chromium.org</owner>
   <owner>samdrazin@chromium.org</owner>
-  <owner>tiborg@chromium.org</owner>
+  <owner>xr-dev@chromium.org</owner>
   <summary>
     Recorded every time a user tries to enter the VR browser without the VR
     feature module installed. Is success if the user could enter the VR browser
@@ -131591,6 +131628,10 @@
 </histogram>
 
 <histogram name="WebstoreWidgetApp.Close" enum="SuggestAppsDialogCloseReason">
+  <obsolete>
+    There is no remaining code that is emmiting this metric. It was removed at
+    an unknown time.
+  </obsolete>
   <owner>joshwoodward@google.com</owner>
   <summary>
     Webstore Widget app: the reason why the suggest apps dialog was closed.
@@ -131598,6 +131639,10 @@
 </histogram>
 
 <histogram name="WebstoreWidgetApp.Install" enum="SuggestAppsDialogInstall">
+  <obsolete>
+    There is no remaining code that is emmiting this metric. It was removed at
+    an unknown time.
+  </obsolete>
   <owner>joshwoodward@google.com</owner>
   <summary>
     Webstore Widget app: whether the Webstore item user selected was
@@ -131606,6 +131651,10 @@
 </histogram>
 
 <histogram name="WebstoreWidgetApp.Load" enum="SuggestAppsDialogLoad">
+  <obsolete>
+    There is no remaining code that is emmiting this metric. It was removed at
+    an unknown time.
+  </obsolete>
   <owner>joshwoodward@google.com</owner>
   <summary>
     Webstore Widget app: whether the initialization of the dialog succeeded or
@@ -131614,6 +131663,10 @@
 </histogram>
 
 <histogram name="WebstoreWidgetApp.LoadTime" units="ms">
+  <obsolete>
+    There is no remaining code that is emmiting this metric. It was removed at
+    an unknown time.
+  </obsolete>
   <owner>joshwoodward@google.com</owner>
   <summary>
     Webstore Widget app: time to load the widget contained in the app. Measured
@@ -131905,6 +131958,26 @@
   </summary>
 </histogram>
 
+<histogram name="Windows.ModuleInspector.ReadCacheResult"
+    enum="InspectionResultsCacheReadResult" expires_after="M78">
+  <owner>chrisha@chromium.org</owner>
+  <owner>pmonette@chromium.org</owner>
+  <summary>
+    The result of reading the InspectionResultsCache from disk. The cache is
+    read once at startup when the ModuleInspector needs it.
+  </summary>
+</histogram>
+
+<histogram name="Windows.ModuleInspector.WriteCacheResult"
+    enum="BooleanSuccess" expires_after="M78">
+  <owner>chrisha@chromium.org</owner>
+  <owner>pmonette@chromium.org</owner>
+  <summary>
+    The result of writing the InspectionResultsCache to disk. This is done every
+    time the ModuleDatabase becomes idle.
+  </summary>
+</histogram>
+
 <histogram name="Windows.NativeWindowVisibility" units="windows">
   <owner>fdoray@chromium.org</owner>
   <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 6e87dcb..b7a8ebe 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -136,6 +136,7 @@
  <item id="history_notice_utils_notice" hash_code="102595701" type="1" second_id="110307337" content_hash_code="130829410" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/>
  <item id="history_notice_utils_popup" hash_code="80832574" type="1" second_id="110307337" content_hash_code="30618510" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/>
  <item id="http_server_error_response" hash_code="32197336" type="0" content_hash_code="61082230" os_list="linux,windows" file_path="net/server/http_server.cc"/>
+ <item id="https_server_previews_navigation" hash_code="35725390" type="0" content_hash_code="84423109" os_list="linux,windows" file_path="chrome/browser/previews/previews_lite_page_serving_url_loader.cc"/>
  <item id="icon_cacher" hash_code="103133150" type="0" content_hash_code="116368348" os_list="linux,windows" file_path="components/ntp_tiles/icon_cacher_impl.cc"/>
  <item id="icon_catcher_get_large_icon" hash_code="44494884" type="0" content_hash_code="98262037" os_list="linux,windows" file_path="components/ntp_tiles/icon_cacher_impl.cc"/>
  <item id="image_annotation" hash_code="107881858" type="0" content_hash_code="121106764" os_list="linux,windows" file_path="services/image_annotation/annotator.cc"/>
diff --git a/tools/usb_gadget/OWNERS b/tools/usb_gadget/OWNERS
index a011e5d..e841f9b 100644
--- a/tools/usb_gadget/OWNERS
+++ b/tools/usb_gadget/OWNERS
@@ -1,3 +1,4 @@
-reillyg@chromium.org
+file://chrome/browser/usb/OWNERS
 
-# COMPONENT: IO>USB
\ No newline at end of file
+# COMPONENT: IO>USB
+# TEAM: device-dev@chromium.org
diff --git a/tools/vim/clang-format.vim b/tools/vim/clang-format.vim
index 982b8d2e..09ceb1c 100644
--- a/tools/vim/clang-format.vim
+++ b/tools/vim/clang-format.vim
@@ -9,11 +9,8 @@
 
 let s:script = expand('<sfile>:p:h') .
   \'/../../buildtools/clang_format/script/clang-format.py'
+let s:shortcut = has('mac') ? "<D-I>" : "<C-I>"
+let s:pyf = has("python3") ? ":py3f" : ":pyf"
 
-if has('mac')
-  execute "map <D-I> :pyf " . s:script . "<CR>"
-  execute "imap <D-I> <ESC>:pyf " . s:script . "<CR>i"
-else
-  execute "map <C-I> :pyf " . s:script . "<CR>"
-  execute "imap <C-I> <ESC>:pyf " . s:script . "<CR>i"
-endif
+execute "map" s:shortcut s:pyf s:script . "<CR>"
+execute "imap" s:shortcut s:pyf s:script . "<CR>i"
diff --git a/ui/aura/mus/client_surface_embedder.cc b/ui/aura/mus/client_surface_embedder.cc
index 8af4974..9d77ab80 100644
--- a/ui/aura/mus/client_surface_embedder.cc
+++ b/ui/aura/mus/client_surface_embedder.cc
@@ -11,15 +11,10 @@
 
 namespace aura {
 
-ClientSurfaceEmbedder::ClientSurfaceEmbedder(
-    Window* window,
-    bool inject_gutter,
-    const gfx::Insets& client_area_insets)
+ClientSurfaceEmbedder::ClientSurfaceEmbedder(Window* window)
     : window_(window),
       surface_layer_owner_(std::make_unique<ui::LayerOwner>(
-          std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR))),
-      inject_gutter_(inject_gutter),
-      client_area_insets_(client_area_insets) {
+          std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR))) {
   surface_layer_owner_->layer()->set_name("ClientSurfaceEmbedder");
   surface_layer_owner_->layer()->SetMasksToBounds(true);
   // The frame provided by the parent window->layer() needs to show through
@@ -39,91 +34,18 @@
 void ClientSurfaceEmbedder::SetSurfaceId(const viz::SurfaceId& surface_id) {
   // Set the background to transparent to avoid a flash of color before the
   // client surface is rendered. See https://crbug.com/930199
+  const gfx::Size size = window_->bounds().size();
+  surface_layer_owner_->layer()->SetBounds(gfx::Rect(size));
   surface_layer_owner_->layer()->SetShowSurface(
-      surface_id, window_->bounds().size(), SK_ColorTRANSPARENT,
+      surface_id, size, SK_ColorTRANSPARENT,
       cc::DeadlinePolicy::UseDefaultDeadline(),
       false /* stretch_content_to_fill_bounds */);
-}
-
-bool ClientSurfaceEmbedder::HasPrimarySurfaceId() const {
-  return surface_layer_owner_->layer()->GetSurfaceId() != nullptr;
-}
-
-void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
-    const viz::SurfaceInfo& surface_info) {
-  fallback_surface_info_ = surface_info;
-  UpdateSizeAndGutters();
-}
-
-void ClientSurfaceEmbedder::SetClientAreaInsets(
-    const gfx::Insets& client_area_insets) {
-  if (client_area_insets_ == client_area_insets)
-    return;
-
-  client_area_insets_ = client_area_insets;
-  if (inject_gutter_)
-    UpdateSizeAndGutters();
-}
-
-void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
-  surface_layer_owner_->layer()->SetBounds(gfx::Rect(window_->bounds().size()));
-  if (!inject_gutter_)
-    return;
-
-  gfx::Size fallback_surface_size_in_dip;
-  if (fallback_surface_info_.is_valid()) {
-    float fallback_device_scale_factor =
-        fallback_surface_info_.device_scale_factor();
-    fallback_surface_size_in_dip = gfx::ConvertSizeToDIP(
-        fallback_device_scale_factor, fallback_surface_info_.size_in_pixels());
-  }
-  gfx::Rect window_bounds(window_->bounds());
-  if (!window_->transparent() &&
-      fallback_surface_size_in_dip.width() < window_bounds.width()) {
-    right_gutter_owner_ = std::make_unique<ui::LayerOwner>(
-        std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR));
-    // TODO(fsamuel): Use the embedded client's background color.
-    right_gutter_owner_->layer()->SetColor(SK_ColorWHITE);
-    int width = window_bounds.width() - fallback_surface_size_in_dip.width();
-    // The right gutter also includes the bottom-right corner, if necessary.
-    int height = window_bounds.height() - client_area_insets_.height();
-    right_gutter_owner_->layer()->SetBounds(gfx::Rect(
-        client_area_insets_.left() + fallback_surface_size_in_dip.width(),
-        client_area_insets_.top(), width, height));
-    window_->layer()->Add(right_gutter_owner_->layer());
-  } else {
-    right_gutter_owner_.reset();
-  }
-
-  // Only create a bottom gutter if a fallback surface is available. Otherwise,
-  // the right gutter will fill the whole window until a fallback is available.
-  if (!window_->transparent() && !fallback_surface_size_in_dip.IsEmpty() &&
-      fallback_surface_size_in_dip.height() < window_bounds.height()) {
-    bottom_gutter_owner_ = std::make_unique<ui::LayerOwner>(
-        std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR));
-    // TODO(fsamuel): Use the embedded client's background color.
-    bottom_gutter_owner_->layer()->SetColor(SK_ColorWHITE);
-    int width = fallback_surface_size_in_dip.width();
-    int height = window_bounds.height() - fallback_surface_size_in_dip.height();
-    bottom_gutter_owner_->layer()->SetBounds(
-        gfx::Rect(0, fallback_surface_size_in_dip.height(), width, height));
-    window_->layer()->Add(bottom_gutter_owner_->layer());
-  } else {
-    bottom_gutter_owner_.reset();
-  }
   window_->layer()->StackAtTop(surface_layer_owner_->layer());
 }
 
-ui::Layer* ClientSurfaceEmbedder::RightGutterForTesting() {
-  return right_gutter_owner_ ? right_gutter_owner_->layer() : nullptr;
-}
-
-ui::Layer* ClientSurfaceEmbedder::BottomGutterForTesting() {
-  return bottom_gutter_owner_ ? bottom_gutter_owner_->layer() : nullptr;
-}
-
-const viz::SurfaceId& ClientSurfaceEmbedder::GetSurfaceIdForTesting() const {
-  return *surface_layer_owner_->layer()->GetSurfaceId();
+viz::SurfaceId ClientSurfaceEmbedder::GetSurfaceId() const {
+  const viz::SurfaceId* id = surface_layer_owner_->layer()->GetSurfaceId();
+  return id ? *id : viz::SurfaceId();
 }
 
 }  // namespace aura
diff --git a/ui/aura/mus/client_surface_embedder.h b/ui/aura/mus/client_surface_embedder.h
index c1940e9..e3a809d5 100644
--- a/ui/aura/mus/client_surface_embedder.h
+++ b/ui/aura/mus/client_surface_embedder.h
@@ -8,53 +8,33 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "components/viz/common/surfaces/surface_info.h"
 #include "ui/aura/aura_export.h"
-#include "ui/gfx/geometry/insets.h"
 
 namespace ui {
-class Layer;
 class LayerOwner;
 }
 
+namespace viz {
+class SurfaceId;
+}
+
 namespace aura {
 
 class Window;
 
-// Used by WindowPortMus when it is embedding a client. Responsible for setting
-// up layers containing content from the client, parenting them to the window's
-// layer, and updating them when the client submits new surfaces.
+// Used to display content from another client. The other client is rendering
+// to viz using the SurfaceId supplied to SetSurfaceId().
 class AURA_EXPORT ClientSurfaceEmbedder {
  public:
-  // TODO(fsamuel): Insets might differ when the window is maximized. We should
-  // deal with that case as well.
-  ClientSurfaceEmbedder(Window* window,
-                        bool inject_gutter,
-                        const gfx::Insets& client_area_insets);
+  explicit ClientSurfaceEmbedder(Window* window);
   ~ClientSurfaceEmbedder();
 
-  // Updates the clip layer and primary SurfaceId of the surface layer based
-  // on the provided |surface_id|.
+  // Sets the current SurfaceId *and* updates the size of the layer to match
+  // that of the window.
   void SetSurfaceId(const viz::SurfaceId& surface_id);
 
-  bool HasPrimarySurfaceId() const;
-
-  // Sets the fallback SurfaceInfo of the surface layer. The clip layer is not
-  // updated.
-  void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info);
-
-  void SetClientAreaInsets(const gfx::Insets& client_area_insets);
-  const gfx::Insets& client_area_insets() const { return client_area_insets_; }
-
-  // Update the surface layer size and the right and bottom gutter layers for
-  // the current window size.
-  void UpdateSizeAndGutters();
-
-  ui::Layer* RightGutterForTesting();
-
-  ui::Layer* BottomGutterForTesting();
-
-  const viz::SurfaceId& GetSurfaceIdForTesting() const;
+  // Returns the SurfaceId, empty if SetSurfaceId() has not been called yet.
+  viz::SurfaceId GetSurfaceId() const;
 
  private:
   // The window which embeds the client.
@@ -64,16 +44,6 @@
   // LayerOwner so that animations clone the layer.
   std::unique_ptr<ui::LayerOwner> surface_layer_owner_;
 
-  // Information describing the currently set fallback surface.
-  viz::SurfaceInfo fallback_surface_info_;
-
-  // Used for showing a gutter when the content is not available.
-  std::unique_ptr<ui::LayerOwner> right_gutter_owner_;
-  std::unique_ptr<ui::LayerOwner> bottom_gutter_owner_;
-
-  bool inject_gutter_;
-  gfx::Insets client_area_insets_;
-
   DISALLOW_COPY_AND_ASSIGN(ClientSurfaceEmbedder);
 };
 
diff --git a/ui/aura/mus/mus_lsi_allocator.cc b/ui/aura/mus/mus_lsi_allocator.cc
index 7c221ad..b224ee99 100644
--- a/ui/aura/mus/mus_lsi_allocator.cc
+++ b/ui/aura/mus/mus_lsi_allocator.cc
@@ -46,8 +46,8 @@
                                  bool is_embedder)
     : MusLsiAllocator(window_port_mus, window_tree_client) {
   if (is_embedder) {
-    client_surface_embedder_ = std::make_unique<ClientSurfaceEmbedder>(
-        GetWindow(), /* inject_gutter */ false, gfx::Insets());
+    client_surface_embedder_ =
+        std::make_unique<ClientSurfaceEmbedder>(GetWindow());
   }
 }
 
@@ -129,7 +129,6 @@
     viz::SurfaceId surface_id(GetWindow()->GetFrameSinkId(),
                               GetLocalSurfaceIdAllocation().local_surface_id());
     client_surface_embedder_->SetSurfaceId(surface_id);
-    client_surface_embedder_->UpdateSizeAndGutters();
   }
 }
 
diff --git a/ui/aura/mus/window_port_mus_unittest.cc b/ui/aura/mus/window_port_mus_unittest.cc
index 649a715d..24b601d 100644
--- a/ui/aura/mus/window_port_mus_unittest.cc
+++ b/ui/aura/mus/window_port_mus_unittest.cc
@@ -102,8 +102,7 @@
   ClientSurfaceEmbedder* client_surface_embedder =
       WindowPortMusTestHelper(&window).GetClientSurfaceEmbedder();
   ASSERT_TRUE(client_surface_embedder);
-  viz::SurfaceId primary_surface_id =
-      client_surface_embedder->GetSurfaceIdForTesting();
+  viz::SurfaceId primary_surface_id = client_surface_embedder->GetSurfaceId();
   EXPECT_EQ(local_surface_id, primary_surface_id.local_surface_id());
 }
 
@@ -139,9 +138,8 @@
   ClientSurfaceEmbedder* client_surface_embedder =
       WindowPortMusTestHelper(&window).GetClientSurfaceEmbedder();
   ASSERT_TRUE(client_surface_embedder);
-  EXPECT_EQ(
-      updated_id,
-      client_surface_embedder->GetSurfaceIdForTesting().local_surface_id());
+  EXPECT_EQ(updated_id,
+            client_surface_embedder->GetSurfaceId().local_surface_id());
 
   // The server is notified of a bounds change, so that it sees the new
   // LocalSurfaceId.
@@ -218,7 +216,7 @@
   ClientSurfaceEmbedder* client_surface_embedder =
       WindowPortMusTestHelper(&window).GetClientSurfaceEmbedder();
   ASSERT_TRUE(client_surface_embedder);
-  EXPECT_TRUE(client_surface_embedder->HasPrimarySurfaceId());
+  EXPECT_TRUE(client_surface_embedder->GetSurfaceId().is_valid());
 }
 
 class TestDragDropDelegate : public client::DragDropDelegate {
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc
index 45d4df6..578ba14 100644
--- a/ui/aura/mus/window_tree_client_unittest.cc
+++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -347,10 +347,7 @@
 
   // Once the bounds have been set, the ClientSurfaceEmbedder should be created.
   client_surface_embedder = window_test_helper.GetClientSurfaceEmbedder();
-  ASSERT_NE(nullptr, client_surface_embedder);
-
-  EXPECT_EQ(nullptr, client_surface_embedder->BottomGutterForTesting());
-  EXPECT_EQ(nullptr, client_surface_embedder->RightGutterForTesting());
+  EXPECT_TRUE(client_surface_embedder);
 }
 
 // Verifies that the viz::LocalSurfaceId generated by an embedder changes when
diff --git a/ui/base/test/scoped_fake_nswindow_fullscreen.mm b/ui/base/test/scoped_fake_nswindow_fullscreen.mm
index 977c011..5ffd6e0 100644
--- a/ui/base/test/scoped_fake_nswindow_fullscreen.mm
+++ b/ui/base/test/scoped_fake_nswindow_fullscreen.mm
@@ -108,8 +108,9 @@
                       object:window];
     DCHECK(base::MessageLoopCurrentForUI::IsSet());
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&Impl::FinishEnterFullscreen,
-                              base::Unretained(this), fullscreen_content_size));
+        FROM_HERE,
+        base::BindOnce(&Impl::FinishEnterFullscreen, base::Unretained(this),
+                       fullscreen_content_size));
   }
 
   void FinishEnterFullscreen(NSSize fullscreen_content_size) {
@@ -148,7 +149,7 @@
     DCHECK(base::MessageLoopCurrentForUI::IsSet());
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
-        base::Bind(&Impl::FinishExitFullscreen, base::Unretained(this)));
+        base::BindOnce(&Impl::FinishExitFullscreen, base::Unretained(this)));
   }
 
   void FinishExitFullscreen() {
diff --git a/ui/base/x/selection_requestor_unittest.cc b/ui/base/x/selection_requestor_unittest.cc
index 9736f039..74b55ed 100644
--- a/ui/base/x/selection_requestor_unittest.cc
+++ b/ui/base/x/selection_requestor_unittest.cc
@@ -126,17 +126,17 @@
   XAtom target2 = gfx::GetAtom("TARGET2");
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&PerformBlockingConvertSelection,
-                            base::Unretained(requestor_.get()), selection,
-                            target2, "Data2"));
+      FROM_HERE, base::BindOnce(&PerformBlockingConvertSelection,
+                                base::Unretained(requestor_.get()), selection,
+                                target2, "Data2"));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&SelectionRequestorTest::SendSelectionNotify,
-                 base::Unretained(this), selection, target1, "Data1"));
+      base::BindOnce(&SelectionRequestorTest::SendSelectionNotify,
+                     base::Unretained(this), selection, target1, "Data1"));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&SelectionRequestorTest::SendSelectionNotify,
-                 base::Unretained(this), selection, target2, "Data2"));
+      base::BindOnce(&SelectionRequestorTest::SendSelectionNotify,
+                     base::Unretained(this), selection, target2, "Data2"));
   PerformBlockingConvertSelection(requestor_.get(), selection, target1,
                                   "Data1");
 }
diff --git a/ui/ozone/demo/gl_renderer.cc b/ui/ozone/demo/gl_renderer.cc
index 2003489..61d6a07 100644
--- a/ui/ozone/demo/gl_renderer.cc
+++ b/ui/ozone/demo/gl_renderer.cc
@@ -74,7 +74,7 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&GlRenderer::RenderFrame, weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&GlRenderer::RenderFrame, weak_ptr_factory_.GetWeakPtr()));
 }
 
 void GlRenderer::OnPresentation(const gfx::PresentationFeedback& feedback) {
diff --git a/ui/ozone/demo/surfaceless_gl_renderer.cc b/ui/ozone/demo/surfaceless_gl_renderer.cc
index fa0ce69..1da2211 100644
--- a/ui/ozone/demo/surfaceless_gl_renderer.cc
+++ b/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -282,8 +282,8 @@
       FALLTHROUGH;  // We want to render a new frame anyways.
     case gfx::SwapResult::SWAP_ACK:
       base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::Bind(&SurfacelessGlRenderer::RenderFrame,
-                                weak_ptr_factory_.GetWeakPtr()));
+          FROM_HERE, base::BindOnce(&SurfacelessGlRenderer::RenderFrame,
+                                    weak_ptr_factory_.GetWeakPtr()));
       break;
     case gfx::SwapResult::SWAP_FAILED:
       LOG(FATAL) << "Failed to swap buffers";
diff --git a/ui/views/cocoa/drag_drop_client_mac_unittest.mm b/ui/views/cocoa/drag_drop_client_mac_unittest.mm
index 7e47378..06b5d562 100644
--- a/ui/views/cocoa/drag_drop_client_mac_unittest.mm
+++ b/ui/views/cocoa/drag_drop_client_mac_unittest.mm
@@ -260,8 +260,8 @@
 
   // Immediately quit drag'n'drop, or we'll hang.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&DragDropClientMac::EndDrag,
-                            base::Unretained(drag_drop_client())));
+      FROM_HERE, base::BindOnce(&DragDropClientMac::EndDrag,
+                                base::Unretained(drag_drop_client())));
 
   // It will call ReleaseCapture().
   drag_drop_client()->StartDragAndDrop(
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
index 781d8512..e961f2f2 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
@@ -515,14 +515,14 @@
   XID toplevel = 1;
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&BasicStep2, client(), toplevel));
+      FROM_HERE, base::BindOnce(&BasicStep2, client(), toplevel));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 
   // Do another drag and drop to test that the data is properly cleaned up as a
   // result of the XdndFinished message.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&BasicStep3, client(), toplevel));
+      FROM_HERE, base::BindOnce(&BasicStep3, client(), toplevel));
   result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 }
@@ -554,7 +554,7 @@
   screen->SetDeviceScaleFactor(2.0f);
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&HighDPIStep, client()));
+      FROM_HERE, base::BindOnce(&HighDPIStep, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
 }
@@ -565,7 +565,7 @@
   screen->SetDeviceScaleFactor(1.5f);
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&HighDPIStep, client()));
+      FROM_HERE, base::BindOnce(&HighDPIStep, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
 }
@@ -599,7 +599,7 @@
 // respond to XdndPosition messages at all.
 TEST_F(DesktopDragDropClientAuraX11Test, TargetDoesNotRespond) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&TargetDoesNotRespondStep2, client()));
+      FROM_HERE, base::BindOnce(&TargetDoesNotRespondStep2, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
 }
@@ -644,7 +644,7 @@
 // message is acked via an XdndStatus message.
 TEST_F(DesktopDragDropClientAuraX11Test, QueuePosition) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&QueuePositionStep2, client()));
+      FROM_HERE, base::BindOnce(&QueuePositionStep2, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 }
@@ -696,7 +696,7 @@
 // Test the behavior when the target changes during a drag.
 TEST_F(DesktopDragDropClientAuraX11Test, TargetChanges) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&TargetChangesStep2, client()));
+      FROM_HERE, base::BindOnce(&TargetChangesStep2, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 }
@@ -765,13 +765,13 @@
 // operation is rejected after the mouse is released.
 TEST_F(DesktopDragDropClientAuraX11Test, RejectAfterMouseRelease) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&RejectAfterMouseReleaseStep2, client()));
+      FROM_HERE, base::BindOnce(&RejectAfterMouseReleaseStep2, client()));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
 
   // Repeat the test but reject the drop in the XdndFinished message instead.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&RejectAfterMouseReleaseStep3, client()));
+      FROM_HERE, base::BindOnce(&RejectAfterMouseReleaseStep3, client()));
   result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE, result);
 }
@@ -970,7 +970,8 @@
 
 TEST_F(DesktopDragDropClientAuraX11ChromeSourceTargetTest, Basic) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&ChromeSourceTargetStep2, client(), ui::EF_NONE));
+      FROM_HERE,
+      base::BindOnce(&ChromeSourceTargetStep2, client(), ui::EF_NONE));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 }
@@ -980,7 +981,7 @@
 TEST_F(DesktopDragDropClientAuraX11ChromeSourceTargetTest, CtrlPressed) {
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::Bind(&ChromeSourceTargetStep2, client(), ui::EF_CONTROL_DOWN));
+      base::BindOnce(&ChromeSourceTargetStep2, client(), ui::EF_CONTROL_DOWN));
   int result = StartDragAndDrop();
   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, result);
 }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 42c4658..b898d97 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -461,8 +461,8 @@
     // may delete ourselves on destroy and the ATL callback would still
     // dereference us when the callback returns).
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::CloseNow,
-                              close_widget_factory_.GetWeakPtr()));
+        FROM_HERE, base::BindOnce(&DesktopWindowTreeHostX11::CloseNow,
+                                  close_widget_factory_.GetWeakPtr()));
   }
 }
 
@@ -998,9 +998,9 @@
   // NonClientView::UpdateFrame() to update the frame-view when theme changes,
   // like all other views).
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::DelayedChangeFrameType,
-                            weak_factory_.GetWeakPtr(),
-                            new_type));
+      FROM_HERE,
+      base::BindOnce(&DesktopWindowTreeHostX11::DelayedChangeFrameType,
+                     weak_factory_.GetWeakPtr(), new_type));
 }
 
 void DesktopWindowTreeHostX11::SetFullscreen(bool fullscreen) {
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index 038f3ca..593f24d 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -95,8 +95,8 @@
         // dispatched without waiting for the drag widget updates.
         base::ThreadTaskRunnerHandle::Get()->PostTask(
             FROM_HERE,
-            base::Bind(&X11WholeScreenMoveLoop::DispatchMouseMovement,
-                       weak_factory_.GetWeakPtr()));
+            base::BindOnce(&X11WholeScreenMoveLoop::DispatchMouseMovement,
+                           weak_factory_.GetWeakPtr()));
       }
       return ui::POST_DISPATCH_NONE;
     }