diff --git a/BUILD.gn b/BUILD.gn
index 4ea9af3..df5bfea 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -290,6 +290,7 @@
       "//chrome/test/vr/perf:motopho_latency_test",
       "//components/invalidation/impl:components_invalidation_impl_junit_tests",
       "//components/policy/android:components_policy_junit_tests",
+      "//components/signin/core/browser/android:components_signin_junit_tests",
       "//content/public/android:content_junit_tests",
       "//content/shell/android:content_shell_apk",
       "//device:device_junit_tests",
diff --git a/DEPS b/DEPS
index f0438af..458b731 100644
--- a/DEPS
+++ b/DEPS
@@ -78,11 +78,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': 'e8bb6da08dc61832062e7a0e86b9ebd44953301c',
+  'skia_revision': 'aebad197dcaf2f02d5c71e9cf9b3f383a36df538',
   # 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': 'a9293af898f384cabaac1a802e5e7e00a1667313',
+  'v8_revision': '73cec2c89096b4cf728b99f41bcc1d846d2e1496',
   # 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.
@@ -90,7 +90,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '8c3988c59ebe97f03c376d30aa94fb6062f4ae48',
+  'angle_revision': 'd8724a947bd8663a796a3dc70057a17fc91ae516',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -134,7 +134,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': 'bd319d25b88622db10d3e63ac613cf23ee83539e',
+  'catapult_revision': '7365f02611830723d60963f0619d5bab45060849',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -329,11 +329,8 @@
   'src/third_party/depot_tools':
     Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ebe839b6bfc3e9276b8d1e42a0d6e830bb04899e',
 
-  # DevTools node modules. Used on Linux buildbots only.
-  'src/third_party/devtools-node-modules': {
-      'url': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
-      'condition': 'checkout_linux',
-  },
+  'src/third_party/devtools-node-modules':
+    Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
 
   'src/third_party/dom_distiller_js/dist':
     Var('chromium_git') + '/chromium/dom-distiller/dist.git' + '@' + '60b46718e28f553ab57e3d2bbda5b3b41456f417',
@@ -643,7 +640,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '94dc17710fd73ccb9717c8947c77c2e0defd3cb1', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + '731082ce7ea6e86a0d0d738460d7366f7df7c0c5', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index e0b3f60a..3f89e94 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -1180,8 +1180,8 @@
     return;
   gfx::Size contents_size_css =
       content::UseZoomForDSFEnabled()
-          ? ScaleToCeiledSize(contents_size,
-                              1 / browser_view_renderer_.dip_scale())
+          ? ScaleToRoundedSize(contents_size,
+                               1 / browser_view_renderer_.dip_scale())
           : contents_size;
   Java_AwContents_onWebLayoutContentsSizeChanged(
       env, obj, contents_size_css.width(), contents_size_css.height());
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index f3089dcb..d1fa22b3 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -288,7 +288,7 @@
     base::RecordAction(UserMetricsAction("Accel_Move_Window_To_Right_Display"));
     direction = DisplayMoveWindowDirection::kRight;
   }
-  HandleMoveWindowToDisplay(direction);
+  HandleMoveActiveWindowToDisplay(direction);
 }
 
 void HandleToggleMirrorMode() {
diff --git a/ash/app_list/model/BUILD.gn b/ash/app_list/model/BUILD.gn
index 1deaded..7701cb6 100644
--- a/ash/app_list/model/BUILD.gn
+++ b/ash/app_list/model/BUILD.gn
@@ -61,3 +61,18 @@
     "//ui/gfx",
   ]
 }
+
+component("speech_ui_model") {
+  sources = [
+    "speech/speech_ui_model.cc",
+    "speech/speech_ui_model.h",
+    "speech/speech_ui_model_observer.h",
+  ]
+
+  defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ]
+
+  deps = [
+    "//base",
+    "//ui/gfx",
+  ]
+}
diff --git a/ui/app_list/speech_ui_model.cc b/ash/app_list/model/speech/speech_ui_model.cc
similarity index 96%
rename from ui/app_list/speech_ui_model.cc
rename to ash/app_list/model/speech/speech_ui_model.cc
index f85109e..05f44eb7 100644
--- a/ui/app_list/speech_ui_model.cc
+++ b/ash/app_list/model/speech/speech_ui_model.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/app_list/speech_ui_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 
 #include <stdint.h>
 
@@ -23,8 +23,7 @@
       sound_level_(0),
       state_(app_list::SPEECH_RECOGNITION_OFF),
       minimum_sound_level_(kDefaultSoundLevel),
-      maximum_sound_level_(kDefaultSoundLevel) {
-}
+      maximum_sound_level_(kDefaultSoundLevel) {}
 
 SpeechUIModel::~SpeechUIModel() {}
 
diff --git a/ui/app_list/speech_ui_model.h b/ash/app_list/model/speech/speech_ui_model.h
similarity index 84%
rename from ui/app_list/speech_ui_model.h
rename to ash/app_list/model/speech/speech_ui_model.h
index 0e7f620..71b14ab8 100644
--- a/ui/app_list/speech_ui_model.h
+++ b/ash/app_list/model/speech/speech_ui_model.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_APP_LIST_SPEECH_UI_MODEL_H_
-#define UI_APP_LIST_SPEECH_UI_MODEL_H_
+#ifndef ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_H_
+#define ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_H_
 
 #include <stdint.h>
 
+#include "ash/app_list/model/app_list_model_export.h"
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
-#include "ui/app_list/app_list_export.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 #include "ui/gfx/image/image_skia.h"
 
 namespace app_list {
 
 // SpeechUIModel provides the interface to update the UI for speech recognition.
-class APP_LIST_EXPORT SpeechUIModel {
+class APP_LIST_MODEL_EXPORT SpeechUIModel {
  public:
   // Construct the model, initially in state SPEECH_RECOGNITION_OFF.
   SpeechUIModel();
@@ -61,4 +61,4 @@
 
 }  // namespace app_list
 
-#endif  // UI_APP_LIST_SPEECH_UI_MODEL_H_
+#endif  // ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_H_
diff --git a/ui/app_list/speech_ui_model_observer.h b/ash/app_list/model/speech/speech_ui_model_observer.h
similarity index 78%
rename from ui/app_list/speech_ui_model_observer.h
rename to ash/app_list/model/speech/speech_ui_model_observer.h
index e4e2e7c..1ec96b5 100644
--- a/ui/app_list/speech_ui_model_observer.h
+++ b/ash/app_list/model/speech/speech_ui_model_observer.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_APP_LIST_SPEECH_UI_MODEL_OBSERVER_H_
-#define UI_APP_LIST_SPEECH_UI_MODEL_OBSERVER_H_
+#ifndef ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_OBSERVER_H_
+#define ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_OBSERVER_H_
 
 #include <stdint.h>
 
+#include "ash/app_list/model/app_list_model_export.h"
 #include "base/strings/string16.h"
-#include "ui/app_list/app_list_export.h"
 
 namespace app_list {
 
@@ -21,7 +21,7 @@
   SPEECH_RECOGNITION_NETWORK_ERROR,
 };
 
-class APP_LIST_EXPORT SpeechUIModelObserver {
+class APP_LIST_MODEL_EXPORT SpeechUIModelObserver {
  public:
   // Invoked when sound level for the speech recognition has changed. |level|
   // represents the current sound-level in the range of [0, 255].
@@ -41,4 +41,4 @@
 
 }  // namespace app_list
 
-#endif  // UI_APP_LIST_SPEECH_UI_MODEL_OBSERVER_H_
+#endif  // ASH_APP_LIST_MODEL_SPEECH_SPEECH_UI_MODEL_OBSERVER_H_
diff --git a/ash/default_wallpaper_delegate.cc b/ash/default_wallpaper_delegate.cc
index 231a053..5982dbf 100644
--- a/ash/default_wallpaper_delegate.cc
+++ b/ash/default_wallpaper_delegate.cc
@@ -25,8 +25,6 @@
   return false;
 }
 
-void DefaultWallpaperDelegate::UpdateWallpaper(bool clear_cache) {}
-
 void DefaultWallpaperDelegate::InitializeWallpaper() {
   Shell::Get()->wallpaper_controller()->CreateEmptyWallpaper();
 }
diff --git a/ash/default_wallpaper_delegate.h b/ash/default_wallpaper_delegate.h
index 12a9223..b25bbd1 100644
--- a/ash/default_wallpaper_delegate.h
+++ b/ash/default_wallpaper_delegate.h
@@ -21,7 +21,6 @@
   int GetAnimationDurationOverride() override;
   void SetAnimationDurationOverride(int animation_duration_in_ms) override;
   bool ShouldShowInitialAnimation() override;
-  void UpdateWallpaper(bool clear_cache) override;
   void InitializeWallpaper() override;
   bool CanOpenSetWallpaperPage() override;
   void OnWallpaperAnimationFinished() override;
diff --git a/ash/display/display_move_window_util.cc b/ash/display/display_move_window_util.cc
index 98fc0f57..5440da6 100644
--- a/ash/display/display_move_window_util.cc
+++ b/ash/display/display_move_window_util.cc
@@ -137,7 +137,7 @@
 
 }  // namespace
 
-void HandleMoveWindowToDisplay(DisplayMoveWindowDirection direction) {
+void HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection direction) {
   aura::Window* window = wm::GetActiveWindow();
   if (!window)
     return;
diff --git a/ash/display/display_move_window_util.h b/ash/display/display_move_window_util.h
index 4aa695be..09b944f 100644
--- a/ash/display/display_move_window_util.h
+++ b/ash/display/display_move_window_util.h
@@ -13,7 +13,8 @@
 
 // Handles moving current active window from its display to another display
 // specified by |Direction|.
-ASH_EXPORT void HandleMoveWindowToDisplay(DisplayMoveWindowDirection direction);
+ASH_EXPORT void HandleMoveActiveWindowToDisplay(
+    DisplayMoveWindowDirection direction);
 
 }  // namespace ash
 
diff --git a/ash/display/display_move_window_util_unittest.cc b/ash/display/display_move_window_util_unittest.cc
index f1730aa..09e1773 100644
--- a/ash/display/display_move_window_util_unittest.cc
+++ b/ash/display/display_move_window_util_unittest.cc
@@ -22,6 +22,7 @@
 #include "ui/display/manager/display_manager.h"
 #include "ui/display/screen.h"
 #include "ui/display/test/display_manager_test_api.h"
+#include "ui/wm/core/window_util.h"
 
 namespace ash {
 
@@ -47,7 +48,7 @@
   aura::Window* window =
       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
   wm::ActivateWindow(window);
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window->GetBoundsInScreen());
 }
 
@@ -68,7 +69,7 @@
   EXPECT_TRUE(window_state->IsMaximized());
   EXPECT_EQ(ScreenUtil::GetMaximizedWindowBoundsInParent(window),
             window->bounds());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window).id());
   // Check that window state is maximized and has updated maximized bounds.
@@ -77,7 +78,7 @@
             window->bounds());
 
   // Set window to fullscreen state.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   const wm::WMEvent fullscreen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
   window_state->OnWMEvent(&fullscreen);
   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
@@ -85,7 +86,7 @@
   EXPECT_TRUE(window_state->IsFullscreen());
   EXPECT_EQ(display_manager()->GetDisplayAt(0).bounds(),
             window->GetBoundsInScreen());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window).id());
   // Check that window state is fullscreen and has updated fullscreen bounds.
@@ -94,7 +95,7 @@
             window->GetBoundsInScreen());
 
   // Set window to left snapped state.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   const wm::WMEvent snap_left(wm::WM_EVENT_SNAP_LEFT);
   window_state->OnWMEvent(&snap_left);
   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
@@ -104,7 +105,7 @@
                 screen->GetDisplayNearestWindow(window)),
             window->GetBoundsInScreen());
   EXPECT_EQ(0.5f, window_state->snapped_width_ratio());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window).id());
   // Check that window state is snapped and has updated snapped bounds.
@@ -144,21 +145,21 @@
   wm::ActivateWindow(window);
   ASSERT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(list[2], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
 
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(list[2], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 
   // No-op for above/below movement since no display is in the above/below of
   // primary display.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 }
 
@@ -194,20 +195,20 @@
   wm::ActivateWindow(window);
   ASSERT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kAbove);
   EXPECT_EQ(list[2], screen->GetDisplayNearestWindow(window).id());
 
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kBelow);
   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 
   // Left/Right is able to be applied between display [p] and [1].
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window).id());
 }
 
@@ -263,20 +264,20 @@
   // Moving window to left display, we have [4] and [5] candidate displays in
   // the left direction. They have the same left space but [4] is selected since
   // it is vertically closer to display [p].
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(list[4], screen->GetDisplayNearestWindow(window).id());
 
   // Moving window to left display, we don't have candidate displays in the left
   // direction. [1][2][3][p] are candidate displays in the cycled direction.
   // [1][2] have the same left space but [1] is selected since it is vertically
   // closer to display [4].
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(list[1], screen->GetDisplayNearestWindow(window).id());
 
   // Moving window to right display, we don't have candidate displays in the
   // right direction. [p][3][4][5] are candidate displays in the cycled
   // direction. [5] has the furthest right space so it is selected.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(list[5], screen->GetDisplayNearestWindow(window).id());
 }
 
@@ -292,7 +293,7 @@
   aura::Window* window =
       CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
   wm::ActivateWindow(window);
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   controller->FlushMojoForTest();
   EXPECT_EQ(mojom::AccessibilityAlert::WINDOW_MOVED_TO_RIGHT_DISPLAY,
             client.last_a11y_alert());
@@ -316,7 +317,7 @@
   MruWindowTracker::WindowList cycle_window_list =
       Shell::Get()->mru_window_tracker()->BuildWindowForCycleList();
   EXPECT_TRUE(cycle_window_list.empty());
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
             screen->GetDisplayNearestWindow(window.get()).id());
 }
@@ -342,23 +343,23 @@
             screen->GetDisplayNearestWindow(window).id());
   // Move window to display [p]. Its window bounds is adjusted by available work
   // area.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
             screen->GetDisplayNearestWindow(window).id());
   EXPECT_EQ(gfx::Rect(10, 20, 200, 252), window->GetBoundsInScreen());
   // Move window back to display [1]. Its window bounds should be restored.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window).id());
   EXPECT_EQ(gfx::Rect(410, 20, 200, 400), window->GetBoundsInScreen());
 
   // Move window to display [p] and set that its bounds is changed by user.
   wm::WindowState* window_state = wm::GetWindowState(window);
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kLeft);
   window_state->set_bounds_changed_by_user(true);
   // Move window back to display [1], but its bounds has been changed by user.
   // Then window bounds should be kept the same as that in display [p].
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window).id());
   EXPECT_EQ(gfx::Rect(410, 20, 200, 252), window->GetBoundsInScreen());
@@ -400,7 +401,7 @@
             *window2_state->pre_auto_manage_window_bounds());
 
   // Move window2 to display [1] and check auto window management.
-  HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
   EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
             screen->GetDisplayNearestWindow(window2).id());
   // Check |pre_added_to_workspace_window_bounds()|, which should be equal to
@@ -413,4 +414,30 @@
   EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window2->GetBoundsInScreen());
 }
 
+TEST_F(DisplayMoveWindowUtilTest, WindowWithTransientChild) {
+  UpdateDisplay("400x300,400x300");
+  aura::Window* window =
+      CreateTestWindowInShellWithBounds(gfx::Rect(10, 20, 200, 100));
+  wm::ActivateWindow(window);
+
+  // Create a |child| window and make it a transient child of |window|.
+  std::unique_ptr<aura::Window> child =
+      CreateChildWindow(window, gfx::Rect(20, 30, 40, 50));
+  ::wm::AddTransientChild(window, child.get());
+  display::Screen* screen = display::Screen::GetScreen();
+  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
+            screen->GetDisplayNearestWindow(window).id());
+  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(),
+            screen->GetDisplayNearestWindow(child.get()).id());
+
+  // Operate moving window to right display. Check display and bounds.
+  HandleMoveActiveWindowToDisplay(DisplayMoveWindowDirection::kRight);
+  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
+            screen->GetDisplayNearestWindow(window).id());
+  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(),
+            screen->GetDisplayNearestWindow(child.get()).id());
+  EXPECT_EQ(gfx::Rect(410, 20, 200, 100), window->GetBoundsInScreen());
+  EXPECT_EQ(gfx::Rect(430, 50, 40, 50), child->GetBoundsInScreen());
+}
+
 }  // namespace ash
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc
index 989d17f..b977b2b 100644
--- a/ash/extended_desktop_unittest.cc
+++ b/ash/extended_desktop_unittest.cc
@@ -28,6 +28,7 @@
 #include "ui/views/controls/textfield/textfield.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
+#include "ui/wm/core/window_util.h"
 #include "ui/wm/public/activation_client.h"
 
 namespace ash {
@@ -135,18 +136,14 @@
 
 class ExtendedDesktopTest : public AshTestBase {
  public:
+  ExtendedDesktopTest() = default;
+  ~ExtendedDesktopTest() override = default;
+
   views::Widget* CreateTestWidget(const gfx::Rect& bounds) {
     return CreateTestWidgetWithParentAndContext(nullptr, CurrentContext(),
                                                 bounds, false);
   }
 
-  views::Widget* CreateTestWidgetWithParent(views::Widget* parent,
-                                            const gfx::Rect& bounds,
-                                            bool child) {
-    CHECK(parent);
-    return CreateTestWidgetWithParentAndContext(parent, nullptr, bounds, child);
-  }
-
   views::Widget* CreateTestWidgetWithParentAndContext(views::Widget* parent,
                                                       gfx::NativeView context,
                                                       const gfx::Rect& bounds,
@@ -162,6 +159,9 @@
     widget->Show();
     return widget;
   }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExtendedDesktopTest);
 };
 
 // Test conditions that root windows in extended desktop mode must satisfy.
@@ -587,47 +587,82 @@
 TEST_F(ExtendedDesktopTest, MoveWindowWithTransient) {
   UpdateDisplay("1000x600,600x400");
   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-  views::Widget* w1 = CreateTestWidget(gfx::Rect(10, 10, 100, 100));
-  views::Widget* w1_t1 = CreateTestWidgetWithParent(
-      w1, gfx::Rect(50, 50, 50, 50), false /* transient */);
-  // Transient child of the transient child.
-  views::Widget* w1_t11 = CreateTestWidgetWithParent(
-      w1_t1, gfx::Rect(1200, 70, 35, 35), false /* transient */);
+  // Create and activate a normal window |w1|.
+  aura::Window* w1 =
+      CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 100, 100));
+  wm::ActivateWindow(w1);
+  // |w1_t1| is a transient child window of |w1|.
+  std::unique_ptr<aura::Window> w1_t1 = CreateChildWindow(
+      w1, gfx::Rect(50, 50, 50, 50), kShellWindowId_DefaultContainer);
+  ::wm::AddTransientChild(w1, w1_t1.get());
+  // |w1_t11| is a transient child window of transient child window |w1_t1|.
+  std::unique_ptr<aura::Window> w1_t11 = CreateChildWindow(
+      w1_t1.get(), gfx::Rect(2, 7, 35, 35), kShellWindowId_DefaultContainer);
+  ::wm::AddTransientChild(w1_t1.get(), w1_t11.get());
 
-  views::Widget* w11 = CreateTestWidgetWithParent(w1, gfx::Rect(10, 10, 40, 40),
-                                                  true /* child */);
-  views::Widget* w11_t1 = CreateTestWidgetWithParent(
-      w1, gfx::Rect(1300, 100, 80, 80), false /* transient */);
+  // |w11| is a non-transient child window of |w1|.
+  std::unique_ptr<aura::Window> w11 = CreateChildWindow(
+      w1, gfx::Rect(10, 10, 40, 40), kShellWindowId_DefaultContainer);
+  // |w11_t1| is a transient child window of |w11|.
+  std::unique_ptr<aura::Window> w11_t1 = CreateChildWindow(
+      w11.get(), gfx::Rect(30, 10, 80, 80), kShellWindowId_DefaultContainer);
+  ::wm::AddTransientChild(w11.get(), w11_t1.get());
 
-  EXPECT_EQ(root_windows[0], w1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], w11->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], w1_t1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], w1_t11->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], w11_t1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ("50,50 50x50", w1_t1->GetWindowBoundsInScreen().ToString());
-  EXPECT_EQ("1200,70 35x35", w1_t11->GetWindowBoundsInScreen().ToString());
-  EXPECT_EQ("20,20 40x40", w11->GetWindowBoundsInScreen().ToString());
-  EXPECT_EQ("1300,100 80x80", w11_t1->GetWindowBoundsInScreen().ToString());
+  EXPECT_EQ(root_windows[0], w1->GetRootWindow());
+  EXPECT_EQ(root_windows[0], w1_t1->GetRootWindow());
+  EXPECT_EQ(root_windows[0], w1_t11->GetRootWindow());
+  EXPECT_EQ(root_windows[0], w11->GetRootWindow());
+  EXPECT_EQ(root_windows[0], w11_t1->GetRootWindow());
+  EXPECT_EQ("10,10 100x100", w1->GetBoundsInScreen().ToString());
+  EXPECT_EQ("60,60 50x50", w1_t1->GetBoundsInScreen().ToString());
+  EXPECT_EQ("62,67 35x35", w1_t11->GetBoundsInScreen().ToString());
+  EXPECT_EQ("20,20 40x40", w11->GetBoundsInScreen().ToString());
+  EXPECT_EQ("50,30 80x80", w11_t1->GetBoundsInScreen().ToString());
 
-  w1->SetBounds(gfx::Rect(1100, 10, 100, 100));
+  w1->SetBoundsInScreen(gfx::Rect(1200, 10, 100, 100), GetSecondaryDisplay());
 
-  EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], w1_t11->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], w11->GetNativeView()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], w11_t1->GetNativeView()->GetRootWindow());
+  EXPECT_EQ(root_windows[1], w1->GetRootWindow());
+  EXPECT_EQ(root_windows[1], w1_t1->GetRootWindow());
+  EXPECT_EQ(root_windows[1], w1_t11->GetRootWindow());
+  EXPECT_EQ(root_windows[1], w11->GetRootWindow());
+  EXPECT_EQ(root_windows[1], w11_t1->GetRootWindow());
 
-  EXPECT_EQ("1110,20 40x40", w11->GetWindowBoundsInScreen().ToString());
-  // Transient window's screen bounds stays the same.
-  EXPECT_EQ("50,50 50x50", w1_t1->GetWindowBoundsInScreen().ToString());
-  EXPECT_EQ("1200,70 35x35", w1_t11->GetWindowBoundsInScreen().ToString());
-  EXPECT_EQ("1300,100 80x80", w11_t1->GetWindowBoundsInScreen().ToString());
+  EXPECT_EQ("1200,10 100x100", w1->GetBoundsInScreen().ToString());
+  EXPECT_EQ("1250,60 50x50", w1_t1->GetBoundsInScreen().ToString());
+  EXPECT_EQ("1252,67 35x35", w1_t11->GetBoundsInScreen().ToString());
+  EXPECT_EQ("1210,20 40x40", w11->GetBoundsInScreen().ToString());
+  EXPECT_EQ("1240,30 80x80", w11_t1->GetBoundsInScreen().ToString());
+}
 
-  // Transient window doesn't move between root window unless
-  // its transient parent moves.
-  w1_t1->SetBounds(gfx::Rect(10, 50, 50, 50));
-  EXPECT_EQ(root_windows[1], w1_t1->GetNativeView()->GetRootWindow());
-  EXPECT_EQ("10,50 50x50", w1_t1->GetWindowBoundsInScreen().ToString());
+// Test transient child is parented after its transient parent moved to another
+// root window.
+TEST_F(ExtendedDesktopTest, PostMoveParentTransientChild) {
+  UpdateDisplay("600X400,600x400");
+  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
+  // Create and activate a normal window.
+  aura::Window* window =
+      CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 100, 100));
+  wm::ActivateWindow(window);
+  // Create a transient child window of |window| without parenting to |window|
+  // yet.
+  std::unique_ptr<aura::Window> child(new aura::Window(nullptr));
+  child->SetType(aura::client::WINDOW_TYPE_NORMAL);
+  child->Init(ui::LAYER_TEXTURED);
+  child->SetBounds(gfx::Rect(50, 50, 50, 50));
+  child->Show();
+  ::wm::AddTransientChild(window, child.get());
+
+  // Move |window| to another display and ensure that crash doesn't happen.
+  window->SetBoundsInScreen(gfx::Rect(610, 10, 100, 100),
+                            GetSecondaryDisplay());
+
+  // Parent |child| to |window| now.
+  window->AddChild(child.get());
+
+  EXPECT_EQ(root_windows[1], window->GetRootWindow());
+  EXPECT_EQ(root_windows[1], child->GetRootWindow());
+  EXPECT_EQ("610,10 100x100", window->GetBoundsInScreen().ToString());
+  EXPECT_EQ("660,60 50x50", child->GetBoundsInScreen().ToString());
 }
 
 // Test if the Window::ConvertPointToTarget works across root windows.
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index b4e8c25..3ce49d2 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -13,6 +13,7 @@
 #include "ash/app_list/model/search/search_box_model.h"
 #include "ash/app_list/model/search/search_model.h"
 #include "ash/app_list/model/search/search_result.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "ash/shell/example_factory.h"
@@ -27,7 +28,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/presenter/app_list.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/rect.h"
diff --git a/ash/wallpaper/test_wallpaper_delegate.cc b/ash/wallpaper/test_wallpaper_delegate.cc
index ec4a594e..33df922 100644
--- a/ash/wallpaper/test_wallpaper_delegate.cc
+++ b/ash/wallpaper/test_wallpaper_delegate.cc
@@ -4,35 +4,14 @@
 
 #include "ash/wallpaper/test_wallpaper_delegate.h"
 
-#include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
-
 namespace ash {
 
-TestWallpaperDelegate::TestWallpaperDelegate() : update_wallpaper_count_(0) {}
+TestWallpaperDelegate::TestWallpaperDelegate() {}
 
 TestWallpaperDelegate::~TestWallpaperDelegate() = default;
 
-void TestWallpaperDelegate::UpdateWallpaper(bool clear_cache) {
-  DefaultWallpaperDelegate::UpdateWallpaper(clear_cache);
-  if (!custom_wallpaper_.isNull()) {
-    wallpaper::WallpaperInfo info("", wallpaper::WALLPAPER_LAYOUT_STRETCH,
-                                  wallpaper::DEFAULT,
-                                  base::Time::Now().LocalMidnight());
-    Shell::Get()->wallpaper_controller()->SetWallpaperImage(custom_wallpaper_,
-                                                            info);
-  }
-  update_wallpaper_count_++;
-}
-
 bool TestWallpaperDelegate::CanOpenSetWallpaperPage() {
   return true;
 }
 
-int TestWallpaperDelegate::GetUpdateWallpaperCountAndReset() {
-  int count = update_wallpaper_count_;
-  update_wallpaper_count_ = 0;
-  return count;
-}
-
 }  // namespace ash
diff --git a/ash/wallpaper/test_wallpaper_delegate.h b/ash/wallpaper/test_wallpaper_delegate.h
index 33e7dea..ef9a3a99 100644
--- a/ash/wallpaper/test_wallpaper_delegate.h
+++ b/ash/wallpaper/test_wallpaper_delegate.h
@@ -7,7 +7,6 @@
 
 #include "ash/default_wallpaper_delegate.h"
 #include "base/macros.h"
-#include "ui/gfx/image/image_skia.h"
 
 namespace ash {
 
@@ -16,24 +15,10 @@
   TestWallpaperDelegate();
   ~TestWallpaperDelegate() override;
 
-  void set_custom_wallpaper(const gfx::ImageSkia& wallpaper) {
-    custom_wallpaper_ = wallpaper;
-  }
-
   // DefaultWallpaperDelegate overrides:
-  void UpdateWallpaper(bool clear_cache) override;
   bool CanOpenSetWallpaperPage() override;
 
-  // Returns and clears |update_wallpaper_count_|.
-  int GetUpdateWallpaperCountAndReset();
-
  private:
-  // Number of times that UpdateWallpaper() has been called.
-  int update_wallpaper_count_;
-
-  // If non-null, used as custom wallpaper by UpdateWallpaper().
-  gfx::ImageSkia custom_wallpaper_;
-
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperDelegate);
 };
 
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index d658447..ea90e6a 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -632,6 +632,12 @@
   return wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED;
 }
 
+wallpaper::WallpaperType WallpaperController::GetWallpaperType() const {
+  if (current_wallpaper_)
+    return current_wallpaper_->wallpaper_info().type;
+  return wallpaper::DEFAULT;
+}
+
 void WallpaperController::SetDefaultWallpaperImpl(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
@@ -824,8 +830,8 @@
       GetInternalDisplayCompositorLock();
       timer_.Start(FROM_HERE,
                    base::TimeDelta::FromMilliseconds(wallpaper_reload_delay_),
-                   base::Bind(&WallpaperController::UpdateWallpaper,
-                              base::Unretained(this), false /* clear cache */));
+                   base::Bind(&WallpaperController::ReloadWallpaper,
+                              base::Unretained(this), false /*clear_cache=*/));
     }
   }
 }
@@ -840,7 +846,7 @@
   if (current_max_display_size_ != max_display_size) {
     current_max_display_size_ = max_display_size;
     if (wallpaper_mode_ == WALLPAPER_IMAGE && current_wallpaper_)
-      UpdateWallpaper(true /* clear cache */);
+      ReloadWallpaper(true /*clear_cache=*/);
   }
 
   InstallDesktopController(root_window);
@@ -1177,22 +1183,22 @@
 
 void WallpaperController::ShowUserWallpaper(
     mojom::WallpaperUserInfoPtr user_info) {
+  current_user_ = std::move(user_info);
+  const AccountId account_id = current_user_->account_id;
+  const bool is_persistent = !current_user_->is_ephemeral;
+
   // Guest user or regular user in ephemeral mode.
   // TODO(wzang/xdai): Check if the wallpaper info for ephemeral users should
   // be saved to local state.
-  if ((user_info->is_ephemeral && user_info->has_gaia_account) ||
-      user_info->type == user_manager::USER_TYPE_GUEST) {
-    InitializeUserWallpaperInfo(user_info->account_id,
-                                !user_info->is_ephemeral);
-    SetDefaultWallpaperImpl(user_info->account_id, user_info->type,
+  if ((!is_persistent && current_user_->has_gaia_account) ||
+      current_user_->type == user_manager::USER_TYPE_GUEST) {
+    InitializeUserWallpaperInfo(account_id, is_persistent);
+    SetDefaultWallpaperImpl(account_id, current_user_->type,
                             true /*show_wallpaper=*/);
     LOG(ERROR) << "User is ephemeral or guest! Fallback to default wallpaper.";
     return;
   }
 
-  current_user_ = std::move(user_info);
-  const AccountId account_id = current_user_->account_id;
-  const bool is_persistent = !current_user_->is_ephemeral;
   WallpaperInfo info;
   if (!GetUserWallpaperInfo(account_id, &info, is_persistent)) {
     InitializeUserWallpaperInfo(account_id, is_persistent);
@@ -1257,6 +1263,7 @@
 }
 
 void WallpaperController::ShowSigninWallpaper() {
+  current_user_.reset();
   // TODO(crbug.com/791654): Call |SetDeviceWallpaperIfApplicable| from here.
   SetDefaultWallpaperImpl(EmptyAccountId(), user_manager::USER_TYPE_REGULAR,
                           true /*show_wallpaper=*/);
@@ -1412,11 +1419,6 @@
                 : kShellWindowId_WallpaperContainer;
 }
 
-void WallpaperController::UpdateWallpaper(bool clear_cache) {
-  current_wallpaper_.reset();
-  Shell::Get()->wallpaper_delegate()->UpdateWallpaper(clear_cache);
-}
-
 void WallpaperController::RemoveUserWallpaperInfo(const AccountId& account_id,
                                                   bool is_persistent) {
   if (wallpaper_cache_map_.find(account_id) != wallpaper_cache_map_.end())
@@ -1643,7 +1645,7 @@
   // Empty image indicates decode failure. Use default wallpaper in this case.
   if (user_image->image().isNull()) {
     LOG(ERROR) << "Failed to decode user wallpaper at " << path.value()
-               << "Falls back to default wallpaper. ";
+               << " Falls back to default wallpaper. ";
     SetDefaultWallpaperImpl(account_id, user_type, show_wallpaper);
     return;
   }
@@ -1654,6 +1656,17 @@
     SetWallpaperImage(user_image->image(), info);
 }
 
+void WallpaperController::ReloadWallpaper(bool clear_cache) {
+  current_wallpaper_.reset();
+  if (clear_cache)
+    wallpaper_cache_map_.clear();
+
+  if (current_user_)
+    ShowUserWallpaper(std::move(current_user_));
+  else
+    ShowSigninWallpaper();
+}
+
 void WallpaperController::SetProminentColors(
     const std::vector<SkColor>& colors) {
   if (prominent_colors_ == colors)
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h
index 175716b..325230c 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller.h
@@ -237,6 +237,8 @@
 
   wallpaper::WallpaperLayout GetWallpaperLayout() const;
 
+  wallpaper::WallpaperType GetWallpaperType() const;
+
   // Sets the wallpaper and alerts observers of changes.
   void SetWallpaperImage(const gfx::ImageSkia& image,
                          const wallpaper::WallpaperInfo& info);
@@ -451,10 +453,6 @@
   // Returns the wallpaper container id for unlocked and locked states.
   int GetWallpaperContainerId(bool locked);
 
-  // Reload the wallpaper. |clear_cache| specifies whether to clear the
-  // wallpaper cache or not.
-  void UpdateWallpaper(bool clear_cache);
-
   // Removes |account_id|'s wallpaper info and color cache if it exists.
   void RemoveUserWallpaperInfo(const AccountId& account_id, bool is_persistent);
 
@@ -509,6 +507,15 @@
                           bool show_wallpaper,
                           std::unique_ptr<user_manager::UserImage> user_image);
 
+  // Reloads the current wallpaper. It may change the wallpaper size based on
+  // the current display's resolution. If |clear_cache| is true, all wallpaper
+  // cache should be cleared. This is required when the display's native
+  // resolution changes to a larger resolution (e.g. when hooked up a large
+  // external display) and we need to load a larger resolution wallpaper for the
+  // display. All the previous small resolution wallpaper cache should be
+  // cleared.
+  void ReloadWallpaper(bool clear_cache);
+
   // Sets |prominent_colors_| and notifies the observers if there is a change.
   void SetProminentColors(const std::vector<SkColor>& prominent_colors);
 
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 2863f5b..342e2da 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -359,9 +359,9 @@
     wallpaper_user_info->is_ephemeral = false;
     wallpaper_user_info->has_gaia_account = true;
 
-    controller_->decode_requests_for_testing_.clear();
     controller_->current_user_wallpaper_info_ = wallpaper::WallpaperInfo();
-    controller_->wallpaper_count_for_testing_ = 0;
+    ClearWallpaperCount();
+    ClearDecodeFilePaths();
 
     return wallpaper_user_info;
   }
@@ -467,6 +467,12 @@
 
   int GetWallpaperCount() { return controller_->wallpaper_count_for_testing_; }
 
+  void ClearWallpaperCount() { controller_->wallpaper_count_for_testing_ = 0; }
+
+  void ClearDecodeFilePaths() {
+    controller_->decode_requests_for_testing_.clear();
+  }
+
   bool CompareDecodeFilePaths(const std::vector<base::FilePath> expected) {
     if (controller_->decode_requests_for_testing_.size() != expected.size())
       return false;
@@ -835,6 +841,7 @@
       type, *image.bitmap(), true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::CUSTOMIZED);
   wallpaper::WallpaperInfo wallpaper_info;
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 true /* is_persistent */));
@@ -867,6 +874,7 @@
                                   url, layout, true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::ONLINE);
   wallpaper::WallpaperInfo wallpaper_info;
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 true /*is_persistent=*/));
@@ -903,11 +911,13 @@
   // info, and the large default wallpaper is set successfully with the correct
   // file path.
   UpdateDisplay("1600x1200");
+  RunAllTasksUntilIdle();
   controller_->SetDefaultWallpaper(InitializeUser(account_id_1),
                                    wallpaper_files_id_1,
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
       {wallpaper_dir_->GetPath().Append(default_large_wallpaper_name)}));
 
@@ -921,11 +931,13 @@
   // info, and the small default wallpaper is set successfully with the correct
   // file path.
   UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
   controller_->SetDefaultWallpaper(InitializeUser(account_id_1),
                                    wallpaper_files_id_1,
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
       {wallpaper_dir_->GetPath().Append(default_small_wallpaper_name)}));
 
@@ -936,16 +948,18 @@
 
   SimulateSettingCustomWallpaper(account_id_1);
   // Verify that when screen is rotated, |SetDefaultWallpaper| removes the
-  // previously set custom wallpaper info, and the large default wallpaper is
+  // previously set custom wallpaper info, and the small default wallpaper is
   // set successfully with the correct file path.
-  UpdateDisplay("1200x800/r");
+  UpdateDisplay("800x600/r");
+  RunAllTasksUntilIdle();
   controller_->SetDefaultWallpaper(InitializeUser(account_id_1),
                                    wallpaper_files_id_1,
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
-      {wallpaper_dir_->GetPath().Append(default_large_wallpaper_name)}));
+      {wallpaper_dir_->GetPath().Append(default_small_wallpaper_name)}));
 
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 true /*is_persistent=*/));
@@ -964,6 +978,7 @@
   // Verify the large child wallpaper is set successfully with the correct file
   // path.
   UpdateDisplay("1600x1200");
+  RunAllTasksUntilIdle();
   mojom::WallpaperUserInfoPtr wallpaper_user_info =
       InitializeUser(child_account_id);
   wallpaper_user_info->type = user_manager::USER_TYPE_CHILD;
@@ -972,12 +987,14 @@
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
       {wallpaper_dir_->GetPath().Append(child_large_wallpaper_name)}));
 
   // Verify the small child wallpaper is set successfully with the correct file
   // path.
   UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
   wallpaper_user_info = InitializeUser(child_account_id);
   wallpaper_user_info->type = user_manager::USER_TYPE_CHILD;
   controller_->SetDefaultWallpaper(std::move(wallpaper_user_info),
@@ -985,6 +1002,7 @@
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
       {wallpaper_dir_->GetPath().Append(child_small_wallpaper_name)}));
 }
@@ -1014,11 +1032,13 @@
   // custom wallpaper info, but a guest specific wallpaper should be set,
   // instead of the regular default wallpaper.
   UpdateDisplay("1600x1200");
+  RunAllTasksUntilIdle();
   controller_->SetDefaultWallpaper(InitializeUser(account_id_1),
                                    wallpaper_files_id_1,
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 true /* is_persistent */));
   EXPECT_EQ(wallpaper_info, default_wallpaper_info);
@@ -1026,11 +1046,13 @@
       {wallpaper_dir_->GetPath().Append(guest_large_wallpaper_name)}));
 
   UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
   controller_->SetDefaultWallpaper(InitializeUser(account_id_1),
                                    wallpaper_files_id_1,
                                    true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
   EXPECT_TRUE(CompareDecodeFilePaths(
       {wallpaper_dir_->GetPath().Append(guest_small_wallpaper_name)}));
 }
@@ -1189,22 +1211,85 @@
   base::FilePath small_wallpaper_path =
       GetCustomWallpaperPath(WallpaperController::kSmallWallpaperSubDir,
                              wallpaper_files_id_1, file_name_1);
+  base::FilePath large_wallpaper_path =
+      GetCustomWallpaperPath(WallpaperController::kLargeWallpaperSubDir,
+                             wallpaper_files_id_1, file_name_1);
 
   CreateAndSaveWallpapers(account_id_1);
   controller_->ShowUserWallpaper(InitializeUser(account_id_1));
   RunAllTasksUntilIdle();
-  EXPECT_EQ(1, GetWallpaperCount());
-
   // Display is initialized to 800x600. The small resolution custom wallpaper is
   // expected. A second decode request with small resolution default wallpaper
   // is also expected. (Because unit tests don't support actual wallpaper
-  // decoding, it falls back the default wallpaper.)
+  // decoding, it falls back to the default wallpaper.)
+  EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_TRUE(CompareDecodeFilePaths(
       {small_wallpaper_path,
        wallpaper_dir_->GetPath().Append(default_small_wallpaper_name)}));
 
-  // TODO(crbug.com/776464): Add tests for large resolution custom wallpapers
-  // after |UpdateWallpaper| is migrated.
+  // Hook up another 800x600 display. This shouldn't trigger a reload.
+  ClearWallpaperCount();
+  ClearDecodeFilePaths();
+  UpdateDisplay("800x600,800x600");
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(0, GetWallpaperCount());
+  EXPECT_TRUE(CompareDecodeFilePaths({}));
+
+  // Detach the secondary display.
+  UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
+  // Hook up a 2000x2000 display. The large resolution custom wallpaper should
+  // be loaded.
+  ClearWallpaperCount();
+  ClearDecodeFilePaths();
+  UpdateDisplay("800x600,2000x2000");
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_TRUE(CompareDecodeFilePaths(
+      {large_wallpaper_path,
+       wallpaper_dir_->GetPath().Append(default_large_wallpaper_name)}));
+
+  // Detach the secondary display.
+  UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
+  // Hook up the 2000x2000 display again. The large resolution default wallpaper
+  // should persist. Test for crbug/165788.
+  ClearWallpaperCount();
+  ClearDecodeFilePaths();
+  UpdateDisplay("800x600,2000x2000");
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_TRUE(CompareDecodeFilePaths(
+      {large_wallpaper_path,
+       wallpaper_dir_->GetPath().Append(default_large_wallpaper_name)}));
+}
+
+// After the display is rotated, the sign in wallpaper should be kept. Test for
+// crbug.com/794725.
+TEST_F(WallpaperControllerTest, SigninWallpaperIsKeptAfterRotation) {
+  CreateDefaultWallpapers();
+
+  UpdateDisplay("800x600");
+  RunAllTasksUntilIdle();
+  controller_->ShowSigninWallpaper();
+  RunAllTasksUntilIdle();
+  // Display is initialized to 800x600. The small resolution default wallpaper
+  // is expected.
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
+  EXPECT_TRUE(CompareDecodeFilePaths(
+      {wallpaper_dir_->GetPath().Append(default_small_wallpaper_name)}));
+
+  ClearWallpaperCount();
+  ClearDecodeFilePaths();
+  // After rotating the display, the small resolution default wallpaper should
+  // still be expected, instead of a custom wallpaper.
+  UpdateDisplay("800x600/r");
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), wallpaper::DEFAULT);
+  EXPECT_TRUE(CompareDecodeFilePaths(
+      {wallpaper_dir_->GetPath().Append(default_small_wallpaper_name)}));
 }
 
 // If clients call |ShowUserWallpaper| twice with the same account id, the
diff --git a/ash/wallpaper/wallpaper_delegate.h b/ash/wallpaper/wallpaper_delegate.h
index 0ec8ac84..4319a21 100644
--- a/ash/wallpaper/wallpaper_delegate.h
+++ b/ash/wallpaper/wallpaper_delegate.h
@@ -29,15 +29,6 @@
   // another's on the login screen)?
   virtual bool ShouldShowInitialAnimation() = 0;
 
-  // Updates current wallpaper. It may switch the size of wallpaper based on the
-  // current display's resolution. If |clear_cache| is true, all wallpaper
-  // cache should be cleared. This is required when the display's native
-  // resolution changes to a larger resolution (e.g. when hooked up a large
-  // external display) and we need to load a larger resolution wallpaper for the
-  // large display. All the previous small resolution wallpaper cache should be
-  // cleared.
-  virtual void UpdateWallpaper(bool clear_cache) = 0;
-
   // Initialize wallpaper.
   virtual void InitializeWallpaper() = 0;
 
diff --git a/ash/wallpaper/wallpaper_delegate_mus.cc b/ash/wallpaper/wallpaper_delegate_mus.cc
index ded9169..9e9ac5a 100644
--- a/ash/wallpaper/wallpaper_delegate_mus.cc
+++ b/ash/wallpaper/wallpaper_delegate_mus.cc
@@ -28,10 +28,6 @@
   return false;
 }
 
-void WallpaperDelegateMus::UpdateWallpaper(bool clear_cache) {
-  NOTIMPLEMENTED_LOG_ONCE();
-}
-
 void WallpaperDelegateMus::InitializeWallpaper() {
   // No action required; ChromeBrowserMainPartsChromeos inits WallpaperManager.
 }
diff --git a/ash/wallpaper/wallpaper_delegate_mus.h b/ash/wallpaper/wallpaper_delegate_mus.h
index f2330c7..40dbd89 100644
--- a/ash/wallpaper/wallpaper_delegate_mus.h
+++ b/ash/wallpaper/wallpaper_delegate_mus.h
@@ -21,7 +21,6 @@
   int GetAnimationDurationOverride() override;
   void SetAnimationDurationOverride(int animation_duration_in_ms) override;
   bool ShouldShowInitialAnimation() override;
-  void UpdateWallpaper(bool clear_cache) override;
   void InitializeWallpaper() override;
   bool CanOpenSetWallpaperPage() override;
   void OnWallpaperAnimationFinished() override;
diff --git a/ash/wm/window_positioning_utils.cc b/ash/wm/window_positioning_utils.cc
index 0e10358..88269a3e8 100644
--- a/ash/wm/window_positioning_utils.cc
+++ b/ash/wm/window_positioning_utils.cc
@@ -50,31 +50,6 @@
                     IsWindowOrAncestorLockedToRoot(window->parent()));
 }
 
-// Move all transient children to |dst_root|, including the ones in
-// the child windows and transient children of the transient children.
-void MoveAllTransientChildrenToNewRoot(const display::Display& display,
-                                       aura::Window* window) {
-  aura::Window* dst_root =
-      Shell::GetRootWindowControllerWithDisplayId(display.id())
-          ->GetRootWindow();
-  for (aura::Window* transient_child : ::wm::GetTransientChildren(window)) {
-    const int container_id = transient_child->parent()->id();
-    DCHECK_GE(container_id, 0);
-    aura::Window* container = dst_root->GetChildById(container_id);
-    const gfx::Rect transient_child_bounds_in_screen =
-        transient_child->GetBoundsInScreen();
-    container->AddChild(transient_child);
-    transient_child->SetBoundsInScreen(transient_child_bounds_in_screen,
-                                       display);
-
-    // Transient children may have transient children.
-    MoveAllTransientChildrenToNewRoot(display, transient_child);
-  }
-  // Move transient children of the child windows if any.
-  for (aura::Window* child : window->children())
-    MoveAllTransientChildrenToNewRoot(display, child);
-}
-
 }  // namespace
 
 void AdjustBoundsSmallerThan(const gfx::Size& max_size, gfx::Rect* bounds) {
@@ -183,8 +158,6 @@
 
       dst_container->AddChild(window);
 
-      MoveAllTransientChildrenToNewRoot(display, window);
-
       // Restore focused/active window.
       if (focused && tracker.Contains(focused)) {
         aura::client::GetFocusClient(focused)->FocusWindow(focused);
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc
index 55ad9207..528daba 100644
--- a/ash/wm/window_state.cc
+++ b/ash/wm/window_state.cc
@@ -106,6 +106,33 @@
          static_cast<float>(maximized_bounds.width());
 }
 
+// Move all transient children to |dst_root|, including the ones in the child
+// windows and transient children of the transient children.
+void MoveAllTransientChildrenToNewRoot(aura::Window* window) {
+  aura::Window* dst_root = window->GetRootWindow();
+  for (aura::Window* transient_child : ::wm::GetTransientChildren(window)) {
+    if (!transient_child->parent())
+      continue;
+    const int container_id = transient_child->parent()->id();
+    DCHECK_GE(container_id, 0);
+    aura::Window* container = dst_root->GetChildById(container_id);
+    if (container->Contains(transient_child))
+      continue;
+    gfx::Rect child_bounds = transient_child->bounds();
+    ::wm::ConvertRectToScreen(dst_root, &child_bounds);
+    container->AddChild(transient_child);
+    transient_child->SetBoundsInScreen(
+        child_bounds,
+        display::Screen::GetScreen()->GetDisplayNearestWindow(window));
+
+    // Transient children may have transient children.
+    MoveAllTransientChildrenToNewRoot(transient_child);
+  }
+  // Move transient children of the child windows if any.
+  for (aura::Window* child : window->children())
+    MoveAllTransientChildrenToNewRoot(child);
+}
+
 }  // namespace
 
 WindowState::~WindowState() {
@@ -627,5 +654,12 @@
   }
 }
 
+void WindowState::OnWindowAddedToRootWindow(aura::Window* window) {
+  DCHECK_EQ(window_, window);
+  if (::wm::GetTransientParent(window))
+    return;
+  MoveAllTransientChildrenToNewRoot(window);
+}
+
 }  // namespace wm
 }  // namespace ash
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h
index e211935..73f0b8e 100644
--- a/ash/wm/window_state.h
+++ b/ash/wm/window_state.h
@@ -389,6 +389,7 @@
   void OnWindowPropertyChanged(aura::Window* window,
                                const void* key,
                                intptr_t old) override;
+  void OnWindowAddedToRootWindow(aura::Window* window) override;
 
   // The owner of this window settings.
   aura::Window* window_;
diff --git a/base/optional.h b/base/optional.h
index 00c586726..fbc62893 100644
--- a/base/optional.h
+++ b/base/optional.h
@@ -171,8 +171,6 @@
 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
 //
 // These are the differences between the specification and the implementation:
-// - The constructor and emplace method using initializer_list are not
-//   implemented because 'initializer_list' is banned from Chromium.
 // - Constructors do not use 'constexpr' as it is a C++14 extension.
 // - 'constexpr' might be missing in some places for reasons specified locally.
 // - No exceptions are thrown, because they are banned from Chromium.
@@ -200,6 +198,17 @@
   constexpr explicit Optional(in_place_t, Args&&... args)
       : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
 
+  template <
+      class U,
+      class... Args,
+      class = std::enable_if_t<std::is_constructible<value_type,
+                                                     std::initializer_list<U>&,
+                                                     Args...>::value>>
+  constexpr explicit Optional(in_place_t,
+                              std::initializer_list<U> il,
+                              Args&&... args)
+      : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
+
   ~Optional() = default;
 
   // Defer copy-/move- assign operator implementation to OptionalBase.
@@ -314,6 +323,18 @@
     Init(std::forward<Args>(args)...);
   }
 
+  template <
+      class U,
+      class... Args,
+      class = std::enable_if_t<std::is_constructible<value_type,
+                                                     std::initializer_list<U>&,
+                                                     Args...>::value>>
+  T& emplace(std::initializer_list<U> il, Args&&... args) {
+    FreeIfNeeded();
+    Init(il, std::forward<Args>(args)...);
+    return storage_.value_;
+  }
+
  private:
   // Accessing template base class's protected member needs explicit
   // declaration to do so.
@@ -506,6 +527,12 @@
   return Optional<typename std::decay<T>::type>(std::forward<T>(value));
 }
 
+template <class T, class U, class... Args>
+constexpr Optional<T> make_optional(std::initializer_list<U> il,
+                                    Args&&... args) {
+  return Optional<T>(in_place, il, std::forward<Args>(args)...);
+}
+
 template <class T>
 void swap(Optional<T>& lhs, Optional<T>& rhs) {
   lhs.swap(rhs);
diff --git a/base/optional_unittest.cc b/base/optional_unittest.cc
index 03c566b7..479424d6 100644
--- a/base/optional_unittest.cc
+++ b/base/optional_unittest.cc
@@ -4,10 +4,16 @@
 
 #include "base/optional.h"
 
+#include <memory>
 #include <set>
+#include <string>
+#include <vector>
 
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using ::testing::ElementsAre;
+
 namespace base {
 
 namespace {
@@ -275,6 +281,22 @@
   }
 }
 
+TEST(OptionalTest, ConstructorForwardInitListAndArguments) {
+  {
+    Optional<std::vector<int>> opt(in_place, {3, 1});
+    EXPECT_TRUE(opt);
+    EXPECT_THAT(*opt, ElementsAre(3, 1));
+    EXPECT_EQ(2u, opt->size());
+  }
+
+  {
+    Optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
+    EXPECT_TRUE(opt);
+    EXPECT_THAT(*opt, ElementsAre(3, 1));
+    EXPECT_EQ(2u, opt->size());
+  }
+}
+
 TEST(OptionalTest, NulloptConstructor) {
   constexpr Optional<int> a(base::nullopt);
   EXPECT_FALSE(a);
@@ -578,6 +600,24 @@
     EXPECT_TRUE(!!a);
     EXPECT_TRUE(TestObject(1, 0.2) == a.value());
   }
+
+  {
+    Optional<std::vector<int>> a;
+    auto& ref = a.emplace({2, 3});
+    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
+    EXPECT_TRUE(a);
+    EXPECT_THAT(*a, ElementsAre(2, 3));
+    EXPECT_EQ(&ref, &*a);
+  }
+
+  {
+    Optional<std::vector<int>> a;
+    auto& ref = a.emplace({4, 5}, std::allocator<int>());
+    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
+    EXPECT_TRUE(a);
+    EXPECT_THAT(*a, ElementsAre(4, 5));
+    EXPECT_EQ(&ref, &*a);
+  }
 }
 
 TEST(OptionalTest, Equals_TwoEmpty) {
@@ -1349,6 +1389,15 @@
     EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED,
               base::make_optional(std::move(value))->state());
   }
+
+  {
+    auto str1 = make_optional<std::string>({'1', '2', '3'});
+    EXPECT_EQ("123", *str1);
+
+    auto str2 =
+        make_optional<std::string>({'a', 'b', 'c'}, std::allocator<char>());
+    EXPECT_EQ("abc", *str2);
+  }
 }
 
 TEST(OptionalTest, NonMemberSwap_bothNoValue) {
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc
index 534863d8..38a5846 100644
--- a/base/trace_event/memory_infra_background_whitelist.cc
+++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -278,13 +278,11 @@
     return true;
   }
 
-  // As are shared memory dumps. Note: we skip the first character after the
-  // slash and last character in the string as they are expected to be brackets.
-  if (base::StartsWith(name, "shared_memory/(", CompareCase::SENSITIVE)) {
-    for (size_t i = strlen("shared_memory/") + 1; i < name.size() - 1; i++)
+  if (base::StartsWith(name, "shared_memory/", CompareCase::SENSITIVE)) {
+    for (size_t i = strlen("shared_memory/"); i < name.size(); i++)
       if (!base::IsHexDigit(name[i]))
         return false;
-    return name.back() == ')';
+    return true;
   }
 
   // Remove special characters, numbers (including hexadecimal which are marked
diff --git a/base/unguessable_token.cc b/base/unguessable_token.cc
index cd9830e6..489bf62 100644
--- a/base/unguessable_token.cc
+++ b/base/unguessable_token.cc
@@ -14,7 +14,7 @@
     : high_(high), low_(low) {}
 
 std::string UnguessableToken::ToString() const {
-  return base::StringPrintf("(%08" PRIX64 "%08" PRIX64 ")", high_, low_);
+  return base::StringPrintf("%08" PRIX64 "%08" PRIX64, high_, low_);
 }
 
 // static
@@ -35,7 +35,7 @@
 }
 
 std::ostream& operator<<(std::ostream& out, const UnguessableToken& token) {
-  return out << token.ToString();
+  return out << "(" << token.ToString() << ")";
 }
 
 }  // namespace base
diff --git a/base/unguessable_token.h b/base/unguessable_token.h
index 3025f19..6858e22a 100644
--- a/base/unguessable_token.h
+++ b/base/unguessable_token.h
@@ -67,6 +67,7 @@
 
   bool is_empty() const { return high_ == 0 && low_ == 0; }
 
+  // Hex representation of the unguessable token.
   std::string ToString() const;
 
   explicit operator bool() const { return !is_empty(); }
diff --git a/base/unguessable_token_unittest.cc b/base/unguessable_token_unittest.cc
index 0158257..287fca31 100644
--- a/base/unguessable_token_unittest.cc
+++ b/base/unguessable_token_unittest.cc
@@ -80,13 +80,14 @@
 
 TEST(UnguessableTokenTest, VerifyToString) {
   UnguessableToken token = UnguessableToken::Deserialize(0x123, 0xABC);
-  std::string expected = "(0000012300000ABC)";
+  std::string expected = "0000012300000ABC";
 
   EXPECT_EQ(expected, token.ToString());
 
+  std::string expected_stream = "(0000012300000ABC)";
   std::stringstream stream;
   stream << token;
-  EXPECT_EQ(expected, stream.str());
+  EXPECT_EQ(expected_stream, stream.str());
 }
 
 TEST(UnguessableTokenTest, VerifySmallerThanOperator) {
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 2facc6f..f7e50d1 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -479,6 +479,8 @@
     "test/push_properties_counting_layer_impl.h",
     "test/render_pass_test_utils.cc",
     "test/render_pass_test_utils.h",
+    "test/resource_provider_test_utils.cc",
+    "test/resource_provider_test_utils.h",
     "test/scheduler_test_common.cc",
     "test/scheduler_test_common.h",
     "test/skia_common.cc",
diff --git a/cc/paint/decoded_draw_image.cc b/cc/paint/decoded_draw_image.cc
index 70bbfce..a8f82ee 100644
--- a/cc/paint/decoded_draw_image.cc
+++ b/cc/paint/decoded_draw_image.cc
@@ -13,8 +13,7 @@
     : image_(std::move(image)),
       src_rect_offset_(src_rect_offset),
       scale_adjustment_(scale_adjustment),
-      filter_quality_(filter_quality),
-      at_raster_decode_(false) {}
+      filter_quality_(filter_quality) {}
 
 DecodedDrawImage::DecodedDrawImage()
     : DecodedDrawImage(nullptr, kNone_SkFilterQuality) {}
diff --git a/cc/paint/decoded_draw_image.h b/cc/paint/decoded_draw_image.h
index 3e10dc9..32c202f 100644
--- a/cc/paint/decoded_draw_image.h
+++ b/cc/paint/decoded_draw_image.h
@@ -36,17 +36,11 @@
            std::abs(scale_adjustment_.height() - 1.f) < FLT_EPSILON;
   }
 
-  void set_at_raster_decode(bool at_raster_decode) {
-    at_raster_decode_ = at_raster_decode;
-  }
-  bool is_at_raster_decode() const { return at_raster_decode_; }
-
  private:
   sk_sp<const SkImage> image_;
   SkSize src_rect_offset_;
   SkSize scale_adjustment_;
   SkFilterQuality filter_quality_;
-  bool at_raster_decode_;
 };
 
 }  // namespace cc
diff --git a/cc/paint/paint_image.h b/cc/paint/paint_image.h
index 5bc445b..b5da344 100644
--- a/cc/paint/paint_image.h
+++ b/cc/paint/paint_image.h
@@ -161,9 +161,6 @@
   // Returns the total number of frames known to exist in this image.
   size_t FrameCount() const;
 
-  // Returns an SkImage for the frame at |index|.
-  sk_sp<SkImage> GetSkImageForFrame(size_t index) const;
-
   std::string ToString() const;
 
  private:
@@ -182,6 +179,9 @@
   void CreateSkImage();
   PaintImage MakeSubset(const gfx::Rect& subset) const;
 
+  // Returns an SkImage for the frame at |index|.
+  sk_sp<SkImage> GetSkImageForFrame(size_t index) const;
+
   sk_sp<SkImage> sk_image_;
 
   sk_sp<PaintRecord> paint_record_;
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 6974e2c4..3c974b7 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -200,8 +200,12 @@
   output_surface_->BindToClient(output_surface_client_.get());
   shared_bitmap_manager_.reset(new TestSharedBitmapManager());
   resource_provider_ = std::make_unique<DisplayResourceProvider>(
-      nullptr, shared_bitmap_manager_.get(), gpu_memory_buffer_manager_.get(),
+      nullptr, shared_bitmap_manager_.get(), nullptr,
       settings_.resource_settings);
+  child_resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
+      nullptr, shared_bitmap_manager_.get(), nullptr, true,
+      settings_.resource_settings);
+
   auto renderer = std::make_unique<viz::SoftwareRenderer>(
       &renderer_settings_, output_surface_.get(), resource_provider_.get());
   software_renderer_ = renderer.get();
diff --git a/cc/test/resource_provider_test_utils.cc b/cc/test/resource_provider_test_utils.cc
new file mode 100644
index 0000000..74d722d
--- /dev/null
+++ b/cc/test/resource_provider_test_utils.cc
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/test/resource_provider_test_utils.h"
+
+#include "base/bind.h"
+
+namespace cc {
+
+const ResourceProvider::ResourceIdMap& SendResourceAndGetChildToParentMap(
+    const ResourceProvider::ResourceIdArray& resource_ids,
+    DisplayResourceProvider* resource_provider,
+    LayerTreeResourceProvider* child_resource_provider) {
+  DCHECK(resource_provider);
+  DCHECK(child_resource_provider);
+  // Transfer resources to the parent.
+  std::vector<viz::TransferableResource> send_to_parent;
+  int child_id = resource_provider->CreateChild(
+      base::BindRepeating([](const std::vector<viz::ReturnedResource>&) {}));
+  child_resource_provider->PrepareSendToParent(resource_ids, &send_to_parent);
+  resource_provider->ReceiveFromChild(child_id, send_to_parent);
+
+  // Return the child to parent map.
+  return resource_provider->GetChildToParentMap(child_id);
+}
+
+}  // namespace cc
diff --git a/cc/test/resource_provider_test_utils.h b/cc/test/resource_provider_test_utils.h
new file mode 100644
index 0000000..e93d76a
--- /dev/null
+++ b/cc/test/resource_provider_test_utils.h
@@ -0,0 +1,21 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TEST_RESOURCE_PROVIDER_TEST_UTILS_H_
+#define CC_TEST_RESOURCE_PROVIDER_TEST_UTILS_H_
+
+#include "cc/resources/display_resource_provider.h"
+#include "cc/resources/layer_tree_resource_provider.h"
+
+namespace cc {
+
+// Transfer resources to the parent and return the child to parent map.
+const ResourceProvider::ResourceIdMap& SendResourceAndGetChildToParentMap(
+    const ResourceProvider::ResourceIdArray& resource_ids,
+    DisplayResourceProvider* resource_provider,
+    LayerTreeResourceProvider* child_resource_provider);
+
+}  // namespace cc
+
+#endif  // CC_TEST_RESOURCE_PROVIDER_TEST_UTILS_H_
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index c6d170b0..b09f6e7 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -126,36 +126,61 @@
 }
 
 // Draws and scales the provided |draw_image| into the |target_pixmap|. If the
-// draw/scale can be done directly, calls directly into SkImage::scalePixels,
+// draw/scale can be done directly, calls directly into PaintImage::Decode.
 // if not, decodes to a compatible temporary pixmap and then converts that into
 // the |target_pixmap|.
 bool DrawAndScaleImage(const DrawImage& draw_image, SkPixmap* target_pixmap) {
-  sk_sp<SkImage> image =
-      draw_image.paint_image().GetSkImageForFrame(draw_image.frame_index());
-  if (image->dimensions() == target_pixmap->bounds().size() ||
-      target_pixmap->info().colorType() == kN32_SkColorType) {
-    // If no scaling is occurring, or if the target colortype is already N32,
-    // just scale directly.
-    return image->scalePixels(*target_pixmap,
-                              CalculateDesiredFilterQuality(draw_image),
-                              SkImage::kDisallow_CachingHint);
+  // We don't want to perform any color conversion here, so create a new pixmap
+  // with a null colorspace that shares |target_pixmap|'s memory.
+  SkPixmap pixmap(target_pixmap->info().makeColorSpace(nullptr),
+                  target_pixmap->writable_addr(), target_pixmap->rowBytes());
+
+  const PaintImage& paint_image = draw_image.paint_image();
+  SkISize supported_size =
+      paint_image.GetSupportedDecodeSize(pixmap.bounds().size());
+
+  if (supported_size == pixmap.bounds().size()) {
+    SkImageInfo info = pixmap.info();
+    return paint_image.Decode(pixmap.writable_addr(), &info, nullptr,
+                              draw_image.frame_index());
   }
 
-  // If the target colortype is not N32, it may be impossible to scale
-  // directly. Instead scale into an N32 pixmap, and convert that into the
-  // |target_pixmap|.
-  SkImageInfo decode_info =
-      target_pixmap->info().makeColorType(kN32_SkColorType);
+  // If we can't decode/scale directly, we will handle this in up to 3 steps.
+  // Step 1: Decode at the nearest (larger) directly supported size.
+  SkImageInfo decode_info = SkImageInfo::MakeN32Premul(supported_size.width(),
+                                                       supported_size.height());
   SkBitmap decode_bitmap;
   if (!decode_bitmap.tryAllocPixels(decode_info))
     return false;
   SkPixmap decode_pixmap(decode_bitmap.info(), decode_bitmap.getPixels(),
                          decode_bitmap.rowBytes());
-  if (!image->scalePixels(decode_pixmap,
-                          CalculateDesiredFilterQuality(draw_image),
-                          SkImage::kDisallow_CachingHint))
+  if (!paint_image.Decode(decode_pixmap.writable_addr(), &decode_info, nullptr,
+                          draw_image.frame_index())) {
     return false;
-  return decode_pixmap.readPixels(*target_pixmap);
+  }
+
+  // Step 2a: Scale to |pixmap| directly if kN32_SkColorType.
+  if (pixmap.info().colorType() == kN32_SkColorType) {
+    return decode_pixmap.scalePixels(pixmap,
+                                     CalculateDesiredFilterQuality(draw_image));
+  }
+
+  // Step 2b: Scale to temporary pixmap of kN32_SkColorType.
+  SkImageInfo scaled_info = pixmap.info().makeColorType(kN32_SkColorType);
+  SkBitmap scaled_bitmap;
+  if (!scaled_bitmap.tryAllocPixels(scaled_info))
+    return false;
+  SkPixmap scaled_pixmap(scaled_bitmap.info(), scaled_bitmap.getPixels(),
+                         scaled_bitmap.rowBytes());
+  if (!decode_pixmap.scalePixels(scaled_pixmap,
+                                 CalculateDesiredFilterQuality(draw_image))) {
+    return false;
+  }
+
+  // Step 3: Copy the temporary scaled pixmap to |pixmap|, performing
+  // color type conversion. We can't do the color conversion in step 1, as
+  // the scale in step 2 must happen in kN32_SkColorType.
+  return scaled_pixmap.readPixels(pixmap);
 }
 
 // Returns the GL texture ID backing the given SkImage.
@@ -191,6 +216,21 @@
                                   kPremul_SkAlphaType, std::move(color_space));
 }
 
+// Immediately deletes an SkImage, preventing caching of that image. Must be
+// called while holding the context lock.
+void DeleteSkImageAndPreventCaching(viz::RasterContextProvider* context,
+                                    sk_sp<SkImage>&& image) {
+  sk_sp<SkImage> image_owned =
+      TakeOwnershipOfSkImageBacking(context->GrContext(), std::move(image));
+  // If context is lost, we may get a null image here.
+  if (image_owned) {
+    // Delete |original_image_owned| as Skia will not clean it up. We are
+    // holding the context lock here, so we can delete immediately.
+    uint32_t texture_id = GlIdFromSkImage(image_owned.get());
+    context->RasterInterface()->DeleteTextures(1, &texture_id);
+  }
+}
+
 }  // namespace
 
 // static
@@ -383,16 +423,23 @@
 
 void GpuImageDecodeCache::DecodedImageData::SetLockedData(
     std::unique_ptr<base::DiscardableMemory> data,
+    sk_sp<SkImage> image,
     bool out_of_raster) {
   DCHECK(data);
   DCHECK(!data_);
+  DCHECK(image);
+  DCHECK(!image_);
   data_ = std::move(data);
+  image_ = std::move(image);
   OnSetLockedData(out_of_raster);
 }
 
 void GpuImageDecodeCache::DecodedImageData::ResetData() {
-  if (data_)
+  if (data_) {
+    DCHECK(image_);
     ReportUsageStats();
+  }
+  image_ = nullptr;
   data_ = nullptr;
   OnResetData();
 }
@@ -444,11 +491,13 @@
     DecodedDataMode mode,
     size_t size,
     const gfx::ColorSpace& target_color_space,
-    const SkImage::DeferredTextureImageUsageParams& upload_params)
+    SkFilterQuality quality,
+    int mip_level)
     : mode(mode),
       size(size),
       target_color_space(target_color_space),
-      upload_params(upload_params) {}
+      quality(quality),
+      mip_level(mip_level) {}
 
 GpuImageDecodeCache::ImageData::~ImageData() {
   // We should never delete ImageData while it is in use or before it has been
@@ -468,12 +517,11 @@
       context_(context),
       persistent_cache_(PersistentCache::NO_AUTO_EVICT),
       max_working_set_bytes_(max_working_set_bytes) {
-  // Acquire the context_lock so that we can safely retrieve the
-  // GrContextThreadSafeProxy. This proxy can then be used with no lock held.
+  // Acquire the context_lock so that we can safely retrieve
+  // |max_texture_size_|.
   {
     viz::RasterContextProvider::ScopedRasterContextLock context_lock(context_);
-    context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>(
-        context_->GrContext()->threadSafeProxy());
+    max_texture_size_ = context_->GrContext()->caps()->maxTextureSize();
   }
 
   // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
@@ -653,12 +701,11 @@
     image_data->upload.mark_used();
   DCHECK(image || image_data->decode.decode_failure);
 
-  SkSize scale_factor = CalculateScaleFactorForMipLevel(
-      draw_image, image_data->upload_params.fPreScaleMipLevel);
+  SkSize scale_factor =
+      CalculateScaleFactorForMipLevel(draw_image, image_data->mip_level);
   DecodedDrawImage decoded_draw_image(
       std::move(image), SkSize(), scale_factor,
       CalculateDesiredFilterQuality(draw_image));
-  decoded_draw_image.set_at_raster_decode(image_data->is_at_raster);
   return decoded_draw_image;
 }
 
@@ -1197,65 +1244,43 @@
   }
 
   TRACE_EVENT0("cc", "GpuImageDecodeCache::DecodeImage");
-  RecordImageMipLevelUMA(image_data->upload_params.fPreScaleMipLevel);
+  RecordImageMipLevelUMA(image_data->mip_level);
 
   image_data->decode.ResetData();
   std::unique_ptr<base::DiscardableMemory> backing_memory;
+  sk_sp<SkImage> image;
   {
     base::AutoUnlock unlock(lock_);
-
     backing_memory = base::DiscardableMemoryAllocator::GetInstance()
                          ->AllocateLockedDiscardableMemory(image_data->size);
-
-    switch (image_data->mode) {
-      case DecodedDataMode::CPU: {
-        SkImageInfo image_info = CreateImageInfoForDrawImage(
-            draw_image, image_data->upload_params.fPreScaleMipLevel);
-        // In order to match GPU scaling quality (which uses mip-maps at high
-        // quality), we want to use at most medium filter quality for the
-        // scale.
-        SkPixmap image_pixmap(image_info.makeColorSpace(nullptr),
-                              backing_memory->data(), image_info.minRowBytes());
-        // Note that scalePixels falls back to readPixels if the scale is 1x, so
-        // no need to special case that as an optimization.
-        if (!DrawAndScaleImage(draw_image, &image_pixmap)) {
-          DLOG(ERROR) << "scalePixels failed.";
-          backing_memory->Unlock();
-          backing_memory.reset();
-        }
-        break;
-      }
-      case DecodedDataMode::GPU: {
-        // TODO(crbug.com/649167): Params should not have changed since initial
-        // sizing. Somehow this still happens. We should investigate and re-add
-        // DCHECKs here to enforce this.
-        sk_sp<SkImage> image = draw_image.paint_image().GetSkImageForFrame(
-            draw_image.frame_index());
-        if (!image->getDeferredTextureImageData(
-                *context_threadsafe_proxy_.get(), &image_data->upload_params, 1,
-                backing_memory->data(), nullptr, color_type_)) {
-          DLOG(ERROR) << "getDeferredTextureImageData failed despite params "
-                      << "having validated.";
-          backing_memory->Unlock();
-          backing_memory.reset();
-        }
-        break;
-      }
+    SkImageInfo image_info =
+        CreateImageInfoForDrawImage(draw_image, image_data->mip_level);
+    SkPixmap pixmap(image_info, backing_memory->data(),
+                    image_info.minRowBytes());
+    if (!DrawAndScaleImage(draw_image, &pixmap)) {
+      DLOG(ERROR) << "DrawAndScaleImage failed.";
+      backing_memory->Unlock();
+      backing_memory.reset();
+    } else {
+      image =
+          SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr);
     }
   }
 
   if (image_data->decode.data()) {
+    DCHECK(image_data->decode.image());
     // An at-raster task decoded this before us. Ingore our decode.
     return;
   }
 
   if (!backing_memory) {
+    DCHECK(!image);
     // If |backing_memory| was not populated, we had a non-decodable image.
     image_data->decode.decode_failure = true;
     return;
   }
 
-  image_data->decode.SetLockedData(std::move(backing_memory),
+  image_data->decode.SetLockedData(std::move(backing_memory), std::move(image),
                                    task_type == TaskType::kOutOfRaster);
 }
 
@@ -1285,34 +1310,26 @@
   DCHECK_GT(image_data->decode.ref_count, 0u);
   DCHECK_GT(image_data->upload.ref_count, 0u);
 
-  sk_sp<SkImage> uploaded_image;
-  {
+  sk_sp<SkImage> uploaded_image = image_data->decode.image();
+  if (image_data->mode == DecodedDataMode::GPU) {
     base::AutoUnlock unlock(lock_);
-    switch (image_data->mode) {
-      case DecodedDataMode::CPU: {
-        SkImageInfo image_info = CreateImageInfoForDrawImage(
-            draw_image, image_data->upload_params.fPreScaleMipLevel);
-        SkPixmap pixmap(image_info, image_data->decode.data()->data(),
-                        image_info.minRowBytes());
-        uploaded_image =
-            SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr);
-        break;
-      }
-      case DecodedDataMode::GPU: {
-        uploaded_image = SkImage::MakeFromDeferredTextureImageData(
-            context_->GrContext(), image_data->decode.data()->data(),
-            SkBudgeted::kNo);
-        break;
-      }
-    }
+    uploaded_image =
+        uploaded_image->makeTextureImage(context_->GrContext(), nullptr);
   }
   image_data->decode.mark_used();
 
-  if (uploaded_image && draw_image.target_color_space().IsValid()) {
+  if (uploaded_image && SupportsColorSpaces() &&
+      draw_image.target_color_space().IsValid()) {
     TRACE_EVENT0("cc", "GpuImageDecodeCache::UploadImage - color conversion");
+    sk_sp<SkImage> pre_converted_image = uploaded_image;
     uploaded_image = uploaded_image->makeColorSpace(
         draw_image.target_color_space().ToSkColorSpace(),
         SkTransferFunctionBehavior::kIgnore);
+
+    // If we created a new image while converting colorspace, we should destroy
+    // the previous image without caching it.
+    if (uploaded_image != pre_converted_image)
+      DeleteSkImageAndPreventCaching(context_, std::move(pre_converted_image));
   }
 
   // At-raster may have decoded this while we were unlocked. If so, ignore our
@@ -1349,30 +1366,22 @@
                "GpuImageDecodeCache::CreateImageData");
   lock_.AssertAcquired();
 
-  DecodedDataMode mode;
-  int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image);
-  // TODO(ericrk): Remove the matrix parameter in this call.
-  auto params = SkImage::DeferredTextureImageUsageParams(
-      SkMatrix::I(), CalculateDesiredFilterQuality(draw_image),
-      upload_scale_mip_level);
-  sk_sp<SkImage> image =
-      draw_image.paint_image().GetSkImageForFrame(draw_image.frame_index());
-  size_t data_size = image->getDeferredTextureImageData(
-      *context_threadsafe_proxy_.get(), &params, 1, nullptr, nullptr,
-      color_type_);
+  int mip_level = CalculateUploadScaleMipLevel(draw_image);
+  SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image, mip_level);
 
-  if (data_size == 0) {
-    // Can't upload image, too large or other failure. Try to use SW fallback.
-    SkImageInfo image_info =
-        CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level);
-    data_size = image_info.computeMinByteSize();
+  DecodedDataMode mode;
+  if (image_info.width() > max_texture_size_ ||
+      image_info.height() > max_texture_size_) {
+    // Image too large to upload. Try to use SW fallback.
     mode = DecodedDataMode::CPU;
   } else {
     mode = DecodedDataMode::GPU;
   }
 
-  return base::MakeRefCounted<ImageData>(
-      mode, data_size, draw_image.target_color_space(), params);
+  size_t data_size = image_info.computeMinByteSize();
+  return base::WrapRefCounted(
+      new ImageData(mode, data_size, draw_image.target_color_space(),
+                    CalculateDesiredFilterQuality(draw_image), mip_level));
 }
 
 void GpuImageDecodeCache::DeleteImage(ImageData* image_data) {
@@ -1430,7 +1439,7 @@
       CalculateSizeForMipLevel(draw_image, upload_scale_mip_level);
   return SkImageInfo::Make(mip_size.width(), mip_size.height(), color_type_,
                            kPremul_SkAlphaType,
-                           draw_image.target_color_space().ToSkColorSpace());
+                           sk_ref_sp(draw_image.paint_image().color_space()));
 }
 
 bool GpuImageDecodeCache::TryLockImage(HaveContextLock have_context_lock,
@@ -1503,11 +1512,11 @@
 // the provided |draw_image|.
 bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
                                        const DrawImage& draw_image) const {
-  bool is_scaled = image_data->upload_params.fPreScaleMipLevel != 0;
-  bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >=
-                             image_data->upload_params.fPreScaleMipLevel;
-  bool quality_is_compatible = CalculateDesiredFilterQuality(draw_image) <=
-                               image_data->upload_params.fQuality;
+  bool is_scaled = image_data->mip_level != 0;
+  bool scale_is_compatible =
+      CalculateUploadScaleMipLevel(draw_image) >= image_data->mip_level;
+  bool quality_is_compatible =
+      CalculateDesiredFilterQuality(draw_image) <= image_data->quality;
   bool color_is_compatible =
       image_data->target_color_space == draw_image.target_color_space();
   if (!color_is_compatible)
@@ -1559,4 +1568,16 @@
   EnsureCapacity(0);
 }
 
+bool GpuImageDecodeCache::SupportsColorSpaces() const {
+  lock_.AssertAcquired();
+  switch (color_type_) {
+    case kRGBA_8888_SkColorType:
+    case kBGRA_8888_SkColorType:
+    case kRGBA_F16_SkColorType:
+      return true;
+    default:
+      return false;
+  }
+}
+
 }  // namespace cc
diff --git a/cc/tiles/gpu_image_decode_cache.h b/cc/tiles/gpu_image_decode_cache.h
index d1f51a4..17c643e 100644
--- a/cc/tiles/gpu_image_decode_cache.h
+++ b/cc/tiles/gpu_image_decode_cache.h
@@ -203,9 +203,14 @@
     void Unlock();
 
     void SetLockedData(std::unique_ptr<base::DiscardableMemory> data,
+                       sk_sp<SkImage> image,
                        bool out_of_raster);
     void ResetData();
     base::DiscardableMemory* data() const { return data_.get(); }
+    sk_sp<SkImage> image() const {
+      DCHECK(is_locked());
+      return image_;
+    }
 
     bool decode_failure = false;
     // Similar to |task|, but only is generated if there is no associated upload
@@ -216,6 +221,7 @@
     void ReportUsageStats() const;
 
     std::unique_ptr<base::DiscardableMemory> data_;
+    sk_sp<SkImage> image_;
   };
 
   // Stores the GPU-side image and supporting fields.
@@ -243,13 +249,15 @@
     ImageData(DecodedDataMode mode,
               size_t size,
               const gfx::ColorSpace& target_color_space,
-              const SkImage::DeferredTextureImageUsageParams& upload_params);
+              SkFilterQuality quality,
+              int mip_level);
 
     const DecodedDataMode mode;
     const size_t size;
     gfx::ColorSpace target_color_space;
+    SkFilterQuality quality;
+    int mip_level;
     bool is_at_raster = false;
-    SkImage::DeferredTextureImageUsageParams upload_params;
 
     // If true, this image is no longer in our |persistent_cache_| and will be
     // deleted as soon as its ref count reaches zero.
@@ -371,9 +379,11 @@
   // These including deleting, unlocking, and locking textures.
   void RunPendingContextThreadOperations();
 
+  bool SupportsColorSpaces() const;
+
   const SkColorType color_type_;
   viz::RasterContextProvider* context_;
-  sk_sp<GrContextThreadSafeProxy> context_threadsafe_proxy_;
+  int max_texture_size_ = 0;
 
   // All members below this point must only be accessed while holding |lock_|.
   // The exception are const members like |normal_max_cache_bytes_| that can
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index aa3ba6aa..3a3993ab 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -747,7 +747,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -779,7 +778,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_TRUE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -812,7 +810,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -855,14 +852,12 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   DecodedDrawImage larger_decoded_draw_image =
       cache->GetDecodedImageForDraw(larger_draw_image);
   EXPECT_TRUE(larger_decoded_draw_image.image());
   EXPECT_TRUE(larger_decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(larger_decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   EXPECT_FALSE(decoded_draw_image.image() == larger_decoded_draw_image.image());
@@ -909,14 +904,12 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   DecodedDrawImage larger_decoded_draw_image =
       cache->GetDecodedImageForDraw(higher_quality_draw_image);
   EXPECT_TRUE(larger_decoded_draw_image.image());
   EXPECT_TRUE(larger_decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(larger_decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   EXPECT_FALSE(decoded_draw_image.image() == larger_decoded_draw_image.image());
@@ -955,7 +948,6 @@
   EXPECT_EQ(decoded_draw_image.image()->width(), 50);
   EXPECT_EQ(decoded_draw_image.image()->height(), 50);
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -991,7 +983,6 @@
   EXPECT_EQ(24000, decoded_draw_image.image()->height());
   EXPECT_EQ(decoded_draw_image.filter_quality(), kMedium_SkFilterQuality);
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
   EXPECT_TRUE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -1024,7 +1015,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->SetWorkingSetLimitForTesting(96 * 1024 * 1024);
@@ -1061,7 +1051,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
   EXPECT_FALSE(cache->DiscardableIsLockedForTesting(draw_image));
 
   DecodedDrawImage another_decoded_draw_image =
@@ -1092,7 +1081,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(decoded_draw_image.image());
   EXPECT_FALSE(decoded_draw_image.image()->isTextureBacked());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
   EXPECT_TRUE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, decoded_draw_image);
@@ -1102,7 +1090,6 @@
       cache->GetDecodedImageForDraw(draw_image);
   EXPECT_TRUE(second_decoded_draw_image.image());
   EXPECT_FALSE(second_decoded_draw_image.image()->isTextureBacked());
-  EXPECT_TRUE(second_decoded_draw_image.is_at_raster_decode());
   EXPECT_TRUE(cache->DiscardableIsLockedForTesting(draw_image));
 
   cache->DrawWithImageFinished(draw_image, second_decoded_draw_image);
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc
index ca7657c..6c5df401 100644
--- a/cc/tiles/software_image_decode_cache.cc
+++ b/cc/tiles/software_image_decode_cache.cc
@@ -625,7 +625,6 @@
   auto decoded_draw_image =
       DecodedDrawImage(cache_entry->image(), cache_entry->src_rect_offset(),
                        GetScaleAdjustment(key), GetDecodedFilterQuality(key));
-  decoded_draw_image.set_at_raster_decode(!cache_entry->is_budgeted);
   return decoded_draw_image;
 }
 
diff --git a/cc/tiles/software_image_decode_cache_unittest.cc b/cc/tiles/software_image_decode_cache_unittest.cc
index 6577930..5508946b 100644
--- a/cc/tiles/software_image_decode_cache_unittest.cc
+++ b/cc/tiles/software_image_decode_cache_unittest.cc
@@ -1007,7 +1007,6 @@
   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
   EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
 
   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
   cache.UnrefImage(draw_image);
@@ -1041,7 +1040,6 @@
   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
   EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
-  EXPECT_FALSE(decoded_draw_image.is_at_raster_decode());
 
   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
   cache.UnrefImage(draw_image);
@@ -1067,7 +1065,6 @@
   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
   EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
 
   cache.DrawWithImageFinished(draw_image, decoded_draw_image);
 }
@@ -1093,7 +1090,6 @@
   EXPECT_FLOAT_EQ(0.5f, decoded_draw_image.scale_adjustment().height());
   EXPECT_EQ(kLow_SkFilterQuality, decoded_draw_image.filter_quality());
   EXPECT_FALSE(decoded_draw_image.is_scale_adjustment_identity());
-  EXPECT_TRUE(decoded_draw_image.is_at_raster_decode());
 
   DecodedDrawImage another_decoded_draw_image =
       cache.GetDecodedImageForDraw(draw_image);
diff --git a/cc/tiles/software_image_decode_cache_unittest_combinations.cc b/cc/tiles/software_image_decode_cache_unittest_combinations.cc
index 9dca164..29443de5 100644
--- a/cc/tiles/software_image_decode_cache_unittest_combinations.cc
+++ b/cc/tiles/software_image_decode_cache_unittest_combinations.cc
@@ -104,7 +104,6 @@
     SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
     EXPECT_EQ(decoded.image()->width(), expected_size.width());
     EXPECT_EQ(decoded.image()->height(), expected_size.height());
-    EXPECT_TRUE(decoded.is_at_raster_decode());
     cache().DrawWithImageFinished(draw_image, decoded);
   }
 };
@@ -128,7 +127,6 @@
     SCOPED_TRACE(base::StringPrintf("Failure from line %d", line));
     EXPECT_EQ(decoded.image()->width(), expected_size.width());
     EXPECT_EQ(decoded.image()->height(), expected_size.height());
-    EXPECT_FALSE(decoded.is_at_raster_decode());
     cache().DrawWithImageFinished(draw_image, decoded);
   }
 };
diff --git a/chrome/VERSION b/chrome/VERSION
index fc4a00c..d20c7af6 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=65
 MINOR=0
-BUILD=3310
+BUILD=3311
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index d2cc3e2..060215d2 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -519,7 +519,6 @@
     "//components/policy/android:policy_java",
     "//components/policy/android:policy_java_test_support",
     "//components/signin/core/browser/android:java",
-    "//components/signin/core/browser/android:javatests",
     "//components/signin/core/browser/android:signin_java_test_support",
     "//components/sync:sync_java_test_support",
     "//components/sync/android:sync_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
index 20111de..ee56d68a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -396,7 +396,7 @@
             mWereInfoBarsHidden = false;
             InfoBarContainer container = getInfoBarContainer();
             if (container != null) {
-                container.setIsObscuredByOtherView(false);
+                container.setHidden(false);
             }
         }
 
@@ -448,7 +448,7 @@
             InfoBarContainer container = getInfoBarContainer();
             if (container != null && container.getVisibility() == View.VISIBLE) {
                 mWereInfoBarsHidden = true;
-                container.setIsObscuredByOtherView(true);
+                container.setHidden(true);
             }
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
index c64240a..90084b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
@@ -114,7 +114,7 @@
                 boolean isFragmentNavigation, Integer pageTransition, int errorCode,
                 int httpStatusCode) {
             if (hasCommitted && isInMainFrame) {
-                setIsObscuredByOtherView(false);
+                setHidden(false);
             }
         }
 
@@ -171,8 +171,8 @@
     /** The view that {@link Tab#getView()} returns. */
     private View mTabView;
 
-    /** Whether or not another View is occupying the same space as this one. */
-    private boolean mIsObscured;
+    /** Whether or not this View should be hidden. */
+    private boolean mIsHidden;
 
     /** Animation used to snap the container to the nearest state if scroll direction changes. */
     private Animator mScrollDirectionChangeAnimation;
@@ -413,15 +413,13 @@
     }
 
     /**
-     * Tells this class that a View with higher priority is occupying the same space.
+     * Hides or stops hiding this View/
      *
-     * Causes this View to hide itself until the obscuring View goes away.
-     *
-     * @param isObscured Whether this View is obscured by another one.
+     * @param isHidden Whether this View is should be hidden.
      */
-    public void setIsObscuredByOtherView(boolean isObscured) {
-        mIsObscured = isObscured;
-        if (isObscured) {
+    public void setHidden(boolean isHidden) {
+        mIsHidden = isHidden;
+        if (isHidden) {
             setVisibility(View.GONE);
         } else {
             setVisibility(View.VISIBLE);
@@ -445,7 +443,7 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        if (!mIsObscured) {
+        if (!mIsHidden) {
             setVisibility(VISIBLE);
             setAlpha(0f);
             animate().alpha(1f).setDuration(REATTACH_FADE_IN_MS);
@@ -481,7 +479,7 @@
                 setVisibility(View.INVISIBLE);
             }
         } else {
-            if (!isShowing && !mIsObscured) {
+            if (!isShowing && !mIsHidden) {
                 setVisibility(View.VISIBLE);
             }
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java
index 75aebde..3ca1c285 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/PictureInPictureController.java
@@ -185,10 +185,14 @@
 
         webContents.setHasPersistentVideo(true);
 
+        // We don't want InfoBars displaying while in PiP, they cover too much content.
+        activity.getActivityTab().getInfoBarContainer().setHidden(true);
+
         mOnLeavePipCallbacks.add(new Callback<ChromeActivity>() {
             @Override
             public void onResult(ChromeActivity activity2) {
                 webContents.setHasPersistentVideo(false);
+                activity.getActivityTab().getInfoBarContainer().setHidden(false);
             }
         });
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index de7df88..2561ffc 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -37,7 +37,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/features.h"
-#include "chrome/common/pause_tabs_field_trial.h"
 #include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/autofill_switches.h"
@@ -69,6 +68,7 @@
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/payments/core/features.h"
 #include "components/previews/core/previews_features.h"
+#include "components/previews/core/previews_switches.h"
 #include "components/proximity_auth/switches.h"
 #include "components/search_provider_logos/features.h"
 #include "components/search_provider_logos/switches.h"
@@ -84,7 +84,6 @@
 #include "components/suggestions/features.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/tracing/common/tracing_switches.h"
-#include "components/translate/core/browser/translate_infobar_delegate.h"
 #include "components/translate/core/browser/translate_prefs.h"
 #include "components/translate/core/browser/translate_ranker_impl.h"
 #include "components/version_info/version_info.h"
@@ -874,35 +873,6 @@
         {"Learning", kSpeculativeResourcePrefetchingLearning,
          arraysize(kSpeculativeResourcePrefetchingLearning), nullptr}};
 
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-const FeatureEntry::FeatureParam kPauseBackgroundTabsMinimalEngagment[] = {
-    {pausetabs::kFeatureName, pausetabs::kModeParamMinimal}};
-
-const FeatureEntry::FeatureParam kPauseBackgroundTabsLowEngagment[] = {
-    {pausetabs::kFeatureName, pausetabs::kModeParamLow}};
-
-const FeatureEntry::FeatureParam kPauseBackgroundTabsMediumEngagment[] = {
-    {pausetabs::kFeatureName, pausetabs::kModeParamMedium}};
-
-const FeatureEntry::FeatureParam kPauseBackgroundTabsHighEngagment[] = {
-    {pausetabs::kFeatureName, pausetabs::kModeParamHigh}};
-
-const FeatureEntry::FeatureParam kPauseBackgroundTabsMaxEngagment[] = {
-    {pausetabs::kFeatureName, pausetabs::kModeParamMax}};
-
-const FeatureEntry::FeatureVariation kPauseBackgroundTabsVariations[] = {
-    {"minimal engagement", kPauseBackgroundTabsMinimalEngagment,
-     arraysize(kPauseBackgroundTabsMinimalEngagment), nullptr},
-    {"low engagement", kPauseBackgroundTabsLowEngagment,
-     arraysize(kPauseBackgroundTabsLowEngagment), nullptr},
-    {"medium engagement", kPauseBackgroundTabsMediumEngagment,
-     arraysize(kPauseBackgroundTabsMediumEngagment), nullptr},
-    {"high engagement", kPauseBackgroundTabsHighEngagment,
-     arraysize(kPauseBackgroundTabsHighEngagment), nullptr},
-    {"max engagement", kPauseBackgroundTabsMaxEngagment,
-     arraysize(kPauseBackgroundTabsMaxEngagment), nullptr}};
-#endif
-
 #if defined(OS_ANDROID)
 const FeatureEntry::FeatureParam
     kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart[] = {
@@ -1833,9 +1803,6 @@
      flag_descriptions::kPullToRefreshEffectName,
      flag_descriptions::kPullToRefreshEffectDescription, kOsAndroid,
      SINGLE_DISABLE_VALUE_TYPE(switches::kDisablePullToRefreshEffect)},
-    {"translate-compact-infobar", flag_descriptions::kTranslateCompactUIName,
-     flag_descriptions::kTranslateCompactUIDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(translate::kTranslateCompactUI)},
 #endif  // OS_ANDROID
 #if defined(OS_MACOSX)
     {"enable-translate-new-ux", flag_descriptions::kTranslateNewUxName,
@@ -2071,6 +2038,10 @@
      flag_descriptions::kDataSaverServerPreviewsDescription, kOsAll,
      FEATURE_VALUE_TYPE(
          data_reduction_proxy::features::kDataReductionProxyDecidesTransform)},
+    {"ignore-previews-blacklist",
+     flag_descriptions::kIgnorePreviewsBlacklistName,
+     flag_descriptions::kIgnorePreviewsBlacklistDescription, kOsAll,
+     SINGLE_VALUE_TYPE(previews::switches::kIgnorePreviewsBlacklist)},
     {"enable-data-reduction-proxy-server-experiment",
      flag_descriptions::kEnableDataReductionProxyServerExperimentName,
      flag_descriptions::kEnableDataReductionProxyServerExperimentDescription,
@@ -3093,14 +3064,6 @@
      FEATURE_VALUE_TYPE(chrome::android::kCustomContextMenu)},
 #endif  // OS_ANDROID
 
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-    {pausetabs::kFeatureName, flag_descriptions::kPauseBackgroundTabsName,
-     flag_descriptions::kPauseBackgroundTabsDescription, kOsDesktop,
-     FEATURE_WITH_PARAMS_VALUE_TYPE(pausetabs::kFeature,
-                                    kPauseBackgroundTabsVariations,
-                                    "PauseBackgroundTabs")},
-#endif
-
 #if defined(OS_CHROMEOS)
     {"ash-disable-smooth-screen-rotation",
      flag_descriptions::kAshDisableSmoothScreenRotationName,
@@ -3587,6 +3550,10 @@
      flag_descriptions::kStopLoadingInBackgroundDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(features::kStopLoadingInBackground)},
 
+    {"stop-in-background", flag_descriptions::kStopInBackgroundName,
+     flag_descriptions::kStopInBackgroundDescription, kOsAll,
+     FEATURE_VALUE_TYPE(features::kStopInBackground)},
+
 #if defined(TOOLKIT_VIEWS)
     {"experimental-tab-controller",
      flag_descriptions::kExperimentalTabControllerName,
diff --git a/chrome/browser/apps/app_browsertest_util.h b/chrome/browser/apps/app_browsertest_util.h
index c0a1bff..2126fc1 100644
--- a/chrome/browser/apps/app_browsertest_util.h
+++ b/chrome/browser/apps/app_browsertest_util.h
@@ -14,7 +14,7 @@
 #include "extensions/browser/app_window/app_window.h"
 
 #if defined(OS_CHROMEOS)
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #endif
 
 namespace base {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index afab552..490133c3 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -50,8 +50,8 @@
 #include "chrome/browser/language/chrome_language_detection_tab_helper.h"
 #include "chrome/browser/media/platform_verification_impl.h"
 #include "chrome/browser/media/router/media_router_feature.h"
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
-#include "chrome/browser/media/router/receiver_presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/memory/chrome_memory_coordinator_delegate.h"
 #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h"
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 9b829b7..35910c5 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -566,6 +566,9 @@
     "extensions/extension_volume_observer.h",
     "extensions/external_cache.cc",
     "extensions/external_cache.h",
+    "extensions/external_cache_delegate.h",
+    "extensions/external_cache_impl.cc",
+    "extensions/external_cache_impl.h",
     "extensions/gfx_utils.cc",
     "extensions/gfx_utils.h",
     "extensions/ime_menu_event_router.cc",
@@ -1665,6 +1668,8 @@
   testonly = true
 
   sources = [
+    "extensions/test_external_cache.cc",
+    "extensions/test_external_cache.h",
     "lock_screen_apps/fake_lock_screen_profile_creator.cc",
     "lock_screen_apps/fake_lock_screen_profile_creator.h",
     "login/enrollment/enterprise_enrollment_helper_mock.cc",
@@ -1777,7 +1782,7 @@
     "extensions/device_local_account_external_policy_loader_unittest.cc",
     "extensions/device_local_account_management_policy_provider_unittest.cc",
     "extensions/extension_tab_util_delegate_chromeos_unittest.cc",
-    "extensions/external_cache_unittest.cc",
+    "extensions/external_cache_impl_unittest.cc",
     "extensions/file_manager/device_event_router_unittest.cc",
     "extensions/file_manager/job_event_router_unittest.cc",
     "extensions/gfx_utils_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index fe783ef..4aaf2eb 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_app_external_loader.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_external_updater.h"
+#include "chrome/browser/chromeos/extensions/external_cache_impl.h"
 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -60,11 +61,18 @@
 namespace {
 
 // Domain that is used for kiosk-app account IDs.
-const char kKioskAppAccountDomain[] = "kiosk-apps";
+constexpr char kKioskAppAccountDomain[] = "kiosk-apps";
 
 // Preference for the dictionary of user ids for which cryptohomes have to be
 // removed upon browser restart.
-const char kKioskUsersToRemove[] = "kiosk-users-to-remove";
+constexpr char kKioskUsersToRemove[] = "kiosk-users-to-remove";
+
+// Sub directory under DIR_USER_DATA to store cached crx files.
+constexpr char kCrxCacheDir[] = "kiosk/crx";
+
+// Sub directory under DIR_USER_DATA to store unpacked crx file for validating
+// its signature.
+constexpr char kCrxUnpackDir[] = "kiosk_unpack";
 
 std::string GenerateKioskAppAccountId(const std::string& app_id) {
   return app_id + '@' + kKioskAppAccountDomain;
@@ -133,12 +141,34 @@
   *present = util.get() && util->IsPublicKeyPresent();
 }
 
+base::FilePath GetCrxCacheDir() {
+  base::FilePath user_data_dir;
+  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
+  return user_data_dir.AppendASCII(kCrxCacheDir);
+}
+
+base::FilePath GetCrxUnpackDir() {
+  base::FilePath temp_dir;
+  base::GetTempDir(&temp_dir);
+  return temp_dir.AppendASCII(kCrxUnpackDir);
+}
+
 scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner() {
   return base::CreateSequencedTaskRunnerWithTraits(
       {base::MayBlock(), base::TaskPriority::BACKGROUND,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
 }
 
+std::unique_ptr<ExternalCache> CreateExternalCache(
+    ExternalCacheDelegate* delegate) {
+  auto cache = std::make_unique<ExternalCacheImpl>(
+      GetCrxCacheDir(), g_browser_process->system_request_context(),
+      GetBackgroundTaskRunner(), delegate, true /* always_check_updates */,
+      false /* wait_for_cache_initialization */);
+  cache->set_flush_on_put(true);
+  return cache;
+}
+
 base::Version GetPlatformVersion() {
   int32_t major_version;
   int32_t minor_version;
@@ -163,8 +193,6 @@
 const char KioskAppManager::kKioskDictionaryName[] = "kiosk";
 const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state";
 const char KioskAppManager::kIconCacheDir[] = "kiosk/icon";
-const char KioskAppManager::kCrxCacheDir[] = "kiosk/crx";
-const char KioskAppManager::kCrxUnpackDir[] = "kiosk_unpack";
 
 // static
 static base::LazyInstance<KioskAppManager>::DestructorAtExit instance =
@@ -534,7 +562,7 @@
     const KioskAppData& app_data = *apps_[i];
     if (app_data.status() != KioskAppData::STATUS_ERROR) {
       apps->push_back(App(
-          app_data, external_cache_->IsExtensionPending(app_data.app_id()),
+          app_data, external_cache_->ExtensionFetchPending(app_data.app_id()),
           app_data.app_id() == currently_auto_launched_with_zero_delay_app_));
     }
   }
@@ -545,7 +573,7 @@
   if (!data)
     return false;
 
-  *app = App(*data, external_cache_->IsExtensionPending(app_id),
+  *app = App(*data, external_cache_->ExtensionFetchPending(app_id),
              app_id == currently_auto_launched_with_zero_delay_app_);
   return true;
 }
@@ -633,7 +661,7 @@
 
 void KioskAppManager::InstallFromCache(const std::string& id) {
   const base::DictionaryValue* extension = nullptr;
-  if (external_cache_->cached_extensions()->GetDictionary(id, &extension)) {
+  if (external_cache_->GetCachedExtensions()->GetDictionary(id, &extension)) {
     std::unique_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
     prefs->Set(id, extension->CreateDeepCopy());
     external_loader_->SetCurrentAppExtensions(std::move(prefs));
@@ -677,8 +705,9 @@
     const std::string& app_id,
     const base::FilePath& crx_path,
     const std::string& version,
-    const ExternalCache::PutExternalExtensionCallback& callback) {
-  external_cache_->PutExternalExtension(app_id, crx_path, version, callback);
+    ExternalCache::PutExternalExtensionCallback callback) {
+  external_cache_->PutExternalExtension(app_id, crx_path, version,
+                                        std::move(callback));
 }
 
 bool KioskAppManager::IsPlatformCompliant(
@@ -731,16 +760,8 @@
     : ownership_established_(false),
       external_loader_created_(false),
       secondary_app_external_loader_created_(false) {
-  base::FilePath cache_dir;
-  GetCrxCacheDir(&cache_dir);
-  external_cache_.reset(
-      new ExternalCache(cache_dir,
-                        g_browser_process->system_request_context(),
-                        GetBackgroundTaskRunner(),
-                        this,
-                        true /* always_check_updates */,
-                        false /* wait_for_cache_initialization */));
-  external_cache_->set_flush_on_put(true);
+  external_cache_ = CreateExternalCache(this);
+
   UpdateAppData();
   local_accounts_subscription_ =
       CrosSettings::Get()->AddSettingsObserver(
@@ -755,12 +776,8 @@
 KioskAppManager::~KioskAppManager() {}
 
 void KioskAppManager::MonitorKioskExternalUpdate() {
-  base::FilePath cache_dir;
-  GetCrxCacheDir(&cache_dir);
-  base::FilePath unpack_dir;
-  GetCrxUnpackDir(&unpack_dir);
-  usb_stick_updater_.reset(new KioskExternalUpdater(
-      GetBackgroundTaskRunner(), cache_dir, unpack_dir));
+  usb_stick_updater_ = std::make_unique<KioskExternalUpdater>(
+      GetBackgroundTaskRunner(), GetCrxCacheDir(), GetCrxUnpackDir());
 }
 
 void KioskAppManager::CleanUp() {
@@ -921,9 +938,7 @@
     observer.OnKioskExtensionLoadedInCache(id);
 }
 
-void KioskAppManager::OnExtensionDownloadFailed(
-    const std::string& id,
-    extensions::ExtensionDownloaderDelegate::Error error) {
+void KioskAppManager::OnExtensionDownloadFailed(const std::string& id) {
   KioskAppData* app_data = GetAppDataMutable(id);
   if (!app_data)
     return;
@@ -931,6 +946,11 @@
     observer.OnKioskExtensionDownloadFailed(id);
 }
 
+std::string KioskAppManager::GetInstalledExtensionVersion(
+    const std::string& id) {
+  return std::string();
+}
+
 KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const {
   PrefService* prefs = g_browser_process->local_state();
   const base::DictionaryValue* dict =
@@ -950,18 +970,6 @@
   prefs->CommitPendingWrite();
 }
 
-void KioskAppManager::GetCrxCacheDir(base::FilePath* cache_dir) {
-  base::FilePath user_data_dir;
-  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
-  *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir);
-}
-
-void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) {
-  base::FilePath temp_dir;
-  base::GetTempDir(&temp_dir);
-  *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir);
-}
-
 base::TimeDelta KioskAppManager::GetAutoLaunchDelay() const {
   int delay;
   if (!CrosSettings::Get()->GetInteger(
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index d15455f9..2fc5b2e 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h"
 #include "chrome/browser/chromeos/extensions/external_cache.h"
+#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/install_attributes.h"
 #include "components/signin/core/account_id/account_id.h"
@@ -46,7 +47,7 @@
 
 // KioskAppManager manages cached app data.
 class KioskAppManager : public KioskAppDataDelegate,
-                        public ExternalCache::Delegate {
+                        public ExternalCacheDelegate {
  public:
   enum ConsumerKioskAutoLaunchStatus {
     // Consumer kiosk mode auto-launch feature can be enabled on this machine.
@@ -92,13 +93,6 @@
   // Sub directory under DIR_USER_DATA to store cached icon files.
   static const char kIconCacheDir[];
 
-  // Sub directory under DIR_USER_DATA to store cached crx files.
-  static const char kCrxCacheDir[];
-
-  // Sub directory under DIR_USER_DATA to store unpacked crx file for validating
-  // its signature.
-  static const char kCrxUnpackDir[];
-
   // Gets the KioskAppManager instance, which is lazily created on first call..
   static KioskAppManager* Get();
 
@@ -218,7 +212,7 @@
       const std::string& app_id,
       const base::FilePath& crx_path,
       const std::string& version,
-      const ExternalCache::PutExternalExtensionCallback& callback);
+      ExternalCache::PutExternalExtensionCallback callback);
 
   // Whether the current platform is compliant with the given required
   // platform version.
@@ -288,12 +282,11 @@
   void OnKioskAppDataChanged(const std::string& app_id) override;
   void OnKioskAppDataLoadFailure(const std::string& app_id) override;
 
-  // ExternalCache::Delegate:
+  // ExternalCacheDelegate:
   void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override;
   void OnExtensionLoadedInCache(const std::string& id) override;
-  void OnExtensionDownloadFailed(
-      const std::string& id,
-      extensions::ExtensionDownloaderDelegate::Error error) override;
+  void OnExtensionDownloadFailed(const std::string& id) override;
+  std::string GetInstalledExtensionVersion(const std::string& id) override;
 
   // Callback for InstallAttributes::LockDevice() during
   // EnableConsumerModeKiosk() call.
@@ -314,9 +307,6 @@
   AutoLoginState GetAutoLoginState() const;
   void SetAutoLoginState(AutoLoginState state);
 
-  void GetCrxCacheDir(base::FilePath* cache_dir);
-  void GetCrxUnpackDir(base::FilePath* unpack_dir);
-
   // Returns the auto launch delay.
   base::TimeDelta GetAutoLaunchDelay() const;
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
index 38f4e4c..f9d8202 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -592,8 +592,8 @@
   ExternalCachePutWaiter put_waiter;
   manager()->PutValidatedExternalExtension(
       kAppId, crx_file, "2.0.0",
-      base::Bind(&ExternalCachePutWaiter::OnPutExtension,
-                 base::Unretained(&put_waiter)));
+      base::BindOnce(&ExternalCachePutWaiter::OnPutExtension,
+                     base::Unretained(&put_waiter)));
   put_waiter.Wait();
   ASSERT_TRUE(put_waiter.success());
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
index 156f504..68a34e79 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -398,8 +398,8 @@
 
   KioskAppManager::Get()->PutValidatedExternalExtension(
       app_id, crx_file, version,
-      base::Bind(&KioskExternalUpdater::OnPutValidatedExtension,
-                 weak_factory_.GetWeakPtr()));
+      base::BindOnce(&KioskExternalUpdater::OnPutValidatedExtension,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void KioskExternalUpdater::OnPutValidatedExtension(const std::string& app_id,
diff --git a/chrome/browser/chromeos/background/ash_wallpaper_delegate.cc b/chrome/browser/chromeos/background/ash_wallpaper_delegate.cc
index b9ae058..4a12ae0 100644
--- a/chrome/browser/chromeos/background/ash_wallpaper_delegate.cc
+++ b/chrome/browser/chromeos/background/ash_wallpaper_delegate.cc
@@ -78,10 +78,6 @@
     return true;
   }
 
-  void UpdateWallpaper(bool clear_cache) override {
-    chromeos::WallpaperManager::Get()->UpdateWallpaper(clear_cache);
-  }
-
   void InitializeWallpaper() override {
     chromeos::WallpaperManager::Get()->InitializeWallpaper();
   }
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
index 71be9b2..eb78793 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
+++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.cc
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/extensions/external_cache_impl.h"
 #include "chrome/browser/extensions/policy_handlers.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/prefs/pref_value_map.h"
@@ -33,22 +34,19 @@
     const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner) {
   DCHECK(!external_cache_);
   store_->AddObserver(this);
-  external_cache_.reset(new ExternalCache(
-      cache_dir_,
-      g_browser_process->system_request_context(),
-      cache_task_runner,
-      this,
-      true  /* always_check_updates */,
-      false  /* wait_for_cache_initialization */));
+  external_cache_ = std::make_unique<ExternalCacheImpl>(
+      cache_dir_, g_browser_process->system_request_context(),
+      cache_task_runner, this, true /* always_check_updates */,
+      false /* wait_for_cache_initialization */);
 
   if (store_->is_initialized())
     UpdateExtensionListFromStore();
 }
 
 void DeviceLocalAccountExternalPolicyLoader::StopCache(
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   if (external_cache_) {
-    external_cache_->Shutdown(callback);
+    external_cache_->Shutdown(std::move(callback));
     external_cache_.reset();
     store_->RemoveObserver(this);
   }
@@ -89,6 +87,18 @@
     LoadFinished(std::move(prefs_));
 }
 
+void DeviceLocalAccountExternalPolicyLoader::OnExtensionLoadedInCache(
+    const std::string& id) {}
+
+void DeviceLocalAccountExternalPolicyLoader::OnExtensionDownloadFailed(
+    const std::string& id) {}
+
+std::string
+DeviceLocalAccountExternalPolicyLoader::GetInstalledExtensionVersion(
+    const std::string& id) {
+  return std::string();
+}
+
 ExternalCache*
 DeviceLocalAccountExternalPolicyLoader::GetExternalCacheForTesting() {
   return external_cache_.get();
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h
index 342bc704..23ff108 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h
+++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_DEVICE_LOCAL_ACCOUNT_EXTERNAL_POLICY_LOADER_H_
 
 #include <memory>
+#include <string>
 
 #include "base/callback_forward.h"
 #include "base/compiler_specific.h"
@@ -13,12 +14,14 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner.h"
-#include "chrome/browser/chromeos/extensions/external_cache.h"
+#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
 #include "chrome/browser/extensions/external_loader.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
 
 namespace chromeos {
 
+class ExternalCache;
+
 // A specialization of the ExternalLoader that serves external extensions from
 // the enterprise policy force-install list. This class is used for device-local
 // accounts in place of the ExternalPolicyLoader. The difference is that while
@@ -27,7 +30,7 @@
 class DeviceLocalAccountExternalPolicyLoader
     : public extensions::ExternalLoader,
       public policy::CloudPolicyStore::Observer,
-      public ExternalCache::Delegate {
+      public ExternalCacheDelegate {
  public:
   // The list of force-installed extensions will be read from |store| and the
   // extensions will be cached in the |cache_dir_|.
@@ -46,7 +49,7 @@
 
   // Stop the cache. The |callback| will be invoked when the cache has shut down
   // completely and write access to the |cache_dir_| is permitted again.
-  void StopCache(const base::Closure& callback);
+  void StopCache(base::OnceClosure callback);
 
   // extensions::ExternalLoader:
   void StartLoading() override;
@@ -55,8 +58,11 @@
   void OnStoreLoaded(policy::CloudPolicyStore* store) override;
   void OnStoreError(policy::CloudPolicyStore* store) override;
 
-  // ExternalCache::Delegate:
+  // ExternalCacheDelegate:
   void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override;
+  void OnExtensionLoadedInCache(const std::string& id) override;
+  void OnExtensionDownloadFailed(const std::string& id) override;
+  std::string GetInstalledExtensionVersion(const std::string& id) override;
 
   ExternalCache* GetExternalCacheForTesting();
 
diff --git a/chrome/browser/chromeos/extensions/external_cache.cc b/chrome/browser/chromeos/extensions/external_cache.cc
index cef9a02..badc8ff 100644
--- a/chrome/browser/chromeos/extensions/external_cache.cc
+++ b/chrome/browser/chromeos/extensions/external_cache.cc
@@ -1,378 +1,84 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "chrome/browser/chromeos/extensions/external_cache.h"
 
-#include <stddef.h>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_util.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
 #include "base/values.h"
-#include "base/version.h"
-#include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/external_provider_impl.h"
-#include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "extensions/browser/notification_types.h"
-#include "extensions/browser/updater/extension_downloader.h"
-#include "extensions/common/extension.h"
-#include "content/public/common/service_manager_connection.h"
 #include "extensions/common/extension_urls.h"
-#include "net/url_request/url_request_context_getter.h"
 
 namespace chromeos {
 
-namespace {
+// static
+GURL ExternalCache::GetExtensionUpdateUrl(const base::Value& extension_value,
+                                          bool always_checking_for_updates) {
+  DCHECK(extension_value.is_dict());
 
-void FlushFile(const base::FilePath& path) {
-  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
-  file.Flush();
-  file.Close();
-}
+  const base::Value* keep_if_present_value = extension_value.FindKeyOfType(
+      extensions::ExternalProviderImpl::kKeepIfPresent,
+      base::Value::Type::BOOLEAN);
 
-}  // namespace
+  // "keep if present" means that the extension should be kept if it's already
+  // present, but it should not be added to extesions system.
+  if (keep_if_present_value && keep_if_present_value->GetBool())
+    return GURL();
 
-ExternalCache::ExternalCache(const base::FilePath& cache_dir,
-                             net::URLRequestContextGetter* request_context,
-                             const scoped_refptr<base::SequencedTaskRunner>&
-                                 backend_task_runner,
-                             Delegate* delegate,
-                             bool always_check_updates,
-                             bool wait_for_cache_initialization)
-    : local_cache_(cache_dir, 0, base::TimeDelta(), backend_task_runner),
-      request_context_(request_context),
-      backend_task_runner_(backend_task_runner),
-      delegate_(delegate),
-      always_check_updates_(always_check_updates),
-      wait_for_cache_initialization_(wait_for_cache_initialization),
-      cached_extensions_(new base::DictionaryValue()),
-      weak_ptr_factory_(this) {
-  notification_registrar_.Add(
-      this,
-      extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
-      content::NotificationService::AllBrowserContextsAndSources());
-}
+  const base::Value* external_update_url_value = extension_value.FindKeyOfType(
+      extensions::ExternalProviderImpl::kExternalUpdateUrl,
+      base::Value::Type::STRING);
 
-ExternalCache::~ExternalCache() {
-}
-
-void ExternalCache::Shutdown(const base::Closure& callback) {
-  local_cache_.Shutdown(callback);
-}
-
-void ExternalCache::UpdateExtensionsList(
-    std::unique_ptr<base::DictionaryValue> prefs) {
-  extensions_ = std::move(prefs);
-
-  if (extensions_->empty()) {
-    // If list of know extensions is empty, don't init cache on disk. It is
-    // important shortcut for test to don't wait forever for cache dir
-    // initialization that should happen outside of Chrome on real device.
-    cached_extensions_->Clear();
-    UpdateExtensionLoader();
-    return;
+  if (external_update_url_value &&
+      !external_update_url_value->GetString().empty()) {
+    return GURL(external_update_url_value->GetString());
   }
 
-  if (local_cache_.is_uninitialized()) {
-    local_cache_.Init(wait_for_cache_initialization_,
-                      base::Bind(&ExternalCache::CheckCache,
-                                 weak_ptr_factory_.GetWeakPtr()));
-  } else {
-    CheckCache();
+  if (always_checking_for_updates)
+    return extension_urls::GetWebstoreUpdateUrl();
+
+  return GURL();
+}
+
+// static
+base::Value ExternalCache::GetExtensionValueToCache(
+    const base::Value& extension,
+    const std::string& path,
+    const std::string& version) {
+  DCHECK(extension.is_dict());
+
+  base::Value result = extension.Clone();
+
+  const base::Value* external_update_url_value = extension.FindKeyOfType(
+      extensions::ExternalProviderImpl::kExternalUpdateUrl,
+      base::Value::Type::STRING);
+  if (external_update_url_value &&
+      extension_urls::IsWebstoreUpdateUrl(
+          GURL(external_update_url_value->GetString()))) {
+    result.SetKey(extensions::ExternalProviderImpl::kIsFromWebstore,
+                  base::Value(true));
   }
+  result.RemoveKey(extensions::ExternalProviderImpl::kExternalUpdateUrl);
+
+  result.SetKey(extensions::ExternalProviderImpl::kExternalVersion,
+                base::Value(version));
+  result.SetKey(extensions::ExternalProviderImpl::kExternalCrx,
+                base::Value(path));
+  return result;
 }
 
-void ExternalCache::OnDamagedFileDetected(const base::FilePath& path) {
-  for (base::DictionaryValue::Iterator it(*cached_extensions_.get());
-       !it.IsAtEnd(); it.Advance()) {
-    const base::DictionaryValue* entry = NULL;
-    if (!it.value().GetAsDictionary(&entry)) {
-      NOTREACHED() << "ExternalCache found bad entry with type "
-                   << it.value().type();
-      continue;
-    }
+// static
+bool ExternalCache::ShouldCacheImmediately(
+    const base::Value& extension,
+    const std::string& installed_version) {
+  DCHECK(extension.is_dict());
 
-    std::string external_crx;
-    if (entry->GetString(extensions::ExternalProviderImpl::kExternalCrx,
-                         &external_crx) &&
-        external_crx == path.value()) {
-      std::string id = it.key();
-      LOG(ERROR) << "ExternalCache extension at " << path.value()
-                 << " failed to install, deleting it.";
-      cached_extensions_->Remove(id, NULL);
-      extensions_->Remove(id, NULL);
+  const base::Value* keep_if_present_value =
+      extension.FindKeyOfType(extensions::ExternalProviderImpl::kKeepIfPresent,
+                              base::Value::Type::BOOLEAN);
 
-      local_cache_.RemoveExtension(id, std::string());
-      UpdateExtensionLoader();
-
-      // Don't try to DownloadMissingExtensions() from here,
-      // since it can cause a fail/retry loop.
-      return;
-    }
-  }
-  DLOG(ERROR) << "ExternalCache cannot find external_crx " << path.value();
-}
-
-void ExternalCache::RemoveExtensions(const std::vector<std::string>& ids) {
-  if (ids.empty())
-    return;
-
-  for (size_t i = 0; i < ids.size(); ++i) {
-    cached_extensions_->Remove(ids[i], NULL);
-    extensions_->Remove(ids[i], NULL);
-    local_cache_.RemoveExtension(ids[i], std::string());
-  }
-  UpdateExtensionLoader();
-}
-
-bool ExternalCache::GetExtension(const std::string& id,
-                                 base::FilePath* file_path,
-                                 std::string* version) {
-  return local_cache_.GetExtension(id, std::string(), file_path, version);
-}
-
-void ExternalCache::PutExternalExtension(
-    const std::string& id,
-    const base::FilePath& crx_file_path,
-    const std::string& version,
-    const PutExternalExtensionCallback& callback) {
-  local_cache_.PutExtension(
-      id, std::string(), crx_file_path, version,
-      base::Bind(&ExternalCache::OnPutExternalExtension,
-                 weak_ptr_factory_.GetWeakPtr(), id, callback));
-}
-
-void ExternalCache::Observe(int type,
-                            const content::NotificationSource& source,
-                            const content::NotificationDetails& details) {
-  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, type);
-
-  extensions::CrxInstaller* installer =
-      content::Source<extensions::CrxInstaller>(source).ptr();
-  OnDamagedFileDetected(installer->source_file());
-}
-
-void ExternalCache::OnExtensionDownloadFailed(
-    const std::string& id,
-    extensions::ExtensionDownloaderDelegate::Error error,
-    const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
-    const std::set<int>& request_ids) {
-  if (error == NO_UPDATE_AVAILABLE) {
-    if (!cached_extensions_->HasKey(id)) {
-      LOG(ERROR) << "ExternalCache extension " << id
-                 << " not found on update server";
-      delegate_->OnExtensionDownloadFailed(id, error);
-    } else {
-      // No version update for an already cached extension.
-      delegate_->OnExtensionLoadedInCache(id);
-    }
-  } else {
-    LOG(ERROR) << "ExternalCache failed to download extension " << id
-               << ", error " << error;
-    delegate_->OnExtensionDownloadFailed(id, error);
-  }
-}
-
-void ExternalCache::OnExtensionDownloadFinished(
-    const extensions::CRXFileInfo& file,
-    bool file_ownership_passed,
-    const GURL& download_url,
-    const std::string& version,
-    const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
-    const std::set<int>& request_ids,
-    const InstallCallback& callback) {
-  DCHECK(file_ownership_passed);
-  local_cache_.PutExtension(
-      file.extension_id, file.expected_hash, file.path, version,
-      base::Bind(&ExternalCache::OnPutExtension, weak_ptr_factory_.GetWeakPtr(),
-                 file.extension_id));
-  if (!callback.is_null())
-    callback.Run(true);
-}
-
-bool ExternalCache::IsExtensionPending(const std::string& id) {
-  // Pending means that there is no installed version yet.
-  return extensions_->HasKey(id) && !cached_extensions_->HasKey(id);
-}
-
-bool ExternalCache::GetExtensionExistingVersion(const std::string& id,
-                                                std::string* version) {
-  base::DictionaryValue* extension_dictionary = NULL;
-  if (cached_extensions_->GetDictionary(id, &extension_dictionary)) {
-    if (extension_dictionary->GetString(
-            extensions::ExternalProviderImpl::kExternalVersion, version)) {
-      return true;
-    }
-    *version = delegate_->GetInstalledExtensionVersion(id);
-    return !version->empty();
-  }
-  return false;
-}
-
-service_manager::Connector* ExternalCache::GetConnector() {
-  return content::ServiceManagerConnection::GetForProcess()->GetConnector();
-
-}
-
-void ExternalCache::UpdateExtensionLoader() {
-  VLOG(1) << "Notify ExternalCache delegate about cache update";
-  if (delegate_)
-    delegate_->OnExtensionListsUpdated(cached_extensions_.get());
-}
-
-void ExternalCache::CheckCache() {
-  if (local_cache_.is_shutdown())
-    return;
-
-  // If request_context_ is missing we can't download anything.
-  if (request_context_.get()) {
-    downloader_ = ChromeExtensionDownloaderFactory::CreateForRequestContext(
-        request_context_.get(), this, GetConnector());
-  }
-
-  cached_extensions_->Clear();
-  for (base::DictionaryValue::Iterator it(*extensions_.get());
-       !it.IsAtEnd(); it.Advance()) {
-    const base::DictionaryValue* entry = NULL;
-    if (!it.value().GetAsDictionary(&entry)) {
-      LOG(ERROR) << "ExternalCache found bad entry with type "
-                 << it.value().type();
-      continue;
-    }
-
-    bool keep_if_present =
-        entry->HasKey(extensions::ExternalProviderImpl::kKeepIfPresent);
-    std::string external_update_url;
-    entry->GetString(extensions::ExternalProviderImpl::kExternalUpdateUrl,
-                     &external_update_url);
-    if (downloader_ && !keep_if_present) {
-      GURL update_url;
-      if (!external_update_url.empty())
-        update_url = GURL(external_update_url);
-      else if (always_check_updates_)
-        update_url = extension_urls::GetWebstoreUpdateUrl();
-
-      if (update_url.is_valid())
-        downloader_->AddPendingExtension(
-            it.key(), update_url, false, 0,
-            extensions::ManifestFetchData::FetchPriority::BACKGROUND);
-    }
-
-    base::FilePath file_path;
-    std::string version;
-    std::string hash;
-    if (local_cache_.GetExtension(it.key(), hash, &file_path, &version)) {
-      // Copy entry to don't modify it inside extensions_.
-      std::unique_ptr<base::DictionaryValue> entry_copy =
-          entry->CreateDeepCopy();
-
-      if (extension_urls::IsWebstoreUpdateUrl(GURL(external_update_url))) {
-        entry_copy->SetBoolean(
-            extensions::ExternalProviderImpl::kIsFromWebstore, true);
-      }
-      entry_copy->Remove(extensions::ExternalProviderImpl::kExternalUpdateUrl,
-                         NULL);
-      entry_copy->SetString(extensions::ExternalProviderImpl::kExternalVersion,
-                            version);
-      entry_copy->SetString(extensions::ExternalProviderImpl::kExternalCrx,
-                            file_path.value());
-      cached_extensions_->Set(it.key(), std::move(entry_copy));
-    } else {
-      bool has_external_crx = entry->HasKey(
-          extensions::ExternalProviderImpl::kExternalCrx);
-      bool is_already_installed =
-          !delegate_->GetInstalledExtensionVersion(it.key()).empty();
-      if (keep_if_present || has_external_crx || is_already_installed) {
-        // Copy entry to don't modify it inside extensions_.
-        cached_extensions_->Set(it.key(), entry->CreateDeepCopy());
-      }
-    }
-  }
-
-  if (downloader_)
-    downloader_->StartAllPending(NULL);
-
-  VLOG(1) << "Updated ExternalCache, there are "
-          << cached_extensions_->size() << " extensions cached";
-
-  UpdateExtensionLoader();
-}
-
-void ExternalCache::OnPutExtension(const std::string& id,
-                                   const base::FilePath& file_path,
-                                   bool file_ownership_passed) {
-  if (local_cache_.is_shutdown() || file_ownership_passed) {
-    backend_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(base::IgnoreResult(&base::DeleteFile), file_path, true));
-    return;
-  }
-
-  VLOG(1) << "ExternalCache installed a new extension in the cache " << id;
-
-  base::DictionaryValue* original_entry = NULL;
-  if (!extensions_->GetDictionary(id, &original_entry)) {
-    LOG(ERROR) << "ExternalCache cannot find entry for extension " << id;
-    return;
-  }
-
-  // Copy original_entry to avoid modifying it inside extensions_.
-  std::unique_ptr<base::DictionaryValue> entry =
-      original_entry->CreateDeepCopy();
-
-  std::string version;
-  std::string hash;
-  if (!local_cache_.GetExtension(id, hash, NULL, &version)) {
-    // Copy entry to don't modify it inside extensions_.
-    LOG(ERROR) << "Can't find installed extension in cache " << id;
-    return;
-  }
-
-  if (flush_on_put_) {
-    backend_task_runner_->PostTask(FROM_HERE,
-                                   base::BindOnce(&FlushFile, file_path));
-  }
-
-  std::string update_url;
-  if (entry->GetString(extensions::ExternalProviderImpl::kExternalUpdateUrl,
-                       &update_url) &&
-      extension_urls::IsWebstoreUpdateUrl(GURL(update_url))) {
-    entry->SetBoolean(extensions::ExternalProviderImpl::kIsFromWebstore, true);
-  }
-  entry->Remove(extensions::ExternalProviderImpl::kExternalUpdateUrl, NULL);
-  entry->SetString(extensions::ExternalProviderImpl::kExternalVersion, version);
-  entry->SetString(extensions::ExternalProviderImpl::kExternalCrx,
-                   file_path.value());
-
-  cached_extensions_->Set(id, std::move(entry));
-  if (delegate_)
-    delegate_->OnExtensionLoadedInCache(id);
-  UpdateExtensionLoader();
-}
-
-void ExternalCache::OnPutExternalExtension(
-    const std::string& id,
-    const PutExternalExtensionCallback& callback,
-    const base::FilePath& file_path,
-    bool file_ownership_passed) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  OnPutExtension(id, file_path, file_ownership_passed);
-  callback.Run(id, !file_ownership_passed);
-}
-
-std::string ExternalCache::Delegate::GetInstalledExtensionVersion(
-    const std::string& id) {
-  return std::string();
+  return !installed_version.empty() ||
+         (keep_if_present_value && keep_if_present_value->GetBool()) ||
+         extension.FindKey(extensions::ExternalProviderImpl::kExternalCrx);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/external_cache.h b/chrome/browser/chromeos/extensions/external_cache.h
index 2b33d492c..9559868d 100644
--- a/chrome/browser/chromeos/extensions/external_cache.h
+++ b/chrome/browser/chromeos/extensions/external_cache.h
@@ -7,200 +7,85 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/callback_forward.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "chrome/browser/extensions/updater/local_extension_cache.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "extensions/browser/updater/extension_downloader_delegate.h"
+#include "url/gurl.h"
 
 namespace base {
 class DictionaryValue;
-}
-
-namespace extensions {
-class ExtensionDownloader;
-}
-
-namespace net {
-class URLRequestContextGetter;
-}
-
-namespace service_manager {
-class Connector;
+class FilePath;
+class Value;
 }
 
 namespace chromeos {
 
 // The ExternalCache manages a cache for external extensions.
-class ExternalCache : public content::NotificationObserver,
-                      public extensions::ExtensionDownloaderDelegate {
+class ExternalCache {
  public:
-  typedef base::Callback<void(const std::string& id, bool success)>
-      PutExternalExtensionCallback;
+  using PutExternalExtensionCallback =
+      base::OnceCallback<void(const std::string& id, bool success)>;
 
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-    // Caller owns |prefs|.
-    virtual void OnExtensionListsUpdated(
-        const base::DictionaryValue* prefs) = 0;
-    // Called after extension with |id| is loaded in cache.
-    virtual void OnExtensionLoadedInCache(const std::string& id) {}
-    // Called when extension with |id| is failed with downloading for |error|.
-    virtual void OnExtensionDownloadFailed(
-        const std::string& id,
-        extensions::ExtensionDownloaderDelegate::Error error) {}
+  virtual ~ExternalCache() = default;
 
-    // Cache needs to provide already installed extensions otherwise they
-    // will be removed. Cache calls this function to get version of installed
-    // extension or empty string if not installed.
-    virtual std::string GetInstalledExtensionVersion(const std::string& id);
-  };
+  // If an external extension should be downloaded, returns the extension's
+  // update URL. Otherwise, returns an empty URL.
+  static GURL GetExtensionUpdateUrl(const base::Value& extension_value,
+                                    bool always_checking_for_updates);
 
-  // The |request_context| is used for update checks. All file I/O is done via
-  // the |backend_task_runner|. If |always_check_updates| is |false|, update
-  // checks are performed for extensions that have an |external_update_url|
-  // only. If |wait_for_cache_initialization| is |true|, the cache contents will
-  // not be read until a flag file appears in the cache directory, signaling
-  // that the cache is ready.
-  ExternalCache(const base::FilePath& cache_dir,
-                net::URLRequestContextGetter* request_context,
-                const scoped_refptr<base::SequencedTaskRunner>&
-                    backend_task_runner,
-                Delegate* delegate,
-                bool always_check_updates,
-                bool wait_for_cache_initialization);
-  ~ExternalCache() override;
+  // Converts an external extension value to the external extension value
+  // describing a cached extension - i.e. a value describing an extension
+  // returned by GetCachedExtensions().
+  static base::Value GetExtensionValueToCache(const base::Value& original_value,
+                                              const std::string& path,
+                                              const std::string& version);
+
+  // If the external extension is not curently cached, whether the extension's
+  // value should be added to the set of cached extensions (returned by
+  // GetCachedExtensions()) regardles of the extension's download status.
+  static bool ShouldCacheImmediately(const base::Value& extension_value,
+                                     const std::string& installed_version);
 
   // Returns already cached extensions.
-  const base::DictionaryValue* cached_extensions() {
-    return cached_extensions_.get();
-  }
-
-  // Implementation of content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
-  // Implementation of ExtensionDownloaderDelegate:
-  void OnExtensionDownloadFailed(const std::string& id,
-                                 Error error,
-                                 const PingResult& ping_result,
-                                 const std::set<int>& request_ids) override;
-
-  void OnExtensionDownloadFinished(const extensions::CRXFileInfo& file,
-                                   bool file_ownership_passed,
-                                   const GURL& download_url,
-                                   const std::string& version,
-                                   const PingResult& ping_result,
-                                   const std::set<int>& request_ids,
-                                   const InstallCallback& callback) override;
-
-  bool IsExtensionPending(const std::string& id) override;
-
-  bool GetExtensionExistingVersion(const std::string& id,
-                                   std::string* version) override;
+  virtual const base::DictionaryValue* GetCachedExtensions() = 0;
 
   // Shut down the cache. The |callback| will be invoked when the cache has shut
   // down completely and there are no more pending file I/O operations.
-  void Shutdown(const base::Closure& callback);
+  virtual void Shutdown(base::OnceClosure callback) = 0;
 
   // Replace the list of extensions to cache with |prefs| and perform update
   // checks for these.
-  void UpdateExtensionsList(std::unique_ptr<base::DictionaryValue> prefs);
+  virtual void UpdateExtensionsList(
+      std::unique_ptr<base::DictionaryValue> prefs) = 0;
 
   // If a user of one of the ExternalCache's extensions detects that
   // the extension is damaged then this method can be used to remove it from
   // the cache and retry to download it after a restart.
-  void OnDamagedFileDetected(const base::FilePath& path);
+  virtual void OnDamagedFileDetected(const base::FilePath& path) = 0;
 
   // Removes extensions listed in |ids| from external cache, corresponding crx
   // files will be removed from disk too.
-  void RemoveExtensions(const std::vector<std::string>& ids);
+  virtual void RemoveExtensions(const std::vector<std::string>& ids) = 0;
 
   // If extension with |id| exists in the cache, returns |true|, |file_path| and
   // |version| for the extension. Extension will be marked as used with current
   // timestamp.
-  bool GetExtension(const std::string& id,
-                    base::FilePath* file_path,
-                    std::string* version);
+  virtual bool GetExtension(const std::string& id,
+                            base::FilePath* file_path,
+                            std::string* version) = 0;
+
+  // Whether the extension with the provided id is currently being cached -
+  // i.e. whether the extension have been added to the external cache, but it's
+  // data has not yet been fetched, and thus is not available using
+  // GetExtension().
+  virtual bool ExtensionFetchPending(const std::string& id) = 0;
 
   // Puts the external |crx_file_path| into |local_cache_| for extension with
   // |id|.
-  void PutExternalExtension(const std::string& id,
-                            const base::FilePath& crx_file_path,
-                            const std::string& version,
-                            const PutExternalExtensionCallback& callback);
-
-  void set_flush_on_put(bool flush_on_put) { flush_on_put_ = flush_on_put; }
-
- protected:
-  // Overridden in tests.
-  virtual service_manager::Connector* GetConnector();
-
- private:
-  // Notifies the that the cache has been updated, providing
-  // extensions loader with an updated list of extensions.
-  void UpdateExtensionLoader();
-
-  // Checks the cache contents and initiate download if needed.
-  void CheckCache();
-
-  // Invoked on the UI thread when a new entry has been installed in the cache.
-  void OnPutExtension(const std::string& id,
-                      const base::FilePath& file_path,
-                      bool file_ownership_passed);
-
-  // Invoked on the UI thread when the external extension has been installed
-  // in the local cache by calling PutExternalExtension.
-  void OnPutExternalExtension(const std::string& id,
-                              const PutExternalExtensionCallback& callback,
-                              const base::FilePath& file_path,
-                              bool file_ownership_passed);
-
-  extensions::LocalExtensionCache local_cache_;
-
-  // Request context used by the |downloader_|.
-  scoped_refptr<net::URLRequestContextGetter> request_context_;
-
-  // Task runner for executing file I/O tasks.
-  const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
-
-  // Delegate that would like to get notifications about cache updates.
-  Delegate* delegate_;
-
-  // Updates needs to be check for the extensions with external_crx too.
-  bool always_check_updates_;
-
-  // Set to true if cache should wait for initialization flag file.
-  bool wait_for_cache_initialization_;
-
-  // Whether to flush the crx file after putting into |local_cache_|.
-  bool flush_on_put_ = false;
-
-  // This is the list of extensions currently configured.
-  std::unique_ptr<base::DictionaryValue> extensions_;
-
-  // This contains extensions that are both currently configured
-  // and that have a valid crx in the cache.
-  std::unique_ptr<base::DictionaryValue> cached_extensions_;
-
-  // Used to download the extensions and to check for updates.
-  std::unique_ptr<extensions::ExtensionDownloader> downloader_;
-
-  // Observes failures to install CRX files.
-  content::NotificationRegistrar notification_registrar_;
-
-  // Weak factory for callbacks.
-  base::WeakPtrFactory<ExternalCache> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalCache);
+  virtual void PutExternalExtension(const std::string& id,
+                                    const base::FilePath& crx_file_path,
+                                    const std::string& version,
+                                    PutExternalExtensionCallback callback) = 0;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/external_cache_delegate.h b/chrome/browser/chromeos/extensions/external_cache_delegate.h
new file mode 100644
index 0000000..fcd983f
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/external_cache_delegate.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_DELEGATE_H_
+
+#include <string>
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace chromeos {
+
+class ExternalCacheDelegate {
+ public:
+  virtual ~ExternalCacheDelegate() = default;
+
+  // Caller owns |prefs|.
+  virtual void OnExtensionListsUpdated(const base::DictionaryValue* prefs) = 0;
+
+  // Called after extension with |id| is loaded in cache.
+  virtual void OnExtensionLoadedInCache(const std::string& id) = 0;
+
+  // Called when extension with |id| fails to load due to a download error.
+  virtual void OnExtensionDownloadFailed(const std::string& id) = 0;
+
+  // Cache needs to provide already installed extensions otherwise they
+  // will be removed. Cache calls this function to get version of installed
+  // extension or empty string if not installed.
+  virtual std::string GetInstalledExtensionVersion(const std::string& id) = 0;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_DELEGATE_H_
diff --git a/chrome/browser/chromeos/extensions/external_cache_impl.cc b/chrome/browser/chromeos/extensions/external_cache_impl.cc
new file mode 100644
index 0000000..53fbdc2
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/external_cache_impl.cc
@@ -0,0 +1,367 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/external_cache_impl.h"
+
+#include <stddef.h>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
+#include "chrome/browser/extensions/crx_installer.h"
+#include "chrome/browser/extensions/external_provider_impl.h"
+#include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/common/service_manager_connection.h"
+#include "extensions/browser/notification_types.h"
+#include "extensions/browser/updater/extension_downloader.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_urls.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace chromeos {
+
+namespace {
+
+void FlushFile(const base::FilePath& path) {
+  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
+  file.Flush();
+  file.Close();
+}
+
+// Wraps a base::OnceCallback with a base::Callback, which can be passed as a
+// callback to extensions::LocalExtensionCache::PutExtension().
+// TODO(tbarzic): Remove this when LocalExtensionCache starts using
+//     OnceCallback.
+void WrapPutExtensionCallback(
+    base::OnceCallback<void(const base::FilePath&, bool)> callback,
+    const base::FilePath& file_path,
+    bool file_ownership_passed) {
+  if (callback)
+    std::move(callback).Run(file_path, file_ownership_passed);
+}
+
+// Wraps OnceClosure with a base::Closure, so it can be passed to
+// extensions::LocalExtensionCache::Shutdown.
+// TODO(tbarzic): Remove this when LocakExtensionCache starts using OnceClosure.
+void WrapOnceClosure(base::OnceClosure closure) {
+  if (closure)
+    std::move(closure).Run();
+}
+
+}  // namespace
+
+ExternalCacheImpl::ExternalCacheImpl(
+    const base::FilePath& cache_dir,
+    net::URLRequestContextGetter* request_context,
+    const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
+    ExternalCacheDelegate* delegate,
+    bool always_check_updates,
+    bool wait_for_cache_initialization)
+    : local_cache_(cache_dir, 0, base::TimeDelta(), backend_task_runner),
+      request_context_(request_context),
+      backend_task_runner_(backend_task_runner),
+      delegate_(delegate),
+      always_check_updates_(always_check_updates),
+      wait_for_cache_initialization_(wait_for_cache_initialization),
+      cached_extensions_(new base::DictionaryValue()),
+      weak_ptr_factory_(this) {
+  notification_registrar_.Add(
+      this, extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
+      content::NotificationService::AllBrowserContextsAndSources());
+}
+
+ExternalCacheImpl::~ExternalCacheImpl() = default;
+
+const base::DictionaryValue* ExternalCacheImpl::GetCachedExtensions() {
+  return cached_extensions_.get();
+}
+
+void ExternalCacheImpl::Shutdown(base::OnceClosure callback) {
+  local_cache_.Shutdown(
+      base::Bind(&WrapOnceClosure, base::Passed(std::move(callback))));
+}
+
+void ExternalCacheImpl::UpdateExtensionsList(
+    std::unique_ptr<base::DictionaryValue> prefs) {
+  extensions_ = std::move(prefs);
+
+  if (extensions_->empty()) {
+    // If list of know extensions is empty, don't init cache on disk. It is
+    // important shortcut for test to don't wait forever for cache dir
+    // initialization that should happen outside of Chrome on real device.
+    cached_extensions_->Clear();
+    UpdateExtensionLoader();
+    return;
+  }
+
+  if (local_cache_.is_uninitialized()) {
+    local_cache_.Init(wait_for_cache_initialization_,
+                      base::Bind(&ExternalCacheImpl::CheckCache,
+                                 weak_ptr_factory_.GetWeakPtr()));
+  } else {
+    CheckCache();
+  }
+}
+
+void ExternalCacheImpl::OnDamagedFileDetected(const base::FilePath& path) {
+  for (base::DictionaryValue::Iterator it(*cached_extensions_.get());
+       !it.IsAtEnd(); it.Advance()) {
+    const base::DictionaryValue* entry = NULL;
+    if (!it.value().GetAsDictionary(&entry)) {
+      NOTREACHED() << "ExternalCacheImpl found bad entry with type "
+                   << it.value().type();
+      continue;
+    }
+
+    std::string external_crx;
+    if (entry->GetString(extensions::ExternalProviderImpl::kExternalCrx,
+                         &external_crx) &&
+        external_crx == path.value()) {
+      std::string id = it.key();
+      LOG(ERROR) << "ExternalCacheImpl extension at " << path.value()
+                 << " failed to install, deleting it.";
+      cached_extensions_->Remove(id, NULL);
+      extensions_->Remove(id, NULL);
+
+      local_cache_.RemoveExtension(id, std::string());
+      UpdateExtensionLoader();
+
+      // Don't try to DownloadMissingExtensions() from here,
+      // since it can cause a fail/retry loop.
+      return;
+    }
+  }
+  DLOG(ERROR) << "ExternalCacheImpl cannot find external_crx " << path.value();
+}
+
+void ExternalCacheImpl::RemoveExtensions(const std::vector<std::string>& ids) {
+  if (ids.empty())
+    return;
+
+  for (size_t i = 0; i < ids.size(); ++i) {
+    cached_extensions_->Remove(ids[i], NULL);
+    extensions_->Remove(ids[i], NULL);
+    local_cache_.RemoveExtension(ids[i], std::string());
+  }
+  UpdateExtensionLoader();
+}
+
+bool ExternalCacheImpl::GetExtension(const std::string& id,
+                                     base::FilePath* file_path,
+                                     std::string* version) {
+  return local_cache_.GetExtension(id, std::string(), file_path, version);
+}
+
+bool ExternalCacheImpl::ExtensionFetchPending(const std::string& id) {
+  return extensions_->HasKey(id) && !cached_extensions_->HasKey(id);
+}
+
+void ExternalCacheImpl::PutExternalExtension(
+    const std::string& id,
+    const base::FilePath& crx_file_path,
+    const std::string& version,
+    PutExternalExtensionCallback callback) {
+  local_cache_.PutExtension(
+      id, std::string(), crx_file_path, version,
+      base::Bind(
+          &WrapPutExtensionCallback,
+          base::Passed(base::BindOnce(
+              &ExternalCacheImpl::OnPutExternalExtension,
+              weak_ptr_factory_.GetWeakPtr(), id, std::move(callback)))));
+}
+
+void ExternalCacheImpl::Observe(int type,
+                                const content::NotificationSource& source,
+                                const content::NotificationDetails& details) {
+  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, type);
+
+  extensions::CrxInstaller* installer =
+      content::Source<extensions::CrxInstaller>(source).ptr();
+  OnDamagedFileDetected(installer->source_file());
+}
+
+void ExternalCacheImpl::OnExtensionDownloadFailed(
+    const std::string& id,
+    extensions::ExtensionDownloaderDelegate::Error error,
+    const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
+    const std::set<int>& request_ids) {
+  if (error == NO_UPDATE_AVAILABLE) {
+    if (!cached_extensions_->HasKey(id)) {
+      LOG(ERROR) << "ExternalCacheImpl extension " << id
+                 << " not found on update server";
+      delegate_->OnExtensionDownloadFailed(id);
+    } else {
+      // No version update for an already cached extension.
+      delegate_->OnExtensionLoadedInCache(id);
+    }
+  } else {
+    LOG(ERROR) << "ExternalCacheImpl failed to download extension " << id
+               << ", error " << error;
+    delegate_->OnExtensionDownloadFailed(id);
+  }
+}
+
+void ExternalCacheImpl::OnExtensionDownloadFinished(
+    const extensions::CRXFileInfo& file,
+    bool file_ownership_passed,
+    const GURL& download_url,
+    const std::string& version,
+    const extensions::ExtensionDownloaderDelegate::PingResult& ping_result,
+    const std::set<int>& request_ids,
+    const InstallCallback& callback) {
+  DCHECK(file_ownership_passed);
+  local_cache_.PutExtension(
+      file.extension_id, file.expected_hash, file.path, version,
+      base::Bind(&ExternalCacheImpl::OnPutExtension,
+                 weak_ptr_factory_.GetWeakPtr(), file.extension_id));
+  if (!callback.is_null())
+    callback.Run(true);
+}
+
+bool ExternalCacheImpl::IsExtensionPending(const std::string& id) {
+  return ExtensionFetchPending(id);
+}
+
+bool ExternalCacheImpl::GetExtensionExistingVersion(const std::string& id,
+                                                    std::string* version) {
+  base::DictionaryValue* extension_dictionary = NULL;
+  if (cached_extensions_->GetDictionary(id, &extension_dictionary)) {
+    if (extension_dictionary->GetString(
+            extensions::ExternalProviderImpl::kExternalVersion, version)) {
+      return true;
+    }
+    *version = delegate_->GetInstalledExtensionVersion(id);
+    return !version->empty();
+  }
+  return false;
+}
+
+service_manager::Connector* ExternalCacheImpl::GetConnector() {
+  if (use_null_connector_)
+    return nullptr;
+  return content::ServiceManagerConnection::GetForProcess()->GetConnector();
+}
+
+void ExternalCacheImpl::UpdateExtensionLoader() {
+  VLOG(1) << "Notify ExternalCacheImpl delegate about cache update";
+  if (delegate_)
+    delegate_->OnExtensionListsUpdated(cached_extensions_.get());
+}
+
+void ExternalCacheImpl::CheckCache() {
+  if (local_cache_.is_shutdown())
+    return;
+
+  // If request_context_ is missing we can't download anything.
+  if (request_context_.get()) {
+    downloader_ = ChromeExtensionDownloaderFactory::CreateForRequestContext(
+        request_context_.get(), this, GetConnector());
+  }
+
+  cached_extensions_->Clear();
+  for (const auto& entry : extensions_->DictItems()) {
+    if (!entry.second.is_dict()) {
+      LOG(ERROR) << "ExternalCacheImpl found bad entry with type "
+                 << entry.second.type();
+      continue;
+    }
+
+    if (downloader_) {
+      GURL update_url =
+          GetExtensionUpdateUrl(entry.second, always_check_updates_);
+
+      if (update_url.is_valid()) {
+        downloader_->AddPendingExtension(
+            entry.first, update_url, false, 0,
+            extensions::ManifestFetchData::FetchPriority::BACKGROUND);
+      }
+    }
+
+    base::FilePath file_path;
+    std::string version;
+    std::string hash;
+    if (local_cache_.GetExtension(entry.first, hash, &file_path, &version)) {
+      cached_extensions_->SetKey(
+          entry.first,
+          GetExtensionValueToCache(entry.second, file_path.value(), version));
+    } else if (ShouldCacheImmediately(
+                   entry.second,
+                   delegate_->GetInstalledExtensionVersion(entry.first))) {
+      cached_extensions_->SetKey(entry.first, entry.second.Clone());
+    }
+  }
+
+  if (downloader_)
+    downloader_->StartAllPending(NULL);
+
+  VLOG(1) << "Updated ExternalCacheImpl, there are "
+          << cached_extensions_->size() << " extensions cached";
+
+  UpdateExtensionLoader();
+}
+
+void ExternalCacheImpl::OnPutExtension(const std::string& id,
+                                       const base::FilePath& file_path,
+                                       bool file_ownership_passed) {
+  if (local_cache_.is_shutdown() || file_ownership_passed) {
+    backend_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(base::IgnoreResult(&base::DeleteFile), file_path, true));
+    return;
+  }
+
+  VLOG(1) << "ExternalCacheImpl installed a new extension in the cache " << id;
+
+  const base::Value* original_entry =
+      extensions_->FindKeyOfType(id, base::Value::Type::DICTIONARY);
+  if (!original_entry) {
+    LOG(ERROR) << "ExternalCacheImpl cannot find entry for extension " << id;
+    return;
+  }
+
+  std::string version;
+  std::string hash;
+  if (!local_cache_.GetExtension(id, hash, NULL, &version)) {
+    // Copy entry to don't modify it inside extensions_.
+    LOG(ERROR) << "Can't find installed extension in cache " << id;
+    return;
+  }
+
+  if (flush_on_put_) {
+    backend_task_runner_->PostTask(FROM_HERE,
+                                   base::BindOnce(&FlushFile, file_path));
+  }
+
+  cached_extensions_->SetKey(
+      id,
+      GetExtensionValueToCache(*original_entry, file_path.value(), version));
+
+  if (delegate_)
+    delegate_->OnExtensionLoadedInCache(id);
+  UpdateExtensionLoader();
+}
+
+void ExternalCacheImpl::OnPutExternalExtension(
+    const std::string& id,
+    PutExternalExtensionCallback callback,
+    const base::FilePath& file_path,
+    bool file_ownership_passed) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  OnPutExtension(id, file_path, file_ownership_passed);
+  std::move(callback).Run(id, !file_ownership_passed);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/external_cache_impl.h b/chrome/browser/chromeos/extensions/external_cache_impl.h
new file mode 100644
index 0000000..0d58e5e3
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/external_cache_impl.h
@@ -0,0 +1,173 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "chrome/browser/chromeos/extensions/external_cache.h"
+#include "chrome/browser/extensions/updater/local_extension_cache.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/updater/extension_downloader_delegate.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace extensions {
+class ExtensionDownloader;
+}
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace service_manager {
+class Connector;
+}
+
+namespace chromeos {
+
+class ExternalCacheDelegate;
+
+// The ExternalCacheImpl manages a cache for external extensions.
+class ExternalCacheImpl : public ExternalCache,
+                          public content::NotificationObserver,
+                          public extensions::ExtensionDownloaderDelegate {
+ public:
+  // The |request_context| is used for update checks. All file I/O is done via
+  // the |backend_task_runner|. If |always_check_updates| is |false|, update
+  // checks are performed for extensions that have an |external_update_url|
+  // only. If |wait_for_cache_initialization| is |true|, the cache contents will
+  // not be read until a flag file appears in the cache directory, signaling
+  // that the cache is ready.
+  ExternalCacheImpl(
+      const base::FilePath& cache_dir,
+      net::URLRequestContextGetter* request_context,
+      const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
+      ExternalCacheDelegate* delegate,
+      bool always_check_updates,
+      bool wait_for_cache_initialization);
+  ~ExternalCacheImpl() override;
+
+  // Implementation of ExternalCache:
+  const base::DictionaryValue* GetCachedExtensions() override;
+  void Shutdown(base::OnceClosure callback) override;
+  void UpdateExtensionsList(
+      std::unique_ptr<base::DictionaryValue> prefs) override;
+  void OnDamagedFileDetected(const base::FilePath& path) override;
+  void RemoveExtensions(const std::vector<std::string>& ids) override;
+  bool GetExtension(const std::string& id,
+                    base::FilePath* file_path,
+                    std::string* version) override;
+  bool ExtensionFetchPending(const std::string& id) override;
+  void PutExternalExtension(const std::string& id,
+                            const base::FilePath& crx_file_path,
+                            const std::string& version,
+                            PutExternalExtensionCallback callback) override;
+
+  // Implementation of content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+  // Implementation of ExtensionDownloaderDelegate:
+  void OnExtensionDownloadFailed(const std::string& id,
+                                 Error error,
+                                 const PingResult& ping_result,
+                                 const std::set<int>& request_ids) override;
+  void OnExtensionDownloadFinished(const extensions::CRXFileInfo& file,
+                                   bool file_ownership_passed,
+                                   const GURL& download_url,
+                                   const std::string& version,
+                                   const PingResult& ping_result,
+                                   const std::set<int>& request_ids,
+                                   const InstallCallback& callback) override;
+  bool IsExtensionPending(const std::string& id) override;
+  bool GetExtensionExistingVersion(const std::string& id,
+                                   std::string* version) override;
+
+  void set_flush_on_put(bool flush_on_put) { flush_on_put_ = flush_on_put; }
+
+  void use_null_connector_for_test() { use_null_connector_ = true; }
+
+ private:
+  // Gets service manager connector this external cache instance should use.
+  // Might be null in tests - see use_null_connector_for_test().
+  service_manager::Connector* GetConnector();
+
+  // Notifies the that the cache has been updated, providing
+  // extensions loader with an updated list of extensions.
+  void UpdateExtensionLoader();
+
+  // Checks the cache contents and initiate download if needed.
+  void CheckCache();
+
+  // Invoked on the UI thread when a new entry has been installed in the cache.
+  void OnPutExtension(const std::string& id,
+                      const base::FilePath& file_path,
+                      bool file_ownership_passed);
+
+  // Invoked on the UI thread when the external extension has been installed
+  // in the local cache by calling PutExternalExtension.
+  void OnPutExternalExtension(const std::string& id,
+                              PutExternalExtensionCallback callback,
+                              const base::FilePath& file_path,
+                              bool file_ownership_passed);
+
+  extensions::LocalExtensionCache local_cache_;
+
+  // Request context used by the |downloader_|.
+  scoped_refptr<net::URLRequestContextGetter> request_context_;
+
+  // Task runner for executing file I/O tasks.
+  const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
+
+  // Delegate that would like to get notifications about cache updates.
+  ExternalCacheDelegate* delegate_;
+
+  // Updates needs to be check for the extensions with external_crx too.
+  bool always_check_updates_;
+
+  // Set to true if cache should wait for initialization flag file.
+  bool wait_for_cache_initialization_;
+
+  // Whether to flush the crx file after putting into |local_cache_|.
+  bool flush_on_put_ = false;
+
+  bool use_null_connector_ = false;
+
+  // This is the list of extensions currently configured.
+  std::unique_ptr<base::DictionaryValue> extensions_;
+
+  // This contains extensions that are both currently configured
+  // and that have a valid crx in the cache.
+  std::unique_ptr<base::DictionaryValue> cached_extensions_;
+
+  // Used to download the extensions and to check for updates.
+  std::unique_ptr<extensions::ExtensionDownloader> downloader_;
+
+  // Observes failures to install CRX files.
+  content::NotificationRegistrar notification_registrar_;
+
+  // Weak factory for callbacks.
+  base::WeakPtrFactory<ExternalCacheImpl> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExternalCacheImpl);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_EXTERNAL_CACHE_IMPL_H_
diff --git a/chrome/browser/chromeos/extensions/external_cache_unittest.cc b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
similarity index 69%
rename from chrome/browser/chromeos/extensions/external_cache_unittest.cc
rename to chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
index a6caf830..7d2e00f9 100644
--- a/chrome/browser/chromeos/extensions/external_cache_unittest.cc
+++ b/chrome/browser/chromeos/extensions/external_cache_impl_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/extensions/external_cache.h"
+#include "chrome/browser/chromeos/extensions/external_cache_impl.h"
 
 #include <map>
 #include <set>
@@ -16,6 +16,7 @@
 #include "base/run_loop.h"
 #include "base/task_scheduler/post_task.h"
 #include "base/values.h"
+#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/extensions/external_provider_impl.h"
@@ -40,42 +41,18 @@
 
 namespace chromeos {
 
-class TestExternalCache : public ExternalCache {
+class ExternalCacheImplTest : public testing::Test,
+                              public ExternalCacheDelegate {
  public:
-  TestExternalCache(const base::FilePath& cache_dir,
-                    net::URLRequestContextGetter* request_context,
-                const scoped_refptr<base::SequencedTaskRunner>&
-                    backend_task_runner,
-                Delegate* delegate,
-                bool always_check_updates,
-                bool wait_for_cache_initialization)
-    : ExternalCache(cache_dir, request_context, backend_task_runner, delegate,
-                    always_check_updates, wait_for_cache_initialization) {}
-
- protected:
-  service_manager::Connector* GetConnector() override {
-    return nullptr;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestExternalCache);
-};
-
-class ExternalCacheTest : public testing::Test,
-                          public ExternalCache::Delegate {
- public:
-  ExternalCacheTest()
-    : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
-  }
-  ~ExternalCacheTest() override {}
+  ExternalCacheImplTest()
+      : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
+  ~ExternalCacheImplTest() override = default;
 
   net::URLRequestContextGetter* request_context_getter() {
     return request_context_getter_.get();
   }
 
-  const base::DictionaryValue* provided_prefs() {
-    return prefs_.get();
-  }
+  const base::DictionaryValue* provided_prefs() { return prefs_.get(); }
 
   // testing::Test overrides:
   void SetUp() override {
@@ -85,11 +62,12 @@
     fetcher_factory_.reset(new net::TestURLFetcherFactory());
   }
 
-  // ExternalCache::Delegate:
+  // ExternalCacheDelegate:
   void OnExtensionListsUpdated(const base::DictionaryValue* prefs) override {
     prefs_.reset(prefs->DeepCopy());
   }
-
+  void OnExtensionLoadedInCache(const std::string& id) override {}
+  void OnExtensionDownloadFailed(const std::string& id) override {}
   std::string GetInstalledExtensionVersion(const std::string& id) override {
     std::map<std::string, std::string>::iterator it =
         installed_extensions_.find(id);
@@ -109,8 +87,8 @@
   }
 
   void CreateFlagFile(const base::FilePath& dir) {
-    CreateFile(dir.Append(
-        extensions::LocalExtensionCache::kCacheReadyFlagFileName));
+    CreateFile(
+        dir.Append(extensions::LocalExtensionCache::kCacheReadyFlagFileName));
   }
 
   void CreateExtensionFile(const base::FilePath& dir,
@@ -133,8 +111,9 @@
       bool from_webstore) {
     auto entry = base::MakeUnique<base::DictionaryValue>();
     entry->SetString(extensions::ExternalProviderImpl::kExternalUpdateUrl,
-        from_webstore ? extension_urls::GetWebstoreUpdateUrl().spec()
-                      : kNonWebstoreUpdateUrl);
+                     from_webstore
+                         ? extension_urls::GetWebstoreUpdateUrl().spec()
+                         : kNonWebstoreUpdateUrl);
     return entry;
   }
 
@@ -157,15 +136,16 @@
   ScopedTestDeviceSettingsService test_device_settings_service_;
   ScopedTestCrosSettings test_cros_settings_;
 
-  DISALLOW_COPY_AND_ASSIGN(ExternalCacheTest);
+  DISALLOW_COPY_AND_ASSIGN(ExternalCacheImplTest);
 };
 
-TEST_F(ExternalCacheTest, Basic) {
+TEST_F(ExternalCacheImplTest, Basic) {
   base::FilePath cache_dir(CreateCacheDir(false));
-  TestExternalCache external_cache(
+  ExternalCacheImpl external_cache(
       cache_dir, request_context_getter(),
       base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}), this, true,
       false);
+  external_cache.use_null_connector_for_test();
 
   std::unique_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
   prefs->Set(kTestExtensionId1, CreateEntryWithUpdateUrl(true));
@@ -184,12 +164,11 @@
   // File in cache from Webstore.
   const base::DictionaryValue* entry1 = NULL;
   ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId1, &entry1));
-  EXPECT_FALSE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalUpdateUrl));
-  EXPECT_TRUE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalCrx));
-  EXPECT_TRUE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalVersion));
+  EXPECT_FALSE(
+      entry1->HasKey(extensions::ExternalProviderImpl::kExternalUpdateUrl));
+  EXPECT_TRUE(entry1->HasKey(extensions::ExternalProviderImpl::kExternalCrx));
+  EXPECT_TRUE(
+      entry1->HasKey(extensions::ExternalProviderImpl::kExternalVersion));
   bool from_webstore = false;
   EXPECT_TRUE(entry1->GetBoolean(
       extensions::ExternalProviderImpl::kIsFromWebstore, &from_webstore));
@@ -198,14 +177,13 @@
   // File in cache not from Webstore.
   const base::DictionaryValue* entry3 = NULL;
   ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId3, &entry3));
-  EXPECT_FALSE(entry3->HasKey(
-      extensions::ExternalProviderImpl::kExternalUpdateUrl));
-  EXPECT_TRUE(entry3->HasKey(
-      extensions::ExternalProviderImpl::kExternalCrx));
-  EXPECT_TRUE(entry3->HasKey(
-      extensions::ExternalProviderImpl::kExternalVersion));
-  EXPECT_FALSE(entry3->HasKey(
-      extensions::ExternalProviderImpl::kIsFromWebstore));
+  EXPECT_FALSE(
+      entry3->HasKey(extensions::ExternalProviderImpl::kExternalUpdateUrl));
+  EXPECT_TRUE(entry3->HasKey(extensions::ExternalProviderImpl::kExternalCrx));
+  EXPECT_TRUE(
+      entry3->HasKey(extensions::ExternalProviderImpl::kExternalVersion));
+  EXPECT_FALSE(
+      entry3->HasKey(extensions::ExternalProviderImpl::kIsFromWebstore));
 
   // Update from Webstore.
   base::FilePath temp_dir(CreateTempDir());
@@ -221,18 +199,17 @@
 
   const base::DictionaryValue* entry2 = NULL;
   ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId2, &entry2));
-  EXPECT_FALSE(entry2->HasKey(
-      extensions::ExternalProviderImpl::kExternalUpdateUrl));
-  EXPECT_TRUE(entry2->HasKey(
-      extensions::ExternalProviderImpl::kExternalCrx));
-  EXPECT_TRUE(entry2->HasKey(
-      extensions::ExternalProviderImpl::kExternalVersion));
+  EXPECT_FALSE(
+      entry2->HasKey(extensions::ExternalProviderImpl::kExternalUpdateUrl));
+  EXPECT_TRUE(entry2->HasKey(extensions::ExternalProviderImpl::kExternalCrx));
+  EXPECT_TRUE(
+      entry2->HasKey(extensions::ExternalProviderImpl::kExternalVersion));
   from_webstore = false;
   EXPECT_TRUE(entry2->GetBoolean(
       extensions::ExternalProviderImpl::kIsFromWebstore, &from_webstore));
   EXPECT_TRUE(from_webstore);
-  EXPECT_TRUE(base::PathExists(
-      GetExtensionFile(cache_dir, kTestExtensionId2, "2")));
+  EXPECT_TRUE(
+      base::PathExists(GetExtensionFile(cache_dir, kTestExtensionId2, "2")));
 
   // Update not from Webstore.
   base::FilePath temp_file4 = temp_dir.Append("d.crx");
@@ -247,31 +224,29 @@
 
   const base::DictionaryValue* entry4 = NULL;
   ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId4, &entry4));
-  EXPECT_FALSE(entry4->HasKey(
-      extensions::ExternalProviderImpl::kExternalUpdateUrl));
-  EXPECT_TRUE(entry4->HasKey(
-      extensions::ExternalProviderImpl::kExternalCrx));
-  EXPECT_TRUE(entry4->HasKey(
-      extensions::ExternalProviderImpl::kExternalVersion));
-  EXPECT_FALSE(entry4->HasKey(
-      extensions::ExternalProviderImpl::kIsFromWebstore));
-  EXPECT_TRUE(base::PathExists(
-      GetExtensionFile(cache_dir, kTestExtensionId4, "4")));
+  EXPECT_FALSE(
+      entry4->HasKey(extensions::ExternalProviderImpl::kExternalUpdateUrl));
+  EXPECT_TRUE(entry4->HasKey(extensions::ExternalProviderImpl::kExternalCrx));
+  EXPECT_TRUE(
+      entry4->HasKey(extensions::ExternalProviderImpl::kExternalVersion));
+  EXPECT_FALSE(
+      entry4->HasKey(extensions::ExternalProviderImpl::kIsFromWebstore));
+  EXPECT_TRUE(
+      base::PathExists(GetExtensionFile(cache_dir, kTestExtensionId4, "4")));
 
   // Damaged file should be removed from disk.
   external_cache.OnDamagedFileDetected(
       GetExtensionFile(cache_dir, kTestExtensionId2, "2"));
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(provided_prefs()->size(), 3ul);
-  EXPECT_FALSE(base::PathExists(
-      GetExtensionFile(cache_dir, kTestExtensionId2, "2")));
+  EXPECT_FALSE(
+      base::PathExists(GetExtensionFile(cache_dir, kTestExtensionId2, "2")));
 
   // Shutdown with callback OnExtensionListsUpdated that clears prefs.
   std::unique_ptr<base::DictionaryValue> empty(new base::DictionaryValue);
   external_cache.Shutdown(
-        base::Bind(&ExternalCacheTest::OnExtensionListsUpdated,
-                   base::Unretained(this),
-                   base::Unretained(empty.get())));
+      base::BindOnce(&ExternalCacheImplTest::OnExtensionListsUpdated,
+                     base::Unretained(this), base::Unretained(empty.get())));
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(provided_prefs()->size(), 0ul);
 
@@ -279,16 +254,17 @@
   external_cache.OnDamagedFileDetected(
       GetExtensionFile(cache_dir, kTestExtensionId4, "4"));
   content::RunAllTasksUntilIdle();
-  EXPECT_TRUE(base::PathExists(
-      GetExtensionFile(cache_dir, kTestExtensionId4, "4")));
+  EXPECT_TRUE(
+      base::PathExists(GetExtensionFile(cache_dir, kTestExtensionId4, "4")));
 }
 
-TEST_F(ExternalCacheTest, PreserveInstalled) {
+TEST_F(ExternalCacheImplTest, PreserveInstalled) {
   base::FilePath cache_dir(CreateCacheDir(false));
-  TestExternalCache external_cache(
+  ExternalCacheImpl external_cache(
       cache_dir, request_context_getter(),
       base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}), this, true,
       false);
+  external_cache.use_null_connector_for_test();
 
   std::unique_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
   prefs->Set(kTestExtensionId1, CreateEntryWithUpdateUrl(true));
@@ -305,12 +281,11 @@
   // File not in cache but extension installed.
   const base::DictionaryValue* entry1 = NULL;
   ASSERT_TRUE(provided_prefs()->GetDictionary(kTestExtensionId1, &entry1));
-  EXPECT_TRUE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalUpdateUrl));
-  EXPECT_FALSE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalCrx));
-  EXPECT_FALSE(entry1->HasKey(
-      extensions::ExternalProviderImpl::kExternalVersion));
+  EXPECT_TRUE(
+      entry1->HasKey(extensions::ExternalProviderImpl::kExternalUpdateUrl));
+  EXPECT_FALSE(entry1->HasKey(extensions::ExternalProviderImpl::kExternalCrx));
+  EXPECT_FALSE(
+      entry1->HasKey(extensions::ExternalProviderImpl::kExternalVersion));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/test_external_cache.cc b/chrome/browser/chromeos/extensions/test_external_cache.cc
new file mode 100644
index 0000000..6d3f29b
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/test_external_cache.cc
@@ -0,0 +1,151 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/test_external_cache.h"
+
+#include <utility>
+
+#include "base/callback.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/extensions/external_cache_delegate.h"
+#include "chrome/browser/extensions/external_provider_impl.h"
+
+namespace chromeos {
+
+TestExternalCache::TestExternalCache(ExternalCacheDelegate* delegate,
+                                     bool always_check_for_updates)
+    : delegate_(delegate),
+      always_check_for_updates_(always_check_for_updates) {}
+
+TestExternalCache::~TestExternalCache() = default;
+
+const base::DictionaryValue* TestExternalCache::GetCachedExtensions() {
+  return &cached_extensions_;
+}
+
+void TestExternalCache::Shutdown(base::OnceClosure callback) {
+  std::move(callback).Run();
+}
+
+void TestExternalCache::UpdateExtensionsList(
+    std::unique_ptr<base::DictionaryValue> prefs) {
+  DCHECK(prefs);
+
+  configured_extensions_ = std::move(prefs);
+  cached_extensions_.Clear();
+
+  if (configured_extensions_->empty()) {
+    delegate_->OnExtensionListsUpdated(&cached_extensions_);
+    return;
+  }
+
+  UpdateCachedExtensions();
+}
+
+void TestExternalCache::OnDamagedFileDetected(const base::FilePath& path) {
+  for (const auto& entry : cached_extensions_.DictItems()) {
+    const base::Value* entry_path = entry.second.FindKeyOfType(
+        extensions::ExternalProviderImpl::kExternalCrx,
+        base::Value::Type::STRING);
+    if (entry_path && entry_path->GetString() == path.value()) {
+      RemoveExtensions({entry.first});
+      return;
+    }
+  }
+}
+
+void TestExternalCache::RemoveExtensions(const std::vector<std::string>& ids) {
+  if (ids.empty())
+    return;
+
+  for (const auto& id : ids) {
+    cached_extensions_.RemoveKey(id);
+    configured_extensions_->RemoveKey(id);
+    crx_cache_.erase(id);
+  }
+
+  delegate_->OnExtensionListsUpdated(&cached_extensions_);
+}
+
+bool TestExternalCache::GetExtension(const std::string& id,
+                                     base::FilePath* file_path,
+                                     std::string* version) {
+  if (!crx_cache_.count(id))
+    return false;
+  *file_path = base::FilePath(crx_cache_[id].path);
+  *version = crx_cache_[id].version;
+  return true;
+}
+
+bool TestExternalCache::ExtensionFetchPending(const std::string& id) {
+  return configured_extensions_->FindKey(id) && !cached_extensions_.FindKey(id);
+}
+
+void TestExternalCache::PutExternalExtension(
+    const std::string& id,
+    const base::FilePath& crx_file_path,
+    const std::string& version,
+    PutExternalExtensionCallback callback) {
+  AddEntryToCrxCache(id, crx_file_path.value(), version);
+  std::move(callback).Run(id, true);
+}
+
+bool TestExternalCache::SimulateExtensionDownloadFinished(
+    const std::string& id,
+    const std::string& crx_path,
+    const std::string& version) {
+  if (!pending_downloads_.count(id))
+    return false;
+
+  AddEntryToCrxCache(id, crx_path, version);
+  delegate_->OnExtensionLoadedInCache(id);
+  return true;
+}
+
+bool TestExternalCache::SimulateExtensionDownloadFailed(const std::string& id) {
+  if (!pending_downloads_.count(id))
+    return false;
+
+  delegate_->OnExtensionDownloadFailed(id);
+  return true;
+}
+
+void TestExternalCache::UpdateCachedExtensions() {
+  for (const auto& entry : configured_extensions_->DictItems()) {
+    DCHECK(entry.second.is_dict());
+    if (GetExtensionUpdateUrl(entry.second, always_check_for_updates_)
+            .is_valid()) {
+      pending_downloads_.insert(entry.first);
+    }
+
+    if (crx_cache_.count(entry.first)) {
+      cached_extensions_.SetKey(
+          entry.first,
+          GetExtensionValueToCache(entry.second, crx_cache_[entry.first].path,
+                                   crx_cache_[entry.first].version));
+    } else if (ShouldCacheImmediately(
+                   entry.second,
+                   delegate_->GetInstalledExtensionVersion(entry.first))) {
+      cached_extensions_.SetKey(entry.first, entry.second.Clone());
+    }
+  }
+
+  delegate_->OnExtensionListsUpdated(&cached_extensions_);
+}
+
+void TestExternalCache::AddEntryToCrxCache(const std::string& id,
+                                           const std::string& crx_path,
+                                           const std::string& version) {
+  crx_cache_[id] = {crx_path, version};
+
+  const base::Value* extension =
+      configured_extensions_->FindKeyOfType(id, base::Value::Type::DICTIONARY);
+  if (extension) {
+    cached_extensions_.SetKey(
+        id, GetExtensionValueToCache(*extension, crx_path, version));
+    delegate_->OnExtensionListsUpdated(&cached_extensions_);
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/test_external_cache.h b/chrome/browser/chromeos/extensions/test_external_cache.h
new file mode 100644
index 0000000..5c649e61
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/test_external_cache.h
@@ -0,0 +1,109 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_TEST_EXTERNAL_CACHE_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_TEST_EXTERNAL_CACHE_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/extensions/external_cache.h"
+
+namespace chromeos {
+
+class ExternalCacheDelegate;
+
+// External cache implementation to be used in tests - instead of using a
+// real local extension cache, which saves cached extension data to disk, it
+// keeps cached extension CRX info in memory.
+class TestExternalCache : public ExternalCache {
+ public:
+  TestExternalCache(ExternalCacheDelegate* delegate,
+                    bool always_check_for_updates);
+  ~TestExternalCache() override;
+
+  // ExternalCache:
+  const base::DictionaryValue* GetCachedExtensions() override;
+  void Shutdown(base::OnceClosure callback) override;
+  void UpdateExtensionsList(
+      std::unique_ptr<base::DictionaryValue> prefs) override;
+  void OnDamagedFileDetected(const base::FilePath& path) override;
+  void RemoveExtensions(const std::vector<std::string>& ids) override;
+  bool GetExtension(const std::string& id,
+                    base::FilePath* file_path,
+                    std::string* version) override;
+  bool ExtensionFetchPending(const std::string& id) override;
+  void PutExternalExtension(const std::string& id,
+                            const base::FilePath& crx_file_path,
+                            const std::string& version,
+                            PutExternalExtensionCallback callback) override;
+
+  // Simulates extension CRX download succeeding - it adds the extension
+  // information to |cache_|.
+  // |id| - the "downloaded" extension ID.
+  // |crx_path| - the path to which the CRX is "downloaded".
+  // |version| - the "downloaded" extension version.
+  // Returns whether the extension information has actually been saved. This
+  // will return false if the cache does not think that the extension's
+  // downaload is pending.
+  bool SimulateExtensionDownloadFinished(const std::string& id,
+                                         const std::string& crx_path,
+                                         const std::string& version);
+
+  // Simulates the extension's download failure. This will remove the extension
+  // info from the set of extensions tracked in this external cache.
+  // Returns whether the extension information has actually been changed. This
+  // will return false if the cache does not think that the extension's
+  // downaload is pending.
+  bool SimulateExtensionDownloadFailed(const std::string& id);
+
+  // Set of the extension IDs in download pending state. Note that |this| does
+  // not actually initiate the download, the user is expected to call either
+  // SimulateExtensionDownloadFinished(), or SimulateExtensionDownloadFailed()
+  // in order to remove an extension from this state and update the extension's
+  // CRX information tracked by the external cache.
+  const std::set<std::string>& pending_downloads() const {
+    return pending_downloads_;
+  }
+
+ private:
+  // An extension CRX information tracked by |this|.
+  struct CrxCacheEntry {
+    // The extension CRX path.
+    std::string path;
+
+    // The extension version associtated with the extension CRX.
+    std::string version;
+  };
+
+  // Updates locally tracked state - called when the set of
+  // |configured_extensions_| changes. It updates |cached_extensions_| and
+  // adds extensions to |pending_downloads_| as needed.
+  void UpdateCachedExtensions();
+
+  // Adds an extension's CRX information to |crx_cache_|.
+  void AddEntryToCrxCache(const std::string& id,
+                          const std::string& crx_path,
+                          const std::string& version);
+
+  ExternalCacheDelegate* const delegate_;
+  const bool always_check_for_updates_;
+
+  std::unique_ptr<base::DictionaryValue> configured_extensions_;
+  base::DictionaryValue cached_extensions_;
+
+  std::set<std::string> pending_downloads_;
+  std::map<std::string, CrxCacheEntry> crx_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestExternalCache);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_TEST_EXTERNAL_CACHE_H_
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
index 53701b66..e013b0b 100644
--- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/cast_config_client_media_router.h"
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
deleted file mode 100644
index 4c46689..0000000
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
-
-#include <stddef.h>
-
-#include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h"
-#include "chrome/browser/ui/ash/session_controller_client.h"
-#include "chrome/browser/ui/ash/wallpaper_controller_client.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "chromeos/chromeos_switches.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "components/session_manager/core/session_manager.h"
-#include "components/signin/core/account_id/account_id.h"
-#include "components/user_manager/user.h"
-#include "components/user_manager/user_manager.h"
-#include "components/user_manager/user_names.h"
-#include "components/wallpaper/wallpaper_files_id.h"
-#include "components/wallpaper/wallpaper_resizer.h"
-#include "content/public/test/test_utils.h"
-#include "ui/aura/env.h"
-#include "ui/display/manager/display_manager.h"
-#include "ui/display/test/display_manager_test_api.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/image/image_skia.h"
-
-using session_manager::SessionManager;
-using wallpaper::WallpaperInfo;
-using wallpaper::WALLPAPER_LAYOUT_CENTER;
-using wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED;
-using wallpaper::WALLPAPER_LAYOUT_STRETCH;
-using wallpaper::WALLPAPER_LAYOUT_TILE;
-
-namespace chromeos {
-
-namespace {
-
-constexpr char kTestUser1[] = "test1@domain.com";
-constexpr char kTestUser1GaiaId[] = "0000000001";
-constexpr char kTestUser1Hash[] = "test1@domain.com-hash";
-constexpr char kTestUser2[] = "test2@domain.com";
-constexpr char kTestUser2GaiaId[] = "0000000002";
-constexpr char kTestUser2Hash[] = "test2@domain.com-hash";
-
-}  // namespace
-
-class WallpaperManagerBrowserTest : public InProcessBrowserTest {
- public:
-  WallpaperManagerBrowserTest() : controller_(NULL), local_state_(NULL) {}
-
-  ~WallpaperManagerBrowserTest() override {}
-
-  void SetUpOnMainThread() override {
-    controller_ = ash::Shell::Get()->wallpaper_controller();
-    controller_->set_wallpaper_reload_delay_for_test(0);
-    local_state_ = g_browser_process->local_state();
-    UpdateDisplay("800x600");
-  }
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitch(switches::kLoginManager);
-    command_line->AppendSwitchASCII(switches::kLoginProfile, "user");
-  }
-
-  void TearDownOnMainThread() override { controller_ = NULL; }
-
-  // Update the display configuration as given in |display_specs|.  See
-  // display::test::DisplayManagerTestApi::UpdateDisplay for more details.
-  void UpdateDisplay(const std::string& display_specs) {
-    display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager())
-        .UpdateDisplay(display_specs);
-  }
-
-  void WaitAsyncWallpaperLoadStarted() { base::RunLoop().RunUntilIdle(); }
-
- protected:
-  // Return custom wallpaper path. Create directory if not exist.
-  base::FilePath GetCustomWallpaperPath(
-      const char* sub_dir,
-      const wallpaper::WallpaperFilesId& wallpaper_files_id,
-      const std::string& id) {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    base::FilePath wallpaper_path =
-        ash::WallpaperController::GetCustomWallpaperPath(
-            sub_dir, wallpaper_files_id.id(), id);
-    if (!base::DirectoryExists(wallpaper_path.DirName()))
-      base::CreateDirectory(wallpaper_path.DirName());
-
-    return wallpaper_path;
-  }
-
-  // Logs in |account_id|.
-  void LogIn(const AccountId& account_id, const std::string& user_id_hash) {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-    SessionManager::Get()->CreateSession(account_id, user_id_hash,
-                                         false /* is_child */);
-    SessionManager::Get()->SessionStarted();
-    // Flush to ensure the created session and ACTIVE state reaches ash.
-    SessionControllerClient::FlushForTesting();
-    WaitAsyncWallpaperLoadStarted();
-  }
-
-  // Logs in |account_id| and sets it as child account.
-  void LogInAsChild(const AccountId& account_id,
-                    const std::string& user_id_hash) {
-    SessionManager::Get()->CreateSession(account_id, user_id_hash,
-                                         true /* is_child */);
-    const user_manager::User* user =
-        user_manager::UserManager::Get()->FindUser(account_id);
-    CHECK(user->GetType() == user_manager::USER_TYPE_CHILD);
-    // TODO(jamescook): For some reason creating the shelf here (which is what
-    // would happen in normal login) causes the child wallpaper tests to fail
-    // with the wallpaper having alpha. This looks like the wallpaper is mid-
-    // animation, but happens even if animations are disabled. Something is
-    // wrong with how these tests simulate login.
-  }
-
-  ash::WallpaperController* controller_;
-  PrefService* local_state_;
-  std::unique_ptr<base::CommandLine> wallpaper_manager_command_line_;
-
-  // Directory created by CreateCmdlineWallpapers () to store default
-  // wallpaper images.
-  std::unique_ptr<base::ScopedTempDir> wallpaper_dir_;
-
-  const AccountId test_account_id1_ =
-      AccountId::FromUserEmailGaiaId(kTestUser1, kTestUser1GaiaId);
-  const AccountId test_account_id2_ =
-      AccountId::FromUserEmailGaiaId(kTestUser2, kTestUser2GaiaId);
-
-  const wallpaper::WallpaperFilesId test_account1_wallpaper_files_id_ =
-      wallpaper::WallpaperFilesId::FromString(kTestUser1Hash);
-  const wallpaper::WallpaperFilesId test_account2_wallpaper_files_id_ =
-      wallpaper::WallpaperFilesId::FromString(kTestUser2Hash);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(WallpaperManagerBrowserTest);
-};
-
-// Test for http://crbug.com/265689. When hooked up a large external monitor,
-// the default large resolution wallpaper should load.
-IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest,
-                       HotPlugInScreenAtGAIALoginScreen) {
-  UpdateDisplay("800x600");
-  // Set initial wallpaper to the default wallpaper.
-  ash::Shell::Get()->wallpaper_controller()->ShowDefaultWallpaperForTesting();
-
-  // Hook up a 2000x2000 display. The large resolution custom wallpaper should
-  // be loaded.
-  UpdateDisplay("800x600,2000x2000");
-}
-
-class TestObserver : public WallpaperManager::Observer {
- public:
-  explicit TestObserver(WallpaperManager* wallpaper_manager)
-      : update_wallpaper_count_(0), wallpaper_manager_(wallpaper_manager) {
-    DCHECK(wallpaper_manager_);
-    wallpaper_manager_->AddObserver(this);
-  }
-
-  ~TestObserver() override { wallpaper_manager_->RemoveObserver(this); }
-
-  void OnUpdateWallpaperForTesting() override { ++update_wallpaper_count_; }
-
-  int GetUpdateWallpaperCountAndReset() {
-    const size_t old = update_wallpaper_count_;
-    update_wallpaper_count_ = 0;
-    return old;
-  }
-
- private:
-  int update_wallpaper_count_;
-  WallpaperManager* wallpaper_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestObserver);
-};
-
-// TODO: test is flaky. http://crbug.com/691548.
-IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, DISABLED_DisplayChange) {
-  TestObserver observer(WallpaperManager::Get());
-
-  // Set the wallpaper to ensure that UpdateWallpaper() will be called when the
-  // display configuration changes.
-  gfx::ImageSkia image = wallpaper_manager_test_utils::CreateTestImage(
-      640, 480, wallpaper_manager_test_utils::kSmallCustomWallpaperColor);
-  WallpaperInfo info("", WALLPAPER_LAYOUT_STRETCH, wallpaper::DEFAULT,
-                     base::Time::Now().LocalMidnight());
-  controller_->SetWallpaperImage(image, info);
-
-  // Small wallpaper images should be used for configurations less than or
-  // equal to kSmallWallpaperMaxWidth by kSmallWallpaperMaxHeight, even if
-  // multiple displays are connected.
-  UpdateDisplay("800x600");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_SMALL,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
-
-  UpdateDisplay("800x600,800x600");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_SMALL,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
-
-  UpdateDisplay("1366x800");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_SMALL,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  // At larger sizes, large wallpapers should be used.
-  UpdateDisplay("1367x800");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_LARGE,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  UpdateDisplay("1367x801");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_LARGE,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  UpdateDisplay("2560x1700");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_LARGE,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  // Rotated smaller screen may use larger image.
-  UpdateDisplay("800x600/r");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_SMALL,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  UpdateDisplay("800x600/r,800x600");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_SMALL,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-  UpdateDisplay("1366x800/r");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(ash::WallpaperController::WALLPAPER_RESOLUTION_LARGE,
-            ash::WallpaperController::GetAppropriateResolution());
-  EXPECT_EQ(1, observer.GetUpdateWallpaperCountAndReset());
-
-  // Max display size didn't change.
-  UpdateDisplay("900x800/r,400x1366");
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(0, observer.GetUpdateWallpaperCountAndReset());
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc b/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
index 7f60562..70573c2 100644
--- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
+++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber_unittest.cc
@@ -43,6 +43,9 @@
                void(data_use_measurement::DataUse* data_use));
   MOCK_METHOD1(OnPageLoadConcluded,
                void(data_use_measurement::DataUse* data_use));
+  MOCK_METHOD2(OnNetworkBytesUpdate,
+               void(const net::URLRequest& request,
+                    data_use_measurement::DataUse* data_use));
 };
 
 }  // namespace
@@ -482,6 +485,11 @@
   EXPECT_EQ(2u, recorders().size());
   DataUse* data_use = &recorders().back().data_use();
 
+  EXPECT_CALL(mock_observer, OnNetworkBytesUpdate(testing::_, data_use))
+      .Times(2);
+  ascriber()->OnNetworkBytesSent(request.get(), 2);
+  ascriber()->OnNetworkBytesReceived(request.get(), 2);
+
   EXPECT_CALL(mock_observer, OnPageResourceLoad(testing::_, data_use)).Times(1);
   ascriber()->OnUrlRequestCompleted(*request, false);
 
@@ -534,6 +542,11 @@
   EXPECT_EQ(2u, recorders().size());
   DataUse* data_use = &recorders().back().data_use();
 
+  EXPECT_CALL(mock_observer, OnNetworkBytesUpdate(testing::_, data_use))
+      .Times(2);
+  ascriber()->OnNetworkBytesSent(request.get(), 2);
+  ascriber()->OnNetworkBytesReceived(request.get(), 2);
+
   EXPECT_CALL(mock_observer, OnPageResourceLoad(testing::_, data_use)).Times(1);
   ascriber()->OnUrlRequestCompleted(*request, false);
 
diff --git a/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.cc b/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.cc
index c367933..e5c55a7 100644
--- a/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.cc
+++ b/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.cc
@@ -30,5 +30,10 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
+void PageLoadObserver::OnNetworkBytesUpdate(const net::URLRequest& request,
+                                            DataUse* data_use) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
 }  // namespace page_load_capping
 }  // namespace data_use_measurement
diff --git a/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.h b/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.h
index 954ca67d..e21e94b 100644
--- a/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.h
+++ b/chrome/browser/data_use_measurement/page_load_capping/page_load_observer.h
@@ -24,6 +24,8 @@
                           DataUse* data_use) override;
   void OnPageDidFinishLoad(DataUse* data_use) override;
   void OnPageLoadConcluded(DataUse* data_use) override;
+  void OnNetworkBytesUpdate(const net::URLRequest& request,
+                            DataUse* data_use) override;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
index 97fa36f..2c6c5c5 100644
--- a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/extensions/test_extension_system.h"
-#include "chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h"
+#include "chrome/browser/media/router/test/mock_dns_sd_registry.h"
 #include "chrome/common/extensions/api/mdns.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/test/mock_render_process_host.h"
diff --git a/chrome/browser/extensions/api/mdns/mdns_apitest.cc b/chrome/browser/extensions/api/mdns/mdns_apitest.cc
index db83c5fd..2d241e4 100644
--- a/chrome/browser/extensions/api/mdns/mdns_apitest.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_apitest.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/extensions/api/mdns/mdns_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h"
+#include "chrome/browser/media/router/test/mock_dns_sd_registry.h"
 #include "chrome/common/extensions/api/mdns.h"
 #include "extensions/common/switches.h"
 #include "extensions/test/result_catcher.h"
diff --git a/chrome/browser/extensions/api/tab_capture/offscreen_tab.cc b/chrome/browser/extensions/api/tab_capture/offscreen_tab.cc
index f6e1c50..0f2740e 100644
--- a/chrome/browser/extensions/api/tab_capture/offscreen_tab.cc
+++ b/chrome/browser/extensions/api/tab_capture/offscreen_tab.cc
@@ -13,8 +13,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
-#include "chrome/browser/media/router/presentation_navigation_policy.h"
-#include "chrome/browser/media/router/receiver_presentation_service_delegate_impl.h"  // nogncheck
+#include "chrome/browser/media/router/presentation/presentation_navigation_policy.h"
+#include "chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h"  // nogncheck
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/web_contents_sizer.h"
 #include "content/public/browser/keyboard_event_processing_result.h"
diff --git a/chrome/browser/extensions/api/tab_capture/offscreen_tab.h b/chrome/browser/extensions/api/tab_capture/offscreen_tab.h
index 0860e2e..f302682e 100644
--- a/chrome/browser/extensions/api/tab_capture/offscreen_tab.h
+++ b/chrome/browser/extensions/api/tab_capture/offscreen_tab.h
@@ -14,7 +14,7 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chrome/browser/media/router/independent_otr_profile_manager.h"
+#include "chrome/browser/media/router/presentation/independent_otr_profile_manager.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 6f0d8bd..de7bb89 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -9,11 +9,6 @@
 
 namespace flag_descriptions {
 
-const char kStopLoadingInBackgroundName[] = "Stop loading in background";
-const char kStopLoadingInBackgroundDescription[] =
-    "Stop loading tasks and loading "
-    "resources, in the background, after certain grace time.";
-
 const char kAccelerated2dCanvasName[] = "Accelerated 2D canvas";
 const char kAccelerated2dCanvasDescription[] =
     "Enables the use of the GPU to perform 2d canvas rendering instead of "
@@ -760,6 +755,10 @@
     "Overrides the built-in software rendering list and enables "
     "GPU-acceleration on unsupported system configurations.";
 
+const char kIgnorePreviewsBlacklistName[] = "Ignore Previews Blacklist";
+const char kIgnorePreviewsBlacklistDescription[] =
+    "Ignore decisions made by the PreviewsBlackList";
+
 const char kImportantSitesInCbdName[] =
     "Important sites options in clear browsing data dialog";
 const char kImportantSitesInCbdDescription[] =
@@ -1351,6 +1350,16 @@
 const char kSpellingFeedbackFieldTrialDescription[] =
     "Enable the field trial for sending user feedback to spelling service.";
 
+const char kStopInBackgroundName[] = "Stop in background";
+const char kStopInBackgroundDescription[] =
+    "Stop scheduler task queues, in the background, "
+    " after certain grace time.";
+
+const char kStopLoadingInBackgroundName[] = "Stop loading in background";
+const char kStopLoadingInBackgroundDescription[] =
+    "Stop loading tasks and loading "
+    "resources, in the background, after certain grace time.";
+
 const char kSuggestionsWithSubStringMatchName[] =
     "Substring matching for Autofill suggestions";
 const char kSuggestionsWithSubStringMatchDescription[] =
@@ -2134,10 +2143,6 @@
     "A new type of inline autocomplete for the omnibox that works with "
     "keyboards that compose text.";
 
-const char kTranslateCompactUIName[] = "New Translate Infobar";
-const char kTranslateCompactUIDescription[] =
-    "Enable the new Translate compact infobar UI.";
-
 const char kUpdateMenuBadgeName[] = "Force show update menu badge";
 const char kUpdateMenuBadgeDescription[] =
     "When enabled, an update badge will be shown on the app menu button.";
@@ -2209,10 +2214,6 @@
     "Show a OneGoogleBar on the local New Tab page if Google is the default "
     "search engine.";
 
-const char kPauseBackgroundTabsName[] = "Pause background tabs";
-const char kPauseBackgroundTabsDescription[] =
-    "Pause timers in background tabs after 5 minutes on desktop.";
-
 const char kUseGoogleLocalNtpName[] = "Enable using the Google local NTP";
 const char kUseGoogleLocalNtpDescription[] =
     "Use the local New Tab page if Google is the default search engine.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index c93f4a3..9d4873a 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -477,6 +477,9 @@
 extern const char kIgnoreGpuBlacklistName[];
 extern const char kIgnoreGpuBlacklistDescription[];
 
+extern const char kIgnorePreviewsBlacklistName[];
+extern const char kIgnorePreviewsBlacklistDescription[];
+
 extern const char kImportantSitesInCbdName[];
 extern const char kImportantSitesInCbdDescription[];
 
@@ -822,6 +825,9 @@
 extern const char kSpellingFeedbackFieldTrialName[];
 extern const char kSpellingFeedbackFieldTrialDescription[];
 
+extern const char kStopInBackgroundName[];
+extern const char kStopInBackgroundDescription[];
+
 extern const char kStopLoadingInBackgroundName[];
 extern const char kStopLoadingInBackgroundDescription[];
 
@@ -1300,9 +1306,6 @@
 extern const char kSpannableInlineAutocompleteName[];
 extern const char kSpannableInlineAutocompleteDescription[];
 
-extern const char kTranslateCompactUIName[];
-extern const char kTranslateCompactUIDescription[];
-
 extern const char kUpdateMenuBadgeName[];
 extern const char kUpdateMenuBadgeDescription[];
 
@@ -1348,9 +1351,6 @@
 extern const char kOneGoogleBarOnLocalNtpName[];
 extern const char kOneGoogleBarOnLocalNtpDescription[];
 
-extern const char kPauseBackgroundTabsName[];
-extern const char kPauseBackgroundTabsDescription[];
-
 extern const char kUseGoogleLocalNtpName[];
 extern const char kUseGoogleLocalNtpDescription[];
 
diff --git a/chrome/browser/loader/chrome_navigation_data.cc b/chrome/browser/loader/chrome_navigation_data.cc
index af6ef04..333cd349 100644
--- a/chrome/browser/loader/chrome_navigation_data.cc
+++ b/chrome/browser/loader/chrome_navigation_data.cc
@@ -5,8 +5,15 @@
 #include "chrome/browser/loader/chrome_navigation_data.h"
 
 #include "base/memory/ptr_util.h"
+#include "base/values.h"
 #include "net/url_request/url_request.h"
 
+namespace {
+const char* kDataReductionProxyDataKey = "data_reduction_proxy_data";
+const char* kPreviewsUserDataKey = "preview_user_data";
+const char* kPreviewsStateKey = "preview_state";
+}  // namespace
+
 const void* const kChromeNavigationDataUserDataKey =
     &kChromeNavigationDataUserDataKey;
 
@@ -15,6 +22,44 @@
 
 ChromeNavigationData::~ChromeNavigationData() {}
 
+base::Value ChromeNavigationData::ToValue() {
+  base::Value value(base::Value::Type::DICTIONARY);
+  if (data_reduction_proxy_data_) {
+    value.SetKey(kDataReductionProxyDataKey,
+                 data_reduction_proxy_data_->ToValue());
+  }
+
+  if (previews_user_data_) {
+    value.SetKey(kPreviewsUserDataKey, previews_user_data_->ToValue());
+  }
+
+  value.SetKey(kPreviewsStateKey, base::Value(previews_state_));
+
+  return value;
+}
+
+ChromeNavigationData::ChromeNavigationData(const base::Value& value)
+    : ChromeNavigationData() {
+  if (value.is_none())
+    return;
+
+  const base::Value* data_reduction_proxy_data =
+      value.FindKey(kDataReductionProxyDataKey);
+  if (data_reduction_proxy_data) {
+    data_reduction_proxy_data_ =
+        std::make_unique<data_reduction_proxy::DataReductionProxyData>(
+            *data_reduction_proxy_data);
+  }
+
+  const base::Value* previews_user_data = value.FindKey(kPreviewsUserDataKey);
+  if (previews_user_data) {
+    previews_user_data_ =
+        std::make_unique<previews::PreviewsUserData>(*previews_user_data);
+  }
+
+  previews_state_ = value.FindKey(kPreviewsStateKey)->GetInt();
+}
+
 ChromeNavigationData* ChromeNavigationData::GetDataAndCreateIfNecessary(
     net::URLRequest* request) {
   if (!request)
@@ -28,15 +73,3 @@
                        base::WrapUnique(data));
   return data;
 }
-
-std::unique_ptr<content::NavigationData> ChromeNavigationData::Clone() const {
-  std::unique_ptr<ChromeNavigationData> copy(new ChromeNavigationData());
-  if (data_reduction_proxy_data_) {
-    copy->SetDataReductionProxyData(data_reduction_proxy_data_->DeepCopy());
-  }
-  if (previews_user_data_) {
-    copy->set_previews_user_data(previews_user_data_->DeepCopy());
-  }
-  copy->previews_state_ = previews_state_;
-  return std::move(copy);
-}
diff --git a/chrome/browser/loader/chrome_navigation_data.h b/chrome/browser/loader/chrome_navigation_data.h
index 29fe6b6e..8189e386 100644
--- a/chrome/browser/loader/chrome_navigation_data.h
+++ b/chrome/browser/loader/chrome_navigation_data.h
@@ -11,24 +11,35 @@
 #include "base/supports_user_data.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 #include "components/previews/core/previews_user_data.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/common/previews_state.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 class URLRequest;
 }
 
-class ChromeNavigationData : public content::NavigationData,
-                             public base::SupportsUserData::Data {
+class ChromeNavigationData : public base::SupportsUserData::Data {
  public:
   ChromeNavigationData();
   ~ChromeNavigationData() override;
 
-  // Creates a new ChromeNavigationData that is a deep copy of the original. Any
-  // changes to the original after the clone is created will not be reflected in
-  // the clone.
-  // |data_reduction_proxy_data_| is deep copied.
-  std::unique_ptr<content::NavigationData> Clone() const override;
+  // Convert from/to a base::Value.
+  base::Value ToValue();
+
+  // Every time a ChromeNavigationData is constructed from a base::Value, a new
+  // instance of it and all of its children is built. If ChromeNavigationData
+  // becomes large or if many observers begin to use it, we should consider only
+  // deserializing the relevant part of ChromeNavigationData, not the whole
+  // object each time.
+  // Serialization is needed to transmit this object using Mojo. Another
+  // approach to consider would be to serialize the object before each mojo
+  // function call and immediatly reconstruct the object after that. Currently,
+  // ChromeNavigationData is serialized when it enters the content/ layer and
+  // reconstructed when it goes out.
+  explicit ChromeNavigationData(const base::Value& value);
 
   // Takes ownership of |data_reduction_proxy_data|.
   void SetDataReductionProxyData(
diff --git a/chrome/browser/loader/chrome_navigation_data_unittest.cc b/chrome/browser/loader/chrome_navigation_data_unittest.cc
index 75f2147..0afc3643 100644
--- a/chrome/browser/loader/chrome_navigation_data_unittest.cc
+++ b/chrome/browser/loader/chrome_navigation_data_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/memory/ptr_util.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 #include "components/previews/core/previews_user_data.h"
-#include "content/public/browser/navigation_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 class ChromeNavigationDataTest : public testing::Test {
@@ -33,24 +32,39 @@
   EXPECT_TRUE(data.previews_user_data());
 }
 
-TEST_F(ChromeNavigationDataTest, Clone) {
-  ChromeNavigationData data;
-  EXPECT_FALSE(data.GetDataReductionProxyData());
-  data.SetDataReductionProxyData(
-      std::make_unique<data_reduction_proxy::DataReductionProxyData>());
-  EXPECT_FALSE(data.previews_user_data());
-  data.set_previews_user_data(std::make_unique<previews::PreviewsUserData>(1u));
+TEST_F(ChromeNavigationDataTest, Serialization) {
+  // data_reduction_proxy
+  {
+    ChromeNavigationData chrome_navigation_data;
+    ChromeNavigationData clone_a(chrome_navigation_data.ToValue());
+    chrome_navigation_data.SetDataReductionProxyData(
+        std::make_unique<data_reduction_proxy::DataReductionProxyData>());
+    ChromeNavigationData clone_b(chrome_navigation_data.ToValue());
 
-  std::unique_ptr<content::NavigationData> clone_data = data.Clone();
-  ChromeNavigationData* clone_chrome_data =
-      static_cast<ChromeNavigationData*>(clone_data.get());
-  EXPECT_NE(&data, clone_data.get());
-  EXPECT_NE(&data, clone_chrome_data);
-  EXPECT_NE(data.GetDataReductionProxyData(),
-            clone_chrome_data->GetDataReductionProxyData());
-  EXPECT_NE(data.previews_user_data(), clone_chrome_data->previews_user_data());
-  EXPECT_TRUE(data.GetDataReductionProxyData());
-  EXPECT_TRUE(data.previews_user_data());
-  EXPECT_TRUE(clone_chrome_data->GetDataReductionProxyData());
-  EXPECT_TRUE(clone_chrome_data->previews_user_data());
+    EXPECT_FALSE(clone_a.GetDataReductionProxyData());
+    EXPECT_TRUE(clone_b.GetDataReductionProxyData());
+  }
+
+  // preview_user_data
+  {
+    ChromeNavigationData chrome_navigation_data;
+    ChromeNavigationData clone_a(chrome_navigation_data.ToValue());
+    chrome_navigation_data.set_previews_user_data(
+        std::make_unique<previews::PreviewsUserData>(1u));
+    ChromeNavigationData clone_b(chrome_navigation_data.ToValue());
+
+    EXPECT_FALSE(clone_a.previews_user_data());
+    EXPECT_TRUE(clone_b.previews_user_data());
+  }
+
+  // preview_state
+  {
+    ChromeNavigationData chrome_navigation_data;
+    ChromeNavigationData clone_a(chrome_navigation_data.ToValue());
+    chrome_navigation_data.set_previews_state(content::PREVIEWS_OFF);
+    ChromeNavigationData clone_b(chrome_navigation_data.ToValue());
+
+    EXPECT_EQ(content::PREVIEWS_UNSPECIFIED, clone_a.previews_state());
+    EXPECT_EQ(content::PREVIEWS_OFF, clone_b.previews_state());
+  }
 }
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index a999df0..3a940542 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -64,7 +65,6 @@
 #include "components/previews/core/previews_user_data.h"
 #include "components/variations/net/variations_http_headers.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/plugin_service_filter.h"
@@ -951,29 +951,33 @@
   g_external_protocol_handler_delegate = delegate;
 }
 
-content::NavigationData*
-ChromeResourceDispatcherHostDelegate::GetNavigationData(
-    net::URLRequest* request) const {
-  ChromeNavigationData* data =
-      ChromeNavigationData::GetDataAndCreateIfNecessary(request);
+base::Value ChromeResourceDispatcherHostDelegate::GetNavigationData(
+    net::URLRequest* request) {
   if (!request)
-    return data;
+    return base::Value();
+
+  ChromeNavigationData* chrome_navigation_data =
+      ChromeNavigationData::GetDataAndCreateIfNecessary(request);
 
   data_reduction_proxy::DataReductionProxyData* data_reduction_proxy_data =
       data_reduction_proxy::DataReductionProxyData::GetData(*request);
   // DeepCopy the DataReductionProxyData from the URLRequest to prevent the
   // URLRequest and DataReductionProxyData from both having ownership of the
-  // same object. This copy will be shortlived as it will be deep copied again
-  // when content makes a clone of NavigationData for the UI thread.
-  if (data_reduction_proxy_data)
-    data->SetDataReductionProxyData(data_reduction_proxy_data->DeepCopy());
+  // same object. This copy will be shortlived as it will be deleted at the end
+  // of this function in ChromeNavigationData's destructor.
+  if (data_reduction_proxy_data) {
+    chrome_navigation_data->SetDataReductionProxyData(
+        data_reduction_proxy_data->DeepCopy());
+  }
 
   previews::PreviewsUserData* previews_user_data =
       previews::PreviewsUserData::GetData(*request);
-  if (previews_user_data)
-    data->set_previews_user_data(previews_user_data->DeepCopy());
+  if (previews_user_data) {
+    chrome_navigation_data->set_previews_user_data(
+        previews_user_data->DeepCopy());
+  }
 
-  return data;
+  return chrome_navigation_data->ToValue();
 }
 
 std::unique_ptr<net::ClientCertStore>
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h
index ea44ecd8..7127fa2ce 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h
@@ -20,10 +20,6 @@
 
 class DownloadRequestLimiter;
 
-namespace content {
-class NavigationData;
-}
-
 namespace extensions {
 class UserScriptListener;
 }
@@ -88,8 +84,7 @@
       net::URLRequest* url_request,
       content::ResourceContext* resource_context,
       content::PreviewsState previews_to_allow) override;
-  content::NavigationData* GetNavigationData(
-      net::URLRequest* request) const override;
+  base::Value GetNavigationData(net::URLRequest* request) override;
   std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
       content::ResourceContext* resource_context) override;
 
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
index 03be7dc..c6de38ad 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_browsertest.cc
@@ -22,6 +22,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/test/scoped_command_line.h"
+#include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/download/download_browsertest.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
@@ -45,7 +46,6 @@
 #include "components/signin/core/browser/signin_pref_names.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
@@ -125,8 +125,7 @@
     request_headers_.MergeFrom(request->extra_request_headers());
   }
 
-  content::NavigationData* GetNavigationData(
-      net::URLRequest* request) const override {
+  base::Value GetNavigationData(net::URLRequest* request) override {
     if (request && should_add_data_reduction_proxy_data_) {
       data_reduction_proxy::DataReductionProxyData* data =
           data_reduction_proxy::DataReductionProxyData::
@@ -174,8 +173,8 @@
   DISALLOW_COPY_AND_ASSIGN(TestDispatcherHostDelegate);
 };
 
-// Helper class to track DidFinishNavigation and verify that NavigationData is
-// added to NavigationHandle and pause/resume execution of the test.
+// Helper class to track DidFinishNavigation and verify that the navigation_data
+// is added to NavigationHandle and pause/resume execution of the test.
 class DidFinishNavigationObserver : public content::WebContentsObserver {
  public:
   DidFinishNavigationObserver(content::WebContents* web_contents,
@@ -186,14 +185,14 @@
 
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override {
-    ChromeNavigationData* data = static_cast<ChromeNavigationData*>(
-        navigation_handle->GetNavigationData());
+    const base::Value& navigation_data = navigation_handle->GetNavigationData();
+    ChromeNavigationData chrome_navigation_data(navigation_data);
     if (add_data_reduction_proxy_data_) {
-      EXPECT_TRUE(data->GetDataReductionProxyData());
-      EXPECT_TRUE(
-          data->GetDataReductionProxyData()->used_data_reduction_proxy());
+      EXPECT_TRUE(chrome_navigation_data.GetDataReductionProxyData());
+      EXPECT_TRUE(chrome_navigation_data.GetDataReductionProxyData()
+                      ->used_data_reduction_proxy());
     } else {
-      EXPECT_FALSE(data->GetDataReductionProxyData());
+      EXPECT_FALSE(chrome_navigation_data.GetDataReductionProxyData());
     }
   }
 
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
index 11887380..963889d 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate_unittest.cc
@@ -6,12 +6,12 @@
 
 #include <memory>
 
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/request_priority.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -55,20 +55,18 @@
       data_reduction_proxy::DataReductionProxyData::GetDataAndCreateIfNecessary(
           fake_request.get());
   data_reduction_proxy_data->set_used_data_reduction_proxy(true);
+
+  // Take it back from the ResourceDispatcherHostDelegate.
   std::unique_ptr<ChromeResourceDispatcherHostDelegate> delegate =
       std::make_unique<ChromeResourceDispatcherHostDelegate>();
-  ChromeNavigationData* chrome_navigation_data =
-      static_cast<ChromeNavigationData*>(
-          delegate->GetNavigationData(fake_request.get()));
-  data_reduction_proxy::DataReductionProxyData* data_reduction_proxy_data_copy =
-      chrome_navigation_data->GetDataReductionProxyData();
-  // The DataReductionProxyData should be a copy of the one on URLRequest
-  EXPECT_NE(data_reduction_proxy_data_copy, data_reduction_proxy_data);
+  base::Value navigation_data = delegate->GetNavigationData(fake_request.get());
+  EXPECT_FALSE(navigation_data.is_none());
+  ChromeNavigationData chrome_navigation_data(navigation_data);
+
   // Make sure DataReductionProxyData was copied.
+  data_reduction_proxy::DataReductionProxyData* data_reduction_proxy_data_copy =
+      chrome_navigation_data.GetDataReductionProxyData();
   EXPECT_TRUE(data_reduction_proxy_data_copy->used_data_reduction_proxy());
-  EXPECT_EQ(
-      chrome_navigation_data,
-      ChromeNavigationData::GetDataAndCreateIfNecessary(fake_request.get()));
 }
 
 TEST_F(ChromeResourceDispatcherHostDelegateTest,
@@ -80,10 +78,10 @@
                              nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
   std::unique_ptr<ChromeResourceDispatcherHostDelegate> delegate =
       std::make_unique<ChromeResourceDispatcherHostDelegate>();
-  ChromeNavigationData* chrome_navigation_data =
-      static_cast<ChromeNavigationData*>(
-          delegate->GetNavigationData(fake_request.get()));
-  EXPECT_FALSE(chrome_navigation_data->GetDataReductionProxyData());
+  base::Value navigation_data = delegate->GetNavigationData(fake_request.get());
+  EXPECT_FALSE(navigation_data.is_none());
+  ChromeNavigationData chrome_navigation_data(navigation_data);
+  EXPECT_FALSE(chrome_navigation_data.GetDataReductionProxyData());
 }
 
 TEST_F(ChromeResourceDispatcherHostDelegateTest,
diff --git a/chrome/browser/media/android/router/media_router_android_unittest.cc b/chrome/browser/media/android/router/media_router_android_unittest.cc
index ee07a35..657cbcb 100644
--- a/chrome/browser/media/android/router/media_router_android_unittest.cc
+++ b/chrome/browser/media/android/router/media_router_android_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/test/mock_callback.h"
 #include "chrome/browser/media/android/router/media_router_android.h"
 #include "chrome/browser/media/android/router/media_router_android_bridge.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "content/public/browser/presentation_service_delegate.h"
 #include "content/public/common/presentation_info.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/media/cast_remoting_connector_unittest.cc b/chrome/browser/media/cast_remoting_connector_unittest.cc
index 8d4a133..5c71c85 100644
--- a/chrome/browser/media/cast_remoting_connector_unittest.cc
+++ b/chrome/browser/media/cast_remoting_connector_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/common/media_router/media_route.h"
 #include "chrome/common/media_router/media_source.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn
index df291727..b675b014b 100644
--- a/chrome/browser/media/router/BUILD.gn
+++ b/chrome/browser/media/router/BUILD.gn
@@ -22,16 +22,10 @@
     "//chrome/common/media_router:router",
   ]
   sources = [
-    "browser_presentation_connection_proxy.cc",
-    "browser_presentation_connection_proxy.h",
     "issue_manager.cc",
     "issue_manager.h",
     "issues_observer.cc",
     "issues_observer.h",
-    "local_presentation_manager.cc",
-    "local_presentation_manager.h",
-    "local_presentation_manager_factory.cc",
-    "local_presentation_manager_factory.h",
     "media_router.h",
     "media_router_base.cc",
     "media_router_base.h",
@@ -45,17 +39,21 @@
     "media_routes_observer.h",
     "media_sinks_observer.cc",
     "media_sinks_observer.h",
-    "presentation_media_sinks_observer.cc",
-    "presentation_media_sinks_observer.h",
-    "presentation_navigation_policy.cc",
-    "presentation_navigation_policy.h",
-    "presentation_service_delegate_impl.cc",
-    "presentation_service_delegate_impl.h",
-    "presentation_service_delegate_observers.cc",
-    "presentation_service_delegate_observers.h",
-    "receiver_presentation_service_delegate_impl.cc",
-    "receiver_presentation_service_delegate_impl.h",
-    "render_frame_host_id.h",
+    "presentation/browser_presentation_connection_proxy.cc",
+    "presentation/browser_presentation_connection_proxy.h",
+    "presentation/local_presentation_manager.cc",
+    "presentation/local_presentation_manager.h",
+    "presentation/local_presentation_manager_factory.cc",
+    "presentation/local_presentation_manager_factory.h",
+    "presentation/presentation_media_sinks_observer.cc",
+    "presentation/presentation_media_sinks_observer.h",
+    "presentation/presentation_service_delegate_impl.cc",
+    "presentation/presentation_service_delegate_impl.h",
+    "presentation/presentation_service_delegate_observers.cc",
+    "presentation/presentation_service_delegate_observers.h",
+    "presentation/receiver_presentation_service_delegate_impl.cc",
+    "presentation/receiver_presentation_service_delegate_impl.h",
+    "presentation/render_frame_host_id.h",
     "route_message_observer.cc",
     "route_message_observer.h",
   ]
@@ -71,8 +69,6 @@
       "event_page_request_manager.h",
       "event_page_request_manager_factory.cc",
       "event_page_request_manager_factory.h",
-      "mojo/extension_media_route_provider_proxy.cc",
-      "mojo/extension_media_route_provider_proxy.h",
       "mojo/media_route_controller.cc",
       "mojo/media_route_controller.h",
       "mojo/media_route_provider_util_win.cc",
@@ -83,17 +79,16 @@
       "mojo/media_router_mojo_impl.h",
       "mojo/media_router_mojo_metrics.cc",
       "mojo/media_router_mojo_metrics.h",
-      "mojo/wired_display_media_route_provider.cc",
-      "mojo/wired_display_media_route_provider.h",
+      "presentation/independent_otr_profile_manager.cc",
+      "presentation/independent_otr_profile_manager.h",
+      "presentation/presentation_navigation_policy.cc",
+      "presentation/presentation_navigation_policy.h",
       "providers/cast/dual_media_sink_service.cc",
       "providers/cast/dual_media_sink_service.h",
-    ]
-  }
-
-  if (!is_android) {
-    sources += [
-      "independent_otr_profile_manager.cc",
-      "independent_otr_profile_manager.h",
+      "providers/extension/extension_media_route_provider_proxy.cc",
+      "providers/extension/extension_media_route_provider_proxy.h",
+      "providers/wired_display/wired_display_media_route_provider.cc",
+      "providers/wired_display/wired_display_media_route_provider.h",
     ]
   }
 }
@@ -108,12 +103,12 @@
     ":router",
   ]
   sources = [
-    "mock_media_router.cc",
-    "mock_media_router.h",
-    "mock_screen_availability_listener.cc",
-    "mock_screen_availability_listener.h",
-    "test_helper.cc",
-    "test_helper.h",
+    "test/mock_media_router.cc",
+    "test/mock_media_router.h",
+    "test/mock_screen_availability_listener.cc",
+    "test/mock_screen_availability_listener.h",
+    "test/test_helper.cc",
+    "test/test_helper.h",
   ]
 
   if (enable_extensions) {
@@ -125,12 +120,12 @@
       "//extensions/common",
     ]
     sources += [
-      "discovery/mdns/mock_dns_sd_registry.cc",
-      "discovery/mdns/mock_dns_sd_registry.h",
-      "mojo/media_router_mojo_test.cc",
-      "mojo/media_router_mojo_test.h",
-      "mojo/mock_mojo_media_router.cc",
-      "mojo/mock_mojo_media_router.h",
+      "test/media_router_mojo_test.cc",
+      "test/media_router_mojo_test.h",
+      "test/mock_dns_sd_registry.cc",
+      "test/mock_dns_sd_registry.h",
+      "test/mock_mojo_media_router.cc",
+      "test/mock_mojo_media_router.h",
     ]
   }
 }
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
index 78ec6a2..9e014ba 100644
--- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/timer/mock_timer.h"
 #include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
 #include "chrome/browser/media/router/discovery/dial/dial_registry.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/service_manager/public/cpp/connector.h"
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
index e1c1dbc..c3b3be3 100644
--- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/test/mock_callback.h"
 #include "base/test/test_simple_task_runner.h"
 #include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/service_manager/public/cpp/connector.h"
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
index 4913406d..1ffbffb 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/timer/mock_timer.h"
 #include "chrome/browser/media/router/media_router_feature.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "components/cast_channel/cast_socket.h"
 #include "components/cast_channel/cast_socket_service.h"
 #include "components/cast_channel/cast_test_util.h"
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
index 8491f294..6272e9a 100644
--- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_unittest.cc
@@ -9,8 +9,8 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/timer/mock_timer.h"
 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h"
-#include "chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/mock_dns_sd_registry.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/cast_channel/cast_socket.h"
 #include "components/cast_channel/cast_socket_service.h"
diff --git a/chrome/browser/media/router/issue_manager_unittest.cc b/chrome/browser/media/router/issue_manager_unittest.cc
index 9f12f49..a0a63f4 100644
--- a/chrome/browser/media/router/issue_manager_unittest.cc
+++ b/chrome/browser/media/router/issue_manager_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/media/router/issue_manager.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
diff --git a/chrome/browser/media/router/media_router_base_unittest.cc b/chrome/browser/media/router/media_router_base_unittest.cc
index 78b9097..f5ef41c 100644
--- a/chrome/browser/media/router/media_router_base_unittest.cc
+++ b/chrome/browser/media/router/media_router_base_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "base/bind.h"
 #include "base/test/mock_callback.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "content/public/common/presentation_info.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/media_router_factory_unittest.cc b/chrome/browser/media/router/media_router_factory_unittest.cc
index 30c324b..d4fff27 100644
--- a/chrome/browser/media/router/media_router_factory_unittest.cc
+++ b/chrome/browser/media/router/media_router_factory_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/media/router/media_router_factory.h"
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/media/router/media_sinks_observer_unittest.cc b/chrome/browser/media/router/media_sinks_observer_unittest.cc
index 8db2973..e8fd3140 100644
--- a/chrome/browser/media/router/media_sinks_observer_unittest.cc
+++ b/chrome/browser/media/router/media_sinks_observer_unittest.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/media/router/mojo/OWNERS b/chrome/browser/media/router/mojo/OWNERS
deleted file mode 100644
index 2c44a46..0000000
--- a/chrome/browser/media/router/mojo/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc
index 5b27ad9..d709e6ac 100644
--- a/chrome/browser/media/router/mojo/media_route_controller_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_route_controller_unittest.cc
@@ -10,8 +10,8 @@
 #include "base/run_loop.h"
 #include "chrome/browser/media/router/event_page_request_manager_factory.h"
 #include "chrome/browser/media/router/media_router_factory.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc
index 778bb102..495469b 100644
--- a/chrome/browser/media/router/mojo/media_router_desktop.cc
+++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/media/router/mojo/media_route_controller.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h"
-#include "chrome/browser/media/router/mojo/wired_display_media_route_provider.h"
+#include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/media_router/media_source_helper.h"
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.h b/chrome/browser/media/router/mojo/media_router_desktop.h
index 28ec294..a33e3baf 100644
--- a/chrome/browser/media/router/mojo/media_router_desktop.h
+++ b/chrome/browser/media/router/mojo/media_router_desktop.h
@@ -7,9 +7,9 @@
 
 #include "base/gtest_prod_util.h"
 #include "build/build_config.h"
-#include "chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
 #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
+#include "chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h"
 
 namespace content {
 class RenderFrameHost;
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
index 82ac575..02a46d3 100644
--- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -18,8 +18,8 @@
 #include "chrome/browser/media/router/event_page_request_manager_factory.h"
 #include "chrome/browser/media/router/media_router_factory.h"
 #include "chrome/browser/media/router/media_router_feature.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
index 0d12d950..dc969b6 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -19,11 +19,11 @@
 #include "base/test/mock_callback.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/media/router/media_router_factory.h"
-#include "chrome/browser/media/router/mock_media_router.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
 #include "chrome/browser/media/router/route_message_observer.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/common/media_router/issue.h"
 #include "chrome/common/media_router/media_route.h"
 #include "chrome/common/media_router/media_source_helper.h"
diff --git a/chrome/browser/media/router/browser_presentation_connection_proxy.cc b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy.cc
similarity index 95%
rename from chrome/browser/media/router/browser_presentation_connection_proxy.cc
rename to chrome/browser/media/router/presentation/browser_presentation_connection_proxy.cc
index fce1b7f..43f7cd9 100644
--- a/chrome/browser/media/router/browser_presentation_connection_proxy.cc
+++ b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/browser_presentation_connection_proxy.h"
+#include "chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h"
 
 #include <vector>
 
 #include "base/memory/ptr_util.h"
-
 #include "chrome/browser/media/router/media_router.h"
 
 namespace media_router {
diff --git a/chrome/browser/media/router/browser_presentation_connection_proxy.h b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h
similarity index 92%
rename from chrome/browser/media/router/browser_presentation_connection_proxy.h
rename to chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h
index 8d1a249..0e7fc2d 100644
--- a/chrome/browser/media/router/browser_presentation_connection_proxy.h
+++ b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
 
 #include <vector>
 
@@ -87,4 +87,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_BROWSER_PRESENTATION_CONNECTION_PROXY_H_
diff --git a/chrome/browser/media/router/browser_presentation_connection_proxy_unittest.cc b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy_unittest.cc
similarity index 93%
rename from chrome/browser/media/router/browser_presentation_connection_proxy_unittest.cc
rename to chrome/browser/media/router/presentation/browser_presentation_connection_proxy_unittest.cc
index 9189854..4a318b39 100644
--- a/chrome/browser/media/router/browser_presentation_connection_proxy_unittest.cc
+++ b/chrome/browser/media/router/presentation/browser_presentation_connection_proxy_unittest.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/browser_presentation_connection_proxy.h"
+#include "chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h"
 
 #include "base/run_loop.h"
 #include "base/test/mock_callback.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/common/media_router/media_source.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "content/public/common/presentation_connection_message.h"
@@ -92,7 +92,7 @@
   std::string message = "test message";
   content::PresentationConnectionMessage connection_message(message);
 
-  base::MockCallback<base::Callback<void(bool)>> mock_on_message_callback;
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_on_message_callback;
   EXPECT_CALL(*mock_router(),
               SendRouteMessageInternal(kMediaRouteId, message, _));
 
@@ -107,7 +107,7 @@
 
   content::PresentationConnectionMessage connection_message(expected_data);
 
-  base::MockCallback<base::Callback<void(bool)>> mock_on_message_callback;
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_on_message_callback;
   EXPECT_CALL(*mock_router(), SendRouteBinaryMessageInternal(_, _, _))
       .WillOnce(Invoke(
           [&expected_data](
diff --git a/chrome/browser/media/router/independent_otr_profile_manager.cc b/chrome/browser/media/router/presentation/independent_otr_profile_manager.cc
similarity index 98%
rename from chrome/browser/media/router/independent_otr_profile_manager.cc
rename to chrome/browser/media/router/presentation/independent_otr_profile_manager.cc
index 32e055a..9004acb 100644
--- a/chrome/browser/media/router/independent_otr_profile_manager.cc
+++ b/chrome/browser/media/router/presentation/independent_otr_profile_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/independent_otr_profile_manager.h"
+#include "chrome/browser/media/router/presentation/independent_otr_profile_manager.h"
 
 #include <algorithm>
 #include <utility>
diff --git a/chrome/browser/media/router/independent_otr_profile_manager.h b/chrome/browser/media/router/presentation/independent_otr_profile_manager.h
similarity index 93%
rename from chrome/browser/media/router/independent_otr_profile_manager.h
rename to chrome/browser/media/router/presentation/independent_otr_profile_manager.h
index be9e404..277a2a2 100644
--- a/chrome/browser/media/router/independent_otr_profile_manager.h
+++ b/chrome/browser/media/router/presentation/independent_otr_profile_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_INDEPENDENT_OTR_PROFILE_MANAGER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_INDEPENDENT_OTR_PROFILE_MANAGER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_INDEPENDENT_OTR_PROFILE_MANAGER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_INDEPENDENT_OTR_PROFILE_MANAGER_H_
 
 #include <cstdint>
 #include <memory>
@@ -103,4 +103,4 @@
   DISALLOW_COPY_AND_ASSIGN(IndependentOTRProfileManager);
 };
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_INDEPENDENT_OTR_PROFILE_MANAGER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_INDEPENDENT_OTR_PROFILE_MANAGER_H_
diff --git a/chrome/browser/media/router/independent_otr_profile_manager_browsertest.cc b/chrome/browser/media/router/presentation/independent_otr_profile_manager_browsertest.cc
similarity index 98%
rename from chrome/browser/media/router/independent_otr_profile_manager_browsertest.cc
rename to chrome/browser/media/router/presentation/independent_otr_profile_manager_browsertest.cc
index 266d1daf..4415cd9 100644
--- a/chrome/browser/media/router/independent_otr_profile_manager_browsertest.cc
+++ b/chrome/browser/media/router/presentation/independent_otr_profile_manager_browsertest.cc
@@ -11,7 +11,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/media/router/independent_otr_profile_manager.h"
+#include "chrome/browser/media/router/presentation/independent_otr_profile_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
diff --git a/chrome/browser/media/router/local_presentation_manager.cc b/chrome/browser/media/router/presentation/local_presentation_manager.cc
similarity index 95%
rename from chrome/browser/media/router/local_presentation_manager.cc
rename to chrome/browser/media/router/presentation/local_presentation_manager.cc
index 614cebc2..5bd0616 100644
--- a/chrome/browser/media/router/local_presentation_manager.cc
+++ b/chrome/browser/media/router/presentation/local_presentation_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
 
 #include <utility>
 
@@ -42,7 +42,7 @@
   DVLOG(2) << __func__
            << " [presentation_id]: " << presentation_info.presentation_id
            << ", [render_frame_host_id]: " << render_frame_host_id.second;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   auto* presentation = GetOrCreateLocalPresentation(presentation_info);
   presentation->RegisterController(
@@ -55,7 +55,7 @@
     const RenderFrameHostId& render_frame_host_id) {
   DVLOG(2) << __func__ << " [presentation_id]: " << presentation_id
            << ", [render_frame_host_id]: " << render_frame_host_id.second;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   auto it = local_presentations_.find(presentation_id);
   if (it == local_presentations_.end())
@@ -75,7 +75,7 @@
     const content::ReceiverConnectionAvailableCallback& receiver_callback) {
   DVLOG(2) << __func__
            << " [presentation_id]: " << presentation_info.presentation_id;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* presentation = GetOrCreateLocalPresentation(presentation_info);
   presentation->RegisterReceiver(receiver_callback);
 }
@@ -83,7 +83,7 @@
 void LocalPresentationManager::OnLocalPresentationReceiverTerminated(
     const std::string& presentation_id) {
   DVLOG(2) << __func__ << " [presentation_id]: " << presentation_id;
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   local_presentations_.erase(presentation_id);
 }
diff --git a/chrome/browser/media/router/local_presentation_manager.h b/chrome/browser/media/router/presentation/local_presentation_manager.h
similarity index 95%
rename from chrome/browser/media/router/local_presentation_manager.h
rename to chrome/browser/media/router/presentation/local_presentation_manager.h
index 47f33d4..3a22613 100644
--- a/chrome/browser/media/router/local_presentation_manager.h
+++ b/chrome/browser/media/router/presentation/local_presentation_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_H_
 
 #include <map>
 #include <memory>
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/threading/thread_checker.h"
-#include "chrome/browser/media/router/render_frame_host_id.h"
+#include "chrome/browser/media/router/presentation/render_frame_host_id.h"
 #include "chrome/common/media_router/media_route.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "content/public/browser/presentation_service_delegate.h"
@@ -40,7 +40,8 @@
 //       LocalPresentationManagerFactory::GetOrCreateForBrowserContext(
 //           web_contents_->GetBrowserContext());
 //   manager->OnLocalPresentationReceiverCreated(presentation_info,
-//       base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable));
+//       base::BindRepeating(
+//           &PresentationServiceImpl::OnReceiverConnectionAvailable));
 //
 // Controlling frame establishes connection with the receiver side, resulting
 // in a connection with the two endpoints being the controller
@@ -83,7 +84,7 @@
 //       const blink::WebString& message) {
 //     target_connection_->OnMessage(
 //         content::PresentationConnectionMessage(message.Utf8()),
-//         base::Bind(&OnMessageReceived));
+//         base::BindOnce(&OnMessageReceived));
 //   }
 //
 // A controller or receiver leaves the local presentation (e.g., due to
@@ -242,11 +243,11 @@
   // Maps from presentation ID to LocalPresentation.
   LocalPresentationMap local_presentations_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(LocalPresentationManager);
 };
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_H_
diff --git a/chrome/browser/media/router/local_presentation_manager_factory.cc b/chrome/browser/media/router/presentation/local_presentation_manager_factory.cc
similarity index 91%
rename from chrome/browser/media/router/local_presentation_manager_factory.cc
rename to chrome/browser/media/router/presentation/local_presentation_manager_factory.cc
index a7519b83..1772a9fc 100644
--- a/chrome/browser/media/router/local_presentation_manager_factory.cc
+++ b/chrome/browser/media/router/presentation/local_presentation_manager_factory.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
 
 #include "base/lazy_instance.h"
 
-#include "chrome/browser/media/router/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
diff --git a/chrome/browser/media/router/local_presentation_manager_factory.h b/chrome/browser/media/router/presentation/local_presentation_manager_factory.h
similarity index 86%
rename from chrome/browser/media/router/local_presentation_manager_factory.h
rename to chrome/browser/media/router/presentation/local_presentation_manager_factory.h
index 1e2bbcb..969d35a 100644
--- a/chrome/browser/media/router/local_presentation_manager_factory.h
+++ b/chrome/browser/media/router/presentation/local_presentation_manager_factory.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
 
 #include "base/lazy_instance.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
@@ -51,4 +51,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_LOCAL_PRESENTATION_MANAGER_FACTORY_H_
diff --git a/chrome/browser/media/router/local_presentation_manager_factory_unittest.cc b/chrome/browser/media/router/presentation/local_presentation_manager_factory_unittest.cc
similarity index 94%
rename from chrome/browser/media/router/local_presentation_manager_factory_unittest.cc
rename to chrome/browser/media/router/presentation/local_presentation_manager_factory_unittest.cc
index 3cb0a0b..c0244a9 100644
--- a/chrome/browser/media/router/local_presentation_manager_factory_unittest.cc
+++ b/chrome/browser/media/router/presentation/local_presentation_manager_factory_unittest.cc
@@ -4,7 +4,7 @@
 
 #include <memory>
 
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/media/router/local_presentation_manager_unittest.cc b/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
similarity index 95%
rename from chrome/browser/media/router/local_presentation_manager_unittest.cc
rename to chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
index 5c011f8f..4cc81b7 100644
--- a/chrome/browser/media/router/local_presentation_manager_unittest.cc
+++ b/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
@@ -6,8 +6,8 @@
 
 #include "base/bind.h"
 #include "base/stl_util.h"
-#include "chrome/browser/media/router/local_presentation_manager.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -41,12 +41,8 @@
   LocalPresentationManagerTest()
       : render_frame_host_id_(1, 1),
         presentation_info_(GURL(kPresentationUrl), kPresentationId),
-        route_("route_1",
-               MediaSource("source_1"),
-               "sink_1",
-               "",
-               false,
-               false) {}
+        route_("route_1", MediaSource("source_1"), "sink_1", "", false, false) {
+  }
 
   LocalPresentationManager* manager() { return &manager_; }
 
@@ -99,9 +95,9 @@
       MockReceiverConnectionAvailableCallback& receiver_callback) {
     manager()->OnLocalPresentationReceiverCreated(
         content::PresentationInfo(GURL(kPresentationUrl), presentation_id),
-        base::Bind(&MockReceiverConnectionAvailableCallback::
-                       OnReceiverConnectionAvailable,
-                   base::Unretained(&receiver_callback)));
+        base::BindRepeating(&MockReceiverConnectionAvailableCallback::
+                                OnReceiverConnectionAvailable,
+                            base::Unretained(&receiver_callback)));
   }
 
   void UnregisterController(const RenderFrameHostId& render_frame_id) {
diff --git a/chrome/browser/media/router/presentation_media_sinks_observer.cc b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc
similarity index 94%
rename from chrome/browser/media/router/presentation_media_sinks_observer.cc
rename to chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc
index ee37df9..4f16471 100644
--- a/chrome/browser/media/router/presentation_media_sinks_observer.cc
+++ b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_media_sinks_observer.h"
+#include "chrome/browser/media/router/presentation/presentation_media_sinks_observer.h"
 
 #include "chrome/browser/media/router/media_router.h"
 #include "chrome/common/media_router/media_source.h"
@@ -22,8 +22,7 @@
   DCHECK(listener_);
 }
 
-PresentationMediaSinksObserver::~PresentationMediaSinksObserver() {
-}
+PresentationMediaSinksObserver::~PresentationMediaSinksObserver() {}
 
 void PresentationMediaSinksObserver::OnSinksReceived(
     const std::vector<MediaSink>& result) {
diff --git a/chrome/browser/media/router/presentation_media_sinks_observer.h b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.h
similarity index 87%
rename from chrome/browser/media/router/presentation_media_sinks_observer.h
rename to chrome/browser/media/router/presentation/presentation_media_sinks_observer.h
index 17e28ee..80b4b10 100644
--- a/chrome/browser/media/router/presentation_media_sinks_observer.h
+++ b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
 
 #include <memory>
 #include <vector>
@@ -55,4 +55,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_MEDIA_SINKS_OBSERVER_H_
diff --git a/chrome/browser/media/router/presentation_media_sinks_observer_unittest.cc b/chrome/browser/media/router/presentation/presentation_media_sinks_observer_unittest.cc
similarity index 93%
rename from chrome/browser/media/router/presentation_media_sinks_observer_unittest.cc
rename to chrome/browser/media/router/presentation/presentation_media_sinks_observer_unittest.cc
index dd3bced..0e0e3e68 100644
--- a/chrome/browser/media/router/presentation_media_sinks_observer_unittest.cc
+++ b/chrome/browser/media/router/presentation/presentation_media_sinks_observer_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_media_sinks_observer.h"
+#include "chrome/browser/media/router/presentation/presentation_media_sinks_observer.h"
 
 #include <memory>
 
 #include "base/macros.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/mock_screen_availability_listener.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_screen_availability_listener.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/presentation_screen_availability_listener.h"
diff --git a/chrome/browser/media/router/presentation_navigation_policy.cc b/chrome/browser/media/router/presentation/presentation_navigation_policy.cc
similarity index 92%
rename from chrome/browser/media/router/presentation_navigation_policy.cc
rename to chrome/browser/media/router/presentation/presentation_navigation_policy.cc
index 1879003..2379053b 100644
--- a/chrome/browser/media/router/presentation_navigation_policy.cc
+++ b/chrome/browser/media/router/presentation/presentation_navigation_policy.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_navigation_policy.h"
+#include "chrome/browser/media/router/presentation/presentation_navigation_policy.h"
 
 #include "content/public/browser/navigation_handle.h"
 
diff --git a/chrome/browser/media/router/presentation_navigation_policy.h b/chrome/browser/media/router/presentation/presentation_navigation_policy.h
similarity index 83%
rename from chrome/browser/media/router/presentation_navigation_policy.h
rename to chrome/browser/media/router/presentation/presentation_navigation_policy.h
index 247eceb..fe081011 100644
--- a/chrome/browser/media/router/presentation_navigation_policy.h
+++ b/chrome/browser/media/router/presentation/presentation_navigation_policy.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_NAVIGATION_POLICY_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_NAVIGATION_POLICY_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_NAVIGATION_POLICY_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_NAVIGATION_POLICY_H_
 
 namespace content {
 class NavigationHandle;
@@ -45,4 +45,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_NAVIGATION_POLICY_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_NAVIGATION_POLICY_H_
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc
similarity index 98%
rename from chrome/browser/media/router/presentation_service_delegate_impl.cc
rename to chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc
index 43f8f180..4aaadf2 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
 
 #include <string>
 #include <unordered_map>
@@ -10,19 +10,17 @@
 #include <vector>
 
 #include "base/containers/small_map.h"
-#include "base/guid.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/media/router/browser_presentation_connection_proxy.h"
-#include "chrome/browser/media/router/local_presentation_manager.h"
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
 #include "chrome/browser/media/router/media_router.h"
 #include "chrome/browser/media/router/media_router_dialog_controller.h"
 #include "chrome/browser/media/router/media_router_factory.h"
 #include "chrome/browser/media/router/media_router_metrics.h"
-#include "chrome/browser/media/router/presentation_media_sinks_observer.h"
+#include "chrome/browser/media/router/presentation/browser_presentation_connection_proxy.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/presentation/presentation_media_sinks_observer.h"
 #include "chrome/browser/media/router/route_message_observer.h"
-#include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/common/media_router/media_route.h"
 #include "chrome/common/media_router/media_sink.h"
 #include "chrome/common/media_router/media_source_helper.h"
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
similarity index 95%
rename from chrome/browser/media/router/presentation_service_delegate_impl.h
rename to chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
index 8a822644..66bd93e4 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.h
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
 
 #include <map>
 #include <memory>
@@ -16,9 +16,10 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/optional.h"
+#include "build/build_config.h"
 #include "chrome/browser/media/router/media_router.h"
-#include "chrome/browser/media/router/presentation_service_delegate_observers.h"
-#include "chrome/browser/media/router/render_frame_host_id.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_observers.h"
+#include "chrome/browser/media/router/presentation/render_frame_host_id.h"
 #include "chrome/common/media_router/media_source.h"
 #include "content/public/browser/presentation_request.h"
 #include "content/public/browser/presentation_service_delegate.h"
@@ -253,4 +254,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
similarity index 97%
rename from chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
rename to chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
index 7119e59..af9e62ac 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
@@ -2,15 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
 
 #include "base/memory/ptr_util.h"
 #include "base/test/mock_callback.h"
-#include "chrome/browser/media/router/local_presentation_manager.h"
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/mock_screen_availability_listener.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "build/build_config.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_screen_availability_listener.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/media_router/media_source.h"
 #include "chrome/common/media_router/media_source_helper.h"
@@ -153,7 +154,7 @@
   }
 
   void RunDefaultPresentationUrlCallbackTest(bool incognito) {
-    auto callback = base::Bind(
+    auto callback = base::BindRepeating(
         &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
         base::Unretained(this));
     std::vector<std::string> urls({kPresentationUrl1});
@@ -233,8 +234,8 @@
 class PresentationServiceDelegateImplIncognitoTest
     : public PresentationServiceDelegateImplTest {
  public:
-  PresentationServiceDelegateImplIncognitoTest() :
-      incognito_web_contents_(nullptr) {}
+  PresentationServiceDelegateImplIncognitoTest()
+      : incognito_web_contents_(nullptr) {}
 
  protected:
   content::WebContents* GetWebContents() override {
@@ -291,7 +292,6 @@
 TEST_F(PresentationServiceDelegateImplTest, AddMultipleListenersToFrame) {
   ON_CALL(router_, RegisterMediaSinksObserver(_)).WillByDefault(Return(true));
 
-
   EXPECT_CALL(router_, RegisterMediaSinksObserver(_)).Times(2);
   EXPECT_TRUE(delegate_impl_->AddScreenAvailabilityListener(
       main_frame_process_id_, main_frame_routing_id_, &listener1_));
@@ -347,7 +347,7 @@
   content::WebContentsTester::For(GetWebContents())
       ->NavigateAndCommit(frame_url_);
 
-  auto callback = base::Bind(
+  auto callback = base::BindRepeating(
       &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
       base::Unretained(this));
   delegate_impl_->SetDefaultPresentationUrls(*presentation_request_, callback);
@@ -380,7 +380,7 @@
 
 TEST_F(PresentationServiceDelegateImplTest,
        DefaultPresentationRequestObserver) {
-  auto callback = base::Bind(
+  auto callback = base::BindRepeating(
       &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
       base::Unretained(this));
 
diff --git a/chrome/browser/media/router/presentation_service_delegate_observers.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_observers.cc
similarity index 91%
rename from chrome/browser/media/router/presentation_service_delegate_observers.cc
rename to chrome/browser/media/router/presentation/presentation_service_delegate_observers.cc
index 4875794b..8c6c0e4 100644
--- a/chrome/browser/media/router/presentation_service_delegate_observers.cc
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_observers.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/presentation_service_delegate_observers.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_observers.h"
 
 #include "base/stl_util.h"
 
diff --git a/chrome/browser/media/router/presentation_service_delegate_observers.h b/chrome/browser/media/router/presentation/presentation_service_delegate_observers.h
similarity index 77%
rename from chrome/browser/media/router/presentation_service_delegate_observers.h
rename to chrome/browser/media/router/presentation/presentation_service_delegate_observers.h
index 2783d2b0..1491176 100644
--- a/chrome/browser/media/router/presentation_service_delegate_observers.h
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_observers.h
@@ -1,12 +1,13 @@
 // Copyright 2016 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
+
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
 
 #include <map>
 
-#include "chrome/browser/media/router/render_frame_host_id.h"
+#include "chrome/browser/media/router/presentation/render_frame_host_id.h"
 #include "content/public/browser/presentation_service_delegate.h"
 
 namespace media_router {
@@ -38,4 +39,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_PRESENTATION_SERVICE_DELEGATE_OBSERVERS_H_
diff --git a/chrome/browser/media/router/receiver_presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.cc
similarity index 91%
rename from chrome/browser/media/router/receiver_presentation_service_delegate_impl.cc
rename to chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.cc
index 1b9a6efc..62ef060 100644
--- a/chrome/browser/media/router/receiver_presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/receiver_presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h"
 
 #include "base/memory/ptr_util.h"
-#include "chrome/browser/media/router/local_presentation_manager.h"
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/web_preferences.h"
diff --git a/chrome/browser/media/router/receiver_presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h
similarity index 88%
rename from chrome/browser/media/router/receiver_presentation_service_delegate_impl.h
rename to chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h
index 2ecbaae..605dfdd 100644
--- a/chrome/browser/media/router/receiver_presentation_service_delegate_impl.h
+++ b/chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
 
 #include <string>
 
-#include "chrome/browser/media/router/presentation_service_delegate_observers.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_observers.h"
 #include "content/public/browser/presentation_service_delegate.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -75,4 +75,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RECEIVER_PRESENTATION_SERVICE_DELEGATE_IMPL_H_
diff --git a/chrome/browser/media/router/render_frame_host_id.h b/chrome/browser/media/router/presentation/render_frame_host_id.h
similarity index 67%
rename from chrome/browser/media/router/render_frame_host_id.h
rename to chrome/browser/media/router/presentation/render_frame_host_id.h
index bbbfe88..f139d5d 100644
--- a/chrome/browser/media/router/render_frame_host_id.h
+++ b/chrome/browser/media/router/presentation/render_frame_host_id.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RENDER_FRAME_HOST_ID_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RENDER_FRAME_HOST_ID_H_
 
 #include <utility>
 
@@ -21,4 +21,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_RENDER_FRAME_HOST_ID_H_
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc
index 9f107d5..fe3433f 100644
--- a/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
 
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy.cc b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc
similarity index 99%
rename from chrome/browser/media/router/mojo/extension_media_route_provider_proxy.cc
rename to chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc
index f3e1f78..e2bf625d 100644
--- a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy.cc
+++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h"
+#include "chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h"
 
 #include <string>
 #include <utility>
diff --git a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
similarity index 96%
rename from chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h
rename to chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
index b5f638d9..47eaeec 100644
--- a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h
+++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOJO_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_EXTENSION_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_EXTENSION_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
 
 #include "base/memory/weak_ptr.h"
 #include "chrome/common/media_router/mojo/media_router.mojom.h"
@@ -176,4 +176,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOJO_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_EXTENSION_EXTENSION_MEDIA_ROUTE_PROVIDER_PROXY_H_
diff --git a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy_unittest.cc b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc
similarity index 98%
rename from chrome/browser/media/router/mojo/extension_media_route_provider_proxy_unittest.cc
rename to chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc
index 7c36d9e2..4ff6792 100644
--- a/chrome/browser/media/router/mojo/extension_media_route_provider_proxy_unittest.cc
+++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/extension_media_route_provider_proxy.h"
+#include "chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h"
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -10,7 +10,7 @@
 #include "base/test/mock_callback.h"
 #include "chrome/browser/media/router/event_page_request_manager.h"
 #include "chrome/browser/media/router/event_page_request_manager_factory.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
similarity index 98%
rename from chrome/browser/media/router/mojo/wired_display_media_route_provider.cc
rename to chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
index deaf09d9..bd51923 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/wired_display_media_route_provider.h"
+#include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h"
 
 #include <string>
 #include <utility>
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider.h b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
similarity index 95%
rename from chrome/browser/media/router/mojo/wired_display_media_route_provider.h
rename to chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
index f126b45..903be19 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider.h
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOJO_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_WIRED_DISPLAY_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_WIRED_DISPLAY_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
 
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
@@ -137,4 +137,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOJO_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_PROVIDERS_WIRED_DISPLAY_WIRED_DISPLAY_MEDIA_ROUTE_PROVIDER_H_
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
similarity index 97%
rename from chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc
rename to chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
index d4f6cc5f..c5308c2 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/wired_display_media_route_provider.h"
+#include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h"
 
 #include "base/run_loop.h"
-#include "chrome/browser/media/router/mojo/mock_mojo_media_router.h"
+#include "chrome/browser/media/router/test/mock_mojo_media_router.h"
 #include "chrome/common/media_router/mojo/media_router.mojom.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.cc b/chrome/browser/media/router/test/media_router_mojo_test.cc
similarity index 99%
rename from chrome/browser/media/router/mojo/media_router_mojo_test.cc
rename to chrome/browser/media/router/test/media_router_mojo_test.cc
index ca2ed0ed..4eb2c260 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_test.cc
+++ b/chrome/browser/media/router/test/media_router_mojo_test.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
 
 #include <utility>
 
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_test.h b/chrome/browser/media/router/test/media_router_mojo_test.h
similarity index 97%
rename from chrome/browser/media/router/mojo/media_router_mojo_test.h
rename to chrome/browser/media/router/test/media_router_mojo_test.h
index b5ae968..2705e0e 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_test.h
+++ b/chrome/browser/media/router/test/media_router_mojo_test.h
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_TEST_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_TEST_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_MEDIA_ROUTER_MOJO_TEST_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_MEDIA_ROUTER_MOJO_TEST_H_
 
 #include <string>
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "chrome/browser/media/router/event_page_request_manager.h"
-#include "chrome/browser/media/router/mock_media_router.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/common/media_router/mojo/media_router.mojom.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -336,4 +336,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTER_MOJO_TEST_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MEDIA_ROUTER_MOJO_TEST_H_
diff --git a/chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.cc b/chrome/browser/media/router/test/mock_dns_sd_registry.cc
similarity index 88%
rename from chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.cc
rename to chrome/browser/media/router/test/mock_dns_sd_registry.cc
index dd32a7f..03fbffb 100644
--- a/chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.cc
+++ b/chrome/browser/media/router/test/mock_dns_sd_registry.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h"
+#include "chrome/browser/media/router/test/mock_dns_sd_registry.h"
 
 namespace media_router {
 
diff --git a/chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h b/chrome/browser/media/router/test/mock_dns_sd_registry.h
similarity index 81%
rename from chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h
rename to chrome/browser/media/router/test/mock_dns_sd_registry.h
index f325a78..8999612 100644
--- a/chrome/browser/media/router/discovery/mdns/mock_dns_sd_registry.h
+++ b/chrome/browser/media/router/test/mock_dns_sd_registry.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_MDNS_MOCK_DNS_SD_REGISTRY_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_MDNS_MOCK_DNS_SD_REGISTRY_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_DNS_SD_REGISTRY_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_DNS_SD_REGISTRY_H_
 
 #include "chrome/browser/media/router/discovery/mdns/dns_sd_registry.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -31,4 +31,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_MDNS_MOCK_DNS_SD_REGISTRY_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_DNS_SD_REGISTRY_H_
diff --git a/chrome/browser/media/router/mock_media_router.cc b/chrome/browser/media/router/test/mock_media_router.cc
similarity index 72%
rename from chrome/browser/media/router/mock_media_router.cc
rename to chrome/browser/media/router/test/mock_media_router.cc
index 860bd541..1f14ab10 100644
--- a/chrome/browser/media/router/mock_media_router.cc
+++ b/chrome/browser/media/router/test/mock_media_router.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 
 namespace media_router {
 
@@ -12,10 +12,8 @@
   return base::MakeUnique<MockMediaRouter>();
 }
 
-MockMediaRouter::MockMediaRouter() {
-}
+MockMediaRouter::MockMediaRouter() {}
 
-MockMediaRouter::~MockMediaRouter() {
-}
+MockMediaRouter::~MockMediaRouter() {}
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/mock_media_router.h b/chrome/browser/media/router/test/mock_media_router.h
similarity index 97%
rename from chrome/browser/media/router/mock_media_router.h
rename to chrome/browser/media/router/test/mock_media_router.h
index 7e6989a4..e69a601 100644
--- a/chrome/browser/media/router/mock_media_router.h
+++ b/chrome/browser/media/router/test/mock_media_router.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOCK_MEDIA_ROUTER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOCK_MEDIA_ROUTER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MEDIA_ROUTER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MEDIA_ROUTER_H_
 
 #include <stdint.h>
 
@@ -184,4 +184,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOCK_MEDIA_ROUTER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MEDIA_ROUTER_H_
diff --git a/chrome/browser/media/router/mojo/mock_mojo_media_router.cc b/chrome/browser/media/router/test/mock_mojo_media_router.cc
similarity index 83%
rename from chrome/browser/media/router/mojo/mock_mojo_media_router.cc
rename to chrome/browser/media/router/test/mock_mojo_media_router.cc
index f4b494c..1a96645f 100644
--- a/chrome/browser/media/router/mojo/mock_mojo_media_router.cc
+++ b/chrome/browser/media/router/test/mock_mojo_media_router.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mojo/mock_mojo_media_router.h"
+#include "chrome/browser/media/router/test/mock_mojo_media_router.h"
 
 namespace media_router {
 
diff --git a/chrome/browser/media/router/mojo/mock_mojo_media_router.h b/chrome/browser/media/router/test/mock_mojo_media_router.h
similarity index 91%
rename from chrome/browser/media/router/mojo/mock_mojo_media_router.h
rename to chrome/browser/media/router/test/mock_mojo_media_router.h
index 0e76d3b..fb16950 100644
--- a/chrome/browser/media/router/mojo/mock_mojo_media_router.h
+++ b/chrome/browser/media/router/test/mock_mojo_media_router.h
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOJO_MOCK_MOJO_MEDIA_ROUTER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOJO_MOCK_MOJO_MEDIA_ROUTER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MOJO_MEDIA_ROUTER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MOJO_MEDIA_ROUTER_H_
 
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/common/media_router/media_route_provider_helper.h"
 #include "chrome/common/media_router/mojo/media_router.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -67,4 +67,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOJO_MOCK_MOJO_MEDIA_ROUTER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_MOJO_MEDIA_ROUTER_H_
diff --git a/chrome/browser/media/router/mock_screen_availability_listener.cc b/chrome/browser/media/router/test/mock_screen_availability_listener.cc
similarity index 85%
rename from chrome/browser/media/router/mock_screen_availability_listener.cc
rename to chrome/browser/media/router/test/mock_screen_availability_listener.cc
index c2cd512..091513b 100644
--- a/chrome/browser/media/router/mock_screen_availability_listener.cc
+++ b/chrome/browser/media/router/test/mock_screen_availability_listener.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/mock_screen_availability_listener.h"
+#include "chrome/browser/media/router/test/mock_screen_availability_listener.h"
 
 namespace media_router {
 
@@ -10,8 +10,7 @@
     const GURL& availability_url)
     : availability_url_(availability_url) {}
 
-MockScreenAvailabilityListener::~MockScreenAvailabilityListener() {
-}
+MockScreenAvailabilityListener::~MockScreenAvailabilityListener() {}
 
 GURL MockScreenAvailabilityListener::GetAvailabilityUrl() const {
   return availability_url_;
diff --git a/chrome/browser/media/router/mock_screen_availability_listener.h b/chrome/browser/media/router/test/mock_screen_availability_listener.h
similarity index 76%
rename from chrome/browser/media/router/mock_screen_availability_listener.h
rename to chrome/browser/media/router/test/mock_screen_availability_listener.h
index 1d7888a..ac436af9 100644
--- a/chrome/browser/media/router/mock_screen_availability_listener.h
+++ b/chrome/browser/media/router/test/mock_screen_availability_listener.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
 
 #include "content/public/browser/presentation_screen_availability_listener.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -27,4 +27,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MOCK_SCREEN_AVAILABILITY_LISTENER_H_
diff --git a/chrome/browser/media/router/test_helper.cc b/chrome/browser/media/router/test/test_helper.cc
similarity index 87%
rename from chrome/browser/media/router/test_helper.cc
rename to chrome/browser/media/router/test/test_helper.cc
index 0a5a247..0a25cce 100644
--- a/chrome/browser/media/router/test_helper.cc
+++ b/chrome/browser/media/router/test/test_helper.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 
 #include "base/base64.h"
 #include "base/json/string_escape.h"
@@ -36,15 +36,13 @@
                                                const MediaSource& source,
                                                const url::Origin& origin)
     : MediaSinksObserver(router, source, origin) {}
-MockMediaSinksObserver::~MockMediaSinksObserver() {
-}
+MockMediaSinksObserver::~MockMediaSinksObserver() {}
 
-MockMediaRoutesObserver::MockMediaRoutesObserver(MediaRouter* router,
+MockMediaRoutesObserver::MockMediaRoutesObserver(
+    MediaRouter* router,
     const MediaSource::Id source_id)
-    : MediaRoutesObserver(router, source_id) {
-}
-MockMediaRoutesObserver::~MockMediaRoutesObserver() {
-}
+    : MediaRoutesObserver(router, source_id) {}
+MockMediaRoutesObserver::~MockMediaRoutesObserver() {}
 
 MockPresentationConnectionProxy::MockPresentationConnectionProxy() {}
 MockPresentationConnectionProxy::~MockPresentationConnectionProxy() {}
diff --git a/chrome/browser/media/router/test_helper.h b/chrome/browser/media/router/test/test_helper.h
similarity index 90%
rename from chrome/browser/media/router/test_helper.h
rename to chrome/browser/media/router/test/test_helper.h
index efc2b7e..8ef5ef1 100644
--- a/chrome/browser/media/router/test_helper.h
+++ b/chrome/browser/media/router/test/test_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_HELPER_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_TEST_HELPER_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_TEST_TEST_HELPER_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_TEST_TEST_HELPER_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -78,12 +78,14 @@
 
 class MockMediaRoutesObserver : public MediaRoutesObserver {
  public:
-  explicit MockMediaRoutesObserver(MediaRouter* router,
+  explicit MockMediaRoutesObserver(
+      MediaRouter* router,
       const MediaSource::Id source_id = std::string());
   ~MockMediaRoutesObserver() override;
 
-  MOCK_METHOD2(OnRoutesUpdated, void(const std::vector<MediaRoute>& routes,
-      const std::vector<MediaRoute::Id>& joinable_route_ids));
+  MOCK_METHOD2(OnRoutesUpdated,
+               void(const std::vector<MediaRoute>& routes,
+                    const std::vector<MediaRoute::Id>& joinable_route_ids));
 };
 
 class MockPresentationConnectionProxy
@@ -133,4 +135,4 @@
 
 }  // namespace media_router
 
-#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_HELPER_H_
+#endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_TEST_HELPER_H_
diff --git a/chrome/browser/offline_pages/android/offline_page_model_factory.cc b/chrome/browser/offline_pages/android/offline_page_model_factory.cc
index 703b0766..488f98d6 100644
--- a/chrome/browser/offline_pages/android/offline_page_model_factory.cc
+++ b/chrome/browser/offline_pages/android/offline_page_model_factory.cc
@@ -11,14 +11,15 @@
 #include "base/path_service.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task_scheduler/post_task.h"
+#include "base/time/default_clock.h"
 #include "chrome/browser/offline_pages/android/cct_origin_observer.h"
 #include "chrome/browser/offline_pages/fresh_offline_content_observer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_constants.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/offline_pages/core/archive_manager.h"
+#include "components/offline_pages/core/model/offline_page_model_taskified.h"
 #include "components/offline_pages/core/offline_page_metadata_store_sql.h"
-#include "components/offline_pages/core/offline_page_model_impl.h"
 
 namespace offline_pages {
 
@@ -35,7 +36,7 @@
 // static
 OfflinePageModel* OfflinePageModelFactory::GetForBrowserContext(
     content::BrowserContext* context) {
-  return static_cast<OfflinePageModelImpl*>(
+  return static_cast<OfflinePageModelTaskified*>(
       GetInstance()->GetServiceForBrowserContext(context, true));
 }
 
@@ -47,7 +48,7 @@
 
   base::FilePath store_path =
       profile->GetPath().Append(chrome::kOfflinePageMetadataDirname);
-  std::unique_ptr<OfflinePageMetadataStore> metadata_store(
+  std::unique_ptr<OfflinePageMetadataStoreSQL> metadata_store(
       new OfflinePageMetadataStoreSQL(background_task_runner, store_path));
 
   base::FilePath persistent_archives_dir =
@@ -61,10 +62,11 @@
   }
   std::unique_ptr<ArchiveManager> archive_manager(new ArchiveManager(
       temporary_archives_dir, persistent_archives_dir, background_task_runner));
+  auto clock = base::MakeUnique<base::DefaultClock>();
 
-  OfflinePageModelImpl* model = new OfflinePageModelImpl(
+  OfflinePageModelTaskified* model = new OfflinePageModelTaskified(
       std::move(metadata_store), std::move(archive_manager),
-      background_task_runner);
+      background_task_runner, std::move(clock));
 
   CctOriginObserver::AttachToOfflinePageModel(model);
 
diff --git a/chrome/browser/offline_pages/background_loader_offliner.cc b/chrome/browser/offline_pages/background_loader_offliner.cc
index da12df4..f3a8d1f 100644
--- a/chrome/browser/offline_pages/background_loader_offliner.cc
+++ b/chrome/browser/offline_pages/background_loader_offliner.cc
@@ -13,6 +13,7 @@
 #include "base/sys_info.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/offline_pages/offline_page_mhtml_archiver.h"
 #include "chrome/browser/offline_pages/offliner_helper.h"
@@ -63,30 +64,35 @@
       error_code);
 }
 
-void RecordOffliningPreviewsUMA(const ClientId& client_id,
-                                ChromeNavigationData* navigation_data) {
-  content::PreviewsState previews_state = content::PreviewsTypes::PREVIEWS_OFF;
-  if (navigation_data)
-    previews_state = navigation_data->previews_state();
+bool IsPreviewsEnabled(const base::Value& value_navigation_data) {
+  if (value_navigation_data.is_none())
+    return false;
 
-  int is_previews_enabled = 0;
-  bool lite_page_received = false;
+  ChromeNavigationData chrome_navigation_data(value_navigation_data);
+
   data_reduction_proxy::DataReductionProxyData* data_reduction_proxy_data =
-      nullptr;
-  if (navigation_data)
-    data_reduction_proxy_data = navigation_data->GetDataReductionProxyData();
-  if (data_reduction_proxy_data)
-    lite_page_received = data_reduction_proxy_data->lite_page_received();
+      chrome_navigation_data.GetDataReductionProxyData();
+  if (data_reduction_proxy_data &&
+      data_reduction_proxy_data->lite_page_received()) {
+    return true;
+  }
 
-  if ((previews_state != content::PreviewsTypes::PREVIEWS_OFF &&
-       previews_state != content::PreviewsTypes::PREVIEWS_NO_TRANSFORM) ||
-      lite_page_received)
-    is_previews_enabled = 1;
+  content::PreviewsState previews_state =
+      chrome_navigation_data.previews_state();
+  if (previews_state != content::PreviewsTypes::PREVIEWS_OFF &&
+      previews_state != content::PreviewsTypes::PREVIEWS_NO_TRANSFORM) {
+    return true;
+  }
 
+  return false;
+}
+
+void RecordOffliningPreviewsUMA(const ClientId& client_id,
+                                const base::Value& navigation_data) {
   base::UmaHistogramBoolean(
       AddHistogramSuffix(client_id,
                          "OfflinePages.Background.OffliningPreviewStatus"),
-      is_previews_enabled);
+      IsPreviewsEnabled(navigation_data));
 }
 
 void HandleLoadTerminationCancel(
@@ -367,10 +373,8 @@
   // ResourceDispatcherHostDelegate::GetNavigationData during commit.
   // Because ChromeResourceDispatcherHostDelegate always returns a
   // ChromeNavigationData, it is safe to static_cast here.
-  ChromeNavigationData* navigation_data = static_cast<ChromeNavigationData*>(
-      navigation_handle->GetNavigationData());
-
-  RecordOffliningPreviewsUMA(pending_request_->client_id(), navigation_data);
+  RecordOffliningPreviewsUMA(pending_request_->client_id(),
+                             navigation_handle->GetNavigationData());
 }
 
 void BackgroundLoaderOffliner::SetSnapshotControllerForTest(
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
index 7a30320b..3ec75147 100644
--- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
+++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/offline_pages/offliner_helper.h"
@@ -607,14 +608,11 @@
           kHttpUrl, offliner()->web_contents()->GetMainFrame(), true,
           net::Error::OK));
   // Set up ChromeNavigationData on the handle.
-  std::unique_ptr<ChromeNavigationData> chrome_navigation_data(
-      new ChromeNavigationData());
-  chrome_navigation_data->set_previews_state(
+  ChromeNavigationData chrome_navigation_data;
+  chrome_navigation_data.set_previews_state(
       content::PreviewsTypes::PREVIEWS_NO_TRANSFORM);
-  std::unique_ptr<content::NavigationData> navigation_data(
-      chrome_navigation_data.release());
   offliner()->web_contents_tester()->SetNavigationData(
-      handle.get(), std::move(navigation_data));
+      handle.get(), chrome_navigation_data.ToValue());
   scoped_refptr<net::HttpResponseHeaders> header(
       new net::HttpResponseHeaders("HTTP/1.1 200 OK"));
   offliner()->web_contents_tester()->SetHttpResponseHeaders(handle.get(),
@@ -641,14 +639,11 @@
           kHttpUrl, offliner()->web_contents()->GetMainFrame(), true,
           net::Error::OK));
   // Set up ChromeNavigationData on the handle.
-  std::unique_ptr<ChromeNavigationData> chrome_navigation_data(
-      new ChromeNavigationData());
-  chrome_navigation_data->set_previews_state(
+  ChromeNavigationData chrome_navigation_data;
+  chrome_navigation_data.set_previews_state(
       content::PreviewsTypes::CLIENT_LOFI_ON);
-  std::unique_ptr<content::NavigationData> navigation_data(
-      chrome_navigation_data.release());
   offliner()->web_contents_tester()->SetNavigationData(
-      handle.get(), std::move(navigation_data));
+      handle.get(), chrome_navigation_data.ToValue());
   scoped_refptr<net::HttpResponseHeaders> header(
       new net::HttpResponseHeaders("HTTP/1.1 200 OK"));
   offliner()->web_contents_tester()->SetHttpResponseHeaders(handle.get(),
diff --git a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
index 7e8e175..4f7db41 100644
--- a/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_request_job_unittest.cc
@@ -31,7 +31,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/offline_pages/core/client_namespace_constants.h"
-#include "components/offline_pages/core/offline_page_model_impl.h"
+#include "components/offline_pages/core/model/offline_page_model_taskified.h"
 #include "components/offline_pages/core/request_header/offline_page_navigation_ui_data.h"
 #include "components/previews/core/previews_decider.h"
 #include "components/previews/core/previews_experiments.h"
@@ -366,7 +366,8 @@
                                    bool is_offline_page_set_in_navigation_data);
 
   content::TestBrowserThreadBundle thread_bundle_;
-  base::SimpleTestClock clock_;
+  std::unique_ptr<base::SimpleTestClock> clock_;
+  base::SimpleTestClock* clock_ptr_;
   TestingProfileManager profile_manager_;
   TestingProfile* profile_;
   std::unique_ptr<content::WebContents> web_contents_;
@@ -400,6 +401,8 @@
 
 OfflinePageRequestJobTest::OfflinePageRequestJobTest()
     : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
+      clock_(new base::SimpleTestClock),
+      clock_ptr_(clock_.get()),
       profile_manager_(TestingBrowserProcess::GetGlobal()),
       offline_id_(-1),
       offline_id2_(-1),
@@ -428,19 +431,19 @@
       profile(), BuildTestOfflinePageModel);
   RunUntilIdle();
 
-  OfflinePageModelImpl* model = static_cast<OfflinePageModelImpl*>(
+  OfflinePageModelTaskified* model = static_cast<OfflinePageModelTaskified*>(
       OfflinePageModelFactory::GetForBrowserContext(profile()));
 
   // Hook up a test clock such that we can control the time when the offline
   // page is created.
-  clock_.SetNow(base::Time::Now());
-  model->set_testing_clock(&clock_);
+  clock_ptr_->SetNow(base::Time::Now());
+  model->SetClockForTesting(std::move(clock_));
 
   // Skip the logic to clear the original URL if it is same as final URL.
   // This is needed in order to test that offline page request handler can
   // omit the redirect under this circumstance, for compatibility with the
   // metadata already written to the store.
-  model->set_skip_clearing_original_url_for_testing();
+  model->SetSkipClearingOriginalUrlForTesting();
 
   // All offline pages being created below will point to real archive files
   // residing in test data directory.
@@ -465,7 +468,7 @@
                                   kTestFileSize2));
 
   // Make sure that the creation time of 2nd offline file is later.
-  clock_.Advance(base::TimeDelta::FromMinutes(10));
+  clock_ptr_->Advance(base::TimeDelta::FromMinutes(10));
 
   SavePage(kTestUrl1, kTestClientId2, GURL(), std::move(archiver2));
 
@@ -509,7 +512,7 @@
 void OfflinePageRequestJobTest::TearDown() {
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(nullptr);
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(nullptr);
 }
 
 void OfflinePageRequestJobTest::SimulateHasNetworkConnectivity(bool online) {
diff --git a/chrome/browser/offline_pages/offline_page_utils.cc b/chrome/browser/offline_pages/offline_page_utils.cc
index f7fae7ea..3efa562 100644
--- a/chrome/browser/offline_pages/offline_page_utils.cc
+++ b/chrome/browser/offline_pages/offline_page_utils.cc
@@ -60,7 +60,7 @@
       }
     } else {
       // This is consistent with exact match against original url done in
-      // OfflinePageModelImpl.
+      // GetPagesTask.
       DCHECK(url == page.original_url);
       if (!selected_page_for_original_url ||
           page.creation_time > selected_page_for_original_url->creation_time) {
diff --git a/chrome/browser/offline_pages/offline_page_utils_unittest.cc b/chrome/browser/offline_pages/offline_page_utils_unittest.cc
index 3e256cc..270713f 100644
--- a/chrome/browser/offline_pages/offline_page_utils_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_utils_unittest.cc
@@ -29,9 +29,9 @@
 #include "components/offline_pages/core/background/network_quality_provider_stub.h"
 #include "components/offline_pages/core/background/request_coordinator.h"
 #include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/model/offline_page_model_taskified.h"
 #include "components/offline_pages/core/offline_page_feature.h"
 #include "components/offline_pages/core/offline_page_model.h"
-#include "components/offline_pages/core/offline_page_model_impl.h"
 #include "components/offline_pages/core/offline_page_test_archiver.h"
 #include "components/offline_pages/core/offline_page_test_store.h"
 #include "components/offline_pages/core/offline_page_types.h"
@@ -359,18 +359,20 @@
   // The clock will be at 03:00:00 after adding pages.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
-  CreateCachedOfflinePages(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
+  CreateCachedOfflinePages(clock_ptr);
 
   // Advance the clock so that we don't hit the time check boundary.
-  clock.Advance(base::TimeDelta::FromMinutes(5));
+  clock_ptr->Advance(base::TimeDelta::FromMinutes(5));
 
   // Get the size of cached offline pages between 01:05:00 and 03:05:00.
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now() - base::TimeDelta::FromHours(2), clock.Now());
+      clock_ptr->Now() - base::TimeDelta::FromHours(2), clock_ptr->Now());
   RunUntilIdle();
   EXPECT_TRUE(ret);
   EXPECT_EQ(kTestFileSize * 2, last_cache_size());
@@ -380,10 +382,12 @@
   // Set a test clock.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
 
-  clock.Advance(base::TimeDelta::FromHours(3));
+  clock_ptr->Advance(base::TimeDelta::FromHours(3));
 
   // Get the size of cached offline pages between 01:00:00 and 03:00:00.
   // Since no temporary pages were added to the model, the cache size should be
@@ -391,7 +395,7 @@
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now() - base::TimeDelta::FromHours(2), clock.Now());
+      clock_ptr->Now() - base::TimeDelta::FromHours(2), clock_ptr->Now());
   RunUntilIdle();
   EXPECT_TRUE(ret);
   EXPECT_EQ(0, last_cache_size());
@@ -402,18 +406,20 @@
   // The clock will be at 03:00:00 after adding pages.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
-  CreateCachedOfflinePages(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
+  CreateCachedOfflinePages(clock_ptr);
 
   // Advance the clock so that we don't hit the time check boundary.
-  clock.Advance(base::TimeDelta::FromMinutes(5));
+  clock_ptr->Advance(base::TimeDelta::FromMinutes(5));
 
   // Get the size of cached offline pages between 03:04:00 and 03:05:00.
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now() - base::TimeDelta::FromMinutes(1), clock.Now());
+      clock_ptr->Now() - base::TimeDelta::FromMinutes(1), clock_ptr->Now());
   RunUntilIdle();
   EXPECT_TRUE(ret);
   EXPECT_EQ(0, last_cache_size());
@@ -424,18 +430,20 @@
   // The clock will be at 03:00:00 after adding pages.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
-  CreateCachedOfflinePages(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
+  CreateCachedOfflinePages(clock_ptr);
 
   // Advance the clock to 23:00:00.
-  clock.Advance(base::TimeDelta::FromHours(20));
+  clock_ptr->Advance(base::TimeDelta::FromHours(20));
 
   // Get the size of cached offline pages between -01:00:00 and 23:00:00.
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now() - base::TimeDelta::FromHours(24), clock.Now());
+      clock_ptr->Now() - base::TimeDelta::FromHours(24), clock_ptr->Now());
   RunUntilIdle();
   EXPECT_TRUE(ret);
   EXPECT_EQ(kTestFileSize * 4, last_cache_size());
@@ -446,12 +454,14 @@
   // The clock will be at 03:00:00 after adding pages.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
-  CreateCachedOfflinePages(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
+  CreateCachedOfflinePages(clock_ptr);
 
   // Advance the clock to 23:00:00.
-  clock.Advance(base::TimeDelta::FromHours(20));
+  clock_ptr->Advance(base::TimeDelta::FromHours(20));
 
   // Get the size of cached offline pages between 23:00:00 and -01:00:00, which
   // is an invalid range, the return value will be false and there will be no
@@ -459,7 +469,7 @@
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now(), clock.Now() - base::TimeDelta::FromHours(24));
+      clock_ptr->Now(), clock_ptr->Now() - base::TimeDelta::FromHours(24));
   RunUntilIdle();
   EXPECT_FALSE(ret);
 }
@@ -469,9 +479,11 @@
   // The clock will be at 03:00:00 after adding pages.
   OfflinePageModel* model =
       OfflinePageModelFactory::GetForBrowserContext(profile());
-  base::SimpleTestClock clock;
-  static_cast<OfflinePageModelImpl*>(model)->set_testing_clock(&clock);
-  CreateCachedOfflinePages(&clock);
+  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  base::SimpleTestClock* clock_ptr = clock.get();
+  static_cast<OfflinePageModelTaskified*>(model)->SetClockForTesting(
+      std::move(clock));
+  CreateCachedOfflinePages(clock_ptr);
 
   // Get the size of cached offline pages between 02:00:00 and 03:00:00, since
   // we are using a [begin_time, end_time) range so there will be only 1 page
@@ -479,7 +491,7 @@
   bool ret = OfflinePageUtils::GetCachedOfflinePageSizeBetween(
       profile(),
       base::Bind(&OfflinePageUtilsTest::OnSizeInBytesCalculated, AsWeakPtr()),
-      clock.Now() - base::TimeDelta::FromHours(1), clock.Now());
+      clock_ptr->Now() - base::TimeDelta::FromHours(1), clock_ptr->Now());
   RunUntilIdle();
   EXPECT_TRUE(ret);
   EXPECT_EQ(kTestFileSize * 1, last_cache_size());
diff --git a/chrome/browser/offline_pages/test_offline_page_model_builder.cc b/chrome/browser/offline_pages/test_offline_page_model_builder.cc
index 7d2baec8..f1e394e 100644
--- a/chrome/browser/offline_pages/test_offline_page_model_builder.cc
+++ b/chrome/browser/offline_pages/test_offline_page_model_builder.cc
@@ -10,10 +10,11 @@
 #include "base/path_service.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/default_clock.h"
 #include "chrome/common/chrome_constants.h"
 #include "components/offline_pages/core/archive_manager.h"
-#include "components/offline_pages/core/offline_page_model_impl.h"
-#include "components/offline_pages/core/offline_page_test_store.h"
+#include "components/offline_pages/core/model/offline_page_model_taskified.h"
+#include "components/offline_pages/core/offline_page_metadata_store_sql.h"
 #include "content/public/browser/browser_context.h"
 
 namespace offline_pages {
@@ -23,8 +24,10 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       base::ThreadTaskRunnerHandle::Get();
 
-  std::unique_ptr<OfflinePageTestStore> metadata_store(
-      new OfflinePageTestStore(task_runner));
+  base::FilePath store_path =
+      context->GetPath().Append(chrome::kOfflinePageMetadataDirname);
+  std::unique_ptr<OfflinePageMetadataStoreSQL> metadata_store(
+      new OfflinePageMetadataStoreSQL(task_runner, store_path));
 
   base::FilePath persistent_archives_dir =
       context->GetPath().Append(chrome::kOfflinePageArchivesDirname);
@@ -37,9 +40,11 @@
   }
   std::unique_ptr<ArchiveManager> archive_manager(new ArchiveManager(
       temporary_archives_dir, persistent_archives_dir, task_runner));
+  std::unique_ptr<base::Clock> clock(new base::DefaultClock);
 
-  return std::unique_ptr<KeyedService>(new OfflinePageModelImpl(
-      std::move(metadata_store), std::move(archive_manager), task_runner));
+  return std::unique_ptr<KeyedService>(new OfflinePageModelTaskified(
+      std::move(metadata_store), std::move(archive_manager), task_runner,
+      std::move(clock)));
 }
 
 }  // namespace offline_pages
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc
index e2e0feff..0c6cc46 100644
--- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer.cc
@@ -10,6 +10,7 @@
 #include "base/optional.h"
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
@@ -24,7 +25,6 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "url/gurl.h"
@@ -106,7 +106,7 @@
 
 DataReductionProxyMetricsObserver::~DataReductionProxyMetricsObserver() {}
 
-// Check if the NavigationData indicates anything about the DataReductionProxy.
+// Check if the navigation data indicates anything about the DataReductionProxy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 DataReductionProxyMetricsObserver::OnCommit(
     content::NavigationHandle* navigation_handle,
@@ -120,18 +120,16 @@
   // will be called is in MetricsWebContentsObserver's destrcutor, which is
   // called in WebContents destructor.
   browser_context_ = navigation_handle->GetWebContents()->GetBrowserContext();
-  // As documented in content/public/browser/navigation_handle.h, this
-  // NavigationData is a clone of the NavigationData instance returned from
-  // ResourceDispatcherHostDelegate::GetNavigationData during commit.
-  // Because ChromeResourceDispatcherHostDelegate always returns a
-  // ChromeNavigationData, it is safe to static_cast here.
-  ChromeNavigationData* chrome_navigation_data =
-      static_cast<ChromeNavigationData*>(
-          navigation_handle->GetNavigationData());
-  if (!chrome_navigation_data)
+  const base::Value& navigation_data = navigation_handle->GetNavigationData();
+  if (navigation_data.is_none())
     return STOP_OBSERVING;
+  // As documented in content/public/browser/navigation_handle.h, this
+  // navigation data is the one returned from
+  // ResourceDispatcherHostDelegate::GetNavigationData() during commit.
+  ChromeNavigationData chrome_navigation_data(navigation_data);
+
   data_reduction_proxy::DataReductionProxyData* data =
-      chrome_navigation_data->GetDataReductionProxyData();
+      chrome_navigation_data.GetDataReductionProxyData();
   if (!data || !data->used_data_reduction_proxy())
     return STOP_OBSERVING;
   data_ = data->DeepCopy();
diff --git a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc
index 9cb933eb..30e5f9b 100644
--- a/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
 #include "chrome/browser/page_load_metrics/observers/histogram_suffixes.h"
@@ -37,20 +38,6 @@
 
 const char kDefaultTestUrl[] = "http://google.com";
 
-data_reduction_proxy::DataReductionProxyData* DataForNavigationHandle(
-    content::WebContents* web_contents,
-    content::NavigationHandle* navigation_handle) {
-  ChromeNavigationData* chrome_navigation_data = new ChromeNavigationData();
-  content::WebContentsTester::For(web_contents)
-      ->SetNavigationData(navigation_handle,
-                          base::WrapUnique(chrome_navigation_data));
-  data_reduction_proxy::DataReductionProxyData* data =
-      new data_reduction_proxy::DataReductionProxyData();
-  chrome_navigation_data->SetDataReductionProxyData(base::WrapUnique(data));
-
-  return data;
-}
-
 // Pingback client responsible for recording the timing information it receives
 // from a SendPingback call.
 class TestPingbackClient
@@ -117,11 +104,17 @@
   // page_load_metrics::PageLoadMetricsObserver implementation:
   ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
                          ukm::SourceId source_id) override {
-    DataReductionProxyData* data =
-        DataForNavigationHandle(web_contents_, navigation_handle);
+    auto data = std::make_unique<DataReductionProxyData>();
     data->set_used_data_reduction_proxy(data_reduction_proxy_used_);
     data->set_request_url(GURL(kDefaultTestUrl));
     data->set_lofi_requested(lofi_used_);
+    ChromeNavigationData chrome_navigation_data;
+    chrome_navigation_data.SetDataReductionProxyData(std::move(data));
+
+    content::WebContentsTester::For(web_contents_)
+        ->SetNavigationData(navigation_handle,
+                            chrome_navigation_data.ToValue());
+
     return DataReductionProxyMetricsObserver::OnCommit(navigation_handle,
                                                        source_id);
   }
diff --git a/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer.cc
index d29f390..bc05f0e 100644
--- a/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer.cc
@@ -6,6 +6,7 @@
 
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
@@ -63,13 +64,13 @@
 NoScriptPreviewPageLoadMetricsObserver::OnCommit(
     content::NavigationHandle* navigation_handle,
     ukm::SourceId source_id) {
-  ChromeNavigationData* nav_data = static_cast<ChromeNavigationData*>(
-      navigation_handle->GetNavigationData());
-  if (!nav_data)
+  const base::Value& navigation_data = navigation_handle->GetNavigationData();
+  if (navigation_data.is_none())
     return STOP_OBSERVING;
+  ChromeNavigationData chrome_navigation_data(navigation_data);
 
-  previews::PreviewsType preview_type =
-      previews::GetMainFramePreviewsType(nav_data->previews_state());
+  previews::PreviewsType preview_type = previews::GetMainFramePreviewsType(
+      chrome_navigation_data.previews_state());
   if (preview_type == previews::PreviewsType::NOSCRIPT)
     return CONTINUE_OBSERVING;
 
diff --git a/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer_unittest.cc
index 9de2842..5e511ec7 100644
--- a/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/noscript_preview_page_load_metrics_observer_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/optional.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
@@ -62,11 +63,12 @@
         content::NavigationSimulator::CreateRendererInitiated(
             GURL(kDefaultTestUrl), main_rfh());
     navigation_simulator->Start();
-    auto chrome_navigation_data = std::make_unique<ChromeNavigationData>();
-    chrome_navigation_data->set_previews_state(previews_state);
+
+    ChromeNavigationData chrome_navigation_data;
+    chrome_navigation_data.set_previews_state(previews_state);
     content::WebContentsTester::For(web_contents())
         ->SetNavigationData(navigation_simulator->GetNavigationHandle(),
-                            std::move(chrome_navigation_data));
+                            chrome_navigation_data.ToValue());
     navigation_simulator->Commit();
     return navigation_simulator->GetGlobalRequestID();
   }
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
index d818087..3796785 100644
--- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer.cc
@@ -6,6 +6,7 @@
 
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
@@ -36,18 +37,18 @@
   // ResourceDispatcherHostDelegate::GetNavigationData during commit.
   // Because ChromeResourceDispatcherHostDelegate always returns a
   // ChromeNavigationData, it is safe to static_cast here.
-  ChromeNavigationData* chrome_navigation_data =
-      static_cast<ChromeNavigationData*>(
-          navigation_handle->GetNavigationData());
-  if (!chrome_navigation_data)
-    return CONTINUE_OBSERVING;
+  const base::Value& navigation_data = navigation_handle->GetNavigationData();
+  if (navigation_data.is_none())
+    return STOP_OBSERVING;
+
+  ChromeNavigationData chrome_navigation_data(navigation_data);
   data_reduction_proxy::DataReductionProxyData* data =
-      chrome_navigation_data->GetDataReductionProxyData();
+      chrome_navigation_data.GetDataReductionProxyData();
   if (data && data->used_data_reduction_proxy() && data->lite_page_received()) {
     lite_page_seen_ = true;
   }
   content::PreviewsState previews_state =
-      chrome_navigation_data->previews_state();
+      chrome_navigation_data.previews_state();
   if (previews_state && previews::GetMainFramePreviewsType(previews_state) ==
                             previews::PreviewsType::NOSCRIPT) {
     noscript_seen_ = true;
diff --git a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
index 86fc1c5..7ae6691 100644
--- a/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/previews_ukm_observer_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/macros.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/optional.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
@@ -27,20 +28,6 @@
 
 const char kDefaultTestUrl[] = "https://www.google.com/";
 
-data_reduction_proxy::DataReductionProxyData* DataForNavigationHandle(
-    content::WebContents* web_contents,
-    content::NavigationHandle* navigation_handle) {
-  ChromeNavigationData* chrome_navigation_data = new ChromeNavigationData();
-  content::WebContentsTester::For(web_contents)
-      ->SetNavigationData(navigation_handle,
-                          base::WrapUnique(chrome_navigation_data));
-  data_reduction_proxy::DataReductionProxyData* data =
-      new data_reduction_proxy::DataReductionProxyData();
-  chrome_navigation_data->SetDataReductionProxyData(base::WrapUnique(data));
-
-  return data;
-}
-
 class TestPreviewsUKMObserver : public PreviewsUKMObserver {
  public:
   TestPreviewsUKMObserver(content::WebContents* web_contents,
@@ -57,23 +44,23 @@
   // page_load_metrics::PageLoadMetricsObserver implementation:
   ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
                          ukm::SourceId source_id) override {
-    data_reduction_proxy::DataReductionProxyData* data =
-        DataForNavigationHandle(web_contents_, navigation_handle);
-    data->set_used_data_reduction_proxy(data_reduction_proxy_used_);
-    data->set_request_url(GURL(kDefaultTestUrl));
-    data->set_lite_page_received(lite_page_received_);
+    ChromeNavigationData chrome_navigation_data;
 
-    if (noscript_on_) {
-      // ChromeNavigationData is guaranteed to be non-null at this point, as
-      // DataForNavigationHandle is always called prior to this and creates one.
-      ChromeNavigationData* chrome_navigation_data =
-          static_cast<ChromeNavigationData*>(
-              navigation_handle->GetNavigationData());
-      content::PreviewsState previews_state =
-          chrome_navigation_data->previews_state();
-      chrome_navigation_data->set_previews_state(previews_state |=
-                                                 content::NOSCRIPT_ON);
-    }
+    auto data_reduction_proxy_data =
+        std::make_unique<data_reduction_proxy::DataReductionProxyData>();
+    data_reduction_proxy_data->set_used_data_reduction_proxy(
+        data_reduction_proxy_used_);
+    data_reduction_proxy_data->set_request_url(GURL(kDefaultTestUrl));
+    data_reduction_proxy_data->set_lite_page_received(lite_page_received_);
+    chrome_navigation_data.SetDataReductionProxyData(
+        std::move(data_reduction_proxy_data));
+
+    if (noscript_on_)
+      chrome_navigation_data.set_previews_state(content::NOSCRIPT_ON);
+
+    content::WebContentsTester::For(web_contents_)
+        ->SetNavigationData(navigation_handle,
+                            chrome_navigation_data.ToValue());
 
     return PreviewsUKMObserver::OnCommit(navigation_handle, source_id);
   }
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.cc b/chrome/browser/payments/chrome_payment_request_delegate.cc
index b5c8c5a..97cb525 100644
--- a/chrome/browser/payments/chrome_payment_request_delegate.cc
+++ b/chrome/browser/payments/chrome_payment_request_delegate.cc
@@ -75,6 +75,11 @@
     dialog_->ShowErrorMessage();
 }
 
+void ChromePaymentRequestDelegate::ShowProcessingSpinner() {
+  if (dialog_)
+    dialog_->ShowProcessingSpinner();
+}
+
 autofill::PersonalDataManager*
 ChromePaymentRequestDelegate::GetPersonalDataManager() {
   // Autofill uses the original profile's PersonalDataManager to make data
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.h b/chrome/browser/payments/chrome_payment_request_delegate.h
index e6b8f0541..44e8736 100644
--- a/chrome/browser/payments/chrome_payment_request_delegate.h
+++ b/chrome/browser/payments/chrome_payment_request_delegate.h
@@ -28,6 +28,7 @@
   void ShowDialog(PaymentRequest* request) override;
   void CloseDialog() override;
   void ShowErrorMessage() override;
+  void ShowProcessingSpinner() override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   const std::string& GetApplicationLocale() const override;
   bool IsIncognito() const override;
diff --git a/chrome/browser/previews/previews_infobar_tab_helper.cc b/chrome/browser/previews/previews_infobar_tab_helper.cc
index db71da1c..92ac6b6 100644
--- a/chrome/browser/previews/previews_infobar_tab_helper.cc
+++ b/chrome/browser/previews/previews_infobar_tab_helper.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/values.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
@@ -72,10 +73,13 @@
 
   previews_user_data_.reset();
   // Store Previews information for this navigation.
-  ChromeNavigationData* nav_data = static_cast<ChromeNavigationData*>(
-      navigation_handle->GetNavigationData());
-  if (nav_data && nav_data->previews_user_data()) {
-    previews_user_data_ = nav_data->previews_user_data()->DeepCopy();
+  const base::Value& navigation_data = navigation_handle->GetNavigationData();
+  if (!navigation_data.is_none()) {
+    ChromeNavigationData chrome_navigation_data(navigation_data);
+    if (chrome_navigation_data.previews_user_data()) {
+      previews_user_data_ =
+          chrome_navigation_data.previews_user_data()->DeepCopy();
+    }
   }
 
   uint64_t page_id = (previews_user_data_) ? previews_user_data_->page_id() : 0;
diff --git a/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc b/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc
index cc1b4e92..8261d8b8 100644
--- a/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc
+++ b/chrome/browser/previews/previews_infobar_tab_helper_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/values.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/loader/chrome_navigation_data.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
@@ -89,20 +90,22 @@
   }
 
   void SetCommittedPreviewsType(previews::PreviewsType previews_type) {
-    ChromeNavigationData* nav_data =
-        static_cast<ChromeNavigationData*>(test_handle_->GetNavigationData());
-    if (nav_data && nav_data->previews_user_data()) {
-      nav_data->previews_user_data()->SetCommittedPreviewsType(previews_type);
-      return;
+    const base::Value& navigation_data = test_handle_->GetNavigationData();
+    ChromeNavigationData chrome_navigation_data(navigation_data);
+
+    // Add a PreviewsUserData if it didn't exist.
+    if (!chrome_navigation_data.previews_user_data()) {
+      auto previews_user_data = std::make_unique<previews::PreviewsUserData>(1);
+      chrome_navigation_data.set_previews_user_data(
+          std::move(previews_user_data));
     }
-    std::unique_ptr<ChromeNavigationData> chrome_nav_data(
-        new ChromeNavigationData());
-    std::unique_ptr<previews::PreviewsUserData> previews_user_data(
-        new previews::PreviewsUserData(1));
-    previews_user_data->SetCommittedPreviewsType(previews_type);
-    chrome_nav_data->set_previews_user_data(std::move(previews_user_data));
+
+    chrome_navigation_data.previews_user_data()->SetCommittedPreviewsType(
+        previews_type);
+
     content::WebContentsTester::For(web_contents())
-        ->SetNavigationData(test_handle_.get(), std::move(chrome_nav_data));
+        ->SetNavigationData(test_handle_.get(),
+                            chrome_navigation_data.ToValue());
   }
 
   void SimulateWillProcessResponse() {
@@ -124,17 +127,13 @@
     EXPECT_TRUE(test_handle_);
     EXPECT_TRUE(previews_user_data);
     // Store Previews information for this navigation.
-    ChromeNavigationData* nav_data =
-        static_cast<ChromeNavigationData*>(test_handle_->GetNavigationData());
-    if (nav_data) {
-      nav_data->set_previews_user_data(std::move(previews_user_data));
-      return;
-    }
-    std::unique_ptr<ChromeNavigationData> navigation_data =
-        base::MakeUnique<ChromeNavigationData>();
-    navigation_data->set_previews_user_data(std::move(previews_user_data));
+    const base::Value& navigation_data = test_handle_->GetNavigationData();
+    ChromeNavigationData chrome_navigation_data(navigation_data);
+    chrome_navigation_data.set_previews_user_data(
+        std::move(previews_user_data));
     content::WebContentsTester::For(web_contents())
-        ->SetNavigationData(test_handle_.get(), std::move(navigation_data));
+        ->SetNavigationData(test_handle_.get(),
+                            chrome_navigation_data.ToValue());
   }
 
  protected:
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index f7a119e..f635b886 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -12,6 +12,7 @@
 #include "ash/app_list/model/app_list_model.h"
 #include "ash/app_list/model/app_list_view_state.h"
 #include "ash/app_list/model/search/search_box_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram_macros.h"
@@ -49,7 +50,6 @@
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
 #include "ui/app_list/search_controller.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/views/controls/webview/webview.h"
diff --git a/chrome/browser/ui/app_list/search/search_resource_manager.cc b/chrome/browser/ui/app_list/search/search_resource_manager.cc
index 824987c..30e3e1fc 100644
--- a/chrome/browser/ui/app_list/search/search_resource_manager.cc
+++ b/chrome/browser/ui/app_list/search/search_resource_manager.cc
@@ -7,12 +7,12 @@
 #include <memory>
 
 #include "ash/app_list/model/search/search_box_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/ui/app_list/start_page_service.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
 #include "ui/app_list/app_list_features.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
diff --git a/chrome/browser/ui/app_list/search/search_resource_manager.h b/chrome/browser/ui/app_list/search/search_resource_manager.h
index 6ef71ff..28d6200 100644
--- a/chrome/browser/ui/app_list/search/search_resource_manager.h
+++ b/chrome/browser/ui/app_list/search/search_resource_manager.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_RESOURCE_MANAGER_H_
 #define CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_RESOURCE_MANAGER_H_
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 class Profile;
 
diff --git a/chrome/browser/ui/app_list/speech_recognizer.cc b/chrome/browser/ui/app_list/speech_recognizer.cc
index 69fbf63..3dc21564 100644
--- a/chrome/browser/ui/app_list/speech_recognizer.cc
+++ b/chrome/browser/ui/app_list/speech_recognizer.cc
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/strings/string16.h"
@@ -23,7 +24,6 @@
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/speech_recognition_error.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 namespace app_list {
 
diff --git a/chrome/browser/ui/app_list/speech_recognizer_delegate.h b/chrome/browser/ui/app_list/speech_recognizer_delegate.h
index f1d0429..056bb1f 100644
--- a/chrome/browser/ui/app_list/speech_recognizer_delegate.h
+++ b/chrome/browser/ui/app_list/speech_recognizer_delegate.h
@@ -8,8 +8,8 @@
 #include <stdint.h>
 #include <string>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/strings/string16.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 namespace app_list {
 
diff --git a/chrome/browser/ui/app_list/start_page_observer.h b/chrome/browser/ui/app_list/start_page_observer.h
index 3dc55fc..2de0ee5f 100644
--- a/chrome/browser/ui/app_list/start_page_observer.h
+++ b/chrome/browser/ui/app_list/start_page_observer.h
@@ -7,8 +7,8 @@
 
 #include <stdint.h>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/strings/string16.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 namespace app_list {
 
diff --git a/chrome/browser/ui/app_list/start_page_service.h b/chrome/browser/ui/app_list/start_page_service.h
index 184c43b..10b1a07a 100644
--- a/chrome/browser/ui/app_list/start_page_service.h
+++ b/chrome/browser/ui/app_list/start_page_service.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -25,7 +26,6 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "net/base/backoff_entry.h"
 #include "net/url_request/url_fetcher_delegate.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 namespace content {
 struct SpeechRecognitionSessionPreamble;
diff --git a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc
index 361d771..09d3187 100644
--- a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "chrome/browser/media/router/media_routes_observer.h"
 #include "chrome/browser/media/router/media_sinks_observer.h"
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/browser/ui/ash/cast_config_client_media_router.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 8cac17b..57f714e 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -360,7 +360,7 @@
 
 // Background window does not steal focus.
 // Flaky, http://crbug.com/62538.
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 #define MAYBE_BackgroundBrowserDontStealFocus \
   DISABLED_BackgroundBrowserDontStealFocus
 #else
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc
index 09191e00..5c8fd3f 100644
--- a/chrome/browser/ui/libgtkui/gtk_util.cc
+++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -25,6 +25,7 @@
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/views/linux_ui/linux_ui.h"
 
 namespace {
 
@@ -53,6 +54,11 @@
   }
 }
 
+float GetDeviceScaleFactor() {
+  views::LinuxUI* linux_ui = views::LinuxUI::instance();
+  return linux_ui ? linux_ui->GetDeviceScaleFactor() : 1;
+}
+
 }  // namespace
 
 namespace libgtkui {
@@ -446,6 +452,7 @@
     }
     gtk_style_context_set_state(child_context, child_state);
   }
+  gtk_style_context_set_scale(child_context, std::ceil(GetDeviceScaleFactor()));
   gtk_style_context_set_parent(child_context, context);
   gtk_widget_path_unref(path);
   return child_context;
diff --git a/chrome/browser/ui/libgtkui/nav_button_provider_gtk3.cc b/chrome/browser/ui/libgtkui/nav_button_provider_gtk3.cc
index edc8c34..d499833 100644
--- a/chrome/browser/ui/libgtkui/nav_button_provider_gtk3.cc
+++ b/chrome/browser/ui/libgtkui/nav_button_provider_gtk3.cc
@@ -204,6 +204,18 @@
     }
     gtk_style_context_set_state(button_context, button_state);
 
+    // Gtk header bars usually have the same height in both maximized and
+    // restored windows.  But chrome's tabstrip background has a smaller height
+    // when maximized.  To prevent buttons from clipping outside of this region,
+    // they are scaled down.  However, this is problematic for themes that do
+    // not expect this case and use bitmaps for frame buttons (like the Breeze
+    // theme).  When the background-size is set to auto, the background bitmap
+    // is not scaled for the (unexpected) smaller button size, and the button's
+    // edges appear cut off.  To fix this, manually set the background to scale
+    // to the button size when it would have clipped.
+    ApplyCssToContext(button_context,
+                      ".titlebutton { background-size: contain; }");
+
     // Gtk doesn't support fractional scale factors, but chrome does.
     // Rendering the button background and border at a fractional
     // scale factor is easy, since we can adjust the cairo context
diff --git a/chrome/browser/ui/media_router/presentation_receiver_window_controller.cc b/chrome/browser/ui/media_router/presentation_receiver_window_controller.cc
index c3e48c9..3466cf7 100644
--- a/chrome/browser/ui/media_router/presentation_receiver_window_controller.cc
+++ b/chrome/browser/ui/media_router/presentation_receiver_window_controller.cc
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "chrome/browser/media/router/receiver_presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/media_router/presentation_receiver_window.h"
 #include "content/public/browser/navigation_controller.h"
diff --git a/chrome/browser/ui/media_router/presentation_receiver_window_controller.h b/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
index a0562fd..4ffaeef 100644
--- a/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
+++ b/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
@@ -10,8 +10,8 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "chrome/browser/media/router/independent_otr_profile_manager.h"
-#include "chrome/browser/media/router/presentation_navigation_policy.h"
+#include "chrome/browser/media/router/presentation/independent_otr_profile_manager.h"
+#include "chrome/browser/media/router/presentation/presentation_navigation_policy.h"
 #include "chrome/browser/ui/media_router/presentation_receiver_window_delegate.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
diff --git a/chrome/browser/ui/media_router/presentation_receiver_window_controller_browsertest.cc b/chrome/browser/ui/media_router/presentation_receiver_window_controller_browsertest.cc
index 0690fd87..091d2825 100644
--- a/chrome/browser/ui/media_router/presentation_receiver_window_controller_browsertest.cc
+++ b/chrome/browser/ui/media_router/presentation_receiver_window_controller_browsertest.cc
@@ -13,8 +13,8 @@
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/timer/elapsed_timer.h"
-#include "chrome/browser/media/router/local_presentation_manager.h"
-#include "chrome/browser/media/router/local_presentation_manager_factory.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager.h"
+#include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
index e9da575..b6b1667 100644
--- a/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
+++ b/chrome/browser/ui/toolbar/media_router_action_controller_unittest.cc
@@ -5,7 +5,7 @@
 #include <memory>
 #include <string>
 
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/browser/ui/toolbar/component_action_delegate.h"
 #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
 #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 7abeb9a..538e0cf5 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -312,7 +312,7 @@
     Profile* profile,
     const GURL& url,
     bool newly_bookmarked)
-    : LocationBarBubbleDelegateView(anchor_view, nullptr),
+    : LocationBarBubbleDelegateView(anchor_view, gfx::Point(), nullptr),
       observer_(observer),
       delegate_(std::move(delegate)),
       profile_(profile),
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc
index 29c2ac4..7d33e99 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -303,7 +303,9 @@
     IntentPickerResponse intent_picker_cb,
     content::WebContents* web_contents,
     bool disable_stay_in_chrome)
-    : LocationBarBubbleDelegateView(nullptr /* anchor_view */, web_contents),
+    : LocationBarBubbleDelegateView(nullptr /* anchor_view */,
+                                    gfx::Point(),
+                                    web_contents),
       content::WebContentsObserver(web_contents),
       intent_picker_cb_(intent_picker_cb),
       selected_app_tag_(0),
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
index f2c1a353..8cb5c9f 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
@@ -74,11 +74,6 @@
       GetLayoutConstant(LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET), 0));
 }
 
-LocationBarBubbleDelegateView::LocationBarBubbleDelegateView(
-    views::View* anchor_view,
-    content::WebContents* web_contents)
-    : LocationBarBubbleDelegateView(anchor_view, gfx::Point(), web_contents) {}
-
 LocationBarBubbleDelegateView::~LocationBarBubbleDelegateView() {}
 
 void LocationBarBubbleDelegateView::ShowForReason(DisplayReason reason) {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
index 32cb9e84..7c61f48 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h
@@ -42,9 +42,6 @@
                                 const gfx::Point& anchor_point,
                                 content::WebContents* web_contents);
 
-  // TODO(varkha): Delete this override and use the constructor above.
-  LocationBarBubbleDelegateView(views::View* anchor_view,
-                                content::WebContents* web_contents);
   ~LocationBarBubbleDelegateView() override;
 
   // Displays the bubble with appearance and behavior tailored for |reason|.
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller_browsertest.cc
index 70463d3..47aa8ea 100644
--- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller_browsertest.cc
@@ -75,7 +75,8 @@
                   ->enabled());
   OpenCVCPromptWithCVC(base::ASCIIToUTF16("012"));
 
-  ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+  ResetEventWaiterForSequence(
+      {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
   views::View* cvc_sheet = dialog_view()->GetViewByID(
       static_cast<int>(DialogViewID::CVC_UNMASK_SHEET));
   cvc_sheet->AcceleratorPressed(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
diff --git a/chrome/browser/ui/views/payments/empty_update_browsertest.cc b/chrome/browser/ui/views/payments/empty_update_browsertest.cc
index 17ca9fc..4c16f1c 100644
--- a/chrome/browser/ui/views/payments/empty_update_browsertest.cc
+++ b/chrome/browser/ui/views/payments/empty_update_browsertest.cc
@@ -26,7 +26,7 @@
   OpenShippingAddressSectionScreen();
 
   ResetEventWaiterForSequence(
-      std::list<DialogEvent>{DialogEvent::DIALOG_CLOSED});
+      {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
 
   ClickOnChildInListViewAndWait(
       /* child_index=*/0, /*total_num_children=*/1,
diff --git a/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
index 9712420..fbf8c6727 100644
--- a/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/error_message_view_controller_browsertest.cc
@@ -40,7 +40,9 @@
   // message should be shown.
   OpenCVCPromptWithCVC(base::ASCIIToUTF16("123"));
 
-  ResetEventWaiter(DialogEvent::ERROR_MESSAGE_SHOWN);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::ERROR_MESSAGE_SHOWN});
   ClickOnDialogViewAndWait(DialogViewID::CVC_PROMPT_CONFIRM_BUTTON);
   EXPECT_FALSE(dialog_view()->throbber_overlay_for_testing()->visible());
 
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
index 90e633b..5979ea5f7 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller_browsertest.cc
@@ -53,8 +53,10 @@
   // Go to the shipping address screen and select the first address (MI state).
   ClickOnBackArrow();
   OpenShippingAddressSectionScreen();
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/0, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
@@ -97,8 +99,10 @@
   // Go to the shipping address screen and select the second address (CA state).
   ClickOnBackArrow();
   OpenShippingAddressSectionScreen();
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/1, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
index c4502c2..8f5188a 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -230,6 +230,16 @@
     event_waiter_->OnEvent(DialogEvent::CVC_PROMPT_SHOWN);
 }
 
+void PaymentRequestBrowserTestBase::OnProcessingSpinnerShown() {
+  if (event_waiter_)
+    event_waiter_->OnEvent(DialogEvent::PROCESSING_SPINNER_SHOWN);
+}
+
+void PaymentRequestBrowserTestBase::OnProcessingSpinnerHidden() {
+  if (event_waiter_)
+    event_waiter_->OnEvent(DialogEvent::PROCESSING_SPINNER_HIDDEN);
+}
+
 void PaymentRequestBrowserTestBase::OnInterfaceRequestFromFrame(
     content::RenderFrameHost* render_frame_host,
     const std::string& interface_name,
@@ -605,7 +615,8 @@
     PaymentRequestDialogView* dialog_view) {
   OpenCVCPromptWithCVC(cvc, dialog_view);
 
-  ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+  ResetEventWaiterForSequence(
+      {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
   ClickOnDialogViewAndWait(DialogViewID::CVC_PROMPT_CONFIRM_BUTTON,
                            dialog_view);
 }
@@ -816,6 +827,12 @@
     case DialogEvent::ABORT_CALLED:
       out << "ABORT_CALLED";
       break;
+    case DialogEvent::PROCESSING_SPINNER_SHOWN:
+      out << "PROCESSING_SPINNER_SHOWN";
+      break;
+    case DialogEvent::PROCESSING_SPINNER_HIDDEN:
+      out << "PROCESSING_SPINNER_HIDDEN";
+      break;
   }
   return out;
 }
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
index 645263d..2d1d0fd 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
@@ -85,6 +85,8 @@
     CVC_PROMPT_SHOWN,
     NOT_SUPPORTED_ERROR,
     ABORT_CALLED,
+    PROCESSING_SPINNER_SHOWN,
+    PROCESSING_SPINNER_HIDDEN,
   };
 
  protected:
@@ -125,6 +127,8 @@
   void OnErrorMessageShown() override;
   void OnSpecDoneUpdating() override;
   void OnCvcPromptShown() override;
+  void OnProcessingSpinnerShown() override;
+  void OnProcessingSpinnerHidden() override;
 
   // content::WebContentsObserver implementation.
   void OnInterfaceRequestFromFrame(
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
index 4746831..a68b20e 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -159,6 +159,13 @@
     observer_for_testing_->OnErrorMessageShown();
 }
 
+void PaymentRequestDialogView::ShowProcessingSpinner() {
+  throbber_.Start();
+  throbber_overlay_.SetVisible(true);
+  if (observer_for_testing_)
+    observer_for_testing_->OnProcessingSpinnerShown();
+}
+
 void PaymentRequestDialogView::OnStartUpdating(
     PaymentRequestSpec::UpdateReason reason) {
   ShowProcessingSpinner();
@@ -329,14 +336,11 @@
     observer_for_testing_->OnEditorViewUpdated();
 }
 
-void PaymentRequestDialogView::ShowProcessingSpinner() {
-  throbber_.Start();
-  throbber_overlay_.SetVisible(true);
-}
-
 void PaymentRequestDialogView::HideProcessingSpinner() {
   throbber_.Stop();
   throbber_overlay_.SetVisible(false);
+  if (observer_for_testing_)
+    observer_for_testing_->OnProcessingSpinnerHidden();
 }
 
 Profile* PaymentRequestDialogView::GetProfile() {
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
index 52f7b64..74983c7 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -79,6 +79,10 @@
     virtual void OnSpecDoneUpdating() = 0;
 
     virtual void OnCvcPromptShown() = 0;
+
+    virtual void OnProcessingSpinnerShown() = 0;
+
+    virtual void OnProcessingSpinnerHidden() = 0;
   };
 
   // Build a Dialog around the PaymentRequest object. |observer| is used to
@@ -104,6 +108,7 @@
   void ShowDialog() override;
   void CloseDialog() override;
   void ShowErrorMessage() override;
+  void ShowProcessingSpinner() override;
 
   // PaymentRequestSpec::Observer:
   void OnStartUpdating(PaymentRequestSpec::UpdateReason reason) override;
@@ -164,9 +169,7 @@
           result_delegate,
       content::WebContents* web_contents) override;
 
-  // Shows/Hides a full dialog spinner with the "processing" label that doesn't
-  // offer a way of closing the dialog.
-  void ShowProcessingSpinner();
+  // Hides the full dialog spinner with the "processing" label.
   void HideProcessingSpinner();
 
   Profile* GetProfile();
diff --git a/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc
index d3c68b3..17212d8 100644
--- a/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_no_update_with_browsertest.cc
@@ -44,8 +44,10 @@
   RunJavaScriptFunctionToOpenPaymentRequestUI("buyWithoutListeners");
 
   OpenShippingAddressSectionScreen();
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/1, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
@@ -76,8 +78,10 @@
   RunJavaScriptFunctionToOpenPaymentRequestUI("buyWithoutCallingUpdateWith");
 
   OpenShippingAddressSectionScreen();
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/1, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
@@ -112,8 +116,10 @@
   ClickOnBackArrow();
 
   OpenShippingAddressSectionScreen();
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/1, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
index e20d698e..35a05e68 100644
--- a/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_payment_app_browsertest.cc
@@ -182,7 +182,8 @@
 
     InvokePaymentRequestUI();
 
-    ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+    ResetEventWaiterForSequence(
+        {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
     ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view());
     ExpectBodyContains({"https://alicepay.com"});
   }
@@ -206,7 +207,8 @@
 
     InvokePaymentRequestUI();
 
-    ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+    ResetEventWaiterForSequence(
+        {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
     ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view());
     ExpectBodyContains({"https://alicepay.com"});
   }
@@ -273,7 +275,8 @@
         "/payment_request_bobpay_and_basic_card_with_modifiers_test.html");
     InvokePaymentRequestUI();
 
-    ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+    ResetEventWaiterForSequence(
+        {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
     ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view());
     ExpectBodyContains({"basic-card"});
   }
@@ -286,7 +289,8 @@
         "/payment_request_bobpay_and_basic_card_with_modifiers_test.html");
     InvokePaymentRequestUI();
 
-    ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+    ResetEventWaiterForSequence(
+        {DialogEvent::PROCESSING_SPINNER_SHOWN, DialogEvent::DIALOG_CLOSED});
     ClickOnDialogViewAndWait(DialogViewID::PAY_BUTTON, dialog_view());
     ExpectBodyContains({"basic-card"});
   }
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
index 04b6b75e..2e7d630 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
@@ -213,7 +213,9 @@
   // We also need to set the state when no region data is provided.
   SetFieldTestValue(autofill::ADDRESS_HOME_STATE);
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
@@ -257,7 +259,9 @@
   // We also need to set the state when no region data is provided.
   SetFieldTestValue(autofill::ADDRESS_HOME_STATE);
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
@@ -303,7 +307,9 @@
 
   std::string country_code(GetSelectedCountryCode());
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
@@ -457,7 +463,9 @@
   // value can be set as the state.
   SetFieldTestValue(autofill::ADDRESS_HOME_STATE);
   SetCommonFields();
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
@@ -498,7 +506,9 @@
   // Now any textual value can be set for the ADDRESS_HOME_STATE.
   SetFieldTestValue(autofill::ADDRESS_HOME_STATE);
   SetCommonFields();
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
@@ -564,7 +574,9 @@
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
   personal_data_manager->AddObserver(&personal_data_observer_);
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Wait until the web database has been updated and the notification sent.
   base::RunLoop data_loop;
@@ -664,7 +676,8 @@
   SetEditorTextfieldValue(base::UTF8ToUTF16("+61 2 9374 4000"),
                           autofill::PHONE_HOME_WHOLE_NUMBER);
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION});
   ClickOnDialogViewAndWait(DialogViewID::SAVE_ADDRESS_BUTTON);
 }
 
@@ -720,7 +733,9 @@
   SetEditorTextfieldValue(base::ASCIIToUTF16(kCountryWithoutStatesPhoneNumber),
                           autofill::PHONE_HOME_WHOLE_NUMBER);
 
-  ResetEventWaiter(DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::BACK_TO_PAYMENT_SHEET_NAVIGATION,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN});
 
   // Verifying the data is in the DB.
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc
index fdbd786..eed4890 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller_browsertest.cc
@@ -54,8 +54,10 @@
                 "To see shipping methods and requirements, select an address"),
             GetLabelText(DialogViewID::SHIPPING_ADDRESS_SECTION_HEADER_LABEL));
 
-  ResetEventWaiterForSequence(std::list<DialogEvent>{
-      DialogEvent::SPEC_DONE_UPDATING, DialogEvent::BACK_NAVIGATION});
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING,
+                               DialogEvent::BACK_NAVIGATION});
   ClickOnChildInListViewAndWait(
       /* child_index=*/0, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW,
@@ -85,7 +87,9 @@
 
   // Go to the shipping address screen and select the second address (Canada).
   OpenShippingAddressSectionScreen();
-  ResetEventWaiter(DialogEvent::SPEC_DONE_UPDATING);
+  ResetEventWaiterForSequence({DialogEvent::PROCESSING_SPINNER_SHOWN,
+                               DialogEvent::PROCESSING_SPINNER_HIDDEN,
+                               DialogEvent::SPEC_DONE_UPDATING});
   ClickOnChildInListViewAndWait(
       /* child_index=*/1, /*total_num_children=*/2,
       DialogViewID::SHIPPING_ADDRESS_SHEET_LIST_VIEW, false);
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
index bc04df3..e31861f 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/previews/core/previews_experiments.h"
+#include "components/previews/core/previews_switches.h"
 #include "net/nqe/network_quality_estimator_params.h"
 
 namespace {
@@ -44,12 +45,15 @@
 const char kEctFlagHtmlId[] = "ect-flag";
 const char kNoScriptFlagHtmlId[] = "noscript-flag";
 const char kOfflinePageFlagHtmlId[] = "offline-page-flag";
+const char kIgnorePreviewsBlacklistFlagHtmlId[] = "ignore-previews-blacklist";
 
 // Links to flags in chrome://flags.
 // TODO(thanhdle): Refactor into vector of structs. crbug.com/787010.
 const char kEctFlagLink[] = "chrome://flags/#force-effective-connection-type";
 const char kNoScriptFlagLink[] = "chrome://flags/#enable-noscript-previews";
 const char kOfflinePageFlagLink[] = "chrome://flags/#enable-offline-previews";
+const char kIgnorePreviewsBlacklistLink[] =
+    "chrome://flags/#ignore-previews-blacklist";
 
 const char kDefaultFlagValue[] = "Default";
 
@@ -80,6 +84,13 @@
   return kDefaultFlagValue;
 }
 
+// Check if the switch flag is enabled or disabled via flag/command-line.
+std::string GetEnabledStateForSwitch(const std::string& switch_name) {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(switch_name)
+             ? "Enabled"
+             : "Disabled";
+}
+
 }  // namespace
 
 InterventionsInternalsPageHandler::InterventionsInternalsPageHandler(
@@ -145,8 +156,10 @@
 }
 
 void InterventionsInternalsPageHandler::OnLastObserverRemove() {
-  // Reset the status of ignoring PreviewsBlackList decisions to false.
-  previews_ui_service_->SetIgnorePreviewsBlacklistDecision(false /* ignored */);
+  // Reset the status of ignoring PreviewsBlackList decisions to default value.
+  previews_ui_service_->SetIgnorePreviewsBlacklistDecision(
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          previews::switches::kIgnorePreviewsBlacklist));
 }
 
 void InterventionsInternalsPageHandler::OnIgnoreBlacklistDecisionStatusChanged(
@@ -215,6 +228,15 @@
   ect_status->htmlId = kEctFlagHtmlId;
   flags.push_back(std::move(ect_status));
 
+  auto ignore_previews_blacklist = mojom::PreviewsFlag::New();
+  ignore_previews_blacklist->description =
+      flag_descriptions::kIgnorePreviewsBlacklistName;
+  ignore_previews_blacklist->link = kIgnorePreviewsBlacklistLink;
+  ignore_previews_blacklist->value =
+      GetEnabledStateForSwitch(previews::switches::kIgnorePreviewsBlacklist);
+  ignore_previews_blacklist->htmlId = kIgnorePreviewsBlacklistFlagHtmlId;
+  flags.push_back(std::move(ignore_previews_blacklist));
+
   auto noscript_status = mojom::PreviewsFlag::New();
   noscript_status->description = flag_descriptions::kEnableNoScriptPreviewsName;
   noscript_status->link = kNoScriptFlagLink;
diff --git a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
index 7215df62..8647d8a 100644
--- a/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/interventions_internals/interventions_internals_page_handler_unittest.cc
@@ -34,6 +34,7 @@
 #include "components/previews/core/previews_features.h"
 #include "components/previews/core/previews_logger.h"
 #include "components/previews/core/previews_logger_observer.h"
+#include "components/previews/core/previews_switches.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/nqe/effective_connection_type.h"
@@ -56,6 +57,8 @@
 
 // The HTML DOM ID used in Javascript.
 constexpr char kEctFlagHtmlId[] = "ect-flag";
+constexpr char kIgnorePreviewsBlacklistFlagHtmlId[] =
+    "ignore-previews-blacklist";
 constexpr char kNoScriptFlagHtmlId[] = "noscript-flag";
 constexpr char kOfflinePageFlagHtmlId[] = "offline-page-flag";
 
@@ -63,6 +66,8 @@
 constexpr char kNoScriptFlagLink[] = "chrome://flags/#enable-noscript-previews";
 constexpr char kEctFlagLink[] =
     "chrome://flags/#force-effective-connection-type";
+constexpr char kIgnorePreviewsBlacklistLink[] =
+    "chrome://flags/#ignore-previews-blacklist";
 constexpr char kOfflinePageFlagLink[] =
     "chrome://flags/#enable-offline-previews";
 
@@ -420,7 +425,7 @@
   page_handler_->GetPreviewsFlagsDetails(
       base::BindOnce(&MockGetPreviewsFlagsCallback));
 
-  constexpr size_t expected = 3;
+  constexpr size_t expected = 4;
   EXPECT_EQ(expected, passed_in_flags.size());
 }
 
@@ -484,6 +489,36 @@
   EXPECT_EQ(kEctFlagLink, ect_flag->second->link);
 }
 
+TEST_F(InterventionsInternalsPageHandlerTest,
+       GetFlagsIgnorePreviewsBlacklistDisabledValue) {
+  // Disabled by default.
+  page_handler_->GetPreviewsFlagsDetails(
+      base::BindOnce(&MockGetPreviewsFlagsCallback));
+  auto ignore_previews_blacklist =
+      passed_in_flags.find(kIgnorePreviewsBlacklistFlagHtmlId);
+
+  ASSERT_NE(passed_in_flags.end(), ignore_previews_blacklist);
+  EXPECT_EQ(flag_descriptions::kIgnorePreviewsBlacklistName,
+            ignore_previews_blacklist->second->description);
+  EXPECT_EQ(kDisabledFlagValue, ignore_previews_blacklist->second->value);
+  EXPECT_EQ(kIgnorePreviewsBlacklistLink,
+            ignore_previews_blacklist->second->link);
+}
+
+TEST_F(InterventionsInternalsPageHandlerTest, GetFlagsNoScriptDisabledValue) {
+  page_handler_->GetPreviewsFlagsDetails(
+      base::BindOnce(&MockGetPreviewsFlagsCallback));
+  auto ignore_previews_blacklist =
+      passed_in_flags.find(kIgnorePreviewsBlacklistFlagHtmlId);
+
+  ASSERT_NE(passed_in_flags.end(), ignore_previews_blacklist);
+  EXPECT_EQ(flag_descriptions::kIgnorePreviewsBlacklistName,
+            ignore_previews_blacklist->second->description);
+  EXPECT_EQ(kDisabledFlagValue, ignore_previews_blacklist->second->value);
+  EXPECT_EQ(kIgnorePreviewsBlacklistLink,
+            ignore_previews_blacklist->second->link);
+}
+
 TEST_F(InterventionsInternalsPageHandlerTest, GetFlagsNoScriptDefaultValue) {
   page_handler_->GetPreviewsFlagsDetails(
       base::BindOnce(&MockGetPreviewsFlagsCallback));
@@ -686,6 +721,20 @@
 
 TEST_F(InterventionsInternalsPageHandlerTest,
        IgnoreBlacklistReversedOnLastObserverRemovedCalled) {
+  ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      previews::switches::kIgnorePreviewsBlacklist));
+  page_handler_->OnLastObserverRemove();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(page_->blacklist_ignored());
+}
+
+TEST_F(InterventionsInternalsPageHandlerTest,
+       IgnoreBlacklistReversedOnLastObserverRemovedCalledIgnoreViaFlag) {
+  base::test::ScopedCommandLine scoped_command_line;
+  base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
+  command_line->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
+  ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      previews::switches::kIgnorePreviewsBlacklist));
   page_handler_->OnLastObserverRemove();
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(page_->blacklist_ignored());
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
index c9e8b281..18164fca 100644
--- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
@@ -12,7 +12,7 @@
 #include "base/macros.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl_unittest.cc
index 659255d..dbc60a9 100644
--- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl_unittest.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl_unittest.cc
@@ -5,7 +5,7 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc
index b306ec2..e28be147 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -28,7 +28,7 @@
 #include "chrome/browser/media/router/media_routes_observer.h"
 #include "chrome/browser/media/router/media_sinks_observer.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/browser_finder.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.h b/chrome/browser/ui/webui/media_router/media_router_ui.h
index 72e0082..08e2cc1 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.h
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -16,7 +16,7 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/media/router/media_router_dialog_controller.h"
 #include "chrome/browser/media/router/mojo/media_route_controller.h"
-#include "chrome/browser/media/router/presentation_service_delegate_impl.h"
+#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
 #include "chrome/browser/ui/webui/media_router/media_cast_mode.h"
 #include "chrome/browser/ui/webui/media_router/media_router_file_dialog.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
index 802baf5..0265e3d 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
@@ -12,9 +12,9 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/media/router/event_page_request_manager_factory.h"
 #include "chrome/browser/media/router/media_router_factory.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
-#include "chrome/browser/media/router/test_helper.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
+#include "chrome/browser/media/router/test/test_helper.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h"
 #include "chrome/common/media_router/media_route.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
index b1f66b7..70fcb50 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
-#include "chrome/browser/media/router/mock_media_router.h"
-#include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/media_router_mojo_test.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/media_router/media_router_ui.h"
diff --git a/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc b/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc
index 4b3d651..f03f84c 100644
--- a/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc
+++ b/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/json/json_writer.h"
 #include "base/macros.h"
 #include "chrome/browser/media/router/media_sinks_observer.h"
-#include "chrome/browser/media/router/mock_media_router.h"
+#include "chrome/browser/media/router/test/mock_media_router.h"
 #include "chrome/common/media_router/media_source_helper.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index ad3b9ed..55eef11 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -156,7 +156,6 @@
     "page_load_metrics/page_track_decider.h",
     "partial_circular_buffer.cc",
     "partial_circular_buffer.h",
-    "pause_tabs_field_trial.h",
     "pdf_uma.cc",
     "pdf_uma.h",
     "pref_names_util.cc",
diff --git a/chrome/common/pause_tabs_field_trial.h b/chrome/common/pause_tabs_field_trial.h
deleted file mode 100644
index bbc8f69..0000000
--- a/chrome/common/pause_tabs_field_trial.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_COMMON_PAUSE_TABS_FIELD_TRIAL_H_
-#define CHROME_COMMON_PAUSE_TABS_FIELD_TRIAL_H_
-
-#include "base/feature_list.h"
-
-namespace pausetabs {
-
-const base::Feature kFeature{"PauseBackgroundTabs",
-                             base::FEATURE_DISABLED_BY_DEFAULT};
-
-const char kFeatureName[] = "pause-background-tabs";
-
-// Mode values.
-const char kModeParamMinimal[] = "minimal";
-const char kModeParamLow[] = "low";
-const char kModeParamMedium[] = "medium";
-const char kModeParamHigh[] = "high";
-const char kModeParamMax[] = "max";
-
-}  // namespace pausetabs
-
-#endif  // CHROME_COMMON_PAUSE_TABS_FIELD_TRIAL_H_
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 3346c213..aa14f288 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -30,7 +30,6 @@
 #include "chrome/common/constants.mojom.h"
 #include "chrome/common/crash_keys.h"
 #include "chrome/common/features.h"
-#include "chrome/common/pause_tabs_field_trial.h"
 #include "chrome/common/pdf_uma.h"
 #include "chrome/common/pepper_permission_util.h"
 #include "chrome/common/plugin.mojom.h"
@@ -1228,12 +1227,7 @@
 }
 
 bool ChromeContentRendererClient::AllowStoppingWhenProcessBackgrounded() {
-#if defined(OS_ANDROID)
-  return true;
-#else
-  // TODO(ojan): Plumb the engagement values for this feature to WebViewImpl.
-  return base::FeatureList::IsEnabled(pausetabs::kFeature);
-#endif
+  return base::FeatureList::IsEnabled(features::kStopInBackground);
 }
 
 bool ChromeContentRendererClient::AllowPopup() {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index bdaf88b..ad9d0ce2 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -538,7 +538,7 @@
       "../browser/media/media_browsertest.h",
       "../browser/media/media_engagement_autoplay_browsertest.cc",
       "../browser/media/media_engagement_browsertest.cc",
-      "../browser/media/router/independent_otr_profile_manager_browsertest.cc",
+      "../browser/media/router/presentation/independent_otr_profile_manager_browsertest.cc",
       "../browser/media/test_license_server.cc",
       "../browser/media/test_license_server.h",
       "../browser/media/test_license_server_config.h",
@@ -2293,17 +2293,17 @@
     "../browser/media/media_storage_id_salt_unittest.cc",
     "../browser/media/midi_permission_context_unittest.cc",
     "../browser/media/midi_sysex_permission_context_unittest.cc",
-    "../browser/media/router/browser_presentation_connection_proxy_unittest.cc",
     "../browser/media/router/issue_manager_unittest.cc",
-    "../browser/media/router/local_presentation_manager_factory_unittest.cc",
-    "../browser/media/router/local_presentation_manager_unittest.cc",
     "../browser/media/router/media_router_base_unittest.cc",
     "../browser/media/router/media_router_dialog_controller_unittest.cc",
     "../browser/media/router/media_router_factory_unittest.cc",
     "../browser/media/router/media_router_metrics_unittest.cc",
     "../browser/media/router/media_sinks_observer_unittest.cc",
-    "../browser/media/router/presentation_media_sinks_observer_unittest.cc",
-    "../browser/media/router/presentation_service_delegate_impl_unittest.cc",
+    "../browser/media/router/presentation/browser_presentation_connection_proxy_unittest.cc",
+    "../browser/media/router/presentation/local_presentation_manager_factory_unittest.cc",
+    "../browser/media/router/presentation/local_presentation_manager_unittest.cc",
+    "../browser/media/router/presentation/presentation_media_sinks_observer_unittest.cc",
+    "../browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc",
     "../browser/media/webrtc/media_stream_device_permission_context_unittest.cc",
     "../browser/metrics/antivirus_metrics_provider_win_unittest.cc",
     "../browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc",
@@ -2988,13 +2988,13 @@
       "../browser/media/router/discovery/mdns/dns_sd_registry_unittest.cc",
       "../browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc",
       "../browser/media/router/event_page_request_manager_unittest.cc",
-      "../browser/media/router/mojo/extension_media_route_provider_proxy_unittest.cc",
       "../browser/media/router/mojo/media_route_controller_unittest.cc",
       "../browser/media/router/mojo/media_router_desktop_unittest.cc",
       "../browser/media/router/mojo/media_router_mojo_impl_unittest.cc",
       "../browser/media/router/mojo/media_router_mojo_metrics_unittest.cc",
-      "../browser/media/router/mojo/wired_display_media_route_provider_unittest.cc",
       "../browser/media/router/providers/cast/dual_media_sink_service_unittest.cc",
+      "../browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc",
+      "../browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc",
       "../browser/policy/local_sync_policy_handler_unittest.cc",
       "../browser/renderer_context_menu/render_view_context_menu_test_util.cc",
       "../browser/renderer_context_menu/render_view_context_menu_test_util.h",
@@ -4696,7 +4696,6 @@
         "../browser/chromeos/login/test/https_forwarder.h",
         "../browser/chromeos/login/test/oobe_base_test.cc",
         "../browser/chromeos/login/test/oobe_base_test.h",
-        "../browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc",
         "../browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc",
         "../browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h",
         "../browser/notifications/login_state_notification_blocker_chromeos_browsertest.cc",
diff --git a/components/app_modal/javascript_dialog_manager_unittest.cc b/components/app_modal/javascript_dialog_manager_unittest.cc
index c4974de1..eb774246 100644
--- a/components/app_modal/javascript_dialog_manager_unittest.cc
+++ b/components/app_modal/javascript_dialog_manager_unittest.cc
@@ -21,83 +21,83 @@
     const char* expected_android;
   } cases[] = {
       // Standard main frame alert.
-      {"http://foo.com/", "http://foo.com/", "foo.com Says", "foo.com says",
-       "foo.com says"},
+      {"http://foo.com/", "http://foo.com/", "From foo.com", "From foo.com",
+       "From foo.com"},
 
       // Subframe alert from the same origin.
-      {"http://foo.com/1", "http://foo.com/2", "foo.com Says", "foo.com says",
-       "foo.com says"},
+      {"http://foo.com/1", "http://foo.com/2", "From foo.com", "From foo.com",
+       "From foo.com"},
       // Subframe alert from a different origin.
-      {"http://foo.com/", "http://bar.com/", "An Embedded Page at bar.com Says",
-       "An embedded page at bar.com says", "An embedded page at bar.com says"},
+      {"http://foo.com/", "http://bar.com/", "From an Embedded Page at bar.com",
+       "From an embedded page at bar.com", "From an embedded page at bar.com"},
 
       // file:
       // - main frame:
       {"file:///path/to/page.html", "file:///path/to/page.html",
-       "This Page Says", "This page says", "This page says"},
+       "From This Page", "From this page", "From this page"},
       // - subframe:
       {"http://foo.com/", "file:///path/to/page.html",
-       "An Embedded Page on This Page Says",
-       "An embedded page on this page says",
-       "An embedded page on this page says"},
+       "From an Embedded Page on This Page",
+       "From an embedded page on this page",
+       "From an embedded page on this page"},
 
       // ftp:
       // - main frame:
       {"ftp://foo.com/path/to/page.html", "ftp://foo.com/path/to/page.html",
-       "foo.com Says", "foo.com says", "ftp://foo.com says"},
+       "From foo.com", "From foo.com", "From ftp://foo.com"},
       // - subframe:
       {"http://foo.com/", "ftp://foo.com/path/to/page.html",
-       "An Embedded Page at foo.com Says", "An embedded page at foo.com says",
-       "An embedded page at ftp://foo.com says"},
+       "From an Embedded Page at foo.com", "From an embedded page at foo.com",
+       "From an embedded page at ftp://foo.com"},
 
       // data:
       // - main frame:
-      {"data:blahblah", "data:blahblah", "This Page Says", "This page says",
-       "This page says"},
+      {"data:blahblah", "data:blahblah", "From This Page", "From this page",
+       "From this page"},
       // - subframe:
-      {"http://foo.com/", "data:blahblah", "An Embedded Page on This Page Says",
-       "An embedded page on this page says",
-       "An embedded page on this page says"},
+      {"http://foo.com/", "data:blahblah", "From an Embedded Page on This Page",
+       "From an embedded page on this page",
+       "From an embedded page on this page"},
 
       // javascript:
       // - main frame:
-      {"javascript:abc", "javascript:abc", "This Page Says", "This page says",
-       "This page says"},
+      {"javascript:abc", "javascript:abc", "From This Page", "From this page",
+       "From this page"},
       // - subframe:
       {"http://foo.com/", "javascript:abc",
-       "An Embedded Page on This Page Says",
-       "An embedded page on this page says",
-       "An embedded page on this page says"},
+       "From an Embedded Page on This Page",
+       "From an embedded page on this page",
+       "From an embedded page on this page"},
 
       // about:
       // - main frame:
-      {"about:blank", "about:blank", "This Page Says", "This page says",
-       "This page says"},
+      {"about:blank", "about:blank", "From This Page", "From this page",
+       "From this page"},
       // - subframe:
-      {"http://foo.com/", "about:blank", "An Embedded Page on This Page Says",
-       "An embedded page on this page says",
-       "An embedded page on this page says"},
+      {"http://foo.com/", "about:blank", "From an Embedded Page on This Page",
+       "From an embedded page on this page",
+       "From an embedded page on this page"},
 
       // blob:
       // - main frame:
       {"blob:http://foo.com/66666666-6666-6666-6666-666666666666",
        "blob:http://foo.com/66666666-6666-6666-6666-666666666666",
-       "foo.com Says", "foo.com says", "foo.com says"},
+       "From foo.com", "From foo.com", "From foo.com"},
       // - subframe:
       {"http://bar.com/",
        "blob:http://foo.com/66666666-6666-6666-6666-666666666666",
-       "An Embedded Page at foo.com Says", "An embedded page at foo.com says",
-       "An embedded page at foo.com says"},
+       "From an Embedded Page at foo.com", "From an embedded page at foo.com",
+       "From an embedded page at foo.com"},
 
       // filesystem:
       // - main frame:
       {"filesystem:http://foo.com/bar.html",
-       "filesystem:http://foo.com/bar.html", "foo.com Says", "foo.com says",
-       "foo.com says"},
+       "filesystem:http://foo.com/bar.html", "From foo.com", "From foo.com",
+       "From foo.com"},
       // - subframe:
       {"http://bar.com/", "filesystem:http://foo.com/bar.html",
-       "An Embedded Page at foo.com Says", "An embedded page at foo.com says",
-       "An embedded page at foo.com says"},
+       "From an Embedded Page at foo.com", "From an embedded page at foo.com",
+       "From an embedded page at foo.com"},
   };
 
   for (const auto& test_case : cases) {
diff --git a/components/app_modal_strings.grdp b/components/app_modal_strings.grdp
index a4a573c..1e6b4fd 100644
--- a/components/app_modal_strings.grdp
+++ b/components/app_modal_strings.grdp
@@ -4,30 +4,30 @@
   <!-- JavaScript Dialog Box strings -->
   <if expr="not use_titlecase">
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage">
-      <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says
+      From <ph name="SITE">$1<ex>http://www.google.com</ex></ph>
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage">
-      An embedded page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says
+      From an embedded page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph>
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL" desc="Title for JavaScript prompt and confirm originating from a webpage with a non-standard URL such as |data:|">
-      This page says
+      From this page
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage with a non-standard URL such as |data:|">
-      An embedded page on this page says
+      From an embedded page on this page
     </message>
   </if>
   <if expr="use_titlecase">
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage">
-      <ph name="SITE">$1<ex>http://www.google.com</ex></ph> Says
+      From <ph name="SITE">$1<ex>http://www.google.com</ex></ph>
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage">
-      An Embedded Page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> Says
+      From an Embedded Page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph>
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL" desc="Title for JavaScript prompt and confirm originating from a webpage with a non-standard URL such as |data:|">
-      This Page Says
+      From This Page
     </message>
     <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE_NONSTANDARD_URL_IFRAME" desc="Title for JavaScript prompt and confirm originating from an iframe inside the webpage with a non-standard URL such as |data:|">
-      An Embedded Page on This Page Says
+      From an Embedded Page on This Page
     </message>
   </if>
   <message name="IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION" desc="Optional UI shown on the message box, in the form of a checkbox, allowing the user to suppress additional message boxes from the page.">
diff --git a/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc b/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
index ba9e0b5..787cb39 100644
--- a/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
+++ b/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
@@ -111,7 +111,7 @@
                              bool lite_page_received,
                              bool app_background_occurred,
                              bool opt_out_occurred) {
-    timing_ = base::MakeUnique<DataReductionProxyPageLoadTiming>(
+    timing_ = std::make_unique<DataReductionProxyPageLoadTiming>(
         base::Time::FromJsTime(1500) /* navigation_start */,
         base::Optional<base::TimeDelta>(
             base::TimeDelta::FromMilliseconds(1600)) /* response_start */,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
index 8a99a5b6..f86c341 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc
@@ -109,7 +109,7 @@
 
  protected:
   std::unique_ptr<DataReductionProxyBypassStats> BuildBypassStats() {
-    return base::MakeUnique<DataReductionProxyBypassStats>(
+    return std::make_unique<DataReductionProxyBypassStats>(
         test_context_->config(), test_context_->unreachable_callback());
   }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
index a035a4c..d203ee0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -12,7 +12,6 @@
 #include "base/feature_list.h"
 #include "base/location.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
@@ -78,7 +77,7 @@
                         base::ListValue* list_update) {
   int64_t value = GetInt64PrefValue(*list_update, index) + length;
   list_update->Set(index,
-                   base::MakeUnique<base::Value>(base::Int64ToString(value)));
+                   std::make_unique<base::Value>(base::Int64ToString(value)));
 }
 
 // DailyContentLengthUpdate maintains a data saving pref. The pref is a list
@@ -529,7 +528,7 @@
   int64_t total_received = GetInt64(prefs::kHttpReceivedContentLength);
   int64_t total_original = GetInt64(prefs::kHttpOriginalContentLength);
 
-  auto dict = base::MakeUnique<base::DictionaryValue>();
+  auto dict = std::make_unique<base::DictionaryValue>();
   // Use strings to avoid overflow. base::Value only supports 32-bit integers.
   dict->SetString("historic_received_content_length",
                   base::Int64ToString(total_received));
@@ -542,7 +541,7 @@
 DataReductionProxyCompressionStats::SessionNetworkStatsInfoToValue() const {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  auto dict = base::MakeUnique<base::DictionaryValue>();
+  auto dict = std::make_unique<base::DictionaryValue>();
   // Use strings to avoid overflow. base::Value only supports 32-bit integers.
   dict->SetString("session_received_content_length",
                   base::Int64ToString(session_total_received_));
@@ -666,7 +665,7 @@
   for (const auto& connection_usage : data_usage->connection_usage()) {
     for (const auto& site_usage : connection_usage.site_usage()) {
       data_usage_map_[site_usage.hostname()] =
-          base::MakeUnique<PerSiteDataUsage>(site_usage);
+          std::make_unique<PerSiteDataUsage>(site_usage);
     }
   }
 
@@ -1187,7 +1186,7 @@
 
   std::string normalized_host = NormalizeHostname(data_usage_host);
   auto j = data_usage_map_.insert(
-      std::make_pair(normalized_host, base::MakeUnique<PerSiteDataUsage>()));
+      std::make_pair(normalized_host, std::make_unique<PerSiteDataUsage>()));
   PerSiteDataUsage* per_site_usage = j.first->second.get();
   per_site_usage->set_hostname(normalized_host);
   per_site_usage->set_original_size(per_site_usage->original_size() +
@@ -1245,7 +1244,7 @@
     // This use case is unlikely to occur in practice since current data usage
     // should have sufficient time to load before user tries to view data usage.
     get_data_usage_callback.Run(
-        base::MakeUnique<std::vector<DataUsageBucket>>());
+        std::make_unique<std::vector<DataUsageBucket>>());
     return;
   }
 #endif
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
index 567d486..a5c0658e 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -161,7 +161,7 @@
 
     for (size_t i = 0; i < kNumDaysInHistory; ++i) {
       original_daily_content_length_list->Set(
-          i, base::MakeUnique<base::Value>(base::NumberToString(i)));
+          i, std::make_unique<base::Value>(base::NumberToString(i)));
     }
 
     received_daily_content_length_list->Clear();
@@ -175,7 +175,7 @@
     base::ListValue* update = compression_stats_->GetList(pref);
     update->Clear();
     for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-      update->Insert(0, base::MakeUnique<base::Value>(base::Int64ToString(0)));
+      update->Insert(0, std::make_unique<base::Value>(base::Int64ToString(0)));
     }
   }
 
@@ -548,7 +548,7 @@
 TEST_F(DataReductionProxyCompressionStatsTest, StatsRestoredOnOnRestart) {
   base::ListValue list_value;
   list_value.Insert(0,
-                    base::MakeUnique<base::Value>(base::Int64ToString(1234)));
+                    std::make_unique<base::Value>(base::Int64ToString(1234)));
   pref_service()->Set(prefs::kDailyHttpOriginalContentLength, list_value);
 
   ResetCompressionStatsWithDelay(
@@ -1078,7 +1078,7 @@
   RecordDataUsage("https://www.foo.com", 1000, 1250, now);
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
@@ -1109,7 +1109,7 @@
 #if !defined(OS_ANDROID)
   // Data usage on disk must be deleted.
   auto expected_data_usage1 =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   DataUsageLoadVerifier verifier1(std::move(expected_data_usage1));
   LoadHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage,
@@ -1117,7 +1117,7 @@
 
   // Public API must return an empty array.
   auto expected_data_usage2 =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>();
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>();
   DataUsageLoadVerifier verifier2(std::move(expected_data_usage2));
   GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage,
                                     base::Unretained(&verifier2)),
@@ -1125,7 +1125,7 @@
 #else
   // For Android don't delete data usage.
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
@@ -1155,7 +1155,7 @@
   RecordDataUsage("http://foobar.com", 1002, 1252, now);
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
@@ -1196,7 +1196,7 @@
   RecordDataUsage("https://bar.com", 1001, 1251, now);
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 2).add_connection_usage();
@@ -1267,7 +1267,7 @@
   base::RunLoop().RunUntilIdle();
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   DataUsageLoadVerifier verifier(std::move(expected_data_usage));
 
@@ -1297,7 +1297,7 @@
   ASSERT_TRUE(compression_stats()->DataUsageMapForTesting().empty());
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   data_reduction_proxy::PerConnectionDataUsage* connection_usage =
       expected_data_usage->at(kNumExpectedBuckets - 1).add_connection_usage();
@@ -1317,7 +1317,7 @@
   base::RunLoop().RunUntilIdle();
 
   expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   DataUsageLoadVerifier verifier2(std::move(expected_data_usage));
   LoadHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage,
@@ -1352,7 +1352,7 @@
   base::RunLoop().RunUntilIdle();
 
   auto expected_data_usage =
-      base::MakeUnique<std::vector<data_reduction_proxy::DataUsageBucket>>(
+      std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(
           kNumExpectedBuckets);
   DataUsageLoadVerifier verifier(std::move(expected_data_usage));
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
index db1491a..e486763 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
@@ -394,7 +393,7 @@
 
   void AddMockSuccess() {
     socket_data_providers_.push_back(
-        (base::MakeUnique<net::StaticSocketDataProvider>(
+        (std::make_unique<net::StaticSocketDataProvider>(
             success_reads_, arraysize(success_reads_), nullptr, 0)));
     mock_socket_factory_->AddSocketDataProvider(
         socket_data_providers_.back().get());
@@ -402,7 +401,7 @@
 
   void AddMockPreviousSuccess() {
     socket_data_providers_.push_back(
-        (base::MakeUnique<net::StaticSocketDataProvider>(
+        (std::make_unique<net::StaticSocketDataProvider>(
             previous_success_reads_, arraysize(previous_success_reads_),
             nullptr, 0)));
     mock_socket_factory_->AddSocketDataProvider(
@@ -411,7 +410,7 @@
 
   void AddMockFailure() {
     socket_data_providers_.push_back(
-        (base::MakeUnique<net::StaticSocketDataProvider>(
+        (std::make_unique<net::StaticSocketDataProvider>(
             not_found_reads_, arraysize(not_found_reads_), nullptr, 0)));
     mock_socket_factory_->AddSocketDataProvider(
         socket_data_providers_.back().get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
index a0e43a8..9964c9a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
@@ -8,7 +8,6 @@
 
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/time/tick_clock.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h"
@@ -31,7 +30,7 @@
     DataReductionProxyConfigurator* configurator,
     DataReductionProxyEventCreator* event_creator)
     : TestDataReductionProxyConfig(
-          base::MakeUnique<TestDataReductionProxyParams>(),
+          std::make_unique<TestDataReductionProxyParams>(),
           io_task_runner,
           net_log,
           configurator,
@@ -56,7 +55,7 @@
 }
 
 void TestDataReductionProxyConfig::ResetParamFlagsForTest() {
-  config_values_ = base::MakeUnique<TestDataReductionProxyParams>();
+  config_values_ = std::make_unique<TestDataReductionProxyParams>();
 }
 
 TestDataReductionProxyParams* TestDataReductionProxyConfig::test_params() {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index a72ff7bf..444f7ef0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -17,7 +17,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
@@ -212,7 +211,7 @@
 
   std::unique_ptr<DataReductionProxyConfig> BuildConfig(
       std::unique_ptr<DataReductionProxyParams> params) {
-    return base::MakeUnique<DataReductionProxyConfig>(
+    return std::make_unique<DataReductionProxyConfig>(
         task_runner(), test_context_->net_log(), std::move(params),
         test_context_->configurator(), test_context_->event_creator());
   }
@@ -933,7 +932,7 @@
   };
 
   std::unique_ptr<DataReductionProxyMutableConfigValues> config_values =
-      base::MakeUnique<DataReductionProxyMutableConfigValues>();
+      std::make_unique<DataReductionProxyMutableConfigValues>();
 
   config_values->UpdateValues(proxies_for_http);
   std::unique_ptr<DataReductionProxyConfig> config(new DataReductionProxyConfig(
@@ -963,11 +962,11 @@
   request->SetLoadFlags(request->load_flags() |
                         net::LOAD_MAIN_FRAME_DEPRECATED);
   std::unique_ptr<TestPreviewsDecider> previews_decider =
-      base::MakeUnique<TestPreviewsDecider>(true);
+      std::make_unique<TestPreviewsDecider>(true);
   EXPECT_TRUE(test_config()->ShouldAcceptServerPreview(
       *request.get(), *previews_decider.get()));
 
-  previews_decider = base::MakeUnique<TestPreviewsDecider>(false);
+  previews_decider = std::make_unique<TestPreviewsDecider>(false);
   EXPECT_FALSE(test_config()->ShouldAcceptServerPreview(
       *request.get(), *previews_decider.get()));
 }
@@ -989,7 +988,7 @@
   request->SetLoadFlags(request->load_flags() |
                         net::LOAD_MAIN_FRAME_DEPRECATED);
   std::unique_ptr<TestPreviewsDecider> previews_decider =
-      base::MakeUnique<TestPreviewsDecider>(true);
+      std::make_unique<TestPreviewsDecider>(true);
 
   // Verify true for no flags.
   EXPECT_TRUE(test_config()->ShouldAcceptServerPreview(
@@ -997,13 +996,13 @@
 
   // Verify PreviewsDecider check.
   base::CommandLine::ForCurrentProcess()->InitFromArgv(0, nullptr);
-  previews_decider = base::MakeUnique<TestPreviewsDecider>(false);
+  previews_decider = std::make_unique<TestPreviewsDecider>(false);
   EXPECT_FALSE(test_config()->ShouldAcceptServerPreview(
       *request.get(), *previews_decider.get()));
   histogram_tester.ExpectBucketCount(
       "DataReductionProxy.Protocol.NotAcceptingTransform",
       1 /* NOT_ACCEPTING_TRANSFORM_BLACKLISTED */, 1);
-  previews_decider = base::MakeUnique<TestPreviewsDecider>(true);
+  previews_decider = std::make_unique<TestPreviewsDecider>(true);
 }
 
 TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherResponse) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
index d9cc350..41c33ac 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.cc
@@ -5,10 +5,24 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
 
 #include "base/memory/ptr_util.h"
+#include "base/values.h"
 #include "net/url_request/url_request.h"
 
 namespace data_reduction_proxy {
 
+namespace {
+const char* kUsedDataReductionProxyKey = "used_data_reduction_proxy";
+const char* kLofiRequestedKey = "lofi_requested";
+const char* kClientLofiRequestedKey = "client_lofi_requested";
+const char* kLitePageReceivedKey = "lite_page_received";
+const char* kLofiPolicyReceivedKey = "lofi_policy_received";
+const char* kLofiReceivedKey = "lofi_received";
+const char* kSessionKeyKey = "session_key";
+const char* kEffectiveConnectionTypeKey = "effective_connection_type";
+const char* kRequestURLKey = "request_url";
+const char* kPageIdKey = "page_id";
+}  // namespace
+
 const void* const kDataReductionProxyUserDataKey =
     &kDataReductionProxyUserDataKey;
 
@@ -23,6 +37,46 @@
 
 DataReductionProxyData::~DataReductionProxyData() {}
 
+// Convert from/to a base::Value.
+base::Value DataReductionProxyData::ToValue() {
+  base::Value value(base::Value::Type::DICTIONARY);
+  value.SetKey(kUsedDataReductionProxyKey,
+               base::Value(used_data_reduction_proxy_));
+  value.SetKey(kLofiRequestedKey, base::Value(lofi_requested_));
+  value.SetKey(kClientLofiRequestedKey, base::Value(client_lofi_requested_));
+  value.SetKey(kLitePageReceivedKey, base::Value(lite_page_received_));
+  value.SetKey(kLofiPolicyReceivedKey, base::Value(lofi_policy_received_));
+  value.SetKey(kLofiReceivedKey, base::Value(lofi_received_));
+  value.SetKey(kSessionKeyKey, base::Value(session_key_));
+  value.SetKey(kEffectiveConnectionTypeKey,
+               base::Value(effective_connection_type_));
+  value.SetKey(kRequestURLKey,
+               base::Value(request_url_.possibly_invalid_spec()));
+  // Store |page_id_| as a string because base::Value can't store a 64 bits
+  // integer.
+  if (page_id_)
+    value.SetKey(kPageIdKey, base::Value(std::to_string(page_id_.value())));
+
+  return value;
+}
+
+DataReductionProxyData::DataReductionProxyData(const base::Value& value)
+    : used_data_reduction_proxy_(
+          value.FindKey(kUsedDataReductionProxyKey)->GetBool()),
+      lofi_requested_(value.FindKey(kLofiRequestedKey)->GetBool()),
+      client_lofi_requested_(value.FindKey(kClientLofiRequestedKey)->GetBool()),
+      lite_page_received_(value.FindKey(kLitePageReceivedKey)->GetBool()),
+      lofi_policy_received_(value.FindKey(kLofiPolicyReceivedKey)->GetBool()),
+      lofi_received_(value.FindKey(kLofiReceivedKey)->GetBool()),
+      session_key_(value.FindKey(kSessionKeyKey)->GetString()),
+      request_url_(GURL(value.FindKey(kRequestURLKey)->GetString())),
+      effective_connection_type_(net::EffectiveConnectionType(
+          value.FindKey(kEffectiveConnectionTypeKey)->GetInt())) {
+  const base::Value* page_id = value.FindKey(kPageIdKey);
+  if (page_id)
+    page_id_ = std::stoll(page_id->GetString());
+}
+
 std::unique_ptr<DataReductionProxyData> DataReductionProxyData::DeepCopy()
     const {
   std::unique_ptr<DataReductionProxyData> copy(new DataReductionProxyData());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
index 19e8d053..6123071 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h
@@ -16,6 +16,10 @@
 #include "net/nqe/effective_connection_type.h"
 #include "url/gurl.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 class URLRequest;
 }
@@ -29,6 +33,10 @@
   DataReductionProxyData();
   ~DataReductionProxyData() override;
 
+  // Convert from/to a base::Value.
+  base::Value ToValue();
+  explicit DataReductionProxyData(const base::Value& value);
+
   // Whether the DataReductionProxy was used for this request or navigation.
   // Also true if the user is the holdback experiment, and the request would
   // otherwise be eligible to use the proxy.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
index a7deafb..0d4fa60 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
+#include "base/values.h"
 #include "net/base/request_priority.h"
 #include "net/nqe/effective_connection_type.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -155,6 +156,121 @@
   EXPECT_FALSE(data);
 }
 
+TEST_F(DataReductionProxyDataTest, Serialization) {
+  // used_data_reduction_proxy.
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_used_data_reduction_proxy(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.used_data_reduction_proxy());
+    EXPECT_TRUE(clone_b.used_data_reduction_proxy());
+  }
+
+  // lofi_requested
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_lofi_requested(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.lofi_requested());
+    EXPECT_TRUE(clone_b.lofi_requested());
+  }
+
+  // client_lofi_requested
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_client_lofi_requested(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.client_lofi_requested());
+    EXPECT_TRUE(clone_b.client_lofi_requested());
+  }
+
+  // lite_page_received
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_lite_page_received(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.lite_page_received());
+    EXPECT_TRUE(clone_b.lite_page_received());
+  }
+
+  // lofi_policy_received
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_lofi_policy_received(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.lofi_policy_received());
+    EXPECT_TRUE(clone_b.lofi_policy_received());
+  }
+
+  // lofi_received
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_lofi_received(true);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.lofi_received());
+    EXPECT_TRUE(clone_b.lofi_received());
+  }
+
+  // session_key
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_session_key("the_session_key");
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_EQ("", clone_a.session_key());
+    EXPECT_EQ("the_session_key", clone_b.session_key());
+  }
+
+  // request_url
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_request_url(GURL("http://example.com"));
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_EQ(GURL(), clone_a.request_url());
+    EXPECT_EQ(GURL("http://example.com"), clone_b.request_url());
+  }
+
+  // effective_connection_type
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_effective_connection_type(net::EFFECTIVE_CONNECTION_TYPE_4G);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
+              clone_a.effective_connection_type());
+    EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_4G,
+              clone_b.effective_connection_type());
+  }
+
+  // page_id
+  {
+    DataReductionProxyData data;
+    DataReductionProxyData clone_a(data.ToValue());
+    data.set_page_id(1ull << 60);
+    DataReductionProxyData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.page_id());
+    EXPECT_TRUE(clone_b.page_id());
+    EXPECT_EQ(1ull << 60, clone_b.page_id().value());
+  }
+}
+
 }  // namespace
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
index c6dbccb..97a821e 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.cc
@@ -4,9 +4,9 @@
 
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h"
 
+#include <memory>
 #include <string>
 
-#include "base/memory/ptr_util.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
@@ -131,7 +131,7 @@
       bytes->IncrementBytes(network_bytes, original_bytes);
     } else {
       data_use->SetUserData(DataUseUserDataBytes::kUserDataKey,
-                            base::MakeUnique<DataUseUserDataBytes>(
+                            std::make_unique<DataUseUserDataBytes>(
                                 network_bytes, original_bytes));
     }
   } else {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h
index f64d037..3c9b8fa 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_data_use_observer.h
@@ -41,6 +41,8 @@
                           data_use_measurement::DataUse* data_use) override;
   void OnPageDidFinishLoad(data_use_measurement::DataUse* data_use) override;
   void OnPageLoadConcluded(data_use_measurement::DataUse* data_use) override {}
+  void OnNetworkBytesUpdate(const net::URLRequest& request,
+                            data_use_measurement::DataUse* data_use) override {}
 
   const void* GetDataUsePreviewsUserDataKeyForTesting();
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
index 8c03fed..dc519c3f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc
@@ -14,7 +14,6 @@
 
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
 #include "base/numerics/safe_conversions.h"
@@ -192,7 +191,7 @@
     }
 
     std::unique_ptr<DataReductionProxyMutableConfigValues> config_values =
-        base::MakeUnique<DataReductionProxyMutableConfigValues>();
+        std::make_unique<DataReductionProxyMutableConfigValues>();
     config_values->UpdateValues(proxies_for_http);
 
     std::unique_ptr<DataReductionProxyConfig> config(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
index c51f22e..27520ed 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc
@@ -540,7 +540,7 @@
   std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers;
   for (MockRead* mock_reads : mock_reads_array) {
     socket_data_providers.push_back(
-        base::MakeUnique<net::StaticSocketDataProvider>(mock_reads, 3, nullptr,
+        std::make_unique<net::StaticSocketDataProvider>(mock_reads, 3, nullptr,
                                                         0));
     mock_socket_factory()->AddSocketDataProvider(
         socket_data_providers.back().get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
index 1c0937c50..665eb61 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol.h"
@@ -125,7 +124,7 @@
   DataReductionProxyMutableConfigValues* raw_mutable_config = nullptr;
   if (use_config_client) {
     std::unique_ptr<DataReductionProxyMutableConfigValues> mutable_config =
-        base::MakeUnique<DataReductionProxyMutableConfigValues>();
+        std::make_unique<DataReductionProxyMutableConfigValues>();
     raw_mutable_config = mutable_config.get();
     config_.reset(new DataReductionProxyConfig(
         io_task_runner, net_log, std::move(mutable_config), configurator_.get(),
@@ -251,7 +250,7 @@
 std::unique_ptr<net::URLRequestInterceptor>
 DataReductionProxyIOData::CreateInterceptor() {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  return base::MakeUnique<DataReductionProxyInterceptor>(
+  return std::make_unique<DataReductionProxyInterceptor>(
       config_.get(), config_client_.get(), bypass_stats_.get(),
       event_creator_.get());
 }
@@ -274,7 +273,7 @@
 std::unique_ptr<DataReductionProxyDelegate>
 DataReductionProxyIOData::CreateProxyDelegate() const {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  return base::MakeUnique<DataReductionProxyDelegate>(
+  return std::make_unique<DataReductionProxyDelegate>(
       config_.get(), configurator_.get(), event_creator_.get(),
       bypass_stats_.get(), net_log_);
 }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
index 70fcaae..f102d9c 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -146,7 +146,7 @@
 
   // Creating a second delegate with bypass statistics tracking should result
   // in usage stats being created.
-  io_data->CreateNetworkDelegate(base::MakeUnique<CountingNetworkDelegate>(),
+  io_data->CreateNetworkDelegate(std::make_unique<CountingNetworkDelegate>(),
                                  true);
   EXPECT_NE(nullptr, io_data->bypass_stats());
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
index 37ff9ce9..c9b6229 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values_unittest.cc
@@ -4,10 +4,10 @@
 
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h"
 
+#include <memory>
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/memory/ptr_util.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
@@ -26,7 +26,7 @@
 
   void Init() {
     mutable_config_values_ =
-        base::MakeUnique<DataReductionProxyMutableConfigValues>();
+        std::make_unique<DataReductionProxyMutableConfigValues>();
   }
 
   DataReductionProxyMutableConfigValues* mutable_config_values() const {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 1d53059..100eaf4 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -15,7 +15,6 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/field_trial.h"
 #include "base/numerics/safe_conversions.h"
@@ -470,7 +469,7 @@
     }
 
     EXPECT_FALSE(socket_);
-    socket_ = base::MakeUnique<net::StaticSocketDataProvider>(
+    socket_ = std::make_unique<net::StaticSocketDataProvider>(
         reads_list->data(), reads_list->size(), writes_list->data(),
         writes_list->size());
     mock_socket_factory_->AddSocketDataProvider(socket_.get());
@@ -747,10 +746,10 @@
 
     std::unique_ptr<net::StaticSocketDataProvider> socket;
     if (!redirect_once) {
-      socket = base::MakeUnique<net::StaticSocketDataProvider>(
+      socket = std::make_unique<net::StaticSocketDataProvider>(
           reads, arraysize(reads), writes, arraysize(writes));
     } else {
-      socket = base::MakeUnique<net::StaticSocketDataProvider>(
+      socket = std::make_unique<net::StaticSocketDataProvider>(
           redirect_reads, arraysize(redirect_reads), redirect_writes,
           arraysize(redirect_writes));
     }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index b64c3f1..aced436 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
@@ -62,9 +61,9 @@
                                  prefs::kDailyHttpReceivedContentLength);
   for (int64_t i = 0; i < kNumDaysInHistory; i++) {
     original_update->Insert(
-        0, base::MakeUnique<base::Value>(base::Int64ToString(2 * i)));
+        0, std::make_unique<base::Value>(base::Int64ToString(2 * i)));
     received_update->Insert(
-        0, base::MakeUnique<base::Value>(base::Int64ToString(i)));
+        0, std::make_unique<base::Value>(base::Int64ToString(i)));
   }
   last_update_time_ = base::Time::Now().LocalMidnight();
   pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
@@ -112,7 +111,7 @@
   if (managed) {
     test_context_->pref_service()->SetManagedPref(
         test_context_->GetDataReductionProxyEnabledPrefName(),
-        base::MakeUnique<base::Value>(enabled));
+        std::make_unique<base::Value>(enabled));
   } else {
     test_context_->SetDataReductionProxyEnabled(enabled);
   }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index 27e20aa..2b1b93e 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -240,7 +240,7 @@
     : DataReductionProxyService(settings,
                                 prefs,
                                 request_context,
-                                base::MakeUnique<TestDataStore>(),
+                                std::make_unique<TestDataStore>(),
                                 nullptr,
                                 task_runner,
                                 task_runner,
@@ -448,7 +448,7 @@
   if (use_config_client_) {
     test_context_flags |= USE_CONFIG_CLIENT;
     std::unique_ptr<DataReductionProxyMutableConfigValues> mutable_config =
-        base::MakeUnique<DataReductionProxyMutableConfigValues>();
+        std::make_unique<DataReductionProxyMutableConfigValues>();
     if (!proxy_servers_.empty()) {
       mutable_config->UpdateValues(proxy_servers_);
     }
@@ -629,11 +629,11 @@
 DataReductionProxyTestContext::CreateDataReductionProxyServiceInternal(
     DataReductionProxySettings* settings) {
   if (test_context_flags_ & USE_MOCK_SERVICE) {
-    return base::MakeUnique<MockDataReductionProxyService>(
+    return std::make_unique<MockDataReductionProxyService>(
         settings, simple_pref_service_.get(), request_context_getter_.get(),
         task_runner_);
   }
-  return base::MakeUnique<DataReductionProxyService>(
+  return std::make_unique<DataReductionProxyService>(
       settings, simple_pref_service_.get(), request_context_getter_.get(),
       base::WrapUnique(new TestDataStore()), nullptr, task_runner_,
       task_runner_, task_runner_, base::TimeDelta());
@@ -646,12 +646,12 @@
   // |request_context_storage| takes ownership of the network delegate.
   std::unique_ptr<DataReductionProxyNetworkDelegate> network_delegate =
       io_data()->CreateNetworkDelegate(
-          base::MakeUnique<net::NetworkDelegateImpl>(), true);
+          std::make_unique<net::NetworkDelegateImpl>(), true);
 
   request_context_storage->set_network_delegate(std::move(network_delegate));
 
   request_context_storage->set_job_factory(
-      base::MakeUnique<net::URLRequestInterceptingJobFactory>(
+      std::make_unique<net::URLRequestInterceptingJobFactory>(
           std::unique_ptr<net::URLRequestJobFactory>(
               new net::URLRequestJobFactoryImpl()),
           io_data()->CreateInterceptor()));
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
index b33aab4..057d572 100644
--- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/data_reduction_proxy/core/browser/warmup_url_fetcher.h"
 
 #include <map>
+#include <memory>
 #include <vector>
 
 #include "base/bind_helpers.h"
@@ -116,7 +117,7 @@
   success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK);
 
   socket_data_providers.push_back(
-      (base::MakeUnique<net::StaticSocketDataProvider>(
+      (std::make_unique<net::StaticSocketDataProvider>(
           success_reads, arraysize(success_reads), nullptr, 0)));
   mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get());
 
@@ -175,7 +176,7 @@
   success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK);
 
   socket_data_providers.push_back(
-      (base::MakeUnique<net::StaticSocketDataProvider>(
+      (std::make_unique<net::StaticSocketDataProvider>(
           success_reads, arraysize(success_reads), nullptr, 0)));
   mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get());
 
@@ -232,7 +233,7 @@
   success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK);
 
   socket_data_providers.push_back(
-      (base::MakeUnique<net::StaticSocketDataProvider>(
+      (std::make_unique<net::StaticSocketDataProvider>(
           success_reads, arraysize(success_reads), nullptr, 0)));
   mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get());
 
@@ -281,7 +282,7 @@
   success_reads[0] = net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_RESET);
 
   socket_data_providers.push_back(
-      (base::MakeUnique<net::StaticSocketDataProvider>(
+      (std::make_unique<net::StaticSocketDataProvider>(
           success_reads, arraysize(success_reads), nullptr, 0)));
   mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get());
 
@@ -322,4 +323,4 @@
 
 }  // namespace
 
-}  // namespace data_reduction_proxy
\ No newline at end of file
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
index e54f4ba..e257a700 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
@@ -71,7 +70,7 @@
 // static
 void DataReductionProxyEventStore::AddConstants(
     base::DictionaryValue* constants_dict) {
-  auto dict = base::MakeUnique<base::DictionaryValue>();
+  auto dict = std::make_unique<base::DictionaryValue>();
   for (size_t i = 0;
        i < arraysize(kDataReductionProxyBypassEventTypeTable); ++i) {
     dict->SetInteger(kDataReductionProxyBypassEventTypeTable[i].name,
@@ -80,7 +79,7 @@
 
   constants_dict->Set("dataReductionProxyBypassEventType", std::move(dict));
 
-  dict = base::MakeUnique<base::DictionaryValue>();
+  dict = std::make_unique<base::DictionaryValue>();
   for (size_t i = 0; i < arraysize(kDataReductionProxyBypassActionTypeTable);
        ++i) {
     dict->SetInteger(kDataReductionProxyBypassActionTypeTable[i].name,
@@ -103,7 +102,7 @@
 DataReductionProxyEventStore::GetSummaryValue() const {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  auto data_reduction_proxy_values = base::MakeUnique<base::DictionaryValue>();
+  auto data_reduction_proxy_values = std::make_unique<base::DictionaryValue>();
   data_reduction_proxy_values->SetBoolean("enabled", enabled_);
   if (current_configuration_) {
     data_reduction_proxy_values->SetKey("proxy_config",
@@ -134,7 +133,7 @@
     }
   }
 
-  auto events_list = base::MakeUnique<base::ListValue>();
+  auto events_list = std::make_unique<base::ListValue>();
 
   DCHECK(oldest_event_index_ == 0 ||
          stored_events_.size() == kMaxEventsToStore);
@@ -223,7 +222,7 @@
     return std::string();
 
   // Explicitly add parameters to prevent automatic adding of new parameters.
-  auto last_bypass = base::MakeUnique<base::DictionaryValue>();
+  auto last_bypass = std::make_unique<base::DictionaryValue>();
 
   std::string str_value;
   int int_value;
diff --git a/components/data_use_measurement/core/data_use_ascriber.cc b/components/data_use_measurement/core/data_use_ascriber.cc
index fa28c4f..5fd4dfe 100644
--- a/components/data_use_measurement/core/data_use_ascriber.cc
+++ b/components/data_use_measurement/core/data_use_ascriber.cc
@@ -27,22 +27,32 @@
 
 void DataUseAscriber::OnBeforeUrlRequest(net::URLRequest* request) {
   DataUseRecorder* recorder = GetOrCreateDataUseRecorder(request);
-  if (recorder)
-    recorder->OnBeforeUrlRequest(request);
+  if (!recorder)
+    return;
+
+  recorder->OnBeforeUrlRequest(request);
 }
 
 void DataUseAscriber::OnNetworkBytesSent(net::URLRequest* request,
                                          int64_t bytes_sent) {
   DataUseRecorder* recorder = GetDataUseRecorder(*request);
-  if (recorder)
-    recorder->OnNetworkBytesSent(request, bytes_sent);
+  if (!recorder)
+    return;
+
+  recorder->OnNetworkBytesSent(request, bytes_sent);
+  for (auto& observer : observers_)
+    observer.OnNetworkBytesUpdate(*request, &recorder->data_use());
 }
 
 void DataUseAscriber::OnNetworkBytesReceived(net::URLRequest* request,
                                              int64_t bytes_received) {
   DataUseRecorder* recorder = GetDataUseRecorder(*request);
-  if (recorder)
-    recorder->OnNetworkBytesReceived(request, bytes_received);
+  if (!recorder)
+    return;
+
+  recorder->OnNetworkBytesReceived(request, bytes_received);
+  for (auto& observer : observers_)
+    observer.OnNetworkBytesUpdate(*request, &recorder->data_use());
 }
 
 void DataUseAscriber::OnUrlRequestCompleted(const net::URLRequest& request,
@@ -50,8 +60,10 @@
 
 void DataUseAscriber::OnUrlRequestDestroyed(net::URLRequest* request) {
   DataUseRecorder* recorder = GetDataUseRecorder(*request);
-  if (recorder)
-    recorder->OnUrlRequestDestroyed(request);
+  if (!recorder)
+    return;
+
+  recorder->OnUrlRequestDestroyed(request);
 }
 
 }  // namespace data_use_measurement
diff --git a/components/data_use_measurement/core/data_use_ascriber.h b/components/data_use_measurement/core/data_use_ascriber.h
index b61bf98..02094697 100644
--- a/components/data_use_measurement/core/data_use_ascriber.h
+++ b/components/data_use_measurement/core/data_use_ascriber.h
@@ -56,6 +56,13 @@
     // The page load completed. This is when the tab is closed or another
     // navigation starts due to omnibox search, link clicks, page reload, etc.
     virtual void OnPageLoadConcluded(DataUse* data_use) = 0;
+
+    // Called whenever a request uses any amount of network data. |request| is
+    // the corresponding request that used data. |data_use| contains the network
+    // data used by the page so far. URL in |data_use| may not be available
+    // until OnCommit.
+    virtual void OnNetworkBytesUpdate(const net::URLRequest& request,
+                                      DataUse* data_use) = 0;
   };
 
   DataUseAscriber();
diff --git a/components/drive/change_list_processor_unittest.cc b/components/drive/change_list_processor_unittest.cc
index bd68317..6f2e4946 100644
--- a/components/drive/change_list_processor_unittest.cc
+++ b/components/drive/change_list_processor_unittest.cc
@@ -50,7 +50,7 @@
 // Returns a basic change list which contains some files and directories.
 std::vector<std::unique_ptr<ChangeList>> CreateBaseChangeList() {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   // Add directories to the change list.
   ResourceEntry directory;
@@ -244,7 +244,7 @@
 
 TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry new_folder;
   new_folder.set_resource_id("new_folder_resource_id");
@@ -288,7 +288,7 @@
   constexpr char kTeamDriveId[] = "theTeamDriveId";
 
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   // Set up a Team Drive root directory.
   ResourceEntry team_drive;
@@ -297,7 +297,7 @@
   team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
   team_drive.mutable_file_info()->set_is_directory(true);
 
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
   change_lists[0]->mutable_entries()->push_back(team_drive);
   change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp);
   change_lists[0]->mutable_parent_resource_ids()->push_back("");
@@ -311,7 +311,7 @@
   ASSERT_TRUE(team_drive_root);
   EXPECT_FALSE(team_drive_root->local_id().empty());
   change_lists.clear();
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   // Add files to the Team Drive directory.
   ResourceEntry new_folder;
@@ -367,7 +367,7 @@
 
 TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry entry;
   entry.set_resource_id("1_folder_resource_id");
@@ -406,7 +406,7 @@
 
 TEST_F(ChangeListProcessorTest, DeltaFileMovedFromDirectoryToRoot) {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry entry;
   entry.set_resource_id("subdirectory_file_1_id");
@@ -438,7 +438,7 @@
 
 TEST_F(ChangeListProcessorTest, DeltaFileRenamedInDirectory) {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry entry;
   entry.set_resource_id("subdirectory_file_1_id");
@@ -478,7 +478,7 @@
 TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileInRoot) {
   // Create ChangeList to add a file.
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry entry;
   entry.set_resource_id("added_in_root_id");
@@ -503,7 +503,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/Added file.txt")));
 
   // Create ChangeList to delete the file.
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   entry.set_deleted(true);
   change_lists[0]->mutable_entries()->push_back(entry);
@@ -526,7 +526,7 @@
 TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileFromExistingDirectory) {
   // Create ChangeList to add a file.
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry entry;
   entry.set_resource_id("added_in_root_id");
@@ -552,7 +552,7 @@
       base::FilePath::FromUTF8Unsafe("drive/root/Directory 1/Added file.txt")));
 
   // Create ChangeList to delete the file.
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   entry.set_deleted(true);
   change_lists[0]->mutable_entries()->push_back(entry);
@@ -579,7 +579,7 @@
   // 2) but the new directory is marked "deleted" (i.e. moved to Trash)
   // Hence, the PDF file should be just ignored.
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   ResourceEntry file;
   file.set_resource_id("file_added_in_deleted_id");
@@ -696,7 +696,7 @@
 
   // Create change lists.
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   // Add a new file with non-existing parent resource id to the change lists.
   ResourceEntry new_file;
@@ -722,7 +722,7 @@
 
   // Create change lists with a new file.
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
 
   const base::Time now = base::Time::Now();
   ResourceEntry new_file_remote;
@@ -772,7 +772,7 @@
   team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
 
   std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
   change_lists[0]->mutable_entries()->push_back(team_drive);
   change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 1);
   change_lists[0]->mutable_parent_resource_ids()->push_back("");
@@ -800,7 +800,7 @@
 
   // Second change, which updates Team Drive name
   change_lists.clear();
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
   team_drive.set_title(kNewName);
   change_lists[0]->mutable_entries()->push_back(team_drive);
   change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 2);
@@ -815,7 +815,7 @@
 
   // Delete the team drive.
   change_lists.clear();
-  change_lists.push_back(base::MakeUnique<ChangeList>());
+  change_lists.push_back(std::make_unique<ChangeList>());
   change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 3);
   team_drive.set_deleted(true);
   change_lists[0]->mutable_parent_resource_ids()->push_back("");
diff --git a/components/drive/chromeos/change_list_loader.cc b/components/drive/chromeos/change_list_loader.cc
index 1c5f3c76..88d25ed 100644
--- a/components/drive/chromeos/change_list_loader.cc
+++ b/components/drive/chromeos/change_list_loader.cc
@@ -12,7 +12,6 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/synchronization/cancellation_flag.h"
@@ -78,7 +77,7 @@
       google_apis::DriveApiErrorCode status,
       std::unique_ptr<google_apis::TeamDriveList> team_drives) {
     DCHECK(is_team_drive_enabled_);
-    change_lists_.push_back(base::MakeUnique<ChangeList>(*team_drives));
+    change_lists_.push_back(std::make_unique<ChangeList>(*team_drives));
 
     if (!team_drives->next_page_token().empty()) {
       scheduler_->GetRemainingTeamDriveList(
@@ -115,7 +114,7 @@
     }
 
     DCHECK(file_list);
-    change_lists_.push_back(base::MakeUnique<ChangeList>(*file_list));
+    change_lists_.push_back(std::make_unique<ChangeList>(*file_list));
 
     if (!file_list->next_link().is_empty()) {
       // There is the remaining result so fetch it.
@@ -179,7 +178,7 @@
     }
 
     DCHECK(change_list);
-    change_lists_.push_back(base::MakeUnique<ChangeList>(*change_list));
+    change_lists_.push_back(std::make_unique<ChangeList>(*change_list));
 
     if (!change_list->next_link().is_empty()) {
       // There is the remaining result so fetch it.
@@ -219,7 +218,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   ++lock_count_;
-  return base::MakeUnique<base::ScopedClosureRunner>(
+  return std::make_unique<base::ScopedClosureRunner>(
       base::Bind(&LoaderController::Unlock, weak_ptr_factory_.GetWeakPtr()));
 }
 
@@ -321,7 +320,7 @@
 
   for (size_t i = 0; i < callbacks.size(); ++i) {
     callbacks[i].Run(
-        status, base::MakeUnique<google_apis::AboutResource>(*about_resource));
+        status, std::make_unique<google_apis::AboutResource>(*about_resource));
   }
 }
 
@@ -549,7 +548,7 @@
   change_feed_fetcher_->Run(
       base::Bind(&ChangeListLoader::LoadChangeListFromServerAfterLoadChangeList,
                  weak_ptr_factory_.GetWeakPtr(),
-                 base::Passed(base::MakeUnique<google_apis::AboutResource>(
+                 base::Passed(std::make_unique<google_apis::AboutResource>(
                      *about_resource_loader_->cached_about_resource())),
                  is_delta_update));
 }
diff --git a/components/drive/chromeos/file_system/download_operation.cc b/components/drive/chromeos/file_system/download_operation.cc
index e38ca4a..1b7dcda6 100644
--- a/components/drive/chromeos/file_system/download_operation.cc
+++ b/components/drive/chromeos/file_system/download_operation.cc
@@ -284,7 +284,7 @@
   void OnCacheFileFound(const base::FilePath& cache_file_path) {
     if (!initialized_callback_.is_null()) {
       initialized_callback_.Run(FILE_ERROR_OK, cache_file_path,
-                                base::MakeUnique<ResourceEntry>(*entry_));
+                                std::make_unique<ResourceEntry>(*entry_));
     }
     completion_callback_.Run(FILE_ERROR_OK, cache_file_path, std::move(entry_));
   }
@@ -297,7 +297,7 @@
 
     DCHECK(entry_);
     initialized_callback_.Run(FILE_ERROR_OK, base::FilePath(),
-                              base::MakeUnique<ResourceEntry>(*entry_));
+                              std::make_unique<ResourceEntry>(*entry_));
   }
 
   void OnError(FileError error) const {
diff --git a/components/drive/chromeos/search_metadata.cc b/components/drive/chromeos/search_metadata.cc
index 38ed49f77..2c5eb93 100644
--- a/components/drive/chromeos/search_metadata.cc
+++ b/components/drive/chromeos/search_metadata.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/i18n/string_search.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
@@ -172,7 +171,7 @@
   if (result_candidates->size() == at_most_num_matches)
     result_candidates->pop();
   result_candidates->push(
-      base::MakeUnique<ResultCandidate>(it->GetID(), entry, highlighted));
+      std::make_unique<ResultCandidate>(it->GetID(), entry, highlighted));
   return FILE_ERROR_OK;
 }
 
@@ -196,7 +195,7 @@
       queries;
   for (const auto& keyword : keywords) {
     queries.push_back(
-        base::MakeUnique<
+        std::make_unique<
             base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
             keyword));
   }
diff --git a/components/drive/file_write_watcher.cc b/components/drive/file_write_watcher.cc
index a4828af..621f4cb 100644
--- a/components/drive/file_write_watcher.cc
+++ b/components/drive/file_write_watcher.cc
@@ -14,7 +14,6 @@
 #include "base/callback.h"
 #include "base/files/file_path_watcher.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner.h"
 #include "base/timer/timer.h"
@@ -135,7 +134,7 @@
 
   // Start watching |path|.
   std::unique_ptr<PathWatchInfo> info =
-      base::MakeUnique<PathWatchInfo>(on_write_callback);
+      std::make_unique<PathWatchInfo>(on_write_callback);
   bool ok = info->watcher.Watch(
       path,
       false,  // recursive
diff --git a/components/drive/job_scheduler.cc b/components/drive/job_scheduler.cc
index 7a6abbb..3589170 100644
--- a/components/drive/job_scheduler.cc
+++ b/components/drive/job_scheduler.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/files/file_util.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -757,7 +756,7 @@
 }
 
 JobScheduler::JobEntry* JobScheduler::CreateNewJob(JobType type) {
-  auto job = base::MakeUnique<JobEntry>(type);
+  auto job = std::make_unique<JobEntry>(type);
   JobEntry* job_raw = job.get();
   int32_t job_key = job_map_.Add(std::move(job));
   job_raw->job_info.job_id = job_key;
diff --git a/components/drive/search_metadata_unittest.cc b/components/drive/search_metadata_unittest.cc
index 85a0a36..89bc5a0a 100644
--- a/components/drive/search_metadata_unittest.cc
+++ b/components/drive/search_metadata_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/i18n/string_search.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
@@ -43,7 +42,7 @@
   std::vector<std::unique_ptr<
       base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
       queries;
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16(query_text)));
   return FindAndHighlight(text, queries, highlighted_text);
@@ -583,7 +582,7 @@
   std::vector<std::unique_ptr<
       base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
       queries;
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16("hello")));
 
@@ -619,10 +618,10 @@
   std::vector<std::unique_ptr<
       base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
       queries;
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16("hello")));
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16("good")));
 
@@ -636,10 +635,10 @@
   std::vector<std::unique_ptr<
       base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>
       queries;
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16("morning")));
-  queries.push_back(base::MakeUnique<
+  queries.push_back(std::make_unique<
                     base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>(
       base::UTF8ToUTF16("ing,")));
 
diff --git a/components/drive/service/drive_api_service.cc b/components/drive/service/drive_api_service.cc
index 7a9d1b70..0af0ada 100644
--- a/components/drive/service/drive_api_service.cc
+++ b/components/drive/service/drive_api_service.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
 #include "components/drive/drive_api_util.h"
 #include "google_apis/drive/auth_service.h"
@@ -331,7 +330,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<TeamDriveListRequest> request =
-      base::MakeUnique<TeamDriveListRequest>(sender_.get(), url_generator_,
+      std::make_unique<TeamDriveListRequest>(sender_.get(), url_generator_,
                                              callback);
   request->set_max_results(kMaxNumTeamDriveResourcePerRequest);
   request->set_fields(kTeamDrivesListFields);
@@ -344,7 +343,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesListRequest> request =
-      base::MakeUnique<FilesListRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesListRequest>(sender_.get(), url_generator_,
                                          callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_q("trashed = false");  // Exclude trashed files.
@@ -429,7 +428,7 @@
   query += " and trashed = false";
 
   std::unique_ptr<FilesListRequest> request =
-      base::MakeUnique<FilesListRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesListRequest>(sender_.get(), url_generator_,
                                          callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_q(query);
@@ -444,7 +443,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<ChangesListRequest> request =
-      base::MakeUnique<ChangesListRequest>(sender_.get(), url_generator_,
+      std::make_unique<ChangesListRequest>(sender_.get(), url_generator_,
                                            callback);
   request->set_max_results(kMaxNumFilesResourcePerRequest);
   request->set_start_change_id(start_changestamp);
@@ -460,7 +459,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<ChangesListNextPageRequest> request =
-      base::MakeUnique<ChangesListNextPageRequest>(sender_.get(), callback);
+      std::make_unique<ChangesListNextPageRequest>(sender_.get(), callback);
   request->set_next_link(next_link);
   request->set_fields(kChangeListFields);
   return sender_->StartRequestWithAuthRetry(std::move(request));
@@ -474,7 +473,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<TeamDriveListRequest> request =
-      base::MakeUnique<TeamDriveListRequest>(sender_.get(), url_generator_,
+      std::make_unique<TeamDriveListRequest>(sender_.get(), url_generator_,
                                              callback);
   request->set_page_token(page_token);
   request->set_fields(kTeamDrivesListFields);
@@ -489,7 +488,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesListNextPageRequest> request =
-      base::MakeUnique<FilesListNextPageRequest>(sender_.get(), callback);
+      std::make_unique<FilesListNextPageRequest>(sender_.get(), callback);
   request->set_next_link(next_link);
   request->set_fields(kFileListFields);
   return sender_->StartRequestWithAuthRetry(std::move(request));
@@ -501,7 +500,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!callback.is_null());
 
-  std::unique_ptr<FilesGetRequest> request = base::MakeUnique<FilesGetRequest>(
+  std::unique_ptr<FilesGetRequest> request = std::make_unique<FilesGetRequest>(
       sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
       callback);
   request->set_file_id(resource_id);
@@ -521,7 +520,7 @@
                << "from the file manager.";
   }
 
-  std::unique_ptr<FilesGetRequest> request = base::MakeUnique<FilesGetRequest>(
+  std::unique_ptr<FilesGetRequest> request = std::make_unique<FilesGetRequest>(
       sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
       base::Bind(&ExtractShareUrlAndRun, callback));
   request->set_file_id(resource_id);
@@ -535,7 +534,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!callback.is_null());
 
-  std::unique_ptr<AboutGetRequest> request = base::MakeUnique<AboutGetRequest>(
+  std::unique_ptr<AboutGetRequest> request = std::make_unique<AboutGetRequest>(
       sender_.get(), url_generator_, callback);
   request->set_fields(kAboutResourceFields);
   return sender_->StartRequestWithAuthRetry(std::move(request));
@@ -545,7 +544,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!callback.is_null());
 
-  return sender_->StartRequestWithAuthRetry(base::MakeUnique<AppsListRequest>(
+  return sender_->StartRequestWithAuthRetry(std::make_unique<AppsListRequest>(
       sender_.get(), url_generator_, google_apis::IsGoogleChromeAPIKeyUsed(),
       callback));
 }
@@ -561,7 +560,7 @@
   // get_content_callback may be null.
 
   return sender_->StartRequestWithAuthRetry(
-      base::MakeUnique<DownloadFileRequest>(
+      std::make_unique<DownloadFileRequest>(
           sender_.get(), url_generator_, resource_id, local_cache_path,
           download_action_callback, get_content_callback, progress_callback));
 }
@@ -574,7 +573,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesDeleteRequest> request =
-      base::MakeUnique<FilesDeleteRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesDeleteRequest>(sender_.get(), url_generator_,
                                            callback);
   request->set_file_id(resource_id);
   request->set_etag(etag);
@@ -588,7 +587,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesTrashRequest> request =
-      base::MakeUnique<FilesTrashRequest>(
+      std::make_unique<FilesTrashRequest>(
           sender_.get(), url_generator_,
           base::Bind(&EntryActionCallbackAdapter, callback));
   request->set_file_id(resource_id);
@@ -605,7 +604,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesInsertRequest> request =
-      base::MakeUnique<FilesInsertRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesInsertRequest>(sender_.get(), url_generator_,
                                            callback);
   request->set_visibility(options.visibility);
   request->set_last_viewed_by_me_date(options.last_viewed_by_me_date);
@@ -628,7 +627,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesCopyRequest> request =
-      base::MakeUnique<FilesCopyRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesCopyRequest>(sender_.get(), url_generator_,
                                          callback);
   request->set_file_id(resource_id);
   request->add_parent(parent_resource_id);
@@ -650,7 +649,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<FilesPatchRequest> request =
-      base::MakeUnique<FilesPatchRequest>(sender_.get(), url_generator_,
+      std::make_unique<FilesPatchRequest>(sender_.get(), url_generator_,
                                           callback);
   request->set_file_id(resource_id);
   request->set_title(new_title);
@@ -680,7 +679,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<ChildrenInsertRequest> request =
-      base::MakeUnique<ChildrenInsertRequest>(sender_.get(), url_generator_,
+      std::make_unique<ChildrenInsertRequest>(sender_.get(), url_generator_,
                                               callback);
   request->set_folder_id(parent_resource_id);
   request->set_id(resource_id);
@@ -695,7 +694,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<ChildrenDeleteRequest> request =
-      base::MakeUnique<ChildrenDeleteRequest>(sender_.get(), url_generator_,
+      std::make_unique<ChildrenDeleteRequest>(sender_.get(), url_generator_,
                                               callback);
   request->set_child_id(resource_id);
   request->set_folder_id(parent_resource_id);
@@ -713,7 +712,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<InitiateUploadNewFileRequest> request =
-      base::MakeUnique<InitiateUploadNewFileRequest>(
+      std::make_unique<InitiateUploadNewFileRequest>(
           sender_.get(), url_generator_, content_type, content_length,
           parent_resource_id, title, callback);
   request->set_modified_date(options.modified_date);
@@ -732,7 +731,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<InitiateUploadExistingFileRequest> request =
-      base::MakeUnique<InitiateUploadExistingFileRequest>(
+      std::make_unique<InitiateUploadExistingFileRequest>(
           sender_.get(), url_generator_, content_type, content_length,
           resource_id, options.etag, callback);
   request->set_parent_resource_id(options.parent_resource_id);
@@ -756,7 +755,7 @@
   DCHECK(!callback.is_null());
 
   return sender_->StartRequestWithAuthRetry(
-      base::MakeUnique<ResumeUploadRequest>(
+      std::make_unique<ResumeUploadRequest>(
           sender_.get(), upload_url, start_position, end_position,
           content_length, content_type, local_file_path, callback,
           progress_callback));
@@ -770,7 +769,7 @@
   DCHECK(!callback.is_null());
 
   return sender_->StartRequestWithAuthRetry(
-      base::MakeUnique<GetUploadStatusRequest>(sender_.get(), upload_url,
+      std::make_unique<GetUploadStatusRequest>(sender_.get(), upload_url,
                                                content_length, callback));
 }
 
@@ -787,9 +786,9 @@
   DCHECK(!callback.is_null());
 
   return sender_->StartRequestWithAuthRetry(
-      base::MakeUnique<google_apis::drive::SingleBatchableDelegateRequest>(
+      std::make_unique<google_apis::drive::SingleBatchableDelegateRequest>(
           sender_.get(),
-          base::MakeUnique<google_apis::drive::MultipartUploadNewFileDelegate>(
+          std::make_unique<google_apis::drive::MultipartUploadNewFileDelegate>(
               sender_->blocking_task_runner(), title, parent_resource_id,
               content_type, content_length, options.modified_date,
               options.last_viewed_by_me_date, local_file_path,
@@ -809,9 +808,9 @@
   DCHECK(!callback.is_null());
 
   return sender_->StartRequestWithAuthRetry(
-      base::MakeUnique<google_apis::drive::SingleBatchableDelegateRequest>(
+      std::make_unique<google_apis::drive::SingleBatchableDelegateRequest>(
           sender_.get(),
-          base::MakeUnique<
+          std::make_unique<
               google_apis::drive::MultipartUploadExistingFileDelegate>(
               sender_->blocking_task_runner(), options.title, resource_id,
               options.parent_resource_id, content_type, content_length,
@@ -834,7 +833,7 @@
   // clients or drive.google.com web UI.)
   if (google_apis::IsGoogleChromeAPIKeyUsed()) {
     std::unique_ptr<google_apis::drive::FilesAuthorizeRequest> request =
-        base::MakeUnique<google_apis::drive::FilesAuthorizeRequest>(
+        std::make_unique<google_apis::drive::FilesAuthorizeRequest>(
             sender_.get(), url_generator_,
             base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
     request->set_app_id(app_id);
@@ -843,7 +842,7 @@
     return sender_->StartRequestWithAuthRetry(std::move(request));
   } else {
     std::unique_ptr<FilesGetRequest> request =
-        base::MakeUnique<FilesGetRequest>(
+        std::make_unique<FilesGetRequest>(
             sender_.get(), url_generator_,
             google_apis::IsGoogleChromeAPIKeyUsed(),
             base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
@@ -860,7 +859,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<google_apis::drive::AppsDeleteRequest> request =
-      base::MakeUnique<google_apis::drive::AppsDeleteRequest>(
+      std::make_unique<google_apis::drive::AppsDeleteRequest>(
           sender_.get(), url_generator_, callback);
   request->set_app_id(app_id);
   return sender_->StartRequestWithAuthRetry(std::move(request));
@@ -875,7 +874,7 @@
   DCHECK(!callback.is_null());
 
   std::unique_ptr<google_apis::drive::PermissionsInsertRequest> request =
-      base::MakeUnique<google_apis::drive::PermissionsInsertRequest>(
+      std::make_unique<google_apis::drive::PermissionsInsertRequest>(
           sender_.get(), url_generator_, callback);
   request->set_id(resource_id);
   request->set_role(role);
@@ -932,7 +931,7 @@
 std::unique_ptr<BatchRequestConfiguratorInterface>
 DriveAPIService::StartBatchRequest() {
   std::unique_ptr<google_apis::drive::BatchUploadRequest> request =
-      base::MakeUnique<google_apis::drive::BatchUploadRequest>(sender_.get(),
+      std::make_unique<google_apis::drive::BatchUploadRequest>(sender_.get(),
                                                                url_generator_);
   const base::WeakPtr<google_apis::drive::BatchUploadRequest> weak_ref =
       request->GetWeakPtrAsBatchUploadRequest();
@@ -943,7 +942,7 @@
   // the sender is deleted. Resolve the circulating dependency and fix it.
   const google_apis::CancelCallback callback =
       sender_->StartRequestWithAuthRetry(std::move(request));
-  return base::MakeUnique<BatchRequestConfigurator>(
+  return std::make_unique<BatchRequestConfigurator>(
       weak_ref, sender_->blocking_task_runner(), url_generator_, callback);
 }
 
diff --git a/components/drive/service/drive_api_service_unittest.cc b/components/drive/service/drive_api_service_unittest.cc
index 70143b4..231d1e9 100644
--- a/components/drive/service/drive_api_service_unittest.cc
+++ b/components/drive/service/drive_api_service_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "components/drive/service/drive_api_service.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/test/test_simple_task_runner.h"
 #include "google_apis/drive/dummy_auth_service.h"
@@ -48,7 +47,7 @@
       new TestAuthService, request_context_getter.get(), task_runner.get(),
       kTestUserAgent, TRAFFIC_ANNOTATION_FOR_TESTS);
   std::unique_ptr<google_apis::drive::BatchUploadRequest> request =
-      base::MakeUnique<google_apis::drive::BatchUploadRequest>(&sender,
+      std::make_unique<google_apis::drive::BatchUploadRequest>(&sender,
                                                                url_generator);
   google_apis::drive::BatchUploadRequest* request_ptr = request.get();
   sender.StartRequestWithAuthRetry(std::move(request));
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc
index 400640c..4638c62 100644
--- a/components/drive/service/fake_drive_service.cc
+++ b/components/drive/service/fake_drive_service.cc
@@ -139,7 +139,7 @@
     const ChangeResource& entry = *change_list->items()[i];
     if (entry.file())
       file_list->mutable_items()->push_back(
-          base::MakeUnique<FileResource>(*entry.file()));
+          std::make_unique<FileResource>(*entry.file()));
   }
   callback.Run(error, std::move(file_list));
 }
@@ -622,7 +622,7 @@
   if (entry && entry->change_resource.file()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::Bind(callback, HTTP_SUCCESS,
-                              base::Passed(base::MakeUnique<FileResource>(
+                              base::Passed(std::make_unique<FileResource>(
                                   *entry->change_resource.file()))));
     return CancelCallback();
   }
@@ -912,7 +912,7 @@
   copied_entry->share_url = entry->share_url;
   copied_entry->change_resource.set_type(ChangeResource::FILE);
   copied_entry->change_resource.set_file(
-      base::MakeUnique<FileResource>(*entry->change_resource.file()));
+      std::make_unique<FileResource>(*entry->change_resource.file()));
 
   ChangeResource* new_change = &copied_entry->change_resource;
   FileResource* new_file = new_change->mutable_file();
@@ -941,7 +941,7 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(callback, HTTP_SUCCESS,
-                 base::Passed(base::MakeUnique<FileResource>(*new_file))));
+                 base::Passed(std::make_unique<FileResource>(*new_file))));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(&FakeDriveService::NotifyObservers,
@@ -1012,7 +1012,7 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(callback, HTTP_SUCCESS,
-                 base::Passed(base::MakeUnique<FileResource>(*file))));
+                 base::Passed(std::make_unique<FileResource>(*file))));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(&FakeDriveService::NotifyObservers,
@@ -1299,7 +1299,7 @@
 
     completion_callback.Run(
         HTTP_CREATED,
-        base::MakeUnique<FileResource>(*new_entry->change_resource.file()));
+        std::make_unique<FileResource>(*new_entry->change_resource.file()));
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::Bind(&FakeDriveService::NotifyObservers,
@@ -1326,7 +1326,7 @@
   AddNewChangestamp(change);
   UpdateETag(file);
 
-  completion_callback.Run(HTTP_SUCCESS, base::MakeUnique<FileResource>(*file));
+  completion_callback.Run(HTTP_SUCCESS, std::make_unique<FileResource>(*file));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(&FakeDriveService::NotifyObservers,
@@ -1487,7 +1487,7 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::Bind(callback, HTTP_CREATED,
-                            base::Passed(base::MakeUnique<FileResource>(
+                            base::Passed(std::make_unique<FileResource>(
                                 *new_entry->change_resource.file()))));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
@@ -1531,7 +1531,7 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::Bind(callback, HTTP_CREATED,
-                            base::Passed(base::MakeUnique<FileResource>(
+                            base::Passed(std::make_unique<FileResource>(
                                 *new_entry->change_resource.file()))));
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
@@ -1570,7 +1570,7 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
       base::Bind(callback, HTTP_SUCCESS,
-                 base::Passed(base::MakeUnique<FileResource>(*file))));
+                 base::Passed(std::make_unique<FileResource>(*file))));
 }
 
 google_apis::DriveApiErrorCode FakeDriveService::SetUserPermission(
@@ -1803,11 +1803,11 @@
       entry_copied->set_file_id(entry.file_id());
       entry_copied->set_deleted(entry.is_deleted());
       if (entry.type() == ChangeResource::FILE && entry.file()) {
-        entry_copied->set_file(base::MakeUnique<FileResource>(*entry.file()));
+        entry_copied->set_file(std::make_unique<FileResource>(*entry.file()));
       }
       if (entry.type() == ChangeResource::TEAM_DRIVE && entry.team_drive()) {
         entry_copied->set_team_drive(
-            base::MakeUnique<TeamDriveResource>(*entry.team_drive()));
+            std::make_unique<TeamDriveResource>(*entry.team_drive()));
       }
       entry_copied->set_modification_date(entry.modification_date());
       entries.push_back(std::move(entry_copied));
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index 411f5f84..03f86f7 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -95,6 +95,9 @@
   RECORD_HISTOGRAM_SNAPSHOTS_FROM_SOURCE,
   PROVIDE_INDEPENDENT_METRICS,
   SCHEDULE_SOURCES_FAILED,
+  OLD_DELETE_FILE_FAILED,
+  OVER_DELETE_FILE_FAILED,
+  ASYNC_DELETE_FILE_FAILED,
   MAX_HAPPENINGS
 };
 
@@ -113,8 +116,12 @@
   // scope. This is the only cross-platform safe way to delete a file that may
   // be open elsewhere, a distinct possibility given the asynchronous nature
   // of the delete task.
-  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
-                            base::File::FLAG_DELETE_ON_CLOSE);
+  {
+    base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
+                              base::File::FLAG_DELETE_ON_CLOSE);
+  }
+  if (base::PathExists(path))
+    RecordHappening(ASYNC_DELETE_FILE_FAILED);
 }
 
 // A task runner to use for testing.
@@ -336,6 +343,8 @@
         // is not removed, it will continue to be ignored bacuse of the older
         // modification time.
         base::DeleteFile(found_file.path, /*recursive=*/false);
+        if (base::PathExists(found_file.path))
+          RecordHappening(OLD_DELETE_FILE_FAILED);
         ++delete_count;
       }
     }
@@ -360,6 +369,8 @@
         now_time - found.info.GetLastModifiedTime() > source->max_age;
     if (too_many || too_big || too_old) {
       base::DeleteFile(found.path, /*recursive=*/false);
+      if (base::PathExists(found.path))
+        RecordHappening(OVER_DELETE_FILE_FAILED);
       ++delete_count;
       --file_count;
       total_size_kib -= found.info.GetSize() >> 10;
diff --git a/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc b/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
index c6acac3..7c39b7d 100644
--- a/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
+++ b/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
@@ -38,7 +38,9 @@
 const char kUnsubscriptionUrlSignedOut[] =
     "http://valid-url.test/unsubscribe?key=fakeAPIkey";
 
-class SubscriptionManagerImplTest : public testing::Test {
+class SubscriptionManagerImplTest
+    : public testing::Test,
+      public OAuth2TokenService::DiagnosticsObserver {
  public:
   SubscriptionManagerImplTest()
       : request_context_getter_(
@@ -51,6 +53,11 @@
     signin::RegisterAccountConsistencyProfilePrefs(
         utils_.pref_service()->registry());
     signin::SetGaiaOriginIsolatedCallback(base::Bind([] { return true; }));
+    utils_.token_service()->AddDiagnosticsObserver(this);
+  }
+
+  void TearDown() override {
+    utils_.token_service()->RemoveDiagnosticsObserver(this);
   }
 
   scoped_refptr<net::URLRequestContextGetter> GetRequestContext() {
@@ -133,6 +140,10 @@
                                                  base::Time::Max());
   }
 
+  void set_on_access_token_request_callback(base::OnceClosure callback) {
+    on_access_token_request_callback_ = std::move(callback);
+  }
+
  private:
   void RespondSuccessfully() {
     net::TestURLFetcher* url_fetcher = GetRunningFetcher();
@@ -151,10 +162,20 @@
     url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
   }
 
+  // OAuth2TokenService::DiagnosticsObserver:
+  void OnAccessTokenRequested(
+      const std::string& account_id,
+      const std::string& consumer_id,
+      const OAuth2TokenService::ScopeSet& scopes) override {
+    if (on_access_token_request_callback_)
+      std::move(on_access_token_request_callback_).Run();
+  }
+
   base::MessageLoop message_loop_;
   test::RemoteSuggestionsTestUtils utils_;
   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
   net::TestURLFetcherFactory url_fetcher_factory_;
+  base::OnceClosure on_access_token_request_callback_;
 };
 
 TEST_F(SubscriptionManagerImplTest, SubscribeSuccessfully) {
@@ -179,6 +200,9 @@
 #if !defined(OS_CHROMEOS)
 TEST_F(SubscriptionManagerImplTest,
        ShouldSubscribeWithAuthenticationWhenAuthenticated) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   // Sign in.
   FakeProfileOAuth2TokenService* auth_token_service = GetOAuth2TokenService();
   SignIn();
@@ -192,6 +216,8 @@
       /*locale=*/"", kAPIKey, GURL(kSubscriptionUrl), GURL(kUnsubscriptionUrl));
   manager.Subscribe(subscription_token);
 
+  run_loop.Run();
+
   // Make sure that subscription is pending an access token.
   ASSERT_FALSE(manager.IsSubscribed());
   ASSERT_EQ(1u, auth_token_service->GetPendingRequests().size());
@@ -274,10 +300,15 @@
   RespondToSubscriptionRequestSuccessfully(/*is_signed_in=*/false);
   ASSERT_FALSE(manager.NeedsToResubscribe());
 
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   // Sign in. This should trigger a resubscribe.
   SignIn();
   IssueRefreshToken(auth_token_service);
   ASSERT_TRUE(manager.NeedsToResubscribe());
+
+  run_loop.Run();
   ASSERT_EQ(1u, auth_token_service->GetPendingRequests().size());
   IssueAccessToken(auth_token_service);
   RespondToSubscriptionRequestSuccessfully(/*is_signed_in=*/true);
@@ -293,6 +324,9 @@
 #if !defined(OS_CHROMEOS)
 TEST_F(SubscriptionManagerImplTest,
        ShouldResubscribeIfSignOutAfterSubscription) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   // Signin and subscribe.
   FakeProfileOAuth2TokenService* auth_token_service = GetOAuth2TokenService();
   SignIn();
@@ -303,6 +337,7 @@
       /*variations_service=*/nullptr, GetSigninManager(), auth_token_service,
       /*locale=*/"", kAPIKey, GURL(kSubscriptionUrl), GURL(kUnsubscriptionUrl));
   manager.Subscribe(subscription_token);
+  run_loop.Run();
   ASSERT_EQ(1u, auth_token_service->GetPendingRequests().size());
   IssueAccessToken(auth_token_service);
   RespondToSubscriptionRequestSuccessfully(/*is_signed_in=*/true);
diff --git a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
index 1ae73b92..a9615ec1 100644
--- a/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
+++ b/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
@@ -104,12 +104,14 @@
 
 }  // namespace
 
-class ContextualSuggestionsFetcherTest : public testing::Test {
+class ContextualSuggestionsFetcherTest
+    : public testing::Test,
+      public OAuth2TokenService::DiagnosticsObserver {
  public:
   ContextualSuggestionsFetcherTest()
       : fake_url_fetcher_factory_(new net::FakeURLFetcherFactory(nullptr)),
-        mock_task_runner_(new base::TestMockTimeTaskRunner()),
-        mock_task_runner_handle_(mock_task_runner_) {
+        mock_task_runner_(new base::TestMockTimeTaskRunner(
+            base::TestMockTimeTaskRunner::Type::kBoundToThread)) {
     scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
         new net::TestURLRequestContextGetter(mock_task_runner_.get());
     fake_token_service_ = std::make_unique<FakeProfileOAuth2TokenService>(
@@ -119,6 +121,11 @@
         test_utils_.fake_signin_manager(), fake_token_service_.get(),
         std::move(request_context_getter), test_utils_.pref_service(),
         base::Bind(&ParseJson));
+    fake_token_service_->AddDiagnosticsObserver(this);
+  }
+
+  ~ContextualSuggestionsFetcherTest() override {
+    fake_token_service_->RemoveDiagnosticsObserver(this);
   }
 
   void FastForwardUntilNoTasksRemain() {
@@ -158,14 +165,27 @@
     return mock_suggestions_available_callback_;
   }
 
+  void set_on_access_token_request_callback(base::OnceClosure callback) {
+    on_access_token_request_callback_ = std::move(callback);
+  }
+
  private:
+  // OAuth2TokenService::DiagnosticsObserver:
+  void OnAccessTokenRequested(
+      const std::string& account_id,
+      const std::string& consumer_id,
+      const OAuth2TokenService::ScopeSet& scopes) override {
+    if (on_access_token_request_callback_)
+      std::move(on_access_token_request_callback_).Run();
+  }
+
   std::unique_ptr<FakeProfileOAuth2TokenService> fake_token_service_;
   std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_;
   std::unique_ptr<ContextualSuggestionsFetcherImpl> fetcher_;
   MockSuggestionsAvailableCallback mock_suggestions_available_callback_;
   scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_;
-  base::ThreadTaskRunnerHandle mock_task_runner_handle_;
   test::RemoteSuggestionsTestUtils test_utils_;
+  base::OnceClosure on_access_token_request_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsFetcherTest);
 };
@@ -176,6 +196,9 @@
 }
 
 TEST_F(ContextualSuggestionsFetcherTest, ShouldFetchSuggestion) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   InitializeFakeCredentials();
   const std::string kValidResponseData =
       "{\"categories\" : [{"
@@ -196,6 +219,9 @@
   fetcher().FetchContextualSuggestions(
       GURL(kValidURL),
       ToSuggestionsAvailableCallback(&mock_suggestions_available_callback()));
+
+  run_loop.Run();
+
   IssueOAuth2Token();
   FastForwardUntilNoTasksRemain();
   EXPECT_THAT(fetcher().GetLastStatusForTesting(), Eq("OK"));
@@ -203,6 +229,9 @@
 }
 
 TEST_F(ContextualSuggestionsFetcherTest, ShouldFetchEmptySuggestionsList) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   InitializeFakeCredentials();
   const std::string kValidEmptyCategoryResponseData =
       "{\"categories\" : [{"
@@ -218,6 +247,9 @@
   fetcher().FetchContextualSuggestions(
       GURL(kValidURL),
       ToSuggestionsAvailableCallback(&mock_suggestions_available_callback()));
+
+  run_loop.Run();
+
   IssueOAuth2Token();
   FastForwardUntilNoTasksRemain();
   EXPECT_THAT(fetcher().GetLastStatusForTesting(), Eq("OK"));
@@ -227,6 +259,9 @@
 
 TEST_F(ContextualSuggestionsFetcherTest,
        ShouldReportErrorForEmptyResponseData) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   InitializeFakeCredentials();
   SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND,
                   net::URLRequestStatus::SUCCESS);
@@ -236,12 +271,18 @@
   fetcher().FetchContextualSuggestions(
       GURL(kValidURL),
       ToSuggestionsAvailableCallback(&mock_suggestions_available_callback()));
+
+  run_loop.Run();
+
   IssueOAuth2Token();
   FastForwardUntilNoTasksRemain();
 }
 
 TEST_F(ContextualSuggestionsFetcherTest,
        ShouldReportErrorForInvalidResponseData) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   InitializeFakeCredentials();
   const std::string kInvalidResponseData = "{ \"recos\": []";
   SetFakeResponse(/*response_data=*/kInvalidResponseData, net::HTTP_OK,
@@ -256,6 +297,9 @@
   fetcher().FetchContextualSuggestions(
       GURL(kValidURL),
       ToSuggestionsAvailableCallback(&mock_suggestions_available_callback()));
+
+  run_loop.Run();
+
   IssueOAuth2Token();
   FastForwardUntilNoTasksRemain();
   EXPECT_THAT(fetcher().GetLastStatusForTesting(),
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
index 6d07944..dea3fd7 100644
--- a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
+++ b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
@@ -259,7 +259,9 @@
 
 }  // namespace
 
-class RemoteSuggestionsFetcherImplTestBase : public testing::Test {
+class RemoteSuggestionsFetcherImplTestBase
+    : public testing::Test,
+      public OAuth2TokenService::DiagnosticsObserver {
  public:
   explicit RemoteSuggestionsFetcherImplTestBase(const GURL& gurl)
       : default_variation_params_(
@@ -267,8 +269,8 @@
         params_manager_(ntp_snippets::kArticleSuggestionsFeature.name,
                         default_variation_params_,
                         {ntp_snippets::kArticleSuggestionsFeature.name}),
-        mock_task_runner_(new base::TestMockTimeTaskRunner()),
-        mock_task_runner_handle_(mock_task_runner_),
+        mock_task_runner_(new base::TestMockTimeTaskRunner(
+            base::TestMockTimeTaskRunner::Type::kBoundToThread)),
         test_url_(gurl) {
     UserClassifier::RegisterProfilePrefs(utils_.pref_service()->registry());
     user_classifier_ = std::make_unique<UserClassifier>(
@@ -278,16 +280,25 @@
     ResetFetcher();
   }
 
+  ~RemoteSuggestionsFetcherImplTestBase() override {
+    if (fake_token_service_)
+      fake_token_service_->RemoveDiagnosticsObserver(this);
+  }
+
   void ResetFetcher() { ResetFetcherWithAPIKey(kAPIKey); }
 
   void ResetFetcherWithAPIKey(const std::string& api_key) {
     scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
         new net::TestURLRequestContextGetter(mock_task_runner_.get());
 
+    if (fake_token_service_)
+      fake_token_service_->RemoveDiagnosticsObserver(this);
     fake_token_service_ = std::make_unique<FakeProfileOAuth2TokenService>(
         std::make_unique<FakeOAuth2TokenServiceDelegate>(
             request_context_getter.get()));
 
+    fake_token_service_->AddDiagnosticsObserver(this);
+
     fetcher_ = std::make_unique<RemoteSuggestionsFetcherImpl>(
         utils_.fake_signin_manager(), fake_token_service_.get(),
         std::move(request_context_getter), utils_.pref_service(), nullptr,
@@ -369,11 +380,23 @@
     fake_url_fetcher_factory_->SetFakeResponse(test_url_, response_data,
                                                response_code, status);
   }
+  void set_on_access_token_request_callback(base::OnceClosure callback) {
+    on_access_token_request_callback_ = std::move(callback);
+  }
 
  protected:
   std::map<std::string, std::string> default_variation_params_;
 
  private:
+  // OAuth2TokenService::DiagnosticsObserver:
+  void OnAccessTokenRequested(
+      const std::string& account_id,
+      const std::string& consumer_id,
+      const OAuth2TokenService::ScopeSet& scopes) override {
+    if (on_access_token_request_callback_)
+      std::move(on_access_token_request_callback_).Run();
+  }
+
   // TODO(tzik): Remove |clock_| after updating GetMockTickClock to own the
   // instance. http://crbug.com/789079
   std::unique_ptr<base::Clock> clock_;
@@ -381,7 +404,6 @@
   test::RemoteSuggestionsTestUtils utils_;
   variations::testing::VariationParamsManager params_manager_;
   scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_;
-  base::ThreadTaskRunnerHandle mock_task_runner_handle_;
   FailingFakeURLFetcherFactory failing_url_fetcher_factory_;
   // Initialized lazily in SetFakeResponse().
   std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_;
@@ -391,6 +413,7 @@
   MockSnippetsAvailableCallback mock_callback_;
   const GURL test_url_;
   base::HistogramTester histogram_tester_;
+  base::OnceClosure on_access_token_request_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsFetcherImplTestBase);
 };
@@ -466,6 +489,9 @@
 }
 
 TEST_F(RemoteSuggestionsSignedInFetcherTest, ShouldFetchSuccessfully) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   SignIn();
   IssueRefreshToken();
 
@@ -497,6 +523,8 @@
   fetcher().FetchSnippets(test_params(),
                           ToSnippetsAvailableCallback(&mock_callback()));
 
+  run_loop.Run();
+
   IssueOAuth2Token();
   // Wait for the fake response.
   FastForwardUntilNoTasksRemain();
@@ -512,6 +540,9 @@
 }
 
 TEST_F(RemoteSuggestionsSignedInFetcherTest, ShouldRetryWhenOAuthCancelled) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   SignIn();
   IssueRefreshToken();
 
@@ -543,7 +574,19 @@
   fetcher().FetchSnippets(test_params(),
                           ToSnippetsAvailableCallback(&mock_callback()));
 
+  // Wait for the first access token request to be made.
+  run_loop.Run();
+
+  // Before cancelling the outstanding access token request, prepare to wait for
+  // the second access token request to be made in response to the cancellation.
+  base::RunLoop run_loop2;
+  set_on_access_token_request_callback(run_loop2.QuitClosure());
+
   CancelOAuth2TokenRequests();
+
+  // Wait for the second access token request to be made.
+  run_loop2.Run();
+
   IssueOAuth2Token();
   // Wait for the fake response.
   FastForwardUntilNoTasksRemain();
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn
index a64ec1f2..a349d06 100644
--- a/components/offline_pages/core/BUILD.gn
+++ b/components/offline_pages/core/BUILD.gn
@@ -27,8 +27,6 @@
     "model/clear_storage_task.h",
     "model/complete_offline_page_upgrade_task.cc",
     "model/complete_offline_page_upgrade_task.h",
-    "model/create_archive_task.cc",
-    "model/create_archive_task.h",
     "model/delete_page_task.cc",
     "model/delete_page_task.h",
     "model/get_pages_task.cc",
@@ -150,7 +148,6 @@
     "model/clear_legacy_temporary_pages_task_unittest.cc",
     "model/clear_storage_task_unittest.cc",
     "model/complete_offline_page_upgrade_task_unittest.cc",
-    "model/create_archive_task_unittest.cc",
     "model/delete_page_task_unittest.cc",
     "model/get_pages_task_unittest.cc",
     "model/mark_page_accessed_task_unittest.cc",
diff --git a/components/offline_pages/core/model/create_archive_task.cc b/components/offline_pages/core/model/create_archive_task.cc
deleted file mode 100644
index 4258913..0000000
--- a/components/offline_pages/core/model/create_archive_task.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/offline_pages/core/model/create_archive_task.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/time/default_clock.h"
-#include "components/offline_pages/core/offline_page_model.h"
-#include "components/offline_pages/core/offline_store_utils.h"
-
-namespace offline_pages {
-
-using ArchiverResult = OfflinePageArchiver::ArchiverResult;
-
-CreateArchiveTask::CreateArchiveTask(
-    const base::FilePath& archives_dir,
-    const OfflinePageModel::SavePageParams& save_page_params,
-    OfflinePageArchiver* archiver,
-    const CreateArchiveTaskCallback& callback)
-    : archives_dir_(archives_dir),
-      save_page_params_(save_page_params),
-      archiver_(archiver),
-      callback_(callback),
-      clock_(new base::DefaultClock()),
-      skip_clearing_original_url_for_testing_(false) {
-  DCHECK(!callback_.is_null());
-}
-
-CreateArchiveTask::~CreateArchiveTask() {}
-
-void CreateArchiveTask::Run() {
-  CreateArchive();
-}
-
-void CreateArchiveTask::CreateArchive() {
-  OfflinePageItem proposed_page;
-
-  // Create a proposed OfflinePageItem to pass in callback, the page will be
-  // missing fields, which are going to be filled when the archive creation
-  // finishes.
-  proposed_page.url = save_page_params_.url;
-  proposed_page.offline_id = save_page_params_.proposed_offline_id;
-  proposed_page.client_id = save_page_params_.client_id;
-  proposed_page.creation_time = clock_->Now();
-  proposed_page.last_access_time = clock_->Now();
-  proposed_page.request_origin = save_page_params_.request_origin;
-
-  // Don't record the original URL if it is identical to the final URL. This is
-  // because some websites might route the redirect finally back to itself upon
-  // the completion of certain action, i.e., authentication, in the middle.
-  if (skip_clearing_original_url_for_testing_ ||
-      save_page_params_.original_url != proposed_page.url) {
-    proposed_page.original_url = save_page_params_.original_url;
-  }
-
-  // Skip saving the page that is not intended to be saved, like local file
-  // page.
-  if (!OfflinePageModel::CanSaveURL(save_page_params_.url)) {
-    InformCreateArchiveFailed(ArchiverResult::ERROR_SKIPPED, proposed_page);
-    return;
-  }
-
-  // The web contents is not available if archiver is not created and passed.
-  if (!archiver_) {
-    InformCreateArchiveFailed(ArchiverResult::ERROR_CONTENT_UNAVAILABLE,
-                              proposed_page);
-    return;
-  }
-
-  if (proposed_page.offline_id == OfflinePageModel::kInvalidOfflineId)
-    proposed_page.offline_id = store_utils::GenerateOfflineId();
-
-  OfflinePageArchiver::CreateArchiveParams create_archive_params;
-  // If the page is being saved in the background, we should try to remove the
-  // popup overlay that obstructs viewing the normal content.
-  create_archive_params.remove_popup_overlay = save_page_params_.is_background;
-  create_archive_params.use_page_problem_detectors =
-      save_page_params_.use_page_problem_detectors;
-  archiver_->CreateArchive(archives_dir_, create_archive_params,
-                           base::Bind(callback_, proposed_page));
-
-  // The task will complete here, and the callback will be called once the
-  // |archiver_| is done with the archive creation. This enables multiple
-  // archive creation going on by not blocking the TaskQueue waiting for the
-  // completion.
-  TaskComplete();
-}
-
-void CreateArchiveTask::InformCreateArchiveFailed(
-    ArchiverResult result,
-    const OfflinePageItem& proposed_page) {
-  callback_.Run(proposed_page, archiver_, result, GURL(), base::FilePath(),
-                base::string16(), 0, std::string());
-  TaskComplete();
-}
-
-}  // namespace offline_pages
diff --git a/components/offline_pages/core/model/create_archive_task.h b/components/offline_pages/core/model/create_archive_task.h
deleted file mode 100644
index 2ac77cb..0000000
--- a/components/offline_pages/core/model/create_archive_task.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
-#define COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/time/clock.h"
-#include "components/offline_pages/core/offline_page_archiver.h"
-#include "components/offline_pages/core/offline_page_model.h"
-#include "components/offline_pages/core/offline_page_types.h"
-#include "components/offline_pages/core/task.h"
-
-namespace base {
-class FilePath;
-}  // namespace base
-
-namespace offline_pages {
-
-// Task that start an archive creation using the OfflinePageArchiver passed in,
-// along with the SavePageParams.
-// The task will complete before the archive creation actually finishes, in
-// order to allow multiple archivers to work in parallel.
-// The lifetime of the archiver needs to be managed by the caller, this task
-// will not own the archiver. The ownership of the callback passed in will be
-// transferred to the archiver, so that it can still get executed after this
-// task gets destroyed.
-// TODO(romax): Verify that this task is actually needed. If we don't access the
-// database, making this a task seems to much, and it can be simplified as a
-// method.
-class CreateArchiveTask : public Task {
- public:
-  // The arguments of the callback are (in order):
-  // - Proposed OfflinePageItem, filled with information from SavePageParams,
-  // - Pointer to the archiver.
-  // - ArchiverResult of the archive creation,
-  // - The saved url, which is acquired from the WebContent of the archiver,
-  // - The file path to the saved archive,
-  // - Title of the saved page,
-  // - Size of the saved file.
-  // - Digest of the saved file.
-  // TODO(romax): simplify the callback and related interface if possible. The
-  // url, path, title and file size can be filled into the OfflinePageItem
-  // during archive creation.
-  typedef base::Callback<void(OfflinePageItem,
-                              OfflinePageArchiver*,
-                              OfflinePageArchiver::ArchiverResult,
-                              const GURL&,
-                              const base::FilePath&,
-                              const base::string16&,
-                              int64_t,
-                              const std::string&)>
-      CreateArchiveTaskCallback;
-
-  CreateArchiveTask(const base::FilePath& archives_dir,
-                    const OfflinePageModel::SavePageParams& save_page_params,
-                    OfflinePageArchiver* archiver,
-                    const CreateArchiveTaskCallback& callback);
-  ~CreateArchiveTask() override;
-
-  // Task implementation.
-  void Run() override;
-
-  void set_clock_for_testing(std::unique_ptr<base::Clock> clock) {
-    clock_ = std::move(clock);
-  }
-
-  void set_skip_clearing_original_url_for_testing() {
-    skip_clearing_original_url_for_testing_ = true;
-  }
-
- private:
-  void CreateArchive();
-  void InformCreateArchiveFailed(OfflinePageArchiver::ArchiverResult result,
-                                 const OfflinePageItem& proposed_page);
-
-  // The directory to save the archive.
-  base::FilePath archives_dir_;
-  OfflinePageModel::SavePageParams save_page_params_;
-  // The archiver used in the task. Not owned.
-  OfflinePageArchiver* archiver_;
-  CreateArchiveTaskCallback callback_;
-  std::unique_ptr<base::Clock> clock_;
-
-  bool skip_clearing_original_url_for_testing_;
-
-  DISALLOW_COPY_AND_ASSIGN(CreateArchiveTask);
-};
-
-}  // namespace offline_pages
-
-#endif  // COMPONENTS_OFFLINE_PAGES_CORE_MODEL_CREATE_ARCHIVE_TASK_H_
diff --git a/components/offline_pages/core/model/create_archive_task_unittest.cc b/components/offline_pages/core/model/create_archive_task_unittest.cc
deleted file mode 100644
index 920ac4c..0000000
--- a/components/offline_pages/core/model/create_archive_task_unittest.cc
+++ /dev/null
@@ -1,432 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/offline_pages/core/model/create_archive_task.h"
-
-#include "base/bind.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/weak_ptr.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/offline_pages/core/offline_page_item.h"
-#include "components/offline_pages/core/offline_page_test_archiver.h"
-#include "components/offline_pages/core/offline_page_test_store.h"
-#include "components/offline_pages/core/offline_page_types.h"
-#include "components/offline_pages/core/test_task.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace offline_pages {
-
-using ArchiverResult = OfflinePageArchiver::ArchiverResult;
-using SavePageParams = OfflinePageModel::SavePageParams;
-
-namespace {
-const char kTestClientNamespace[] = "default";
-const GURL kTestUrl("http://example.com");
-const GURL kTestUrl2("http://other.page.com");
-const GURL kFileUrl("file:///foo");
-const ClientId kTestClientId1(kTestClientNamespace, "1234");
-const int64_t kTestFileSize = 876543LL;
-const base::string16 kTestTitle = base::UTF8ToUTF16("a title");
-const std::string kRequestOrigin("abc.xyz");
-const std::string kTestDigest("test digest");
-}  // namespace
-
-class CreateArchiveTaskTest
-    : public testing::Test,
-      public OfflinePageTestArchiver::Observer,
-      public base::SupportsWeakPtr<CreateArchiveTaskTest> {
- public:
-  CreateArchiveTaskTest();
-  ~CreateArchiveTaskTest() override;
-
-  void SetUp() override;
-
-  // OfflinePageTestArchiver::Observer implementation.
-  void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override;
-
-  void PumpLoop();
-  void ResetResults();
-  void OnCreateArchiveDone(OfflinePageItem offline_page,
-                           OfflinePageArchiver* archiver,
-                           ArchiverResult result,
-                           const GURL& saved_url,
-                           const base::FilePath& file_path,
-                           const base::string16& title,
-                           int64_t file_size,
-                           const std::string& file_hash);
-  std::unique_ptr<OfflinePageTestArchiver> BuildArchiver(const GURL& url,
-                                                         ArchiverResult result);
-  void CreateArchiveWithParams(const SavePageParams& save_page_params,
-                               OfflinePageArchiver* archiver);
-
-  void CreateArchiveWithArchiver(const GURL& gurl,
-                                 const ClientId& client_id,
-                                 const GURL& original_url,
-                                 const std::string& request_origin,
-                                 OfflinePageArchiver* archiver);
-
-  void CreateArchiveWithResult(const GURL& gurl,
-                               const ClientId& client_id,
-                               const GURL& original_url,
-                               const std::string& request_origin,
-                               ArchiverResult expected_result);
-
-  const base::FilePath& archives_dir() { return temp_dir_.GetPath(); }
-  const OfflinePageItem& last_page_of_archive() {
-    return last_page_of_archive_;
-  }
-  OfflinePageArchiver* last_saved_archiver() { return last_saved_archiver_; }
-  ArchiverResult last_create_archive_result() {
-    return last_create_archive_result_;
-  }
-  const base::FilePath& last_archiver_path() const {
-    return last_archiver_path_;
-  }
-  const GURL& last_saved_url() const { return last_saved_url_; }
-  const base::FilePath& last_saved_file_path() const {
-    return last_saved_file_path_;
-  }
-  const base::string16& last_saved_title() const { return last_saved_title_; }
-  int64_t last_saved_file_size() const { return last_saved_file_size_; }
-  const std::string& last_saved_digest() const { return last_saved_digest_; }
-
- private:
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  base::ThreadTaskRunnerHandle task_runner_handle_;
-  base::ScopedTempDir temp_dir_;
-
-  OfflinePageItem last_page_of_archive_;
-  OfflinePageArchiver* last_saved_archiver_;
-  ArchiverResult last_create_archive_result_;
-  base::FilePath last_archiver_path_;
-  GURL last_saved_url_;
-  base::FilePath last_saved_file_path_;
-  base::string16 last_saved_title_;
-  int64_t last_saved_file_size_;
-  std::string last_saved_digest_;
-  // Owning a task to prevent it being destroyed in the heap when calling
-  // CreateArchiveWithParams, which will lead to a heap-use-after-free on
-  // trybots.
-  std::unique_ptr<CreateArchiveTask> task_;
-};
-
-CreateArchiveTaskTest::CreateArchiveTaskTest()
-    : task_runner_(new base::TestSimpleTaskRunner()),
-      task_runner_handle_(task_runner_) {}
-
-CreateArchiveTaskTest::~CreateArchiveTaskTest() {}
-
-void CreateArchiveTaskTest::SetUp() {
-  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-}
-
-void CreateArchiveTaskTest::SetLastPathCreatedByArchiver(
-    const base::FilePath& file_path) {
-  last_archiver_path_ = file_path;
-}
-
-void CreateArchiveTaskTest::PumpLoop() {
-  task_runner_->RunUntilIdle();
-}
-
-void CreateArchiveTaskTest::ResetResults() {
-  last_create_archive_result_ = ArchiverResult::ERROR_CANCELED;
-  last_page_of_archive_ = OfflinePageItem();
-  last_saved_url_ = GURL();
-  last_saved_file_path_ = base::FilePath();
-  last_saved_title_ = base::string16();
-  last_saved_file_size_ = 0;
-  last_archiver_path_.clear();
-  last_saved_digest_.clear();
-}
-void CreateArchiveTaskTest::OnCreateArchiveDone(OfflinePageItem offline_page,
-                                                OfflinePageArchiver* archiver,
-                                                ArchiverResult result,
-                                                const GURL& saved_url,
-                                                const base::FilePath& file_path,
-                                                const base::string16& title,
-                                                int64_t file_size,
-                                                const std::string& digest) {
-  last_page_of_archive_ = offline_page;
-  last_saved_archiver_ = archiver;
-  last_create_archive_result_ = result;
-  last_saved_url_ = saved_url;
-  last_saved_file_path_ = file_path;
-  last_saved_title_ = title;
-  last_saved_file_size_ = file_size;
-  last_saved_digest_ = digest;
-}
-
-std::unique_ptr<OfflinePageTestArchiver> CreateArchiveTaskTest::BuildArchiver(
-    const GURL& url,
-    ArchiverResult result) {
-  return std::unique_ptr<OfflinePageTestArchiver>(new OfflinePageTestArchiver(
-      this, url, result, kTestTitle, kTestFileSize, kTestDigest,
-      base::ThreadTaskRunnerHandle::Get()));
-}
-
-void CreateArchiveTaskTest::CreateArchiveWithParams(
-    const SavePageParams& save_page_params,
-    OfflinePageArchiver* archiver) {
-  task_ = base::MakeUnique<CreateArchiveTask>(
-      archives_dir(), save_page_params, archiver,
-      base::Bind(&CreateArchiveTaskTest::OnCreateArchiveDone, AsWeakPtr()));
-  task_->Run();
-  PumpLoop();
-  // Check if the archiver is the same with the one in the callback.
-  EXPECT_EQ(archiver, last_saved_archiver());
-}
-
-void CreateArchiveTaskTest::CreateArchiveWithArchiver(
-    const GURL& gurl,
-    const ClientId& client_id,
-    const GURL& original_url,
-    const std::string& request_origin,
-    OfflinePageArchiver* archiver) {
-  OfflinePageModel::SavePageParams save_page_params;
-  save_page_params.url = gurl;
-  save_page_params.client_id = client_id;
-  save_page_params.original_url = original_url;
-  save_page_params.is_background = false;
-  save_page_params.request_origin = request_origin;
-  CreateArchiveWithParams(save_page_params, archiver);
-}
-
-void CreateArchiveTaskTest::CreateArchiveWithResult(
-    const GURL& gurl,
-    const ClientId& client_id,
-    const GURL& original_url,
-    const std::string& request_origin,
-    ArchiverResult expected_result) {
-  std::unique_ptr<OfflinePageTestArchiver> archiver(
-      BuildArchiver(gurl, expected_result));
-  CreateArchiveWithArchiver(gurl, client_id, original_url, request_origin,
-                            archiver.get());
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessful) {
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, kTestUrl2, "",
-      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
-
-  // Check the last result to be successful.
-  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
-  const OfflinePageItem& offline_page = last_page_of_archive();
-
-  // The values will be set during archive creation.
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(kTestUrl2, offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-
-  // The values that will not be set during archive creation, but will be set to
-  // default value in the constructor of OfflinePageItem.
-  EXPECT_EQ(0, offline_page.access_count);
-  EXPECT_EQ(0, offline_page.flags);
-
-  // The values that will not be set during archive creation, but will be in the
-  // CreateArchiveTaskCallback.
-  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
-  EXPECT_EQ(kTestFileSize, last_saved_file_size());
-  EXPECT_EQ(kTestTitle, last_saved_title());
-  EXPECT_EQ(kTestDigest, last_saved_digest());
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessfulWithSameOriginalURL) {
-  // Pass the original URL same as the final URL, the original will be empty in
-  // this case.
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, kTestUrl, "",
-      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
-
-  // Check the last result to be successful.
-  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
-  const OfflinePageItem& offline_page = last_page_of_archive();
-
-  // The original URL should be empty.
-  EXPECT_TRUE(offline_page.original_url.is_empty());
-
-  // The values will be set during archive creation.
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ("", offline_page.request_origin);
-
-  // The values that will not be set during archive creation, but will be set to
-  // default value in the constructor of OfflinePageItem.
-  EXPECT_EQ(0, offline_page.access_count);
-  EXPECT_EQ(0, offline_page.flags);
-
-  // The values that will not be set during archive creation, but will be in the
-  // CreateArchiveTaskCallback.
-  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
-  EXPECT_EQ(kTestFileSize, last_saved_file_size());
-  EXPECT_EQ(kTestTitle, last_saved_title());
-  EXPECT_EQ(kTestDigest, last_saved_digest());
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveSuccessfulWithRequestOrigin) {
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, kTestUrl2, kRequestOrigin,
-      OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED);
-
-  // Check the last result to be successful.
-  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
-  const OfflinePageItem& offline_page = last_page_of_archive();
-
-  // The values will be set during archive creation.
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(kTestUrl2, offline_page.original_url);
-  EXPECT_EQ(kRequestOrigin, offline_page.request_origin);
-
-  // The values that will not be set during archive creation, but will be set to
-  // default value in the constructor of OfflinePageItem.
-  EXPECT_EQ(0, offline_page.access_count);
-  EXPECT_EQ(0, offline_page.flags);
-
-  // The values that will not be set during archive creation, but will be in the
-  // CreateArchiveTaskCallback.
-  EXPECT_EQ(last_archiver_path(), last_saved_file_path());
-  EXPECT_EQ(kTestFileSize, last_saved_file_size());
-  EXPECT_EQ(kTestTitle, last_saved_title());
-  EXPECT_EQ(kTestDigest, last_saved_digest());
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverCanceled) {
-  CreateArchiveWithResult(kTestUrl, kTestClientId1, GURL(), "",
-                          OfflinePageArchiver::ArchiverResult::ERROR_CANCELED);
-  EXPECT_EQ(ArchiverResult::ERROR_CANCELED, last_create_archive_result());
-
-  // The values will be set during archive creation.
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverDeviceFull) {
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, GURL(), "",
-      OfflinePageArchiver::ArchiverResult::ERROR_DEVICE_FULL);
-  EXPECT_EQ(ArchiverResult::ERROR_DEVICE_FULL, last_create_archive_result());
-
-  // The values will be set during archive creation.
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverContentUnavailable) {
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, GURL(), "",
-      OfflinePageArchiver::ArchiverResult::ERROR_CONTENT_UNAVAILABLE);
-  EXPECT_EQ(ArchiverResult::ERROR_CONTENT_UNAVAILABLE,
-            last_create_archive_result());
-
-  // The values will be set during archive creation.
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveWithCreationFailed) {
-  CreateArchiveWithResult(
-      kTestUrl, kTestClientId1, GURL(), "",
-      OfflinePageArchiver::ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED);
-  EXPECT_EQ(ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED,
-            last_create_archive_result());
-
-  // The values will be set during archive creation.
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveWithArchiverReturnedWrongUrl) {
-  GURL test_url("http://other.random.url.com");
-  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
-      test_url, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  CreateArchiveWithArchiver(kTestUrl, kTestClientId1, GURL(), "",
-                            archiver.get());
-
-  // Since the task will not judge the result even if the |saved_url| in the
-  // callback is not the same with the SavePageParams.url, so the result will be
-  // SUCCESSFULLY_CREATED, but the |last_saved_url()| will be |test_url|. The
-  // creator of the task will be responsible to detect this failure case.
-  EXPECT_EQ(ArchiverResult::SUCCESSFULLY_CREATED, last_create_archive_result());
-  EXPECT_EQ(test_url, last_saved_url());
-
-  // The values will be set during archive creation.
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_NE(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveLocalFileFailed) {
-  // Don't create archiver since it will not be needed for pages that are not
-  // going to be saved.
-  CreateArchiveWithArchiver(kFileUrl, kTestClientId1, GURL(), "", nullptr);
-  EXPECT_EQ(ArchiverResult::ERROR_SKIPPED, last_create_archive_result());
-
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kFileUrl, offline_page.url);
-  EXPECT_EQ(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveFailedWithNullptr) {
-  // Passing in a nullptr intentionally for test.
-  CreateArchiveWithArchiver(kTestUrl, kTestClientId1, GURL(), "", nullptr);
-  EXPECT_EQ(ArchiverResult::ERROR_CONTENT_UNAVAILABLE,
-            last_create_archive_result());
-
-  const OfflinePageItem& offline_page = last_page_of_archive();
-  EXPECT_EQ(kTestUrl, offline_page.url);
-  EXPECT_EQ(OfflinePageModel::kInvalidOfflineId, offline_page.offline_id);
-  EXPECT_EQ(kTestClientId1, offline_page.client_id);
-  EXPECT_EQ(GURL(), offline_page.original_url);
-  EXPECT_EQ("", offline_page.request_origin);
-}
-
-TEST_F(CreateArchiveTaskTest, CreateArchiveInBackground) {
-  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
-      kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  OfflinePageTestArchiver* archiver_ptr = archiver.get();
-
-  OfflinePageModel::SavePageParams save_page_params;
-  save_page_params.url = kTestUrl;
-  save_page_params.client_id = kTestClientId1;
-  save_page_params.is_background = true;
-  save_page_params.use_page_problem_detectors = false;
-
-  CreateArchiveWithParams(save_page_params, archiver_ptr);
-
-  EXPECT_TRUE(archiver_ptr->create_archive_called());
-  // |remove_popup_overlay| should be turned on on background mode.
-  EXPECT_TRUE(archiver_ptr->create_archive_params().remove_popup_overlay);
-}
-
-}  // namespace offline_pages
diff --git a/components/offline_pages/core/model/delete_page_task.cc b/components/offline_pages/core/model/delete_page_task.cc
index 97011a7..6c50521 100644
--- a/components/offline_pages/core/model/delete_page_task.cc
+++ b/components/offline_pages/core/model/delete_page_task.cc
@@ -317,7 +317,7 @@
   }
 
   // Since the page information was selected by ascending order of last access
-  // time, only the first |size - limit + 1| pages needs to be deleted.
+  // time, only the first |size - limit| pages needs to be deleted.
   int page_to_delete = info_wrappers.size() - limit;
   if (page_to_delete < 0)
     page_to_delete = 0;
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc
index 341f034..2b94dde 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified.cc
+++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -19,7 +19,6 @@
 #include "components/offline_pages/core/client_namespace_constants.h"
 #include "components/offline_pages/core/model/add_page_task.h"
 #include "components/offline_pages/core/model/clear_legacy_temporary_pages_task.h"
-#include "components/offline_pages/core/model/create_archive_task.h"
 #include "components/offline_pages/core/model/delete_page_task.h"
 #include "components/offline_pages/core/model/get_pages_task.h"
 #include "components/offline_pages/core/model/mark_page_accessed_task.h"
@@ -30,6 +29,7 @@
 #include "components/offline_pages/core/offline_page_metadata_store.h"
 #include "components/offline_pages/core/offline_page_metadata_store_sql.h"
 #include "components/offline_pages/core/offline_page_model.h"
+#include "components/offline_pages/core/offline_store_utils.h"
 #include "url/gurl.h"
 
 namespace offline_pages {
@@ -125,8 +125,9 @@
     : store_(std::move(store)),
       archive_manager_(std::move(archive_manager)),
       policy_controller_(new ClientPolicyController()),
-      task_queue_(this),
       clock_(std::move(clock)),
+      task_queue_(this),
+      skip_clearing_original_url_for_testing_(false),
       weak_ptr_factory_(this) {
   CreateArchivesDirectoryIfNeeded();
   PostClearLegacyTemporaryPagesTask();
@@ -152,13 +153,39 @@
     const SavePageParams& save_page_params,
     std::unique_ptr<OfflinePageArchiver> archiver,
     const SavePageCallback& callback) {
-  auto task = base::MakeUnique<CreateArchiveTask>(
+  // Skip saving the page that is not intended to be saved, like local file
+  // page.
+  if (!OfflinePageModel::CanSaveURL(save_page_params.url)) {
+    InformSavePageDone(callback, SavePageResult::SKIPPED,
+                       save_page_params.client_id, kInvalidOfflineId);
+    return;
+  }
+
+  // The web contents is not available if archiver is not created and passed.
+  if (!archiver.get()) {
+    InformSavePageDone(callback, SavePageResult::CONTENT_UNAVAILABLE,
+                       save_page_params.client_id, kInvalidOfflineId);
+    return;
+  }
+
+  // If we already have an offline id, use it.  If not, generate one.
+  int64_t offline_id = save_page_params.proposed_offline_id;
+  if (offline_id == kInvalidOfflineId)
+    offline_id = store_utils::GenerateOfflineId();
+
+  OfflinePageArchiver::CreateArchiveParams create_archive_params;
+  // If the page is being saved in the background, we should try to remove the
+  // popup overlay that obstructs viewing the normal content.
+  create_archive_params.remove_popup_overlay = save_page_params.is_background;
+  create_archive_params.use_page_problem_detectors =
+      save_page_params.use_page_problem_detectors;
+  archiver->CreateArchive(
       GetArchiveDirectory(save_page_params.client_id.name_space),
-      save_page_params, archiver.get(),
+      create_archive_params,
       base::Bind(&OfflinePageModelTaskified::OnCreateArchiveDone,
-                 weak_ptr_factory_.GetWeakPtr(), callback));
+                 weak_ptr_factory_.GetWeakPtr(), save_page_params, offline_id,
+                 GetCurrentTime(), callback));
   pending_archivers_.push_back(std::move(archiver));
-  task_queue_.AddTask(std::move(task));
 }
 
 void OfflinePageModelTaskified::AddPage(const OfflinePageItem& page,
@@ -306,37 +333,37 @@
   return &offline_event_logger_;
 }
 
-// TODO(romax): see if this method can be moved into anonymous namespace after
-// migrating UMAs.
 void OfflinePageModelTaskified::InformSavePageDone(
     const SavePageCallback& callback,
     SavePageResult result,
-    const OfflinePageItem& page) {
-  UMA_HISTOGRAM_ENUMERATION(
-      "OfflinePages.SavePageCount",
-      model_utils::ToNamespaceEnum(page.client_id.name_space),
-      OfflinePagesNamespaceEnumeration::RESULT_COUNT);
+    const ClientId& client_id,
+    int64_t offline_id) {
+  UMA_HISTOGRAM_ENUMERATION("OfflinePages.SavePageCount",
+                            model_utils::ToNamespaceEnum(client_id.name_space),
+                            OfflinePagesNamespaceEnumeration::RESULT_COUNT);
   base::UmaHistogramEnumeration(
-      model_utils::AddHistogramSuffix(page.client_id,
-                                      "OfflinePages.SavePageResult"),
+      model_utils::AddHistogramSuffix(client_id, "OfflinePages.SavePageResult"),
       result, SavePageResult::RESULT_COUNT);
 
   if (result == SavePageResult::ARCHIVE_CREATION_FAILED)
     CreateArchivesDirectoryIfNeeded();
   if (!callback.is_null())
-    callback.Run(result, page.offline_id);
+    callback.Run(result, offline_id);
 }
 
 void OfflinePageModelTaskified::OnCreateArchiveDone(
+    const SavePageParams& save_page_params,
+    int64_t offline_id,
+    const base::Time& start_time,
     const SavePageCallback& callback,
-    OfflinePageItem proposed_page,
     OfflinePageArchiver* archiver,
     ArchiverResult archiver_result,
     const GURL& saved_url,
     const base::FilePath& file_path,
     const base::string16& title,
     int64_t file_size,
-    const std::string& digest) {
+    const std::string& file_hash) {
+  // Remove the |archiver| from the pending list once it completes creation.
   pending_archivers_.erase(
       std::find_if(pending_archivers_.begin(), pending_archivers_.end(),
                    [archiver](const std::unique_ptr<OfflinePageArchiver>& a) {
@@ -345,22 +372,34 @@
 
   if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
     SavePageResult result = ArchiverResultToSavePageResult(archiver_result);
-    InformSavePageDone(callback, result, proposed_page);
+    InformSavePageDone(callback, result, save_page_params.client_id,
+                       offline_id);
     return;
   }
-  if (proposed_page.url != saved_url) {
+  if (save_page_params.url != saved_url) {
     DVLOG(1) << "Saved URL does not match requested URL.";
     InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED,
-                       proposed_page);
+                       save_page_params.client_id, offline_id);
     return;
   }
-  proposed_page.file_path = file_path;
-  proposed_page.file_size = file_size;
-  proposed_page.title = title;
-  proposed_page.digest = digest;
-  AddPage(proposed_page,
+
+  OfflinePageItem offline_page(saved_url, offline_id,
+                               save_page_params.client_id, file_path, file_size,
+                               start_time);
+  offline_page.title = title;
+  offline_page.digest = file_hash;
+  offline_page.request_origin = save_page_params.request_origin;
+  // Don't record the original URL if it is identical to the final URL. This is
+  // because some websites might route the redirect finally back to itself upon
+  // the completion of certain action, i.e., authentication, in the middle.
+  if (skip_clearing_original_url_for_testing_ ||
+      save_page_params.original_url != offline_page.url) {
+    offline_page.original_url = save_page_params.original_url;
+  }
+
+  AddPage(offline_page,
           base::Bind(&OfflinePageModelTaskified::OnAddPageForSavePageDone,
-                     weak_ptr_factory_.GetWeakPtr(), callback, proposed_page));
+                     weak_ptr_factory_.GetWeakPtr(), callback, offline_page));
 }
 
 void OfflinePageModelTaskified::OnAddPageForSavePageDone(
@@ -370,12 +409,20 @@
     int64_t offline_id) {
   SavePageResult save_page_result =
       AddPageResultToSavePageResult(add_page_result);
-  InformSavePageDone(callback, save_page_result, page_attempted);
+  InformSavePageDone(callback, save_page_result, page_attempted.client_id,
+                     offline_id);
   if (save_page_result == SavePageResult::SUCCESS) {
     ReportPageHistogramAfterSuccessfulSaving(page_attempted, GetCurrentTime());
-    RemovePagesMatchingUrlAndNamespace(page_attempted);
+    // TODO(romax): Just keep the same with logic in OPMImpl (which was wrong).
+    // This should be fixed once we have the new strategy for clearing pages.
+    if (policy_controller_->GetPolicy(page_attempted.client_id.name_space)
+            .pages_allowed_per_url != kUnlimitedPages) {
+      RemovePagesMatchingUrlAndNamespace(page_attempted);
+      PostClearCachedPagesTask(false /* is_initializing */);
+    }
+  } else {
+    PostClearCachedPagesTask(false /* is_initializing */);
   }
-  PostClearCachedPagesTask(false /* is_initializing */);
 }
 
 void OfflinePageModelTaskified::OnAddPageDone(const OfflinePageItem& page,
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.h b/components/offline_pages/core/model/offline_page_model_taskified.h
index f9f0cb6..7595d90 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified.h
+++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -131,6 +131,12 @@
 
   // Methods for testing only:
   OfflinePageMetadataStoreSQL* GetStoreForTesting() { return store_.get(); }
+  void SetClockForTesting(std::unique_ptr<base::Clock> clock) {
+    clock_ = std::move(clock);
+  }
+  void SetSkipClearingOriginalUrlForTesting() {
+    skip_clearing_original_url_for_testing_ = true;
+  }
 
  private:
   // TODO(romax): https://crbug.com/791115, remove the friend class usage.
@@ -139,13 +145,16 @@
   // Callbacks for saving pages.
   void InformSavePageDone(const SavePageCallback& calback,
                           SavePageResult result,
-                          const OfflinePageItem& page);
+                          const ClientId& client_id,
+                          int64_t offline_id);
   void OnAddPageForSavePageDone(const SavePageCallback& callback,
                                 const OfflinePageItem& page_attempted,
                                 AddPageResult add_page_result,
                                 int64_t offline_id);
-  void OnCreateArchiveDone(const SavePageCallback& callback,
-                           OfflinePageItem proposed_page,
+  void OnCreateArchiveDone(const SavePageParams& save_page_params,
+                           int64_t offline_id,
+                           const base::Time& start_time,
+                           const SavePageCallback& callback,
                            OfflinePageArchiver* archiver,
                            OfflinePageArchiver::ArchiverResult archiver_result,
                            const GURL& saved_url,
@@ -208,18 +217,23 @@
   // destructed after the |task_queue_|.
   std::vector<std::unique_ptr<OfflinePageArchiver>> pending_archivers_;
 
-  // The task queue used for executing various tasks.
-  TaskQueue task_queue_;
+  // Clock for testing only.
+  std::unique_ptr<base::Clock> clock_;
 
   // Logger to facilitate recording of events.
   OfflinePageModelEventLogger offline_event_logger_;
 
+  // The task queue used for executing various tasks.
+  TaskQueue task_queue_;
+
   // Time of when the most recent cached pages clearing happened. The value will
   // not persist across Chrome restarts.
   base::Time last_clear_cached_pages_time_;
 
-  // Clock for testing only.
-  std::unique_ptr<base::Clock> clock_;
+  // For testing only.
+  // This value will be affecting the CreateArchiveTasks that are created by the
+  // model to skip saving original_urls.
+  bool skip_clearing_original_url_for_testing_;
 
   base::WeakPtrFactory<OfflinePageModelTaskified> weak_ptr_factory_;
 
@@ -228,4 +242,4 @@
 
 }  // namespace offline_pages
 
-#endif  // COMPONENTS_OFFLINE_PAGES_CORE_MODEL_OFFLINE_PAGE_MODEL_IMPL_TASKIFIED_H_
+#endif  // COMPONENTS_OFFLINE_PAGES_CORE_MODEL_OFFLINE_PAGE_MODEL_TASKIFIED_H_
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
index 836c37e6..b130277 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
+++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -650,6 +650,37 @@
       2);
 }
 
+TEST_F(OfflinePageModelTaskifiedTest, SavePageOnBackground) {
+  auto archiver = BuildArchiver(kTestUrl, ArchiverResult::SUCCESSFULLY_CREATED);
+  OfflinePageTestArchiver* archiver_ptr = archiver.get();
+
+  OfflinePageModel::SavePageParams save_page_params;
+  save_page_params.url = kTestUrl;
+  save_page_params.client_id = kTestClientId1;
+  save_page_params.original_url = kTestUrl2;
+  save_page_params.is_background = true;
+  save_page_params.use_page_problem_detectors = false;
+
+  base::MockCallback<SavePageCallback> callback;
+  EXPECT_CALL(callback, Run(Eq(SavePageResult::SUCCESS), A<int64_t>()));
+  model()->SavePage(save_page_params, std::move(archiver), callback.Get());
+  EXPECT_TRUE(archiver_ptr->create_archive_called());
+  // |remove_popup_overlay| should be turned on on background mode.
+  EXPECT_TRUE(archiver_ptr->create_archive_params().remove_popup_overlay);
+
+  PumpLoop();
+}
+
+TEST_F(OfflinePageModelTaskifiedTest, SavePageWithNullArchiver) {
+  SavePageWithExpectedResult(kTestUrl, kTestClientId1, GURL(),
+                             kEmptyRequestOrigin, nullptr,
+                             SavePageResult::CONTENT_UNAVAILABLE);
+  histogram_tester()->ExpectUniqueSample(
+      model_utils::AddHistogramSuffix(kTestClientId1,
+                                      "OfflinePages.SavePageResult"),
+      static_cast<int>(SavePageResult::CONTENT_UNAVAILABLE), 1);
+}
+
 TEST_F(OfflinePageModelTaskifiedTest, AddPage) {
   // Creates a fresh page.
   page_generator()->SetArchiveDirectory(temporary_dir_path());
diff --git a/components/payments/content/payment_request_dialog.h b/components/payments/content/payment_request_dialog.h
index c734139..04603fa 100644
--- a/components/payments/content/payment_request_dialog.h
+++ b/components/payments/content/payment_request_dialog.h
@@ -25,6 +25,8 @@
 
   virtual void ShowErrorMessage() = 0;
 
+  virtual void ShowProcessingSpinner() = 0;
+
   // Shows the CVC unmask sheet and starts a FullCardRequest with the info
   // entered by the user.
   virtual void ShowCvcUnmaskPrompt(
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc
index 572b2d1..d6e3e85 100644
--- a/components/payments/content/payment_request_state.cc
+++ b/components/payments/content/payment_request_state.cc
@@ -92,7 +92,7 @@
     std::unique_ptr<ServiceWorkerPaymentInstrument> instrument =
         std::make_unique<ServiceWorkerPaymentInstrument>(
             context, top_level_origin, frame_origin, spec_,
-            std::move(app.second));
+            std::move(app.second), payment_request_delegate_);
     instrument->ValidateCanMakePayment(
         base::BindOnce(&PaymentRequestState::OnSWPaymentInstrumentValidated,
                        weak_ptr_factory_.GetWeakPtr()));
diff --git a/components/payments/content/service_worker_payment_instrument.cc b/components/payments/content/service_worker_payment_instrument.cc
index 3016941..9ef9fe2 100644
--- a/components/payments/content/service_worker_payment_instrument.cc
+++ b/components/payments/content/service_worker_payment_instrument.cc
@@ -7,6 +7,7 @@
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/payments/content/payment_request_converter.h"
+#include "components/payments/core/payment_request_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/payment_app_provider.h"
 #include "ui/gfx/image/image_skia.h"
@@ -20,7 +21,8 @@
     const GURL& top_level_origin,
     const GURL& frame_origin,
     const PaymentRequestSpec* spec,
-    std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info)
+    std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info,
+    PaymentRequestDelegate* payment_request_delegate)
     : PaymentInstrument(0, PaymentInstrument::Type::SERVICE_WORKER_APP),
       browser_context_(context),
       top_level_origin_(top_level_origin),
@@ -28,6 +30,7 @@
       spec_(spec),
       stored_payment_app_info_(std::move(stored_payment_app_info)),
       delegate_(nullptr),
+      payment_request_delegate_(payment_request_delegate),
       can_make_payment_result_(false),
       weak_ptr_factory_(this) {
   DCHECK(browser_context_);
@@ -147,6 +150,8 @@
       CreatePaymentRequestEventData(),
       base::BindOnce(&ServiceWorkerPaymentInstrument::OnPaymentAppInvoked,
                      weak_ptr_factory_.GetWeakPtr()));
+
+  payment_request_delegate_->ShowProcessingSpinner();
 }
 
 mojom::PaymentRequestEventDataPtr
diff --git a/components/payments/content/service_worker_payment_instrument.h b/components/payments/content/service_worker_payment_instrument.h
index 4fad70c0..f599ee4 100644
--- a/components/payments/content/service_worker_payment_instrument.h
+++ b/components/payments/content/service_worker_payment_instrument.h
@@ -14,6 +14,8 @@
 
 namespace payments {
 
+class PaymentRequestDelegate;
+
 // Represents a service worker based payment app.
 class ServiceWorkerPaymentInstrument : public PaymentInstrument {
  public:
@@ -22,7 +24,8 @@
       const GURL& top_level_origin,
       const GURL& frame_origin,
       const PaymentRequestSpec* spec,
-      std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info);
+      std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info,
+      PaymentRequestDelegate* payment_request_delegate);
   ~ServiceWorkerPaymentInstrument() override;
 
   // The callback for ValidateCanMakePayment.
@@ -76,6 +79,9 @@
   // PaymentRequestState which also owns PaymentResponseHelper.
   Delegate* delegate_;
 
+  // Weak pointer that must outlive this object.
+  PaymentRequestDelegate* payment_request_delegate_;
+
   // PaymentAppProvider::CanMakePayment result of this payment instrument.
   bool can_make_payment_result_;
 
diff --git a/components/payments/content/service_worker_payment_instrument_unittest.cc b/components/payments/content/service_worker_payment_instrument_unittest.cc
index fa3b43d..8139d58e 100644
--- a/components/payments/content/service_worker_payment_instrument_unittest.cc
+++ b/components/payments/content/service_worker_payment_instrument_unittest.cc
@@ -6,13 +6,48 @@
 
 #include <memory>
 
+#include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/payments/core/payment_request_delegate.h"
 #include "content/public/browser/stored_payment_app.h"
 #include "content/public/test/test_browser_context.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/modules/payments/payment_request.mojom.h"
 
 namespace payments {
+namespace {
+
+class MockPaymentRequestDelegate : public PaymentRequestDelegate {
+ public:
+  MockPaymentRequestDelegate() {}
+  ~MockPaymentRequestDelegate() override {}
+  MOCK_METHOD1(ShowDialog, void(PaymentRequest* request));
+  MOCK_METHOD0(CloseDialog, void());
+  MOCK_METHOD0(ShowErrorMessage, void());
+  MOCK_METHOD0(ShowProcessingSpinner, void());
+  MOCK_CONST_METHOD0(IsBrowserWindowActive, bool());
+  MOCK_METHOD0(GetPersonalDataManager, autofill::PersonalDataManager*());
+  MOCK_CONST_METHOD0(GetApplicationLocale, const std::string&());
+  MOCK_CONST_METHOD0(IsIncognito, bool());
+  MOCK_METHOD0(IsSslCertificateValid, bool());
+  MOCK_CONST_METHOD0(GetLastCommittedURL, const GURL&());
+  MOCK_METHOD2(
+      DoFullCardRequest,
+      void(const autofill::CreditCard& credit_card,
+           base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
+               result_delegate));
+  MOCK_METHOD0(GetAddressNormalizer, autofill::AddressNormalizer*());
+  MOCK_METHOD0(GetRegionDataLoader, autofill::RegionDataLoader*());
+  MOCK_METHOD0(GetUkmRecorder, ukm::UkmRecorder*());
+  MOCK_CONST_METHOD0(GetAuthenticatedEmail, std::string());
+  MOCK_METHOD0(GetPrefService, PrefService*());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockPaymentRequestDelegate);
+};
+
+}  // namespace
 
 class ServiceWorkerPaymentInstrumentTest : public testing::Test,
                                            public PaymentRequestSpec::Observer {
@@ -107,7 +142,7 @@
     instrument_ = std::make_unique<ServiceWorkerPaymentInstrument>(
         &browser_context_, GURL("https://testmerchant.com"),
         GURL("https://testmerchant.com/bobpay"), spec_.get(),
-        std::move(stored_app));
+        std::move(stored_app), &delegate_);
   }
 
   ServiceWorkerPaymentInstrument* GetInstrument() { return instrument_.get(); }
@@ -121,6 +156,7 @@
   }
 
  private:
+  MockPaymentRequestDelegate delegate_;
   content::TestBrowserContext browser_context_;
 
   std::unique_ptr<PaymentRequestSpec> spec_;
diff --git a/components/payments/content/test_content_payment_request_delegate.cc b/components/payments/content/test_content_payment_request_delegate.cc
index fcd4659..f7e36aa 100644
--- a/components/payments/content/test_content_payment_request_delegate.cc
+++ b/components/payments/content/test_content_payment_request_delegate.cc
@@ -36,6 +36,10 @@
   core_delegate_.ShowErrorMessage();
 }
 
+void TestContentPaymentRequestDelegate::ShowProcessingSpinner() {
+  core_delegate_.ShowProcessingSpinner();
+}
+
 bool TestContentPaymentRequestDelegate::IsBrowserWindowActive() const {
   return core_delegate_.IsBrowserWindowActive();
 }
diff --git a/components/payments/content/test_content_payment_request_delegate.h b/components/payments/content/test_content_payment_request_delegate.h
index aa7ba30..13e21ac 100644
--- a/components/payments/content/test_content_payment_request_delegate.h
+++ b/components/payments/content/test_content_payment_request_delegate.h
@@ -27,6 +27,7 @@
   void ShowDialog(PaymentRequest* request) override;
   void CloseDialog() override;
   void ShowErrorMessage() override;
+  void ShowProcessingSpinner() override;
   bool IsBrowserWindowActive() const override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   const std::string& GetApplicationLocale() const override;
diff --git a/components/payments/core/payment_request_delegate.h b/components/payments/core/payment_request_delegate.h
index 4fb695c..13c5d9c 100644
--- a/components/payments/core/payment_request_delegate.h
+++ b/components/payments/core/payment_request_delegate.h
@@ -26,6 +26,9 @@
   // failed.
   virtual void ShowErrorMessage() = 0;
 
+  // Disables user interaction by showing a spinner.
+  virtual void ShowProcessingSpinner() = 0;
+
   // Returns whether the browser window is active.
   virtual bool IsBrowserWindowActive() const = 0;
 };
diff --git a/components/payments/core/test_payment_request_delegate.h b/components/payments/core/test_payment_request_delegate.h
index 47f947c..382fad46 100644
--- a/components/payments/core/test_payment_request_delegate.h
+++ b/components/payments/core/test_payment_request_delegate.h
@@ -53,6 +53,7 @@
   void ShowDialog(PaymentRequest* request) override {}
   void CloseDialog() override {}
   void ShowErrorMessage() override {}
+  void ShowProcessingSpinner() override {}
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   const std::string& GetApplicationLocale() const override;
   bool IsIncognito() const override;
diff --git a/components/previews/content/previews_io_data.cc b/components/previews/content/previews_io_data.cc
index 9d5ed7a6..7f85fac 100644
--- a/components/previews/content/previews_io_data.cc
+++ b/components/previews/content/previews_io_data.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
@@ -18,6 +19,7 @@
 #include "components/previews/content/previews_ui_service.h"
 #include "components/previews/core/previews_experiments.h"
 #include "components/previews/core/previews_opt_out_store.h"
+#include "components/previews/core/previews_switches.h"
 #include "components/previews/core/previews_user_data.h"
 #include "net/base/load_flags.h"
 #include "net/nqe/network_quality_estimator.h"
@@ -77,12 +79,17 @@
   return false;
 }
 
+bool IsPreviewsBlacklistIgnoredViaFlag() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kIgnorePreviewsBlacklist);
+}
+
 }  // namespace
 
 PreviewsIOData::PreviewsIOData(
     const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
     const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
-    : blacklist_ignored_(false),
+    : blacklist_ignored_(IsPreviewsBlacklistIgnoredViaFlag()),
       ui_task_runner_(ui_task_runner),
       io_task_runner_(io_task_runner),
       page_id_(1u),
diff --git a/components/previews/content/previews_io_data_unittest.cc b/components/previews/content/previews_io_data_unittest.cc
index b00298ad..bb684dc9 100644
--- a/components/previews/content/previews_io_data_unittest.cc
+++ b/components/previews/content/previews_io_data_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
+#include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/field_trial.h"
@@ -19,6 +20,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/test/histogram_tester.h"
+#include "base/test/scoped_command_line.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -33,6 +35,7 @@
 #include "components/previews/core/previews_features.h"
 #include "components/previews/core/previews_logger.h"
 #include "components/previews/core/previews_opt_out_store.h"
+#include "components/previews/core/previews_switches.h"
 #include "components/previews/core/previews_user_data.h"
 #include "components/variations/variations_associated_data.h"
 #include "net/base/load_flags.h"
@@ -327,8 +330,9 @@
  public:
   PreviewsIODataTest()
       : field_trial_list_(nullptr),
-        io_data_(scoped_task_environment_.GetMainThreadTaskRunner(),
-                 scoped_task_environment_.GetMainThreadTaskRunner()),
+        io_data_(base::MakeUnique<TestPreviewsIOData>(
+            scoped_task_environment_.GetMainThreadTaskRunner(),
+            scoped_task_environment_.GetMainThreadTaskRunner())),
         optimization_guide_service_(
             scoped_task_environment_.GetMainThreadTaskRunner()),
         context_(true) {
@@ -345,9 +349,15 @@
     variations::testing::ClearAllVariationParams();
   }
 
+  void InitializeIOData() {
+    io_data_ = base::MakeUnique<TestPreviewsIOData>(
+        scoped_task_environment_.GetMainThreadTaskRunner(),
+        scoped_task_environment_.GetMainThreadTaskRunner());
+  }
+
   void InitializeUIServiceWithoutWaitingForBlackList() {
     ui_service_.reset(new TestPreviewsUIService(
-        &io_data_, scoped_task_environment_.GetMainThreadTaskRunner(),
+        io_data_.get(), scoped_task_environment_.GetMainThreadTaskRunner(),
         base::MakeUnique<TestPreviewsOptOutStore>(),
         base::MakeUnique<TestPreviewsOptimizationGuide>(
             &optimization_guide_service_,
@@ -381,7 +391,7 @@
     return request;
   }
 
-  TestPreviewsIOData* io_data() { return &io_data_; }
+  TestPreviewsIOData* io_data() { return io_data_.get(); }
   TestPreviewsUIService* ui_service() { return ui_service_.get(); }
   net::TestURLRequestContext* context() { return &context_; }
   net::TestNetworkQualityEstimator* network_quality_estimator() {
@@ -391,7 +401,7 @@
  private:
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   base::FieldTrialList field_trial_list_;
-  TestPreviewsIOData io_data_;
+  std::unique_ptr<TestPreviewsIOData> io_data_;
   optimization_guide::OptimizationGuideService optimization_guide_service_;
   std::unique_ptr<TestPreviewsUIService> ui_service_;
   net::TestNetworkQualityEstimator network_quality_estimator_;
@@ -1084,6 +1094,35 @@
   }
 }
 
+TEST_F(PreviewsIODataTest, IgnoreBlacklistEnabledViaFlag) {
+  base::test::ScopedCommandLine scoped_command_line;
+  base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
+  command_line->AppendSwitch(switches::kIgnorePreviewsBlacklist);
+  ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kIgnorePreviewsBlacklist));
+
+  InitializeIOData();
+  InitializeUIService();
+
+  CreateFieldTrialWithParams("PreviewsClientLoFi", "Enabled", {});
+  std::unique_ptr<TestPreviewsBlackList> blacklist =
+      base::MakeUnique<TestPreviewsBlackList>(
+          PreviewsEligibilityReason::HOST_BLACKLISTED, io_data());
+  io_data()->InjectTestBlacklist(std::move(blacklist));
+  network_quality_estimator()->set_effective_connection_type(
+      net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+  auto expected_reason = PreviewsEligibilityReason::ALLOWED;
+  EXPECT_TRUE(io_data()->ShouldAllowPreviewAtECT(
+      *CreateRequest(), PreviewsType::LOFI,
+      params::EffectiveConnectionTypeThresholdForClientLoFi(),
+      params::GetBlackListedHostsForClientLoFiFieldTrial()));
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_THAT(ui_service()->decision_reasons(),
+              ::testing::Contains(expected_reason));
+}
+
 TEST_F(PreviewsIODataTest, LogDecisionMadeAllowPreviewsOnECT) {
   InitializeUIService();
   CreateFieldTrialWithParams("PreviewsClientLoFi", "Enabled", {});
diff --git a/components/previews/core/BUILD.gn b/components/previews/core/BUILD.gn
index 7d77e83..fa7217d 100644
--- a/components/previews/core/BUILD.gn
+++ b/components/previews/core/BUILD.gn
@@ -21,6 +21,8 @@
     "previews_opt_out_store.h",
     "previews_opt_out_store_sql.cc",
     "previews_opt_out_store_sql.h",
+    "previews_switches.cc",
+    "previews_switches.h",
     "previews_user_data.cc",
     "previews_user_data.h",
   ]
diff --git a/components/previews/core/previews_logger.cc b/components/previews/core/previews_logger.cc
index f1520e2..ad51f6ef 100644
--- a/components/previews/core/previews_logger.cc
+++ b/components/previews/core/previews_logger.cc
@@ -4,9 +4,11 @@
 
 #include "components/previews/core/previews_logger.h"
 
+#include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
 #include "components/previews/core/previews_logger_observer.h"
+#include "components/previews/core/previews_switches.h"
 
 namespace previews {
 
@@ -101,7 +103,9 @@
       time(other.time),
       page_id(other.page_id) {}
 
-PreviewsLogger::PreviewsLogger() : blacklist_ignored_(false) {}
+PreviewsLogger::PreviewsLogger()
+    : blacklist_ignored_(base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIgnorePreviewsBlacklist)) {}
 
 PreviewsLogger::~PreviewsLogger() {}
 
diff --git a/components/previews/core/previews_logger_unittest.cc b/components/previews/core/previews_logger_unittest.cc
index 8d31b9a4..75c5540 100644
--- a/components/previews/core/previews_logger_unittest.cc
+++ b/components/previews/core/previews_logger_unittest.cc
@@ -8,12 +8,15 @@
 #include <unordered_map>
 #include <vector>
 
+#include "base/command_line.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_split.h"
+#include "base/test/scoped_command_line.h"
 #include "base/time/time.h"
 #include "components/previews/core/previews_black_list.h"
 #include "components/previews/core/previews_logger_observer.h"
+#include "components/previews/core/previews_switches.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace previews {
@@ -734,6 +737,31 @@
   EXPECT_TRUE(observer.blacklist_ignored());
 }
 
+TEST_F(PreviewsLoggerTest,
+       ObserverNotifiedOfBlacklistIgnoreStatusDisabledViaFlag) {
+  ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kIgnorePreviewsBlacklist));
+
+  TestPreviewsLoggerObserver observer;
+  PreviewsLogger logger;
+  logger.AddAndNotifyObserver(&observer);
+  EXPECT_FALSE(observer.blacklist_ignored());
+}
+
+TEST_F(PreviewsLoggerTest,
+       ObserverNotifiedOfBlacklistIgnoreStatusEnabledViaFlag) {
+  base::test::ScopedCommandLine scoped_command_line;
+  base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
+  command_line->AppendSwitch(switches::kIgnorePreviewsBlacklist);
+  ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kIgnorePreviewsBlacklist));
+
+  TestPreviewsLoggerObserver observer;
+  PreviewsLogger logger;
+  logger.AddAndNotifyObserver(&observer);
+  EXPECT_TRUE(observer.blacklist_ignored());
+}
+
 TEST_F(PreviewsLoggerTest, LastObserverRemovedIsNotified) {
   TestPreviewsLoggerObserver observers[3];
   const size_t number_of_obs = 3;
diff --git a/components/previews/core/previews_switches.cc b/components/previews/core/previews_switches.cc
new file mode 100644
index 0000000..de4e7155
--- /dev/null
+++ b/components/previews/core/previews_switches.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/previews/core/previews_switches.h"
+
+namespace previews {
+namespace switches {
+
+// Ignore decisions made by PreviewsBlackList.
+const char kIgnorePreviewsBlacklist[] = "ignore-previews-blacklist";
+
+}  // namespace switches
+}  // namespace previews
diff --git a/components/previews/core/previews_switches.h b/components/previews/core/previews_switches.h
new file mode 100644
index 0000000..f95a061
--- /dev/null
+++ b/components/previews/core/previews_switches.h
@@ -0,0 +1,16 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PREVIEWS_CORE_PREVIEWS_SWITCHES_H_
+#define COMPONENTS_PREVIEWS_CORE_PREVIEWS_SWITCHES_H_
+
+namespace previews {
+namespace switches {
+
+extern const char kIgnorePreviewsBlacklist[];
+
+}  // namespace switches
+}  // namespace previews
+
+#endif  // COMPONENTS_PREVIEWS_CORE_PREVIEWS_SWITCHES_H_
diff --git a/components/previews/core/previews_user_data.cc b/components/previews/core/previews_user_data.cc
index 37cb2e83..d1374b8 100644
--- a/components/previews/core/previews_user_data.cc
+++ b/components/previews/core/previews_user_data.cc
@@ -5,17 +5,39 @@
 #include "components/previews/core/previews_user_data.h"
 
 #include "base/memory/ptr_util.h"
+#include "base/values.h"
 #include "net/url_request/url_request.h"
 
 namespace previews {
 
+namespace {
 const void* const kPreviewsUserDataKey = &kPreviewsUserDataKey;
+const char* kPageIdKey = "page_id";
+const char* kCommittedPreviewsTypeKey = "committed_previews_type";
+}  // namespace
 
 PreviewsUserData::PreviewsUserData(uint64_t page_id)
     : page_id_(page_id), committed_previews_type_(PreviewsType::NONE) {}
 
 PreviewsUserData::~PreviewsUserData() {}
 
+base::Value PreviewsUserData::ToValue() {
+  base::Value value(base::Value::Type::DICTIONARY);
+
+  // Store |page_id_| as a string because base::Value can't store a 64 bits
+  // integer.
+  value.SetKey(kPageIdKey, base::Value(std::to_string(page_id_)));
+  value.SetKey(kCommittedPreviewsTypeKey,
+               base::Value((int)committed_previews_type_));
+
+  return value;
+}
+
+PreviewsUserData::PreviewsUserData(const base::Value& value)
+    : page_id_(std::stoll(value.FindKey(kPageIdKey)->GetString())),
+      committed_previews_type_(
+          (PreviewsType)value.FindKey(kCommittedPreviewsTypeKey)->GetInt()) {}
+
 std::unique_ptr<PreviewsUserData> PreviewsUserData::DeepCopy() const {
   std::unique_ptr<PreviewsUserData> copy(new PreviewsUserData(page_id_));
   copy->SetCommittedPreviewsType(committed_previews_type_);
diff --git a/components/previews/core/previews_user_data.h b/components/previews/core/previews_user_data.h
index a1fdc83..bd8aa66 100644
--- a/components/previews/core/previews_user_data.h
+++ b/components/previews/core/previews_user_data.h
@@ -11,6 +11,10 @@
 #include "base/supports_user_data.h"
 #include "components/previews/core/previews_experiments.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 class URLRequest;
 }
@@ -23,6 +27,10 @@
   PreviewsUserData(uint64_t page_id);
   ~PreviewsUserData() override;
 
+  // Convert from/to a base::Value.
+  base::Value ToValue();
+  explicit PreviewsUserData(const base::Value& value);
+
   // Makes a deep copy.
   std::unique_ptr<PreviewsUserData> DeepCopy() const;
 
diff --git a/components/previews/core/previews_user_data_unittest.cc b/components/previews/core/previews_user_data_unittest.cc
index 2301929..6bfb7cd 100644
--- a/components/previews/core/previews_user_data_unittest.cc
+++ b/components/previews/core/previews_user_data_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
+#include "base/values.h"
 #include "net/base/request_priority.h"
 #include "net/nqe/effective_connection_type.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -60,6 +61,29 @@
   EXPECT_EQ(id, data->DeepCopy()->page_id());
 }
 
+TEST_F(PreviewsUserDataTest, Serialization) {
+  // page_id
+  {
+    PreviewsUserData data(1ull << 60);
+    PreviewsUserData clone(data.ToValue());
+
+    EXPECT_EQ(1ull << 60, data.page_id());
+    EXPECT_EQ(1ull << 60, clone.page_id());
+  }
+
+  // page_id
+  {
+    PreviewsUserData data(0ull);
+    PreviewsUserData clone_a(data.ToValue());
+    data.SetCommittedPreviewsType(PreviewsType::OFFLINE);
+    PreviewsUserData clone_b(data.ToValue());
+
+    EXPECT_FALSE(clone_a.HasCommittedPreviewsType());
+    EXPECT_TRUE(clone_b.HasCommittedPreviewsType());
+    EXPECT_EQ(PreviewsType::OFFLINE, clone_b.GetCommittedPreviewsType());
+  }
+}
+
 }  // namespace
 
 }  // namespace previews
diff --git a/components/printing/service/BUILD.gn b/components/printing/service/BUILD.gn
index 4043453..e18edb1 100644
--- a/components/printing/service/BUILD.gn
+++ b/components/printing/service/BUILD.gn
@@ -45,19 +45,21 @@
       "pdf_compositor_service_unittest.cc",
     ]
 
-    include_dirs = [ "testing/gmock/include" ]
+    include_dirs = [
+      "//skia/config",
+      "//testing/gmock/include",
+      "//third_party/skia/include/core",
+    ]
     deps = [
       ":service",
       "//base/test:test_support",
+      "//cc/paint:paint",
       "//components/printing/service/public/interfaces",
       "//mojo/common",
       "//services/service_manager/public/cpp:service_test_support",
       "//testing/gmock",
       "//testing/gtest",
     ]
-    data = [
-      "//components/test/data/printing/google.mskp",
-    ]
   }
 
   service_manifest("pdf_compositor_service_unittest_manifest") {
diff --git a/components/printing/service/DEPS b/components/printing/service/DEPS
index 0145b6a4..b576620 100644
--- a/components/printing/service/DEPS
+++ b/components/printing/service/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+cc/paint",
   "+components/discardable_memory/client",
   "+content/public/child",  # Windows direct write proxy access.
   "+content/public/utility",
diff --git a/components/printing/service/pdf_compositor_service_unittest.cc b/components/printing/service/pdf_compositor_service_unittest.cc
index 3b15e55..50c1cce 100644
--- a/components/printing/service/pdf_compositor_service_unittest.cc
+++ b/components/printing/service/pdf_compositor_service_unittest.cc
@@ -11,6 +11,8 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/test/test_discardable_memory_allocator.h"
+#include "cc/paint/paint_flags.h"
+#include "cc/paint/skia_paint_canvas.h"
 #include "components/printing/service/pdf_compositor_service.h"
 #include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
@@ -21,6 +23,8 @@
 #include "services/service_manager/public/interfaces/service_factory.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkStream.h"
+#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
 
 namespace printing {
 
@@ -117,29 +121,34 @@
     return std::make_unique<PdfServiceTestClient>(this);
   }
 
-  base::SharedMemoryHandle LoadFileInSharedMemory() {
-    base::FilePath path;
-    PathService::Get(base::DIR_SOURCE_ROOT, &path);
-    base::FilePath test_file =
-        path.AppendASCII("components/test/data/printing/google.mskp");
-    std::string content;
-    base::SharedMemoryHandle invalid_handle;
-    if (!base::ReadFileToString(test_file, &content))
-      return invalid_handle;
-    size_t len = content.size();
+  base::SharedMemoryHandle CreateMSKPInSharedMemory() {
+    SkDynamicMemoryWStream stream;
+    sk_sp<SkDocument> doc = SkMakeMultiPictureDocument(&stream);
+    cc::SkiaPaintCanvas canvas(doc->beginPage(800, 600));
+    SkRect rect = SkRect::MakeXYWH(10, 10, 250, 250);
+    cc::PaintFlags flags;
+    flags.setAntiAlias(false);
+    flags.setColor(SK_ColorRED);
+    flags.setStyle(cc::PaintFlags::kFill_Style);
+    canvas.drawRect(rect, flags);
+    doc->endPage();
+    doc->close();
+
+    size_t len = stream.bytesWritten();
     base::SharedMemoryCreateOptions options;
     options.size = len;
     options.share_read_only = true;
+
     base::SharedMemory shared_memory;
     if (shared_memory.Create(options) && shared_memory.Map(len)) {
-      memcpy(shared_memory.memory(), content.data(), len);
+      stream.copyTo(shared_memory.memory());
       return base::SharedMemory::DuplicateHandle(shared_memory.handle());
     }
-    return invalid_handle;
+    return base::SharedMemoryHandle();
   }
 
   void CallCompositorWithSuccess(mojom::PdfCompositorPtr ptr) {
-    auto handle = LoadFileInSharedMemory();
+    auto handle = CreateMSKPInSharedMemory();
     ASSERT_TRUE(handle.IsValid());
     mojo::ScopedSharedBufferHandle buffer_handle =
         mojo::WrapSharedMemoryHandle(handle, handle.GetSize(), true);
diff --git a/components/security_interstitials/core/browser/resources/interstitial_large.js b/components/security_interstitials/core/browser/resources/interstitial_large.js
index 3deac633..066e8b6 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_large.js
+++ b/components/security_interstitials/core/browser/resources/interstitial_large.js
@@ -13,7 +13,7 @@
  * @param {string} e The key that was just pressed.
  */
 function handleKeypress(e) {
-  var BYPASS_SEQUENCE = 'badidea';
+  var BYPASS_SEQUENCE = 'thisisnotsafe';
   if (BYPASS_SEQUENCE.charCodeAt(keyPressState) == e.keyCode) {
     keyPressState++;
     if (keyPressState == BYPASS_SEQUENCE.length) {
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn
index bd931ba..bcc83e0 100644
--- a/components/signin/core/browser/android/BUILD.gn
+++ b/components/signin/core/browser/android/BUILD.gn
@@ -38,20 +38,16 @@
   ]
 }
 
-android_library("javatests") {
-  testonly = true
+junit_binary("components_signin_junit_tests") {
+  java_files = [ "junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ]
   deps = [
     ":java",
     ":signin_java_test_support",
     "//base:base_java",
     "//base:base_java_test_support",
-    "//third_party/android_support_test_runner:rules_java",
-    "//third_party/android_support_test_runner:runner_java",
     "//third_party/android_tools:android_support_annotations_java",
     "//third_party/junit",
   ]
-
-  java_files = [ "javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ]
 }
 
 android_library("signin_java_test_support") {
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
similarity index 89%
rename from components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
rename to components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
index c5a7198..497fc17 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
+++ b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
@@ -13,17 +13,20 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.test.util.AccountHolder;
 import org.chromium.components.signin.test.util.FakeAccountManagerDelegate;
+import org.chromium.testing.local.CustomShadowAsyncTask;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
 
 /**
  * Test class for {@link AccountManagerFacade}.
  */
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, shadows = {CustomShadowAsyncTask.class})
 public class AccountManagerFacadeTest {
     @Rule
     public UiThreadTestRule mRule = new UiThreadTestRule();
@@ -89,7 +92,8 @@
     private Account addTestAccount(String accountName) {
         Account account = AccountManagerFacade.createAccountFromName(accountName);
         AccountHolder holder = AccountHolder.builder(account).alwaysAccept(true).build();
-        mDelegate.addAccountHolderBlocking(holder);
+        mDelegate.addAccountHolderExplicitly(holder);
+        Assert.assertFalse(AccountManagerFacade.get().isUpdatePending());
         return account;
     }
 }
diff --git a/components/test/data/printing/google.mskp b/components/test/data/printing/google.mskp
deleted file mode 100644
index 2f7d44a..0000000
--- a/components/test/data/printing/google.mskp
+++ /dev/null
Binary files differ
diff --git a/components/viz/client/client_layer_tree_frame_sink.cc b/components/viz/client/client_layer_tree_frame_sink.cc
index e89e538..3131dbd 100644
--- a/components/viz/client/client_layer_tree_frame_sink.cc
+++ b/components/viz/client/client_layer_tree_frame_sink.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/trace_event/trace_event.h"
 #include "cc/trees/layer_tree_frame_sink_client.h"
 #include "components/viz/client/hit_test_data_provider.h"
@@ -104,7 +103,7 @@
   if (synthetic_begin_frame_source_) {
     client->SetBeginFrameSource(synthetic_begin_frame_source_.get());
   } else {
-    begin_frame_source_ = base::MakeUnique<ExternalBeginFrameSource>(this);
+    begin_frame_source_ = std::make_unique<ExternalBeginFrameSource>(this);
     begin_frame_source_->OnSetBeginFrameSourcePaused(begin_frames_paused_);
     client->SetBeginFrameSource(begin_frame_source_.get());
   }
diff --git a/components/viz/client/client_shared_bitmap_manager.cc b/components/viz/client/client_shared_bitmap_manager.cc
index 63b30e7..6c931d5 100644
--- a/components/viz/client/client_shared_bitmap_manager.cc
+++ b/components/viz/client/client_shared_bitmap_manager.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/debug/alias.h"
-#include "base/memory/ptr_util.h"
 #include "base/process/memory.h"
 #include "base/process/process_metrics.h"
 #include "base/trace_event/trace_event.h"
@@ -106,7 +105,7 @@
     return nullptr;
   }
 
-  return base::MakeUnique<base::SharedMemory>(shared_buf, false);
+  return std::make_unique<base::SharedMemory>(shared_buf, false);
 }
 
 }  // namespace
@@ -138,7 +137,7 @@
   // remains available.
   memory->Close();
 
-  return base::MakeUnique<ClientSharedBitmap>(
+  return std::make_unique<ClientSharedBitmap>(
       shared_bitmap_allocation_notifier_, std::move(memory), id,
       sequence_number);
 }
@@ -154,7 +153,7 @@
 ClientSharedBitmapManager::GetBitmapForSharedMemory(base::SharedMemory* mem) {
   SharedBitmapId id = SharedBitmap::GenerateId();
   uint32_t sequence_number = NotifyAllocatedSharedBitmap(mem, id);
-  return base::MakeUnique<ClientSharedBitmap>(
+  return std::make_unique<ClientSharedBitmap>(
       shared_bitmap_allocation_notifier_, mem, id, sequence_number);
 }
 
diff --git a/components/viz/common/frame_sinks/delay_based_time_source_unittest.cc b/components/viz/common/frame_sinks/delay_based_time_source_unittest.cc
index 5cb092b..47744c91 100644
--- a/components/viz/common/frame_sinks/delay_based_time_source_unittest.cc
+++ b/components/viz/common/frame_sinks/delay_based_time_source_unittest.cc
@@ -21,9 +21,9 @@
 class DelayBasedTimeSourceTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    now_src_ = base::MakeUnique<base::SimpleTestTickClock>();
+    now_src_ = std::make_unique<base::SimpleTestTickClock>();
     task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>();
-    delay_based_time_source_ = base::MakeUnique<FakeDelayBasedTimeSource>(
+    delay_based_time_source_ = std::make_unique<FakeDelayBasedTimeSource>(
         now_src_.get(), task_runner_.get());
     delay_based_time_source_->SetClient(&client_);
   }
diff --git a/components/viz/common/gl_helper.cc b/components/viz/common/gl_helper.cc
index aabade3..e906c6e3 100644
--- a/components/viz/common/gl_helper.cc
+++ b/components/viz/common/gl_helper.cc
@@ -14,7 +14,6 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "base/numerics/safe_conversions.h"
@@ -1215,7 +1214,7 @@
   if (supported == GLHelperReadbackSupport::SWIZZLE)
     swizzle = kSwizzleBGRA;
 
-  return base::MakeUnique<ReadbackYUVImpl>(
+  return std::make_unique<ReadbackYUVImpl>(
       gl_, this, helper_->scaler_impl_.get(), flip_vertically, swizzle,
       use_mrt && (max_draw_buffers_ >= 2));
 }
diff --git a/components/viz/common/gl_helper_scaling.cc b/components/viz/common/gl_helper_scaling.cc
index d4d6d89..6c37e6b7 100644
--- a/components/viz/common/gl_helper_scaling.cc
+++ b/components/viz/common/gl_helper_scaling.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -14,7 +15,6 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "base/optional.h"
@@ -729,7 +729,7 @@
 
   std::unique_ptr<ScalerImpl> ret;
   for (unsigned int i = 0; i < scaler_stages.size(); i++) {
-    ret = base::MakeUnique<ScalerImpl>(gl_, this, scaler_stages[i],
+    ret = std::make_unique<ScalerImpl>(gl_, this, scaler_stages[i],
                                        std::move(ret));
   }
   ret->SetChainProperties(scale_from, scale_to, swizzle);
@@ -744,7 +744,7 @@
       SHADER_PLANAR, gfx::Vector2d(4, 1), gfx::Vector2d(1, 1),
       true,          flipped_source,      flip_output,
       swizzle};
-  auto result = base::MakeUnique<ScalerImpl>(gl_, this, stage, nullptr);
+  auto result = std::make_unique<ScalerImpl>(gl_, this, stage, nullptr);
   result->SetColorWeights(0, kRGBtoGrayscaleColorWeights);
   result->SetChainProperties(stage.scale_from, stage.scale_to, swizzle);
   return result;
@@ -763,7 +763,7 @@
       flipped_source,
       flip_output,
       swizzle};
-  auto result = base::MakeUnique<ScalerImpl>(gl_, this, stage, nullptr);
+  auto result = std::make_unique<ScalerImpl>(gl_, this, stage, nullptr);
   switch (plane) {
     case 0:
       result->SetColorWeights(0, kRGBtoYColorWeights);
@@ -792,7 +792,7 @@
                              flipped_source,
                              flip_output,
                              swizzle};
-  auto result = base::MakeUnique<ScalerImpl>(gl_, this, stage, nullptr);
+  auto result = std::make_unique<ScalerImpl>(gl_, this, stage, nullptr);
   result->SetColorWeights(0, kRGBtoYColorWeights);
   result->SetColorWeights(1, kRGBtoUColorWeights);
   result->SetColorWeights(2, kRGBtoVColorWeights);
@@ -809,7 +809,7 @@
                              false,
                              false,
                              swizzle};
-  auto result = base::MakeUnique<ScalerImpl>(gl_, this, stage, nullptr);
+  auto result = std::make_unique<ScalerImpl>(gl_, this, stage, nullptr);
   result->SetChainProperties(stage.scale_from, stage.scale_to, swizzle);
   return result;
 }
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
index 7872a99..d723de4 100644
--- a/components/viz/host/host_frame_sink_manager.cc
+++ b/components/viz/host/host_frame_sink_manager.cc
@@ -114,7 +114,7 @@
       frame_sink_id, surface_handle, force_software_compositing,
       renderer_settings, std::move(request), std::move(client),
       std::move(display_private_request), std::move(display_client));
-  display_hit_test_query_[frame_sink_id] = base::MakeUnique<HitTestQuery>();
+  display_hit_test_query_[frame_sink_id] = std::make_unique<HitTestQuery>();
 }
 
 void HostFrameSinkManager::CreateCompositorFrameSink(
diff --git a/components/viz/host/host_frame_sink_manager_unittest.cc b/components/viz/host/host_frame_sink_manager_unittest.cc
index d91d44f..c5ae9813 100644
--- a/components/viz/host/host_frame_sink_manager_unittest.cc
+++ b/components/viz/host/host_frame_sink_manager_unittest.cc
@@ -150,8 +150,8 @@
   // testing::Test:
   void SetUp() override {
     manager_impl_ =
-        base::MakeUnique<testing::NiceMock<MockFrameSinkManagerImpl>>();
-    host_manager_ = base::MakeUnique<HostFrameSinkManager>();
+        std::make_unique<testing::NiceMock<MockFrameSinkManagerImpl>>();
+    host_manager_ = std::make_unique<HostFrameSinkManager>();
 
     manager_impl_->SetLocalClient(host_manager_.get());
     host_manager_->SetLocalManager(manager_impl_.get());
@@ -174,7 +174,7 @@
     DCHECK(!manager_impl_);
 
     manager_impl_ =
-        base::MakeUnique<testing::NiceMock<MockFrameSinkManagerImpl>>();
+        std::make_unique<testing::NiceMock<MockFrameSinkManagerImpl>>();
 
     mojom::FrameSinkManagerPtr frame_sink_manager;
     mojom::FrameSinkManagerRequest frame_sink_manager_request =
@@ -193,7 +193,7 @@
 
   // testing::Test:
   void SetUp() override {
-    host_manager_ = base::MakeUnique<HostFrameSinkManager>();
+    host_manager_ = std::make_unique<HostFrameSinkManager>();
     ConnectToGpu();
   }
 
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc
index d5c8f311..dabec1d 100644
--- a/components/viz/service/display/display.cc
+++ b/components/viz/service/display/display.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/trace_event/trace_event.h"
@@ -206,28 +205,28 @@
 }
 
 void Display::InitializeRenderer() {
-  resource_provider_ = base::MakeUnique<cc::DisplayResourceProvider>(
+  resource_provider_ = std::make_unique<cc::DisplayResourceProvider>(
       output_surface_->context_provider(), bitmap_manager_,
       gpu_memory_buffer_manager_, settings_.resource_settings);
 
   if (output_surface_->context_provider()) {
     if (!settings_.use_skia_renderer) {
-      renderer_ = base::MakeUnique<GLRenderer>(
+      renderer_ = std::make_unique<GLRenderer>(
           &settings_, output_surface_.get(), resource_provider_.get(),
           current_task_runner_);
     } else {
-      renderer_ = base::MakeUnique<SkiaRenderer>(
+      renderer_ = std::make_unique<SkiaRenderer>(
           &settings_, output_surface_.get(), resource_provider_.get());
     }
   } else if (output_surface_->vulkan_context_provider()) {
 #if BUILDFLAG(ENABLE_VULKAN)
-    renderer_ = base::MakeUnique<SkiaRenderer>(
+    renderer_ = std::make_unique<SkiaRenderer>(
         &settings_, output_surface_.get(), resource_provider_.get());
 #else
     NOTREACHED();
 #endif
   } else {
-    auto renderer = base::MakeUnique<SoftwareRenderer>(
+    auto renderer = std::make_unique<SoftwareRenderer>(
         &settings_, output_surface_.get(), resource_provider_.get());
     software_renderer_ = renderer.get();
     renderer_ = std::move(renderer);
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc
index d6ce6fc..74051f7 100644
--- a/components/viz/service/display/display_unittest.cc
+++ b/components/viz/service/display/display_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/test/null_task_runner.h"
 #include "cc/base/math_util.h"
@@ -117,12 +116,12 @@
       provider->BindToCurrentThread();
       output_surface = cc::FakeOutputSurface::Create3d(std::move(provider));
     } else {
-      auto device = base::MakeUnique<TestSoftwareOutputDevice>();
+      auto device = std::make_unique<TestSoftwareOutputDevice>();
       software_output_device_ = device.get();
       output_surface = cc::FakeOutputSurface::CreateSoftware(std::move(device));
     }
     output_surface_ = output_surface.get();
-    auto scheduler = base::MakeUnique<TestDisplayScheduler>(
+    auto scheduler = std::make_unique<TestDisplayScheduler>(
         begin_frame_source_.get(), task_runner_.get());
     scheduler_ = scheduler.get();
     display_ = CreateDisplay(settings, kArbitraryFrameSinkId,
@@ -136,7 +135,7 @@
       const FrameSinkId& frame_sink_id,
       std::unique_ptr<DisplayScheduler> scheduler,
       std::unique_ptr<OutputSurface> output_surface) {
-    auto display = base::MakeUnique<Display>(
+    auto display = std::make_unique<Display>(
         &shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
         settings, frame_sink_id, std::move(output_surface),
         std::move(scheduler), task_runner_);
@@ -546,7 +545,7 @@
   settings.partial_swap_enabled = true;
   settings.finish_rendering_on_resize = true;
 
-  auto context = base::MakeUnique<MockedContext>();
+  auto context = std::make_unique<MockedContext>();
   MockedContext* context_ptr = context.get();
   EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
 
@@ -651,14 +650,14 @@
   auto support2 = std::make_unique<CompositorFrameSinkSupport>(
       nullptr, &manager_, kAnotherFrameSinkId, true /* is_root */,
       true /* needs_sync_points */);
-  auto begin_frame_source2 = base::MakeUnique<StubBeginFrameSource>();
-  auto scheduler_for_display2 = base::MakeUnique<TestDisplayScheduler>(
+  auto begin_frame_source2 = std::make_unique<StubBeginFrameSource>();
+  auto scheduler_for_display2 = std::make_unique<TestDisplayScheduler>(
       begin_frame_source2.get(), task_runner_.get());
   TestDisplayScheduler* scheduler2 = scheduler_for_display2.get();
   auto display2 = CreateDisplay(
       settings, kAnotherFrameSinkId, std::move(scheduler_for_display2),
       cc::FakeOutputSurface::CreateSoftware(
-          base::MakeUnique<TestSoftwareOutputDevice>()));
+          std::make_unique<TestSoftwareOutputDevice>()));
   manager_.RegisterBeginFrameSource(begin_frame_source2.get(),
                                     kAnotherFrameSinkId);
   StubDisplayClient client2;
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 3296c7e..31622f8 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -553,7 +553,7 @@
     }
 
     current_sync_query_ = available_sync_queries_.empty()
-                              ? base::MakeUnique<SyncQuery>(gl_)
+                              ? std::make_unique<SyncQuery>(gl_)
                               : cc::PopFront(&available_sync_queries_);
 
     read_lock_fence = current_sync_query_->Begin();
@@ -1385,7 +1385,7 @@
     params->source_needs_flip = params->flip_texture;
   } else {
     params->bypass_quad_resource_lock =
-        base::MakeUnique<cc::DisplayResourceProvider::ScopedSamplerGL>(
+        std::make_unique<cc::DisplayResourceProvider::ScopedSamplerGL>(
             resource_provider_, params->bypass_quad_texture->id(), GL_LINEAR);
     DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
               params->bypass_quad_resource_lock->target());
@@ -2971,8 +2971,8 @@
   gl_->GenFramebuffers(1, &offscreen_framebuffer_id_);
 
   shared_geometry_ =
-      base::MakeUnique<StaticGeometryBinding>(gl_, QuadVertexRect());
-  clipped_geometry_ = base::MakeUnique<DynamicGeometryBinding>(gl_);
+      std::make_unique<StaticGeometryBinding>(gl_, QuadVertexRect());
+  clipped_geometry_ = std::make_unique<DynamicGeometryBinding>(gl_);
 }
 
 void GLRenderer::PrepareGeometry(BoundGeometry binding) {
@@ -3160,7 +3160,7 @@
     unsigned texture_id = 0;
     if (contents_resource_id) {
       pending_overlay_resources_.push_back(
-          base::MakeUnique<cc::DisplayResourceProvider::ScopedReadLockGL>(
+          std::make_unique<cc::DisplayResourceProvider::ScopedReadLockGL>(
               resource_provider_, contents_resource_id));
       texture_id = pending_overlay_resources_.back()->texture_id();
     }
@@ -3217,7 +3217,7 @@
     for (const auto& contents_resource_id : dc_layer_overlay.resources) {
       if (contents_resource_id) {
         pending_overlay_resources_.push_back(
-            base::MakeUnique<cc::DisplayResourceProvider::ScopedReadLockGL>(
+            std::make_unique<cc::DisplayResourceProvider::ScopedReadLockGL>(
                 resource_provider_, contents_resource_id));
         texture_ids[i] = pending_overlay_resources_.back()->texture_id();
         ids_to_send = i + 1;
@@ -3274,7 +3274,7 @@
       DCHECK(texture_id || IsContextLost());
     } else {
       pending_overlay_resources_.push_back(
-          base::MakeUnique<cc::DisplayResourceProvider::ScopedReadLockGL>(
+          std::make_unique<cc::DisplayResourceProvider::ScopedReadLockGL>(
               resource_provider_, overlay_candidate.resource_id));
       texture_id = pending_overlay_resources_.back()->texture_id();
     }
@@ -3450,7 +3450,7 @@
     return;
 
   pending_overlay_resources_.push_back(
-      base::MakeUnique<cc::DisplayResourceProvider::ScopedReadLockGL>(
+      std::make_unique<cc::DisplayResourceProvider::ScopedReadLockGL>(
           resource_provider_, resource->id()));
   unsigned texture_id = pending_overlay_resources_.back()->texture_id();
 
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc
index cabcd4e..df542e8 100644
--- a/components/viz/service/display/gl_renderer_unittest.cc
+++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -6,11 +6,11 @@
 
 #include <stdint.h>
 
+#include <memory>
 #include <set>
 #include <vector>
 
 #include "base/location.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -23,6 +23,7 @@
 #include "cc/test/fake_resource_provider.h"
 #include "cc/test/pixel_test.h"
 #include "cc/test/render_pass_test_utils.h"
+#include "cc/test/resource_provider_test_utils.h"
 #include "cc/test/test_gles2_interface.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_web_graphics_context_3d.h"
@@ -453,7 +454,7 @@
     resource_provider_ =
         cc::FakeResourceProvider::CreateDisplayResourceProvider(
             output_surface_->context_provider(), shared_bitmap_manager_.get());
-    renderer_ = base::MakeUnique<FakeRendererGL>(
+    renderer_ = std::make_unique<FakeRendererGL>(
         &settings_, output_surface_.get(), resource_provider_.get());
     renderer_->Initialize();
     renderer_->SetVisible(true);
@@ -488,6 +489,12 @@
                                        resource_provider_.get()));
     renderer_->Initialize();
     renderer_->SetVisible(true);
+
+    child_context_provider_ = cc::TestContextProvider::Create();
+    child_context_provider_->BindToCurrentThread();
+    child_resource_provider_ =
+        cc::FakeResourceProvider::CreateLayerTreeResourceProvider(
+            child_context_provider_.get(), shared_bitmap_manager_.get());
   }
 
   void TestRenderPassProgram(TexCoordPrecision precision,
@@ -578,6 +585,8 @@
   std::unique_ptr<cc::FakeOutputSurface> output_surface_;
   std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_;
   std::unique_ptr<cc::DisplayResourceProvider> resource_provider_;
+  scoped_refptr<cc::TestContextProvider> child_context_provider_;
+  std::unique_ptr<cc::LayerTreeResourceProvider> child_resource_provider_;
   std::unique_ptr<FakeRendererGL> renderer_;
 };
 
@@ -696,7 +705,7 @@
   }
 };
 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
-  auto context = base::MakeUnique<ForbidSynchronousCallContext>();
+  auto context = std::make_unique<ForbidSynchronousCallContext>();
   auto provider = cc::TestContextProvider::Create(std::move(context));
   provider->BindToCurrentThread();
 
@@ -732,7 +741,7 @@
 };
 
 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
-  auto context = base::MakeUnique<LoseContextOnFirstGetContext>();
+  auto context = std::make_unique<LoseContextOnFirstGetContext>();
   auto provider = cc::TestContextProvider::Create(std::move(context));
   provider->BindToCurrentThread();
 
@@ -1090,7 +1099,7 @@
 };
 
 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
-  auto gl_owned = base::MakeUnique<ScissorTestOnClearCheckingGLES2Interface>();
+  auto gl_owned = std::make_unique<ScissorTestOnClearCheckingGLES2Interface>();
 
   auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
   provider->BindToCurrentThread();
@@ -1165,7 +1174,7 @@
 };
 
 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
-  auto gl_owned = base::MakeUnique<DiscardCheckingGLES2Interface>();
+  auto gl_owned = std::make_unique<DiscardCheckingGLES2Interface>();
   auto* gl = gl_owned.get();
 
   auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
@@ -1365,7 +1374,7 @@
 };
 
 TEST_F(GLRendererTest, NoResourceLeak) {
-  auto gl_owned = base::MakeUnique<ResourceTrackingGLES2Interface>();
+  auto gl_owned = std::make_unique<ResourceTrackingGLES2Interface>();
   auto* gl = gl_owned.get();
 
   auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
@@ -1417,7 +1426,7 @@
 class GLRendererSkipTest : public GLRendererTest {
  protected:
   GLRendererSkipTest() {
-    auto gl_owned = base::MakeUnique<StrictMock<DrawElementsGLES2Interface>>();
+    auto gl_owned = std::make_unique<StrictMock<DrawElementsGLES2Interface>>();
     gl_ = gl_owned.get();
 
     auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
@@ -1431,7 +1440,7 @@
         cc::FakeResourceProvider::CreateDisplayResourceProvider(
             output_surface_->context_provider(), shared_bitmap_manager_.get());
     settings_.partial_swap_enabled = true;
-    renderer_ = base::MakeUnique<FakeRendererGL>(
+    renderer_ = std::make_unique<FakeRendererGL>(
         &settings_, output_surface_.get(), resource_provider_.get());
     renderer_->Initialize();
     renderer_->SetVisible(true);
@@ -1559,10 +1568,16 @@
   int root_pass_id = 1;
   RenderPass* root_pass;
 
-  ResourceId mask = resource_provider_->CreateGpuTextureResource(
+  ResourceId mask = child_resource_provider_->CreateGpuTextureResource(
       gfx::Size(20, 12), ResourceTextureHint::kDefault,
-      resource_provider_->best_texture_format(), gfx::ColorSpace());
-  resource_provider_->AllocateForTesting(mask);
+      child_resource_provider_->best_texture_format(), gfx::ColorSpace());
+  child_resource_provider_->AllocateForTesting(mask);
+
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({mask}, resource_provider_.get(),
+                                         child_resource_provider_.get());
+  ResourceId mapped_mask = resource_map[mask];
 
   SkScalar matrix[20];
   float amount = 0.5f;
@@ -1639,7 +1654,7 @@
                                   gfx::Rect(viewport_size), gfx::Transform(),
                                   cc::FilterOperations());
 
-    cc::AddRenderPassQuad(root_pass, child_pass, mask, gfx::Transform(),
+    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask, gfx::Transform(),
                           xfer_mode);
 
     renderer_->DecideRenderPassAllocationsForFrame(
@@ -1658,7 +1673,7 @@
                                   gfx::Rect(viewport_size), gfx::Transform(),
                                   cc::FilterOperations());
 
-    cc::AddRenderPassQuad(root_pass, child_pass, mask, gfx::Transform(),
+    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask, gfx::Transform(),
                           xfer_mode);
 
     renderer_->DecideRenderPassAllocationsForFrame(
@@ -1715,8 +1730,8 @@
                                   gfx::Rect(viewport_size), gfx::Transform(),
                                   cc::FilterOperations());
 
-    cc::AddRenderPassQuad(root_pass, child_pass, mask, transform_causing_aa,
-                          xfer_mode);
+    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask,
+                          transform_causing_aa, xfer_mode);
 
     renderer_->DecideRenderPassAllocationsForFrame(
         render_passes_in_draw_order_);
@@ -1734,8 +1749,8 @@
                                   gfx::Rect(viewport_size),
                                   transform_causing_aa, cc::FilterOperations());
 
-    cc::AddRenderPassQuad(root_pass, child_pass, mask, transform_causing_aa,
-                          xfer_mode);
+    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask,
+                          transform_causing_aa, xfer_mode);
 
     renderer_->DecideRenderPassAllocationsForFrame(
         render_passes_in_draw_order_);
@@ -1858,12 +1873,12 @@
 class MockOutputSurfaceTest : public GLRendererTest {
  protected:
   void SetUp() override {
-    auto context = base::MakeUnique<StrictMock<OutputSurfaceMockContext>>();
+    auto context = std::make_unique<StrictMock<OutputSurfaceMockContext>>();
     context_ = context.get();
     auto provider = cc::TestContextProvider::Create(std::move(context));
     provider->BindToCurrentThread();
     output_surface_ =
-        base::MakeUnique<StrictMock<MockOutputSurface>>(std::move(provider));
+        std::make_unique<StrictMock<MockOutputSurface>>(std::move(provider));
 
     cc::FakeOutputSurfaceClient output_surface_client_;
     output_surface_->BindToClient(&output_surface_client_);
@@ -2123,8 +2138,8 @@
   class SingleOverlayValidator : public OverlayCandidateValidator {
    public:
     void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
-      strategies->push_back(base::MakeUnique<OverlayStrategySingleOnTop>(this));
-      strategies->push_back(base::MakeUnique<OverlayStrategyUnderlay>(this));
+      strategies->push_back(std::make_unique<OverlayStrategySingleOnTop>(this));
+      strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(this));
     }
 
     bool AllowCALayerOverlays() override { return false; }
@@ -2142,7 +2157,7 @@
 
   void Initialize() override {
     strategies_.push_back(
-        base::MakeUnique<OverlayStrategySingleOnTop>(&validator_));
+        std::make_unique<OverlayStrategySingleOnTop>(&validator_));
   }
 
   SingleOverlayValidator validator_;
@@ -2384,7 +2399,7 @@
  protected:
   void RunTest(bool partial_swap, bool set_draw_rectangle) {
     auto gl_owned =
-        base::MakeUnique<PartialSwapMockGLES2Interface>(set_draw_rectangle);
+        std::make_unique<PartialSwapMockGLES2Interface>(set_draw_rectangle);
     auto* gl = gl_owned.get();
 
     auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
@@ -2497,7 +2512,7 @@
 TEST_F(GLRendererTest, DCLayerOverlaySwitch) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(features::kDirectCompositionUnderlays);
-  auto gl_owned = base::MakeUnique<PartialSwapMockGLES2Interface>(true);
+  auto gl_owned = std::make_unique<PartialSwapMockGLES2Interface>(true);
   auto* gl = gl_owned.get();
 
   auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
@@ -2621,7 +2636,7 @@
   };
 
   void SetUp() override {
-    auto context_support = base::MakeUnique<MockContextSupport>();
+    auto context_support = std::make_unique<MockContextSupport>();
     context_support_ptr_ = context_support.get();
     auto context_provider = cc::TestContextProvider::Create(
         cc::TestWebGraphicsContext3D::Create(), std::move(context_support));
@@ -2633,7 +2648,7 @@
     resource_provider_ =
         cc::FakeResourceProvider::CreateDisplayResourceProvider(
             output_surface_->context_provider(), nullptr);
-    renderer_ = base::MakeUnique<GLRenderer>(&settings_, output_surface_.get(),
+    renderer_ = std::make_unique<GLRenderer>(&settings_, output_surface_.get(),
                                              resource_provider_.get(), nullptr);
     renderer_->Initialize();
   }
@@ -2704,7 +2719,7 @@
 class GLRendererSwapWithBoundsTest : public GLRendererTest {
  protected:
   void RunTest(const std::vector<gfx::Rect>& content_bounds) {
-    auto gl_owned = base::MakeUnique<SwapWithBoundsMockGLES2Interface>();
+    auto gl_owned = std::make_unique<SwapWithBoundsMockGLES2Interface>();
 
     auto provider = cc::TestContextProvider::Create(std::move(gl_owned));
     provider->BindToCurrentThread();
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index 5a629c8..bb2bd0a 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -18,6 +18,7 @@
 #include "cc/test/fake_recording_source.h"
 #include "cc/test/pixel_test.h"
 #include "cc/test/render_pass_test_utils.h"
+#include "cc/test/resource_provider_test_utils.h"
 #include "cc/test/test_in_process_context_provider.h"
 #include "components/viz/common/quads/picture_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
@@ -123,7 +124,8 @@
     SkColor background_color,
     bool premultiplied_alpha,
     const SharedQuadState* shared_state,
-    cc::ResourceProvider* resource_provider,
+    cc::DisplayResourceProvider* resource_provider,
+    cc::LayerTreeResourceProvider* child_resource_provider,
     RenderPass* render_pass) {
   SkPMColor pixel_color = premultiplied_alpha
                               ? SkPreMultiplyColor(texel_color)
@@ -147,16 +149,22 @@
 
   ResourceId resource;
   if (gpu_resource) {
-    resource = resource_provider->CreateGpuTextureResource(
+    resource = child_resource_provider->CreateGpuTextureResource(
         rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
         gfx::ColorSpace());
   } else {
-    resource =
-        resource_provider->CreateBitmapResource(rect.size(), gfx::ColorSpace());
+    resource = child_resource_provider->CreateBitmapResource(rect.size(),
+                                                             gfx::ColorSpace());
   }
-  resource_provider->CopyToResource(
+  child_resource_provider->CopyToResource(
       resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource}, resource_provider,
+                                         child_resource_provider);
+  ResourceId mapped_resource = resource_map[resource];
+
   bool needs_blending = true;
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
   const gfx::PointF uv_top_left(0.0f, 0.0f);
@@ -164,21 +172,23 @@
   const bool flipped = false;
   const bool nearest_neighbor = false;
   auto* quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, rect, rect, needs_blending, resource,
+  quad->SetNew(shared_state, rect, rect, needs_blending, mapped_resource,
                premultiplied_alpha, uv_top_left, uv_bottom_right,
                background_color, vertex_opacity, flipped, nearest_neighbor,
                false);
 }
 
-void CreateTestTextureDrawQuad(bool gpu_resource,
-                               const gfx::Rect& rect,
-                               SkColor texel_color,
-                               float vertex_opacity[4],
-                               SkColor background_color,
-                               bool premultiplied_alpha,
-                               const SharedQuadState* shared_state,
-                               cc::ResourceProvider* resource_provider,
-                               RenderPass* render_pass) {
+void CreateTestTextureDrawQuad(
+    bool gpu_resource,
+    const gfx::Rect& rect,
+    SkColor texel_color,
+    float vertex_opacity[4],
+    SkColor background_color,
+    bool premultiplied_alpha,
+    const SharedQuadState* shared_state,
+    cc::DisplayResourceProvider* resource_provider,
+    cc::LayerTreeResourceProvider* child_resource_provider,
+    RenderPass* render_pass) {
   SkPMColor pixel_color = premultiplied_alpha
                               ? SkPreMultiplyColor(texel_color)
                               : SkPackARGB32NoCheck(SkColorGetA(texel_color),
@@ -190,45 +200,51 @@
 
   ResourceId resource;
   if (gpu_resource) {
-    resource = resource_provider->CreateGpuTextureResource(
+    resource = child_resource_provider->CreateGpuTextureResource(
         rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
         gfx::ColorSpace());
   } else {
-    resource =
-        resource_provider->CreateBitmapResource(rect.size(), gfx::ColorSpace());
+    resource = child_resource_provider->CreateBitmapResource(rect.size(),
+                                                             gfx::ColorSpace());
   }
-  resource_provider->CopyToResource(
+  child_resource_provider->CopyToResource(
       resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource}, resource_provider,
+                                         child_resource_provider);
+  ResourceId mapped_resource = resource_map[resource];
+
   bool needs_blending = true;
   const gfx::PointF uv_top_left(0.0f, 0.0f);
   const gfx::PointF uv_bottom_right(1.0f, 1.0f);
   const bool flipped = false;
   const bool nearest_neighbor = false;
   auto* quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, rect, rect, needs_blending, resource,
+  quad->SetNew(shared_state, rect, rect, needs_blending, mapped_resource,
                premultiplied_alpha, uv_top_left, uv_bottom_right,
                background_color, vertex_opacity, flipped, nearest_neighbor,
                false);
 }
 
-void CreateTestTextureDrawQuad(bool gpu_resource,
-                               const gfx::Rect& rect,
-                               SkColor texel_color,
-                               SkColor background_color,
-                               bool premultiplied_alpha,
-                               const SharedQuadState* shared_state,
-                               cc::ResourceProvider* resource_provider,
-                               RenderPass* render_pass) {
+void CreateTestTextureDrawQuad(
+    bool gpu_resource,
+    const gfx::Rect& rect,
+    SkColor texel_color,
+    SkColor background_color,
+    bool premultiplied_alpha,
+    const SharedQuadState* shared_state,
+    cc::DisplayResourceProvider* resource_provider,
+    cc::LayerTreeResourceProvider* child_resource_provider,
+    RenderPass* render_pass) {
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
   CreateTestTextureDrawQuad(gpu_resource, rect, texel_color, vertex_opacity,
                             background_color, premultiplied_alpha, shared_state,
-                            resource_provider, render_pass);
+                            resource_provider, child_resource_provider,
+                            render_pass);
 }
 
-static void CollectResources(std::vector<ReturnedResource>* array,
-                             const std::vector<ReturnedResource>& returned) {}
-
 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
     const SharedQuadState* shared_state,
     scoped_refptr<media::VideoFrame> video_frame,
@@ -283,25 +299,17 @@
             resources.release_callbacks[media::VideoFrame::kAPlane])));
   }
 
-  // Transfer resources to the parent.
   cc::ResourceProvider::ResourceIdArray resource_ids_to_transfer;
   resource_ids_to_transfer.push_back(resource_y);
   resource_ids_to_transfer.push_back(resource_u);
   resource_ids_to_transfer.push_back(resource_v);
   if (with_alpha)
     resource_ids_to_transfer.push_back(resource_a);
-  std::vector<TransferableResource> send_to_parent;
-  std::vector<ReturnedResource> returned_to_child;
-  int child_id = resource_provider->CreateChild(
-      base::Bind(&CollectResources, &returned_to_child));
-  child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
-                                               &send_to_parent);
-  resource_provider->ReceiveFromChild(child_id, send_to_parent);
-
-  // Before create DrawQuad in DisplayResourceProvider's namespace, get the
-  // mapped resource id first.
+  // Transfer resources to the parent, and get the resource map.
   cc::ResourceProvider::ResourceIdMap resource_map =
-      resource_provider->GetChildToParentMap(child_id);
+      SendResourceAndGetChildToParentMap(
+          resource_ids_to_transfer, resource_provider, child_resource_provider);
+
   ResourceId mapped_resource_y = resource_map[resource_y];
   ResourceId mapped_resource_u = resource_map[resource_u];
   ResourceId mapped_resource_v = resource_map[resource_v];
@@ -377,21 +385,10 @@
       resources.resources[0],
       SingleReleaseCallback::Create(std::move(resources.release_callbacks[0])));
 
-  // Transfer resource to the parent.
-  cc::ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(resource_y);
-  std::vector<TransferableResource> send_to_parent;
-  std::vector<ReturnedResource> returned_to_child;
-  int child_id = resource_provider->CreateChild(
-      base::Bind(&CollectResources, &returned_to_child));
-  child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
-                                               &send_to_parent);
-  resource_provider->ReceiveFromChild(child_id, send_to_parent);
-
-  // Before create DrawQuad in DisplayResourceProvider's namespace, get the
-  // mapped resource id first.
+  // Transfer resources to the parent, and get the resource map.
   cc::ResourceProvider::ResourceIdMap resource_map =
-      resource_provider->GetChildToParentMap(child_id);
+      SendResourceAndGetChildToParentMap({resource_y}, resource_provider,
+                                         child_resource_provider);
   ResourceId mapped_resource_y = resource_map[resource_y];
 
   auto* quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
@@ -608,17 +605,19 @@
       child_resource_provider);
 }
 
-void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
-                                     media::ColorSpace video_frame_color_space,
-                                     const gfx::ColorSpace& video_color_space,
-                                     const gfx::RectF& tex_coord_rect,
-                                     uint8_t y,
-                                     uint8_t u,
-                                     uint8_t v,
-                                     RenderPass* render_pass,
-                                     const gfx::Rect& rect,
-                                     const gfx::Rect& visible_rect,
-                                     cc::ResourceProvider* resource_provider) {
+void CreateTestYUVVideoDrawQuad_NV12(
+    const SharedQuadState* shared_state,
+    media::ColorSpace video_frame_color_space,
+    const gfx::ColorSpace& video_color_space,
+    const gfx::RectF& tex_coord_rect,
+    uint8_t y,
+    uint8_t u,
+    uint8_t v,
+    RenderPass* render_pass,
+    const gfx::Rect& rect,
+    const gfx::Rect& visible_rect,
+    cc::DisplayResourceProvider* resource_provider,
+    cc::LayerTreeResourceProvider* child_resource_provider) {
   gfx::ColorSpace gfx_color_space = gfx::ColorSpace::CreateREC601();
   if (video_frame_color_space == media::COLOR_SPACE_JPEG) {
     gfx_color_space = gfx::ColorSpace::CreateJpeg();
@@ -629,22 +628,33 @@
   const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
       media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size());
 
-  ResourceId y_resource = resource_provider->CreateGpuTextureResource(
+  ResourceId resource_y = child_resource_provider->CreateGpuTextureResource(
       rect.size(), ResourceTextureHint::kDefault,
-      resource_provider->YuvResourceFormat(8), gfx_color_space);
-  ResourceId u_resource = resource_provider->CreateGpuTextureResource(
+      child_resource_provider->YuvResourceFormat(8), gfx_color_space);
+  ResourceId resource_u = child_resource_provider->CreateGpuTextureResource(
       uv_tex_size, ResourceTextureHint::kDefault, RGBA_8888, gfx_color_space);
-  ResourceId v_resource = u_resource;
-  ResourceId a_resource = 0;
+  ResourceId resource_v = resource_u;
+  ResourceId resource_a = 0;
 
   std::vector<uint8_t> y_pixels(ya_tex_size.GetArea(), y);
-  resource_provider->CopyToResource(y_resource, y_pixels.data(), ya_tex_size);
+  child_resource_provider->CopyToResource(resource_y, y_pixels.data(),
+                                          ya_tex_size);
 
   // U goes in the R component and V goes in the G component.
   uint32_t rgba_pixel = (u << 24) | (v << 16);
   std::vector<uint32_t> uv_pixels(uv_tex_size.GetArea(), rgba_pixel);
-  resource_provider->CopyToResource(
-      u_resource, reinterpret_cast<uint8_t*>(uv_pixels.data()), uv_tex_size);
+  child_resource_provider->CopyToResource(
+      resource_u, reinterpret_cast<uint8_t*>(uv_pixels.data()), uv_tex_size);
+
+  // Transfer resources to the parent, and get the resource map.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource_y, resource_u, resource_v},
+                                         resource_provider,
+                                         child_resource_provider);
+
+  ResourceId mapped_resource_y = resource_map[resource_y];
+  ResourceId mapped_resource_u = resource_map[resource_u];
+  ResourceId mapped_resource_v = resource_map[resource_v];
 
   gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
                                tex_coord_rect.y() * ya_tex_size.height(),
@@ -658,8 +668,9 @@
   auto* yuv_quad = render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
   yuv_quad->SetNew(shared_state, rect, visible_rect, needs_blending,
                    ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
-                   uv_tex_size, y_resource, u_resource, v_resource, a_resource,
-                   video_color_space, 0.0f, 1.0f, 8);
+                   uv_tex_size, mapped_resource_y, mapped_resource_u,
+                   mapped_resource_v, resource_a, video_color_space, 0.0f, 1.0f,
+                   8);
 }
 
 void CreateTestY16TextureDrawQuad_TwoColor(
@@ -834,12 +845,13 @@
   SharedQuadState* shared_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
 
-  CreateTestTextureDrawQuad(
-      this->use_gpu(), gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-      SK_ColorTRANSPARENT,             // Background color.
-      true,                            // Premultiplied alpha.
-      shared_state, this->resource_provider_.get(), pass.get());
+  CreateTestTextureDrawQuad(this->use_gpu(),
+                            gfx::Rect(this->device_viewport_size_),
+                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
+                            SK_ColorTRANSPARENT,  // Background color.
+                            true,                 // Premultiplied alpha.
+                            shared_state, this->resource_provider_.get(),
+                            this->child_resource_provider_.get(), pass.get());
 
   auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
   color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
@@ -862,12 +874,13 @@
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
   texture_quad_state->opacity = 0.8f;
 
-  CreateTestTextureDrawQuad(
-      this->use_gpu(), gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-      SK_ColorGREEN,                       // Background color.
-      true,                                // Premultiplied alpha.
-      texture_quad_state, this->resource_provider_.get(), pass.get());
+  CreateTestTextureDrawQuad(this->use_gpu(),
+                            gfx::Rect(this->device_viewport_size_),
+                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
+                            SK_ColorGREEN,  // Background color.
+                            true,           // Premultiplied alpha.
+                            texture_quad_state, this->resource_provider_.get(),
+                            this->child_resource_provider_.get(), pass.get());
 
   SharedQuadState* color_quad_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
@@ -993,13 +1006,14 @@
   texture_quad_state->opacity = 0.8f;
 
   float vertex_opacity[4] = {1.f, 1.f, 0.f, 0.f};
-  CreateTestTextureDrawQuad(
-      this->use_gpu(), gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-      vertex_opacity,
-      SK_ColorGREEN,  // Background color.
-      true,           // Premultiplied alpha.
-      texture_quad_state, this->resource_provider_.get(), pass.get());
+  CreateTestTextureDrawQuad(this->use_gpu(),
+                            gfx::Rect(this->device_viewport_size_),
+                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
+                            vertex_opacity,
+                            SK_ColorGREEN,  // Background color.
+                            true,           // Premultiplied alpha.
+                            texture_quad_state, this->resource_provider_.get(),
+                            this->child_resource_provider_.get(), pass.get());
 
   SharedQuadState* color_quad_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
@@ -1151,13 +1165,13 @@
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
       true, this->front_quad_state_, this->resource_provider_.get(),
-      this->render_pass_.get());
+      this->child_resource_provider_.get(), this->render_pass_.get());
   CreateTestTwoColoredTextureDrawQuad(
       this->use_gpu(), this->quad_rect_,
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
       true, this->back_quad_state_, this->resource_provider_.get(),
-      this->render_pass_.get());
+      this->child_resource_provider_.get(), this->render_pass_.get());
 
   SCOPED_TRACE("IntersectingTexturedQuads");
   this->AppendBackgroundAndRunTest(
@@ -1232,19 +1246,18 @@
       CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
   SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
       gfx::Transform(), this->quad_rect_, child_pass2.get());
-
   CreateTestTwoColoredTextureDrawQuad(
       this->use_gpu(), this->quad_rect_,
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
       true, child1_quad_state, this->resource_provider_.get(),
-      child_pass1.get());
+      this->child_resource_provider_.get(), child_pass1.get());
   CreateTestTwoColoredTextureDrawQuad(
       this->use_gpu(), this->quad_rect_,
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
       GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
       true, child2_quad_state, this->resource_provider_.get(),
-      child_pass2.get());
+      this->child_resource_provider_.get(), child_pass2.get());
 
   CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
                                child_pass_id1, this->render_pass_.get());
@@ -1323,12 +1336,13 @@
   SharedQuadState* shared_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
 
-  CreateTestTextureDrawQuad(
-      this->use_gpu(), gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-      SK_ColorTRANSPARENT,             // Background color.
-      false,                           // Premultiplied alpha.
-      shared_state, this->resource_provider_.get(), pass.get());
+  CreateTestTextureDrawQuad(this->use_gpu(),
+                            gfx::Rect(this->device_viewport_size_),
+                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
+                            SK_ColorTRANSPARENT,  // Background color.
+                            false,                // Premultiplied alpha.
+                            shared_state, this->resource_provider_.get(),
+                            this->child_resource_provider_.get(), pass.get());
 
   auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
   color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
@@ -1352,12 +1366,13 @@
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
   texture_quad_state->opacity = 0.8f;
 
-  CreateTestTextureDrawQuad(
-      this->use_gpu(), gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-      SK_ColorGREEN,                       // Background color.
-      false,                               // Premultiplied alpha.
-      texture_quad_state, this->resource_provider_.get(), pass.get());
+  CreateTestTextureDrawQuad(this->use_gpu(),
+                            gfx::Rect(this->device_viewport_size_),
+                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
+                            SK_ColorGREEN,  // Background color.
+                            false,          // Premultiplied alpha.
+                            texture_quad_state, this->resource_provider_.get(),
+                            this->child_resource_provider_.get(), pass.get());
 
   SharedQuadState* color_quad_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
@@ -1614,7 +1629,7 @@
   CreateTestYUVVideoDrawQuad_NV12(
       shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(),
       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect,
-      resource_provider_.get());
+      resource_provider_.get(), child_resource_provider_.get());
 
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -2180,18 +2195,25 @@
 
   ResourceId mask_resource_id;
   if (this->use_gpu()) {
-    mask_resource_id = this->resource_provider_->CreateGpuTextureResource(
+    mask_resource_id = this->child_resource_provider_->CreateGpuTextureResource(
         mask_rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
         gfx::ColorSpace());
   } else {
-    mask_resource_id = this->resource_provider_->CreateBitmapResource(
+    mask_resource_id = this->child_resource_provider_->CreateBitmapResource(
         mask_rect.size(), gfx::ColorSpace());
   }
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
       mask_rect.size());
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({mask_resource_id},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_mask_resource_id = resource_map[mask_resource_id];
+
   // This RenderPassDrawQuad does not include the full |viewport_rect|
   // which is the size of the child render pass.
   gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
@@ -2204,7 +2226,7 @@
   auto* mask_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
   mask_quad->SetNew(
       root_pass_shared_state, sub_rect, sub_rect, child_pass_id,
-      mask_resource_id,
+      mapped_mask_resource_id,
       gfx::ScaleRect(gfx::RectF(sub_rect), 2.f / mask_rect.width(),
                      2.f / mask_rect.height()),  // mask_uv_rect
       gfx::Size(mask_rect.size()),               // mask_texture_size
@@ -2272,18 +2294,25 @@
 
   ResourceId mask_resource_id;
   if (this->use_gpu()) {
-    mask_resource_id = this->resource_provider_->CreateGpuTextureResource(
+    mask_resource_id = this->child_resource_provider_->CreateGpuTextureResource(
         mask_rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
         gfx::ColorSpace());
   } else {
-    mask_resource_id = this->resource_provider_->CreateBitmapResource(
+    mask_resource_id = this->child_resource_provider_->CreateBitmapResource(
         mask_rect.size(), gfx::ColorSpace());
   }
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
       mask_rect.size());
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({mask_resource_id},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_mask_resource_id = resource_map[mask_resource_id];
+
   // This RenderPassDrawQuad does not include the full |viewport_rect|
   // which is the size of the child render pass.
   gfx::Rect sub_rect = gfx::Rect(50, 20, 200, 60);
@@ -2296,7 +2325,7 @@
   auto* mask_quad = root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
   mask_quad->SetNew(
       root_pass_shared_state, sub_rect, sub_rect, child_pass_id,
-      mask_resource_id,
+      mapped_mask_resource_id,
       gfx::ScaleRect(gfx::RectF(sub_rect), 2.f / mask_rect.width(),
                      2.f / mask_rect.height()),  // mask_uv_rect
       gfx::Size(mask_rect.size()),               // mask_texture_size
@@ -2751,16 +2780,23 @@
   gfx::Size tile_size(32, 32);
   ResourceId resource;
   if (this->use_gpu()) {
-    resource = this->resource_provider_->CreateGpuTextureResource(
+    resource = this->child_resource_provider_->CreateGpuTextureResource(
         tile_size, ResourceTextureHint::kDefault, RGBA_8888, gfx::ColorSpace());
   } else {
-    resource = this->resource_provider_->CreateBitmapResource(
+    resource = this->child_resource_provider_->CreateBitmapResource(
         tile_size, gfx::ColorSpace());
   }
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_resource = resource_map[resource];
+
   int id = 1;
   gfx::Transform transform_to_root;
   std::unique_ptr<RenderPass> pass =
@@ -2777,7 +2813,7 @@
   SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
       hole_quad_to_target_transform, rect, pass.get());
   TileDrawQuad* hole = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  hole->SetNew(hole_shared_state, rect, rect, needs_blending, resource,
+  hole->SetNew(hole_shared_state, rect, rect, needs_blending, mapped_resource,
                gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents,
                nearest_neighbor, force_anti_aliasing_off);
 
@@ -3177,15 +3213,20 @@
   gfx::Size tile_size(2, 2);
   ResourceId resource;
   if (this->use_gpu()) {
-    resource = this->resource_provider_->CreateGpuTextureResource(
+    resource = this->child_resource_provider_->CreateGpuTextureResource(
         tile_size, ResourceTextureHint::kDefault, RGBA_8888, gfx::ColorSpace());
   } else {
-    resource = this->resource_provider_->CreateBitmapResource(
+    resource = this->child_resource_provider_->CreateBitmapResource(
         tile_size, gfx::ColorSpace());
   }
-
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_resource = resource_map[resource];
 
   int id = 1;
   gfx::Transform transform_to_root;
@@ -3197,9 +3238,9 @@
       CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
 
   auto* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  quad->SetNew(shared_state, viewport, viewport, needs_blending, resource,
-               gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents,
-               nearest_neighbor, force_anti_aliasing_off);
+  quad->SetNew(shared_state, viewport, viewport, needs_blending,
+               mapped_resource, gfx::RectF(gfx::Rect(tile_size)), tile_size,
+               swizzle_contents, nearest_neighbor, force_anti_aliasing_off);
 
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -3226,12 +3267,19 @@
   draw_point_color(&canvas, 1, 1, SK_ColorGREEN);
 
   gfx::Size tile_size(2, 2);
-  ResourceId resource = this->resource_provider_->CreateBitmapResource(
+  ResourceId resource = this->child_resource_provider_->CreateBitmapResource(
       tile_size, gfx::ColorSpace());
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_resource = resource_map[resource];
+
   int id = 1;
   gfx::Transform transform_to_root;
   std::unique_ptr<RenderPass> pass =
@@ -3243,9 +3291,9 @@
 
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
   auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, viewport, viewport, needs_blending, resource,
-               false, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
-               vertex_opacity, false, nearest_neighbor, false);
+  quad->SetNew(shared_state, viewport, viewport, needs_blending,
+               mapped_resource, false, gfx::PointF(0, 0), gfx::PointF(1, 1),
+               SK_ColorBLACK, vertex_opacity, false, nearest_neighbor, false);
 
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -3274,12 +3322,19 @@
   }
 
   gfx::Size tile_size(2, 2);
-  ResourceId resource = this->resource_provider_->CreateBitmapResource(
+  ResourceId resource = this->child_resource_provider_->CreateBitmapResource(
       tile_size, gfx::ColorSpace());
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_resource = resource_map[resource];
+
   int id = 1;
   gfx::Transform transform_to_root;
   std::unique_ptr<RenderPass> pass =
@@ -3291,9 +3346,9 @@
 
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
   auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, viewport, viewport, needs_blending, resource,
-               false, gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
-               vertex_opacity, false, nearest_neighbor, false);
+  quad->SetNew(shared_state, viewport, viewport, needs_blending,
+               mapped_resource, false, gfx::PointF(0, 0), gfx::PointF(1, 1),
+               SK_ColorBLACK, vertex_opacity, false, nearest_neighbor, false);
 
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -3613,14 +3668,22 @@
     inset_rect.Inset(6, 6, 4, 4);
   }
 
-  ResourceId resource = this->resource_provider_->CreateGpuTextureResource(
-      mask_rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
-      gfx::ColorSpace());
+  ResourceId resource =
+      this->child_resource_provider_->CreateGpuTextureResource(
+          mask_rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
+          gfx::ColorSpace());
 
-  this->resource_provider_->CopyToResource(
+  this->child_resource_provider_->CopyToResource(
       resource, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
       mask_rect.size());
 
+  // Return the mapped resource id.
+  cc::ResourceProvider::ResourceIdMap resource_map =
+      SendResourceAndGetChildToParentMap({resource},
+                                         this->resource_provider_.get(),
+                                         this->child_resource_provider_.get());
+  ResourceId mapped_resource = resource_map[resource];
+
   // Arbitrary dividing lengths to divide up the resource into 16 quads.
   int widths[] = {
       0, 60, 50, 40,
@@ -3645,7 +3708,7 @@
 
       auto* texture_quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
       texture_quad->SetNew(shared_state, layer_rect, layer_rect, needs_blending,
-                           resource, true, uv_rect.origin(),
+                           mapped_resource, true, uv_rect.origin(),
                            uv_rect.bottom_right(), SK_ColorWHITE,
                            vertex_opacity, false, false, false);
     }
@@ -3787,11 +3850,18 @@
     SharedQuadState* shared_state =
         CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
 
-    ResourceId resource = resource_provider_->CreateGpuTextureResource(
+    ResourceId resource = child_resource_provider_->CreateGpuTextureResource(
         rect.size(), ResourceTextureHint::kDefault, RGBA_8888,
         src_color_space_);
-    resource_provider_->CopyToResource(resource, input_colors.data(),
-                                       rect.size());
+    this->child_resource_provider_->CopyToResource(
+        resource, input_colors.data(), rect.size());
+
+    // Return the mapped resource id.
+    cc::ResourceProvider::ResourceIdMap resource_map =
+        SendResourceAndGetChildToParentMap(
+            {resource}, this->resource_provider_.get(),
+            this->child_resource_provider_.get());
+    ResourceId mapped_resource = resource_map[resource];
 
     bool needs_blending = true;
     const gfx::PointF uv_top_left(0.0f, 0.0f);
@@ -3802,7 +3872,7 @@
     auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
 
     float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-    quad->SetNew(shared_state, rect, rect, needs_blending, resource,
+    quad->SetNew(shared_state, rect, rect, needs_blending, mapped_resource,
                  premultiplied_alpha, uv_top_left, uv_bottom_right,
                  SK_ColorBLACK, vertex_opacity, flipped, nearest_neighbor,
                  false);
diff --git a/components/viz/service/display/surface_aggregator_perftest.cc b/components/viz/service/display/surface_aggregator_perftest.cc
index ef7bc854..a0b4f09 100644
--- a/components/viz/service/display/surface_aggregator_perftest.cc
+++ b/components/viz/service/display/surface_aggregator_perftest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/ptr_util.h"
 #include "cc/base/lap_timer.h"
 #include "cc/resources/display_resource_provider.h"
 #include "cc/test/fake_output_surface_client.h"
@@ -34,7 +33,7 @@
   SurfaceAggregatorPerfTest() {
     context_provider_ = cc::TestContextProvider::Create();
     context_provider_->BindToCurrentThread();
-    shared_bitmap_manager_ = base::MakeUnique<cc::TestSharedBitmapManager>();
+    shared_bitmap_manager_ = std::make_unique<cc::TestSharedBitmapManager>();
 
     resource_provider_ =
         cc::FakeResourceProvider::CreateDisplayResourceProvider(
@@ -54,7 +53,7 @@
           nullptr, &manager_, FrameSinkId(1, i + 1), kIsChildRoot,
           kNeedsSyncPoints);
     }
-    aggregator_ = base::MakeUnique<SurfaceAggregator>(
+    aggregator_ = std::make_unique<SurfaceAggregator>(
         manager_.surface_manager(), resource_provider_.get(), optimize_damage);
     for (int i = 0; i < num_surfaces; i++) {
       LocalSurfaceId local_surface_id(i + 1, kArbitraryToken);
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 1506b9ed..719d05d 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -10,7 +10,6 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/stringprintf.h"
 #include "cc/resources/display_resource_provider.h"
@@ -2428,12 +2427,12 @@
 class SurfaceAggregatorWithResourcesTest : public testing::Test {
  public:
   void SetUp() override {
-    shared_bitmap_manager_ = base::MakeUnique<cc::TestSharedBitmapManager>();
+    shared_bitmap_manager_ = std::make_unique<cc::TestSharedBitmapManager>();
     resource_provider_ =
         cc::FakeResourceProvider::CreateDisplayResourceProvider(
             nullptr, shared_bitmap_manager_.get());
 
-    aggregator_ = base::MakeUnique<SurfaceAggregator>(
+    aggregator_ = std::make_unique<SurfaceAggregator>(
         manager_.surface_manager(), resource_provider_.get(), false);
     aggregator_->set_output_is_secure(true);
   }
diff --git a/components/viz/service/display_embedder/buffer_queue.cc b/components/viz/service/display_embedder/buffer_queue.cc
index f2bfa394c..8782e86d 100644
--- a/components/viz/service/display_embedder/buffer_queue.cc
+++ b/components/viz/service/display_embedder/buffer_queue.cc
@@ -5,7 +5,6 @@
 #include "components/viz/service/display_embedder/buffer_queue.h"
 
 #include "base/containers/adapters.h"
-#include "base/memory/ptr_util.h"
 #include "build/build_config.h"
 #include "components/viz/common/gl_helper.h"
 #include "gpu/GLES2/gl2extchromium.h"
@@ -285,7 +284,7 @@
   allocated_count_++;
   gl_->BindTexture(texture_target_, texture);
   gl_->BindTexImage2DCHROMIUM(texture_target_, id);
-  return base::MakeUnique<AllocatedSurface>(this, std::move(buffer), texture,
+  return std::make_unique<AllocatedSurface>(this, std::move(buffer), texture,
                                             id, stencil, gfx::Rect(size_));
 }
 
diff --git a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.cc b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.cc
index b142c625..a91ebec 100644
--- a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.cc
+++ b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/memory/ptr_util.h"
 #include "components/viz/service/display/overlay_processor.h"
 #include "components/viz/service/display/overlay_strategy_underlay.h"
 #include "ui/gfx/geometry/rect_conversions.h"
@@ -21,7 +20,7 @@
 
 void CompositorOverlayCandidateValidatorAndroid::GetStrategies(
     OverlayProcessor::StrategyList* strategies) {
-  strategies->push_back(base::MakeUnique<OverlayStrategyUnderlay>(this));
+  strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(this));
 }
 
 void CompositorOverlayCandidateValidatorAndroid::CheckOverlaySupport(
diff --git a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
index 4d26a085..88f74d0 100644
--- a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
+++ b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_split.h"
 #include "components/viz/service/display/overlay_strategy_fullscreen.h"
 #include "components/viz/service/display/overlay_strategy_single_on_top.h"
@@ -24,7 +23,7 @@
 template <typename S>
 std::unique_ptr<OverlayProcessor::Strategy> MakeOverlayStrategy(
     CompositorOverlayCandidateValidatorOzone* capability_checker) {
-  return base::MakeUnique<S>(capability_checker);
+  return std::make_unique<S>(capability_checker);
 }
 
 }  // namespace
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc
index bc3b503a..ffb3d87 100644
--- a/components/viz/service/display_embedder/gpu_display_provider.cc
+++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "cc/base/switches.h"
 #include "components/viz/common/display/renderer_settings.h"
@@ -70,7 +69,7 @@
       gpu_service_(std::move(gpu_service)),
       gpu_channel_manager_delegate_(gpu_channel_manager->delegate()),
       gpu_memory_buffer_manager_(
-          base::MakeUnique<InProcessGpuMemoryBufferManager>(
+          std::make_unique<InProcessGpuMemoryBufferManager>(
               gpu_channel_manager)),
       image_factory_(GetImageFactory(gpu_channel_manager)),
       compositing_mode_reporter_(compositing_mode_reporter),
@@ -87,8 +86,8 @@
     const RendererSettings& renderer_settings,
     std::unique_ptr<SyntheticBeginFrameSource>* out_begin_frame_source) {
   auto synthetic_begin_frame_source =
-      base::MakeUnique<DelayBasedBeginFrameSource>(
-          base::MakeUnique<DelayBasedTimeSource>(task_runner_.get()),
+      std::make_unique<DelayBasedBeginFrameSource>(
+          std::make_unique<DelayBasedTimeSource>(task_runner_.get()),
           restart_id_);
 
   // TODO(crbug.com/730660): Fallback to software if gpu doesn't work with
@@ -126,19 +125,19 @@
 
     if (context_provider->ContextCapabilities().surfaceless) {
 #if defined(USE_OZONE)
-      output_surface = base::MakeUnique<GLOutputSurfaceOzone>(
+      output_surface = std::make_unique<GLOutputSurfaceOzone>(
           std::move(context_provider), surface_handle,
           synthetic_begin_frame_source.get(), gpu_memory_buffer_manager_.get(),
           GL_TEXTURE_2D, GL_RGB);
 #elif defined(OS_MACOSX)
-      output_surface = base::MakeUnique<GLOutputSurfaceMac>(
+      output_surface = std::make_unique<GLOutputSurfaceMac>(
           std::move(context_provider), surface_handle,
           synthetic_begin_frame_source.get(), gpu_memory_buffer_manager_.get());
 #else
       NOTREACHED();
 #endif
     } else {
-      output_surface = base::MakeUnique<GLOutputSurface>(
+      output_surface = std::make_unique<GLOutputSurface>(
           std::move(context_provider), synthetic_begin_frame_source.get());
     }
   }
@@ -146,14 +145,14 @@
   int max_frames_pending = output_surface->capabilities().max_frames_pending;
   DCHECK_GT(max_frames_pending, 0);
 
-  auto scheduler = base::MakeUnique<DisplayScheduler>(
+  auto scheduler = std::make_unique<DisplayScheduler>(
       synthetic_begin_frame_source.get(), task_runner_.get(),
       max_frames_pending);
 
   // The ownership of the BeginFrameSource is transfered to the caller.
   *out_begin_frame_source = std::move(synthetic_begin_frame_source);
 
-  return base::MakeUnique<Display>(
+  return std::make_unique<Display>(
       ServerSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(),
       renderer_settings, frame_sink_id, std::move(output_surface),
       std::move(scheduler), task_runner_);
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
index 840bf19..5bf500a 100644
--- a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
+++ b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
@@ -10,7 +10,6 @@
 
 #include "base/lazy_instance.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -90,7 +89,7 @@
 
   SharedBitmapId id = SharedBitmap::GenerateId();
   handle_map_[id] = data;
-  return base::MakeUnique<ServerSharedBitmap>(data->pixels.get(), data, id,
+  return std::make_unique<ServerSharedBitmap>(data->pixels.get(), data, id,
                                               this);
 }
 
@@ -110,14 +109,14 @@
     return nullptr;
 
   if (data->pixels) {
-    return base::MakeUnique<ServerSharedBitmap>(data->pixels.get(), data, id,
+    return std::make_unique<ServerSharedBitmap>(data->pixels.get(), data, id,
                                                 nullptr);
   }
   if (!data->memory->memory()) {
     return nullptr;
   }
 
-  return base::MakeUnique<ServerSharedBitmap>(
+  return std::make_unique<ServerSharedBitmap>(
       static_cast<uint8_t*>(data->memory->memory()), data, id, nullptr);
 }
 
@@ -166,7 +165,7 @@
   if (handle_map_.find(id) != handle_map_.end())
     return false;
   auto data = base::MakeRefCounted<BitmapData>(buffer_size);
-  data->memory = base::MakeUnique<base::SharedMemory>(handle, false);
+  data->memory = std::make_unique<base::SharedMemory>(handle, false);
   data->memory->Map(data->buffer_size);
   data->memory->Close();
   handle_map_[id] = std::move(data);
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc b/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
index 859d6c3..66ee418 100644
--- a/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
+++ b/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
 
-#include "base/memory/ptr_util.h"
 #include "components/viz/service/display_embedder/shared_bitmap_allocation_notifier_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -14,7 +13,7 @@
 class ServerSharedBitmapManagerTest : public testing::Test {
  protected:
   void SetUp() override {
-    manager_ = base::MakeUnique<ServerSharedBitmapManager>();
+    manager_ = std::make_unique<ServerSharedBitmapManager>();
   }
 
   void TearDown() override { manager_.reset(); }
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
index c0c250d..be4e7ab 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -4,6 +4,8 @@
 
 #include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "cc/trees/layer_tree_frame_sink_client.h"
 #include "components/viz/common/quads/compositor_frame.h"
@@ -76,7 +78,7 @@
   support_ = support_manager_->CreateCompositorFrameSinkSupport(
       this, frame_sink_id_, is_root,
       capabilities_.delegated_sync_points_required);
-  begin_frame_source_ = base::MakeUnique<ExternalBeginFrameSource>(this);
+  begin_frame_source_ = std::make_unique<ExternalBeginFrameSource>(this);
   client_->SetBeginFrameSource(begin_frame_source_.get());
 
   // Avoid initializing GL context here, as this should be sharing the
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
index 22465738..9b5a2a6d 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -106,13 +106,13 @@
 
   auto root1 = CreateCompositorFrameSinkSupport(FrameSinkId(1, 1));
   std::unique_ptr<FakeExternalBeginFrameSource> external_source1 =
-      base::MakeUnique<FakeExternalBeginFrameSource>(60.f, false);
+      std::make_unique<FakeExternalBeginFrameSource>(60.f, false);
   manager_.RegisterBeginFrameSource(external_source1.get(),
                                     root1->frame_sink_id());
 
   auto root2 = CreateCompositorFrameSinkSupport(FrameSinkId(2, 2));
   std::unique_ptr<FakeExternalBeginFrameSource> external_source2 =
-      base::MakeUnique<FakeExternalBeginFrameSource>(60.f, false);
+      std::make_unique<FakeExternalBeginFrameSource>(60.f, false);
   manager_.RegisterBeginFrameSource(external_source2.get(),
                                     root2->frame_sink_id());
 
diff --git a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
index e9627f6..d2f361091 100644
--- a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
+++ b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
@@ -166,9 +166,9 @@
     testing::Test::SetUp();
 
     begin_frame_source_ =
-        base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false);
+        std::make_unique<FakeExternalBeginFrameSource>(0.f, false);
     begin_frame_source_->SetClient(&begin_frame_source_client_);
-    now_src_ = base::MakeUnique<base::SimpleTestTickClock>();
+    now_src_ = std::make_unique<base::SimpleTestTickClock>();
     frame_sink_manager_.surface_manager()->AddObserver(&surface_observer_);
     supports_[kDisplayFrameSink] = std::make_unique<CompositorFrameSinkSupport>(
         &support_client_, &frame_sink_manager_, kDisplayFrameSink, kIsRoot,
@@ -1000,9 +1000,12 @@
 
   // Create the child surface by submitting a frame to it.
   EXPECT_EQ(nullptr, GetSurfaceForId(child_id));
-  child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
-                                         MakeDefaultCompositorFrame());
-
+  TransferableResource resource;
+  resource.id = 1234;
+  child_support1().SubmitCompositorFrame(
+      child_id.local_surface_id(),
+      MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
+                          {resource}));
   // Verify that the child surface is created.
   Surface* surface = GetSurfaceForId(child_id);
   EXPECT_NE(nullptr, surface);
@@ -1022,9 +1025,17 @@
 
   // Child submits another frame to the same local surface id that is marked
   // destroyed.
-  surface_observer().Reset();
-  child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
-                                         MakeDefaultCompositorFrame());
+  {
+    std::vector<ReturnedResource> returned_resources =
+        TransferableResource::ReturnResources({resource});
+    EXPECT_CALL(support_client_, ReclaimResources(_)).Times(0);
+    EXPECT_CALL(support_client_,
+                DidReceiveCompositorFrameAck(Eq(returned_resources)));
+    surface_observer().Reset();
+    child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
+                                           MakeDefaultCompositorFrame());
+    testing::Mock::VerifyAndClearExpectations(&support_client_);
+  }
 
   // Verify that the surface that was marked destroyed is recovered and is being
   // used again.
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index 1c736fef..f042c958 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -4,6 +4,8 @@
 
 #include "components/viz/service/gl/gpu_service_impl.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/lazy_instance.h"
@@ -115,7 +117,7 @@
       gpu_preferences_(gpu_preferences),
       gpu_info_(gpu_info),
       gpu_feature_info_(gpu_feature_info),
-      bindings_(base::MakeUnique<mojo::BindingSet<mojom::GpuService>>()),
+      bindings_(std::make_unique<mojo::BindingSet<mojom::GpuService>>()),
       weak_ptr_factory_(this) {
   DCHECK(!io_runner_->BelongsToCurrentThread());
 #if defined(OS_CHROMEOS)
@@ -187,19 +189,19 @@
 
   sync_point_manager_ = sync_point_manager;
   if (!sync_point_manager_) {
-    owned_sync_point_manager_ = base::MakeUnique<gpu::SyncPointManager>();
+    owned_sync_point_manager_ = std::make_unique<gpu::SyncPointManager>();
     sync_point_manager_ = owned_sync_point_manager_.get();
   }
 
   shutdown_event_ = shutdown_event;
   if (!shutdown_event_) {
-    owned_shutdown_event_ = base::MakeUnique<base::WaitableEvent>(
+    owned_shutdown_event_ = std::make_unique<base::WaitableEvent>(
         base::WaitableEvent::ResetPolicy::MANUAL,
         base::WaitableEvent::InitialState::NOT_SIGNALED);
     shutdown_event_ = owned_shutdown_event_.get();
   }
 
-  scheduler_ = base::MakeUnique<gpu::Scheduler>(
+  scheduler_ = std::make_unique<gpu::Scheduler>(
       base::ThreadTaskRunnerHandle::Get(), sync_point_manager_);
 
   // Defer creation of the render thread. This is to prevent it from handling
@@ -556,7 +558,7 @@
       client_id, client_tracing_id, is_gpu_host);
 
   mojo::MessagePipe pipe;
-  gpu_channel->Init(base::MakeUnique<gpu::SyncChannelFilteredSender>(
+  gpu_channel->Init(std::make_unique<gpu::SyncChannelFilteredSender>(
       pipe.handle0.release(), gpu_channel, io_runner_, shutdown_event_));
 
   media_gpu_channel_manager_->AddChannel(client_id);
diff --git a/components/viz/service/gl/gpu_service_impl_unittest.cc b/components/viz/service/gl/gpu_service_impl_unittest.cc
index 67986d6..c36a072f 100644
--- a/components/viz/service/gl/gpu_service_impl_unittest.cc
+++ b/components/viz/service/gl/gpu_service_impl_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "components/viz/service/gl/gpu_service_impl.h"
 
+#include <memory>
+
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
@@ -48,7 +49,7 @@
   // testing::Test
   void SetUp() override {
     ASSERT_TRUE(io_thread_.Start());
-    gpu_service_ = base::MakeUnique<GpuServiceImpl>(
+    gpu_service_ = std::make_unique<GpuServiceImpl>(
         gpu::GPUInfo(), nullptr /* watchdog_thread */, io_thread_.task_runner(),
         gpu::GpuFeatureInfo(), gpu::GpuPreferences());
   }
diff --git a/components/viz/service/hit_test/hit_test_aggregator_unittest.cc b/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
index dbe4778..57cd1d3 100644
--- a/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
+++ b/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/viz/service/hit_test/hit_test_aggregator.h"
 
 #include <map>
+#include <memory>
 
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/common/surfaces/local_surface_id.h"
@@ -96,7 +97,7 @@
       : frame_sink_manager_(frame_sink_manager),
         frame_sink_id_(frame_sink_id),
         aggregator_(
-            base::MakeUnique<TestHitTestAggregator>(hit_test_manager, this)) {}
+            std::make_unique<TestHitTestAggregator>(hit_test_manager, this)) {}
   ~TestGpuRootCompositorFrameSink() override = default;
 
   // HitTestAggregatorDelegate:
@@ -192,7 +193,7 @@
   void CreateRootCompositorFrameSinkLocal(TestHitTestManager* hit_test_manager,
                                           const FrameSinkId& frame_sink_id) {
     compositor_frame_sinks_[frame_sink_id] =
-        base::MakeUnique<TestGpuRootCompositorFrameSink>(hit_test_manager, this,
+        std::make_unique<TestGpuRootCompositorFrameSink>(hit_test_manager, this,
                                                          frame_sink_id);
   }
 
@@ -242,10 +243,10 @@
 
   // testing::Test:
   void SetUp() override {
-    frame_sink_manager_ = base::MakeUnique<TestFrameSinkManagerImpl>();
-    host_frame_sink_manager_ = base::MakeUnique<TestHostFrameSinkManager>();
+    frame_sink_manager_ = std::make_unique<TestFrameSinkManagerImpl>();
+    host_frame_sink_manager_ = std::make_unique<TestHostFrameSinkManager>();
     hit_test_manager_ =
-        base::MakeUnique<TestHitTestManager>(frame_sink_manager_.get());
+        std::make_unique<TestHitTestManager>(frame_sink_manager_.get());
     frame_sink_manager_->SetLocalClient(host_frame_sink_manager_.get());
     frame_sink_manager_->CreateRootCompositorFrameSinkLocal(
         hit_test_manager_.get(), kDisplayFrameSink);
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc
index 417d52a6..9066f83 100644
--- a/components/viz/service/main/viz_main_impl.cc
+++ b/components/viz/service/main/viz_main_impl.cc
@@ -4,8 +4,9 @@
 
 #include "components/viz/service/main/viz_main_impl.h"
 
+#include <memory>
+
 #include "base/command_line.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/power_monitor/power_monitor_device_source.h"
 #include "base/single_thread_task_runner.h"
@@ -87,8 +88,8 @@
   // split into separate processes. Until then this is necessary to be able to
   // run Mushrome (chrome --mus) with Mus running in the browser process.
   if (!base::PowerMonitor::Get()) {
-    power_monitor_ = base::MakeUnique<base::PowerMonitor>(
-        base::MakeUnique<base::PowerMonitorDeviceSource>());
+    power_monitor_ = std::make_unique<base::PowerMonitor>(
+        std::make_unique<base::PowerMonitorDeviceSource>());
   }
 
   if (!gpu_init_) {
@@ -125,7 +126,7 @@
 
   CreateUkmRecorderIfNeeded(dependencies.connector);
 
-  gpu_service_ = base::MakeUnique<GpuServiceImpl>(
+  gpu_service_ = std::make_unique<GpuServiceImpl>(
       gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(),
       io_thread_ ? io_thread_->task_runner()
                  : dependencies_.io_thread_task_runner,
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc
index 78f8e4b..0fc08cf8 100644
--- a/components/viz/service/surfaces/surface.cc
+++ b/components/viz/service/surfaces/surface.cc
@@ -43,9 +43,13 @@
 
 void Surface::Reset(base::WeakPtr<SurfaceClient> client) {
   seen_first_frame_activation_ = false;
+  if (surface_client_.get() == client.get()) {
+    UnrefFrameResourcesAndRunCallbacks(std::move(pending_frame_data_));
+    UnrefFrameResourcesAndRunCallbacks(std::move(active_frame_data_));
+  }
+  surface_client_ = client;
   pending_frame_data_.reset();
   active_frame_data_.reset();
-  surface_client_ = client;
 }
 
 bool Surface::InheritActivationDeadlineFrom(
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc
index ac5386f..ccc7262 100644
--- a/components/viz/service/surfaces/surface_manager.cc
+++ b/components/viz/service/surfaces/surface_manager.cc
@@ -72,7 +72,10 @@
   // destroyed.
   temporary_references_.clear();
   temporary_reference_ranges_.clear();
-  const auto& children = GetSurfacesReferencedByParent(root_surface_id_);
+  // Create a copy of the children set as RemoveSurfaceReferenceImpl below will
+  // mutate that set.
+  base::flat_set<SurfaceId> children(
+      GetSurfacesReferencedByParent(root_surface_id_));
   for (const auto& child : children)
     RemoveSurfaceReferenceImpl(root_surface_id_, child);
 
@@ -114,7 +117,7 @@
   auto it = surface_map_.find(surface_info.id());
   if (it == surface_map_.end()) {
     surface_map_[surface_info.id()] =
-        base::MakeUnique<Surface>(surface_info, this, surface_client,
+        std::make_unique<Surface>(surface_info, this, surface_client,
                                   begin_frame_source, needs_sync_tokens);
     if (lifetime_type_ == LifetimeType::REFERENCES) {
       // We can get into a situation where multiple CompositorFrames arrive for
diff --git a/components/viz/service/surfaces/surface_unittest.cc b/components/viz/service/surfaces/surface_unittest.cc
index 6717e9d..1745dd6 100644
--- a/components/viz/service/surfaces/surface_unittest.cc
+++ b/components/viz/service/surfaces/surface_unittest.cc
@@ -42,6 +42,7 @@
             .Build();
     EXPECT_CALL(client, DidReceiveCompositorFrameAck(testing::_)).Times(1);
     support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+    testing::Mock::VerifyAndClearExpectations(&client);
   }
 
   {
@@ -55,6 +56,7 @@
     EXPECT_CALL(client, DidDiscardCompositorFrame(1)).Times(1);
     EXPECT_CALL(client, DidReceiveCompositorFrameAck(testing::_)).Times(1);
     support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+    testing::Mock::VerifyAndClearExpectations(&client);
   }
 
   {
@@ -66,6 +68,7 @@
                                 .Build();
     EXPECT_CALL(client, DidDiscardCompositorFrame(3)).Times(1);
     support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+    testing::Mock::VerifyAndClearExpectations(&client);
   }
 
   {
@@ -77,6 +80,7 @@
             .SetDeviceScaleFactor(2.f)
             .SetPresentationToken(4)
             .Build();
+    EXPECT_CALL(client, DidDiscardCompositorFrame(2)).Times(1);
     EXPECT_CALL(client, DidDiscardCompositorFrame(4)).Times(1);
     support->SubmitCompositorFrame(local_surface_id, std::move(frame));
   }
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index 8b270d4..14064fc 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -5,9 +5,10 @@
 #include "components/viz/test/test_layer_tree_frame_sink.h"
 
 #include <stdint.h>
+
+#include <memory>
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "cc/trees/layer_tree_frame_sink_client.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
@@ -71,7 +72,7 @@
   if (!LayerTreeFrameSink::BindToClient(client))
     return false;
 
-  frame_sink_manager_ = base::MakeUnique<FrameSinkManagerImpl>();
+  frame_sink_manager_ = std::make_unique<FrameSinkManagerImpl>();
 
   std::unique_ptr<OutputSurface> display_output_surface =
       test_client_->CreateDisplayOutputSurface(context_provider());
@@ -79,22 +80,22 @@
   std::unique_ptr<DisplayScheduler> scheduler;
   if (!synchronous_composite_) {
     if (disable_display_vsync_) {
-      begin_frame_source_ = base::MakeUnique<BackToBackBeginFrameSource>(
-          base::MakeUnique<DelayBasedTimeSource>(
+      begin_frame_source_ = std::make_unique<BackToBackBeginFrameSource>(
+          std::make_unique<DelayBasedTimeSource>(
               compositor_task_runner_.get()));
     } else {
-      begin_frame_source_ = base::MakeUnique<DelayBasedBeginFrameSource>(
-          base::MakeUnique<DelayBasedTimeSource>(compositor_task_runner_.get()),
+      begin_frame_source_ = std::make_unique<DelayBasedBeginFrameSource>(
+          std::make_unique<DelayBasedTimeSource>(compositor_task_runner_.get()),
           BeginFrameSource::kNotRestartableId);
       begin_frame_source_->SetAuthoritativeVSyncInterval(
           base::TimeDelta::FromMilliseconds(1000.f / refresh_rate_));
     }
-    scheduler = base::MakeUnique<DisplayScheduler>(
+    scheduler = std::make_unique<DisplayScheduler>(
         begin_frame_source_.get(), compositor_task_runner_.get(),
         display_output_surface->capabilities().max_frames_pending);
   }
 
-  display_ = base::MakeUnique<Display>(
+  display_ = std::make_unique<Display>(
       shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings_,
       frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
       compositor_task_runner_);
diff --git a/components/viz/test/viz_test_suite.cc b/components/viz/test/viz_test_suite.cc
index f72dcb2b..63868d65 100644
--- a/components/viz/test/viz_test_suite.cc
+++ b/components/viz/test/viz_test_suite.cc
@@ -4,7 +4,6 @@
 
 #include "components/viz/test/viz_test_suite.h"
 
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_id_name_manager.h"
 #include "components/viz/test/paths.h"
@@ -22,7 +21,7 @@
   gl::GLSurfaceTestSupport::InitializeOneOff();
   Paths::RegisterPathProvider();
 
-  message_loop_ = base::MakeUnique<base::MessageLoop>();
+  message_loop_ = std::make_unique<base::MessageLoop>();
 
   base::ThreadIdNameManager::GetInstance()->SetName(
       base::PlatformThread::CurrentId(), "Main");
diff --git a/content/app/strings/content_strings.grd b/content/app/strings/content_strings.grd
index 448e474..6c96f6c6 100644
--- a/content/app/strings/content_strings.grd
+++ b/content/app/strings/content_strings.grd
@@ -812,6 +812,9 @@
       <message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button.">
        Download
       </message>
+      <message name="IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a picture in picture button.">
+        Picture in Picture
+      </message>
       <message name="IDS_MEDIA_REMOTING_CAST_TEXT" desc="Text message shown to the user when casting a video to a known remote device.">
        Now casting to <ph name="DEVICE_FRIENDLY_NAME">$1<ex>Living Room TV</ex></ph>
       </message>
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 421bc58..41ff9900 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1287,7 +1287,6 @@
     "renderer_host/input/touch_emulator.cc",
     "renderer_host/input/touch_emulator.h",
     "renderer_host/input/touch_emulator_client.h",
-    "renderer_host/input/touch_event_queue.h",
     "renderer_host/input/touch_selection_controller_client_aura.cc",
     "renderer_host/input/touch_selection_controller_client_aura.h",
     "renderer_host/input/touch_selection_controller_client_child_frame.cc",
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 6923be31..9dbf316f 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -505,8 +505,8 @@
   return base_url_for_data_url_;
 }
 
-NavigationData* NavigationHandleImpl::GetNavigationData() {
-  return navigation_data_.get();
+const base::Value& NavigationHandleImpl::GetNavigationData() {
+  return navigation_data_;
 }
 
 void NavigationHandleImpl::SetOnDeferCallbackForTesting(
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 6c37ca47a..fb95634 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -18,11 +18,11 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/optional.h"
+#include "base/values.h"
 #include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/browser/navigation_type.h"
 #include "content/public/browser/restore_type.h"
@@ -154,7 +154,7 @@
   void CancelDeferredNavigation(NavigationThrottle* cancelling_throttle,
                                 NavigationThrottle::ThrottleCheckResult result);
 
-  NavigationData* GetNavigationData() override;
+  const base::Value& GetNavigationData() override;
 
   // Used in tests.
   State state_for_testing() const { return state_; }
@@ -318,7 +318,7 @@
   // Called during commit. Takes ownership of the embedder's NavigationData
   // instance. This NavigationData may have been cloned prior to being added
   // here.
-  void set_navigation_data(std::unique_ptr<NavigationData> navigation_data) {
+  void set_navigation_data(base::Value navigation_data) {
     navigation_data_ = std::move(navigation_data);
   }
 
@@ -499,7 +499,7 @@
   std::unique_ptr<AppCacheNavigationHandle> appcache_handle_;
 
   // Embedder data from the IO thread tied to this navigation.
-  std::unique_ptr<NavigationData> navigation_data_;
+  base::Value navigation_data_;
 
   // Embedder data from the UI thread tied to this navigation.
   std::unique_ptr<NavigationUIData> navigation_ui_data_;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index db5c8fc5..d14556e 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -9,6 +9,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
 #include "build/build_config.h"
 #include "content/browser/appcache/appcache_navigation_handle.h"
 #include "content/browser/appcache/chrome_appcache_service.h"
@@ -35,7 +36,6 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/global_request_id.h"
 #include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_ui_data.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/storage_partition.h"
@@ -736,7 +736,7 @@
     mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     std::unique_ptr<StreamHandle> body,
     const net::SSLInfo& ssl_info,
-    std::unique_ptr<NavigationData> navigation_data,
+    base::Value navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
     bool is_stream,
@@ -805,7 +805,7 @@
     }
   }
 
-  if (navigation_data)
+  if (!navigation_data.is_none())
     navigation_handle_->set_navigation_data(std::move(navigation_data));
 
   // Store the response and the StreamHandle until checks have been processed.
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index e9cba4a2..df5f88b 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -22,6 +22,10 @@
 #include "content/public/browser/navigation_throttle.h"
 #include "content/public/common/previews_state.h"
 
+namespace base {
+class Value;
+}
+
 namespace content {
 
 class FrameNavigationEntry;
@@ -29,7 +33,6 @@
 class NavigationControllerImpl;
 class NavigationHandleImpl;
 class NavigationURLLoader;
-class NavigationData;
 class ResourceRequestBody;
 class SiteInstanceImpl;
 class StreamHandle;
@@ -226,7 +229,7 @@
       mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       std::unique_ptr<StreamHandle> body,
       const net::SSLInfo& ssl_info,
-      std::unique_ptr<NavigationData> navigation_data,
+      base::Value navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
       bool is_stream,
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 67f268d..5841e72 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/feature_list.h"
 #include "base/macros.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "build/build_config.h"
 #include "content/browser/frame_host/navigation_controller_impl.h"
 #include "content/browser/frame_host/navigation_entry_impl.h"
@@ -20,7 +21,6 @@
 #include "content/common/frame.mojom.h"
 #include "content/common/frame_messages.h"
 #include "content/common/navigation_params.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/stream_handle.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/url_constants.h"
@@ -123,7 +123,7 @@
   // Have the current RenderFrameHost commit the navigation.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(request)->CallOnResponseStarted(
-      response, MakeEmptyStream(), nullptr);
+      response, MakeEmptyStream(), base::Value() /* navigation_data */);
   EXPECT_TRUE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
   EXPECT_TRUE(main_test_rfh()->is_loading());
   EXPECT_FALSE(node->navigation_request());
@@ -390,7 +390,8 @@
   response->head.headers = new net::HttpResponseHeaders(
       std::string(kNoContentHeaders, arraysize(kNoContentHeaders)));
   GetLoaderForNavigationRequest(main_request)
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
 
   // There should be no pending nor speculative RenderFrameHost; the navigation
   // was aborted.
@@ -415,7 +416,8 @@
   response->head.headers = new net::HttpResponseHeaders(
       std::string(kResetContentHeaders, arraysize(kResetContentHeaders)));
   GetLoaderForNavigationRequest(main_request)
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
 
   // There should be no pending nor speculative RenderFrameHost; the navigation
   // was aborted.
@@ -448,7 +450,8 @@
 
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(main_request)
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
   EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
   EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
@@ -491,7 +494,8 @@
   // Have the RenderFrameHost commit the navigation.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(main_request)
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
   TestRenderFrameHost* final_speculative_rfh =
       GetSpeculativeRenderFrameHost(node);
   EXPECT_TRUE(final_speculative_rfh);
@@ -563,7 +567,7 @@
   // Have the RenderFrameHost commit the navigation.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(
-      response, MakeEmptyStream(), nullptr);
+      response, MakeEmptyStream(), base::Value() /* navigation_data */);
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
   EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
 
@@ -755,7 +759,7 @@
   // Have the RenderFrameHost commit the navigation.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(
-      response, MakeEmptyStream(), nullptr);
+      response, MakeEmptyStream(), base::Value() /* navigation_data */);
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
   EXPECT_FALSE(main_test_rfh()->GetProcess()->did_frame_commit_navigation());
 
@@ -901,7 +905,8 @@
   // OnResponseStarted.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(node->navigation_request())
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
   EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
   EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
@@ -960,7 +965,8 @@
   // OnResponseStarted.
   scoped_refptr<ResourceResponse> response(new ResourceResponse);
   GetLoaderForNavigationRequest(main_request)
-      ->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+      ->CallOnResponseStarted(response, MakeEmptyStream(),
+                              base::Value() /* navigation_data */);
   speculative_rfh = GetSpeculativeRenderFrameHost(node);
   ASSERT_TRUE(speculative_rfh);
   EXPECT_TRUE(speculative_rfh->GetProcess()->did_frame_commit_navigation());
diff --git a/content/browser/loader/cross_site_document_resource_handler.cc b/content/browser/loader/cross_site_document_resource_handler.cc
index 2670ef6..ca0fcc4 100644
--- a/content/browser/loader/cross_site_document_resource_handler.cc
+++ b/content/browser/loader/cross_site_document_resource_handler.cc
@@ -307,6 +307,8 @@
       // Block the response and throw away the data.  Report zero bytes read.
       bytes_read = 0;
       blocked_read_completed_ = true;
+      ResourceRequestInfoImpl* info = GetRequestInfo();
+      info->set_blocked_cross_site_document(true);
 
       // Log the blocking event.  Inline the Serialize call to avoid it when
       // tracing is disabled.
@@ -323,7 +325,7 @@
               ? CrossSiteDocumentResourceHandler::Action::kBlockedAfterSniffing
               : CrossSiteDocumentResourceHandler::Action::
                     kBlockedWithoutSniffing);
-      ResourceType resource_type = GetRequestInfo()->GetResourceType();
+      ResourceType resource_type = info->GetResourceType();
       UMA_HISTOGRAM_ENUMERATION("SiteIsolation.XSD.Browser.Blocked",
                                 resource_type,
                                 content::RESOURCE_TYPE_LAST_TYPE);
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc
index d24a3b5..05d5bb7 100644
--- a/content/browser/loader/mojo_async_resource_handler.cc
+++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -463,6 +463,8 @@
   loader_status.encoded_data_length = request()->GetTotalReceivedBytes();
   loader_status.encoded_body_length = request()->GetRawBodyBytes();
   loader_status.decoded_body_length = total_written_bytes_;
+  loader_status.blocked_cross_site_document =
+      GetRequestInfo()->blocked_cross_site_document();
 
   url_loader_client_->OnComplete(loader_status);
   controller->Resume();
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc
index 1dff2e2..166c443 100644
--- a/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -19,13 +19,13 @@
 #include "base/run_loop.h"
 #include "base/test/gtest_util.h"
 #include "base/test/test_simple_task_runner.h"
+#include "base/values.h"
 #include "content/browser/loader/mock_resource_loader.h"
 #include "content/browser/loader/resource_controller.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/loader/resource_request_info_impl.h"
 #include "content/browser/loader/resource_scheduler.h"
 #include "content/public/browser/appcache_service.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/browser/resource_throttle.h"
@@ -183,9 +183,9 @@
     return PREVIEWS_UNSPECIFIED;
   }
 
-  NavigationData* GetNavigationData(net::URLRequest* request) const override {
+  base::Value GetNavigationData(net::URLRequest* request) override {
     ADD_FAILURE() << "GetNavigationData should not be called.";
-    return nullptr;
+    return base::Value();
   }
 
   std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
diff --git a/content/browser/loader/navigation_resource_handler.cc b/content/browser/loader/navigation_resource_handler.cc
index 054ada49..fbcb3c8 100644
--- a/content/browser/loader/navigation_resource_handler.cc
+++ b/content/browser/loader/navigation_resource_handler.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/optional.h"
+#include "base/values.h"
 #include "content/browser/loader/navigation_url_loader_impl_core.h"
 #include "content/browser/loader/resource_controller.h"
 #include "content/browser/loader/resource_loader.h"
@@ -16,7 +17,6 @@
 #include "content/browser/resource_context_impl.h"
 #include "content/browser/streams/stream.h"
 #include "content/browser/streams/stream_context.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 #include "content/public/browser/stream_handle.h"
 #include "content/public/common/resource_response.h"
@@ -115,21 +115,17 @@
 
   response->head.encoded_data_length = request()->raw_header_size();
 
-  std::unique_ptr<NavigationData> cloned_data;
+  base::Value navigation_data;
   if (resource_dispatcher_host_delegate_) {
     // Ask the embedder for a NavigationData instance.
-    NavigationData* navigation_data =
+    navigation_data =
         resource_dispatcher_host_delegate_->GetNavigationData(request());
-
-    // Clone the embedder's NavigationData before moving it to the UI thread.
-    if (navigation_data)
-      cloned_data = navigation_data->Clone();
   }
 
-  core_->NotifyResponseStarted(response, std::move(stream_handle_),
-                               request()->ssl_info(), std::move(cloned_data),
-                               info->GetGlobalRequestID(), info->IsDownload(),
-                               info->is_stream());
+  core_->NotifyResponseStarted(
+      response, std::move(stream_handle_), request()->ssl_info(),
+      std::move(navigation_data), info->GetGlobalRequestID(),
+      info->IsDownload(), info->is_stream());
   HoldController(std::move(controller));
   response_ = response;
 }
diff --git a/content/browser/loader/navigation_url_loader_delegate.h b/content/browser/loader/navigation_url_loader_delegate.h
index 49013ca..99c42a8 100644
--- a/content/browser/loader/navigation_url_loader_delegate.h
+++ b/content/browser/loader/navigation_url_loader_delegate.h
@@ -13,6 +13,10 @@
 #include "content/common/content_export.h"
 #include "content/public/common/url_loader.mojom.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 struct RedirectInfo;
 class SSLInfo;
@@ -20,7 +24,6 @@
 
 namespace content {
 
-class NavigationData;
 class StreamHandle;
 struct GlobalRequestID;
 struct ResourceResponse;
@@ -50,7 +53,7 @@
       mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       std::unique_ptr<StreamHandle> body_stream,
       const net::SSLInfo& ssl_info,
-      std::unique_ptr<NavigationData> navigation_data,
+      base::Value navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
       bool is_stream,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index d61951d..63307a2 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -10,6 +10,7 @@
 #include "base/location.h"
 #include "base/optional.h"
 #include "base/trace_event/trace_event.h"
+#include "base/values.h"
 #include "content/browser/appcache/appcache_navigation_handle.h"
 #include "content/browser/appcache/appcache_navigation_handle_core.h"
 #include "content/browser/frame_host/navigation_request_info.h"
@@ -20,7 +21,6 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_ui_data.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/stream_handle.h"
@@ -99,7 +99,7 @@
     const scoped_refptr<ResourceResponse>& response,
     std::unique_ptr<StreamHandle> body,
     const net::SSLInfo& ssl_info,
-    std::unique_ptr<NavigationData> navigation_data,
+    base::Value navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
     bool is_stream) {
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index 5a53fd2..36236d6d 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -14,6 +14,10 @@
 #include "base/time/time.h"
 #include "content/browser/loader/navigation_url_loader.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 struct RedirectInfo;
 class SSLInfo;
@@ -23,7 +27,6 @@
 
 class AppCacheNavigationHandle;
 class NavigationURLLoaderImplCore;
-class NavigationData;
 class ServiceWorkerNavigationHandle;
 class StreamHandle;
 struct GlobalRequestID;
@@ -56,7 +59,7 @@
   void NotifyResponseStarted(const scoped_refptr<ResourceResponse>& response,
                              std::unique_ptr<StreamHandle> body,
                              const net::SSLInfo& ssl_info,
-                             std::unique_ptr<NavigationData> navigation_data,
+                             base::Value navigation_data,
                              const GlobalRequestID& request_id,
                              bool is_download,
                              bool is_stream);
diff --git a/content/browser/loader/navigation_url_loader_impl_core.cc b/content/browser/loader/navigation_url_loader_impl_core.cc
index 6a7d05c8..a252da6 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.cc
+++ b/content/browser/loader/navigation_url_loader_impl_core.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "content/browser/frame_host/navigation_request_info.h"
 #include "content/browser/loader/navigation_resource_handler.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -14,7 +15,6 @@
 #include "content/common/navigation_params.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_ui_data.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/stream_handle.h"
@@ -118,7 +118,7 @@
     ResourceResponse* response,
     std::unique_ptr<StreamHandle> body,
     const net::SSLInfo& ssl_info,
-    std::unique_ptr<NavigationData> navigation_data,
+    base::Value navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
     bool is_stream) {
@@ -140,7 +140,7 @@
       BrowserThread::UI, FROM_HERE,
       base::BindOnce(&NavigationURLLoaderImpl::NotifyResponseStarted, loader_,
                      response->DeepCopy(), base::Passed(&body), ssl_info,
-                     base::Passed(&navigation_data), request_id, is_download,
+                     std::move(navigation_data), request_id, is_download,
                      is_stream));
 }
 
diff --git a/content/browser/loader/navigation_url_loader_impl_core.h b/content/browser/loader/navigation_url_loader_impl_core.h
index 64fa6b0..5ba81dd 100644
--- a/content/browser/loader/navigation_url_loader_impl_core.h
+++ b/content/browser/loader/navigation_url_loader_impl_core.h
@@ -12,6 +12,10 @@
 #include "base/memory/weak_ptr.h"
 #include "content/browser/loader/navigation_url_loader_impl.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 class URLRequestContextGetter;
 struct RedirectInfo;
@@ -25,7 +29,6 @@
 
 class AppCacheNavigationHandleCore;
 class NavigationResourceHandler;
-class NavigationData;
 class ResourceContext;
 class ServiceWorkerNavigationHandleCore;
 class StreamHandle;
@@ -76,7 +79,7 @@
   void NotifyResponseStarted(ResourceResponse* response,
                              std::unique_ptr<StreamHandle> body,
                              const net::SSLInfo& ssl_info,
-                             std::unique_ptr<NavigationData> navigation_data,
+                             base::Value navigation_data,
                              const GlobalRequestID& request_id,
                              bool is_download,
                              bool is_stream);
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 248c1c7f..e50e455 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -10,6 +10,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/task_scheduler/post_task.h"
 #include "base/trace_event/trace_event.h"
+#include "base/values.h"
 #include "content/browser/appcache/appcache_navigation_handle.h"
 #include "content/browser/appcache/appcache_request_handler.h"
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
@@ -35,7 +36,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/navigation_ui_data.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/stream_handle.h"
@@ -842,7 +842,7 @@
 
   delegate_->OnResponseStarted(
       std::move(response), std::move(url_loader_client_endpoints), nullptr,
-      std::move(ssl_info), std::unique_ptr<NavigationData>(),
+      std::move(ssl_info), base::Value() /* navigation_data */,
       GlobalRequestID(-1, g_next_request_id), is_download,
       false /* is_stream */,
       request_controller_->TakeSubresourceLoaderParams());
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index b96745d..24367bf 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -186,7 +186,8 @@
       previews_state_(previews_state),
       body_(body),
       initiated_in_secure_context_(initiated_in_secure_context),
-      suggested_filename_(suggested_filename) {}
+      suggested_filename_(suggested_filename),
+      blocked_cross_site_document_(false) {}
 
 ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
 }
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index a70967c7..54a65fc 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -208,6 +208,13 @@
     return suggested_filename_;
   }
 
+  bool blocked_cross_site_document() const {
+    return blocked_cross_site_document_;
+  }
+  void set_blocked_cross_site_document(bool value) {
+    blocked_cross_site_document_ = value;
+  }
+
  private:
   FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest,
                            DeletedFilterDetached);
@@ -247,6 +254,7 @@
   bool initiated_in_secure_context_;
   std::unique_ptr<NavigationUIData> navigation_ui_data_;
   base::Optional<std::string> suggested_filename_;
+  bool blocked_cross_site_document_;
 
   // Keeps upload body blobs alive for the duration of the request.
   BlobHandles blob_handles_;
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h
index 175028b..3d50253 100644
--- a/content/browser/renderer_host/input/input_router.h
+++ b/content/browser/renderer_host/input/input_router.h
@@ -8,7 +8,7 @@
 #include "cc/input/touch_action.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
+#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
 #include "content/common/widget.mojom.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/common/input_event_ack_state.h"
@@ -26,7 +26,7 @@
   struct CONTENT_EXPORT Config {
     Config();
     GestureEventQueue::Config gesture_config;
-    TouchEventQueue::Config touch_config;
+    PassthroughTouchEventQueue::Config touch_config;
   };
 
   ~InputRouter() override {}
diff --git a/content/browser/renderer_host/input/input_router_config_helper.cc b/content/browser/renderer_host/input/input_router_config_helper.cc
index f5db6a7..46fd57cf 100644
--- a/content/browser/renderer_host/input/input_router_config_helper.cc
+++ b/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -21,8 +21,8 @@
 const int kDesktopTouchAckTimeoutDelayMs = 200;
 const int kMobileTouchAckTimeoutDelayMs = 1000;
 
-TouchEventQueue::Config GetTouchEventQueueConfig() {
-  TouchEventQueue::Config config;
+PassthroughTouchEventQueue::Config GetTouchEventQueueConfig() {
+  PassthroughTouchEventQueue::Config config;
 
   config.desktop_touch_ack_timeout_delay =
       base::TimeDelta::FromMilliseconds(kDesktopTouchAckTimeoutDelayMs);
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index eb6ee90..793a1941 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -16,8 +16,6 @@
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 #include "content/browser/renderer_host/input/input_disposition_handler.h"
 #include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/edit_command.h"
@@ -82,6 +80,7 @@
       wheel_scroll_latching_enabled_(base::FeatureList::IsEnabled(
           features::kTouchpadAndWheelScrollLatching)),
       wheel_event_queue_(this, wheel_scroll_latching_enabled_),
+      touch_event_queue_(this, config.touch_config),
       gesture_event_queue_(this, this, this, config.gesture_config),
       device_scale_factor_(1.f),
       host_binding_(this),
@@ -89,9 +88,6 @@
       weak_ptr_factory_(this) {
   weak_this_ = weak_ptr_factory_.GetWeakPtr();
 
-  touch_event_queue_.reset(
-      new PassthroughTouchEventQueue(this, config.touch_config));
-
   DCHECK(client);
   DCHECK(disposition_handler);
   UpdateTouchAckTimeoutEnabled();
@@ -155,9 +151,9 @@
       // then no scrolling really ever occurs (even though we still send
       // GestureScrollBegin).
       touch_scroll_started_sent_ = true;
-      touch_event_queue_->PrependTouchScrollNotification();
+      touch_event_queue_.PrependTouchScrollNotification();
     }
-    touch_event_queue_->OnGestureScrollEvent(gesture_event);
+    touch_event_queue_.OnGestureScrollEvent(gesture_event);
   }
 
   if (!gesture_event_queue_.QueueEvent(gesture_event)) {
@@ -172,15 +168,15 @@
   TouchEventWithLatencyInfo updatd_touch_event = touch_event;
   SetMovementXYForTouchPoints(&updatd_touch_event.event);
   input_stream_validator_.Validate(updatd_touch_event.event);
-  touch_event_queue_->QueueEvent(updatd_touch_event);
+  touch_event_queue_.QueueEvent(updatd_touch_event);
 }
 
 void InputRouterImpl::NotifySiteIsMobileOptimized(bool is_mobile_optimized) {
-  touch_event_queue_->SetIsMobileOptimizedSite(is_mobile_optimized);
+  touch_event_queue_.SetIsMobileOptimizedSite(is_mobile_optimized);
 }
 
 bool InputRouterImpl::HasPendingEvents() const {
-  return !touch_event_queue_->Empty() || !gesture_event_queue_.empty() ||
+  return !touch_event_queue_.Empty() || !gesture_event_queue_.empty() ||
          wheel_event_queue_.has_pending() || active_renderer_fling_count_ > 0;
 }
 
@@ -216,7 +212,7 @@
 }
 
 void InputRouterImpl::CancelTouchTimeout() {
-  touch_event_queue_->SetAckTimeoutEnabled(false);
+  touch_event_queue_.SetAckTimeoutEnabled(false);
 }
 
 void InputRouterImpl::SetWhiteListedTouchAction(cc::TouchAction touch_action,
@@ -352,7 +348,7 @@
     const GestureEventWithLatencyInfo& event,
     InputEventAckSource ack_source,
     InputEventAckState ack_result) {
-  touch_event_queue_->OnGestureEventAck(event, ack_result);
+  touch_event_queue_.OnGestureEventAck(event, ack_result);
   disposition_handler_->OnGestureEventAck(event, ack_source, ack_result);
 }
 
@@ -486,8 +482,8 @@
     OnSetTouchAction(touch_action.value());
 
   // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
-  touch_event_queue_->ProcessTouchAck(source, state, latency,
-                                      touch_event.event.unique_touch_event_id);
+  touch_event_queue_.ProcessTouchAck(source, state, latency,
+                                     touch_event.event.unique_touch_event_id);
 }
 
 void InputRouterImpl::GestureEventHandled(
@@ -550,13 +546,13 @@
   if (!has_handlers)
     touch_action_filter_.ResetTouchAction();
 
-  touch_event_queue_->OnHasTouchEventHandlers(has_handlers);
+  touch_event_queue_.OnHasTouchEventHandlers(has_handlers);
   client_->OnHasTouchEventHandlers(has_handlers);
 }
 
 void InputRouterImpl::OnSetTouchAction(cc::TouchAction touch_action) {
   // Synthetic touchstart events should get filtered out in RenderWidget.
-  DCHECK(touch_event_queue_->IsPendingAckTouchStart());
+  DCHECK(touch_event_queue_.IsPendingAckTouchStart());
   TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", "action",
                touch_action);
 
@@ -572,7 +568,7 @@
   // to page functionality, so the timeout could do more harm than good.
   const bool touch_ack_timeout_enabled =
       touch_action_filter_.allowed_touch_action() != cc::kTouchActionNone;
-  touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled);
+  touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h
index a7755f5..91f6a0d5 100644
--- a/content/browser/renderer_host/input/input_router_impl.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -19,8 +19,8 @@
 #include "content/browser/renderer_host/input/input_router.h"
 #include "content/browser/renderer_host/input/input_router_client.h"
 #include "content/browser/renderer_host/input/mouse_wheel_event_queue.h"
+#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
 #include "content/browser/renderer_host/input/touch_action_filter.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
 #include "content/common/input/input_event_stream_validator.h"
 #include "content/common/input/input_handler.mojom.h"
@@ -53,7 +53,7 @@
       public GestureEventQueueClient,
       public FlingControllerClient,
       public MouseWheelEventQueueClient,
-      public TouchEventQueueClient,
+      public PassthroughTouchEventQueueClient,
       public TouchpadTapSuppressionControllerClient,
       public mojom::WidgetInputHandlerHost {
  public:
@@ -106,7 +106,7 @@
   void SendMouseEventImmediately(
       const MouseEventWithLatencyInfo& mouse_event) override;
 
-  // TouchEventQueueClient
+  // PassthroughTouchEventQueueClient
   void SendTouchEventImmediately(
       const TouchEventWithLatencyInfo& touch_event) override;
   void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
@@ -203,7 +203,7 @@
 
   bool wheel_scroll_latching_enabled_;
   MouseWheelEventQueue wheel_event_queue_;
-  std::unique_ptr<TouchEventQueue> touch_event_queue_;
+  PassthroughTouchEventQueue touch_event_queue_;
   GestureEventQueue gesture_event_queue_;
   TouchActionFilter touch_action_filter_;
   InputEventStreamValidator input_stream_validator_;
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index 383f1e2..8b2b7a1b 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -399,11 +399,11 @@
   InputRouterImpl* input_router() const { return input_router_.get(); }
 
   bool TouchEventQueueEmpty() const {
-    return input_router()->touch_event_queue_->Empty();
+    return input_router()->touch_event_queue_.Empty();
   }
 
   bool TouchEventTimeoutEnabled() const {
-    return input_router()->touch_event_queue_->IsAckTimeoutEnabled();
+    return input_router()->touch_event_queue_.IsAckTimeoutEnabled();
   }
 
   bool HasPendingEvents() const { return input_router_->HasPendingEvents(); }
diff --git a/content/browser/renderer_host/input/legacy_input_router_impl.cc b/content/browser/renderer_host/input/legacy_input_router_impl.cc
index b5fa3424..4bfe6481 100644
--- a/content/browser/renderer_host/input/legacy_input_router_impl.cc
+++ b/content/browser/renderer_host/input/legacy_input_router_impl.cc
@@ -17,7 +17,6 @@
 #include "content/browser/renderer_host/input/input_disposition_handler.h"
 #include "content/browser/renderer_host/input/input_router_client.h"
 #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/edit_command.h"
diff --git a/content/browser/renderer_host/input/legacy_input_router_impl.h b/content/browser/renderer_host/input/legacy_input_router_impl.h
index 2104924c..19b2ea0 100644
--- a/content/browser/renderer_host/input/legacy_input_router_impl.h
+++ b/content/browser/renderer_host/input/legacy_input_router_impl.h
@@ -18,8 +18,8 @@
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 #include "content/browser/renderer_host/input/input_router.h"
 #include "content/browser/renderer_host/input/mouse_wheel_event_queue.h"
+#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
 #include "content/browser/renderer_host/input/touch_action_filter.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
 #include "content/common/input/input_event_dispatch_type.h"
 #include "content/common/input/input_event_stream_validator.h"
@@ -49,7 +49,7 @@
       public GestureEventQueueClient,
       public FlingControllerClient,
       public MouseWheelEventQueueClient,
-      public TouchEventQueueClient,
+      public PassthroughTouchEventQueueClient,
       public TouchpadTapSuppressionControllerClient {
  public:
   LegacyInputRouterImpl(IPC::Sender* sender,
@@ -102,7 +102,7 @@
   void SendMouseEventImmediately(
       const MouseEventWithLatencyInfo& mouse_event) override;
 
-  // TouchEventQueueClient
+  // PassthroughTouchEventQueueClient
   void SendTouchEventImmediately(
       const TouchEventWithLatencyInfo& touch_event) override;
   void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
@@ -258,7 +258,7 @@
   bool wheel_scroll_latching_enabled_;
 
   MouseWheelEventQueue wheel_event_queue_;
-  std::unique_ptr<TouchEventQueue> touch_event_queue_;
+  std::unique_ptr<PassthroughTouchEventQueue> touch_event_queue_;
   GestureEventQueue gesture_event_queue_;
   TouchActionFilter touch_action_filter_;
   InputEventStreamValidator input_stream_validator_;
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
index c80d26d..2a5358c 100644
--- a/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
+++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.cc
@@ -53,7 +53,7 @@
 }
 
 PassthroughTouchEventQueue::PassthroughTouchEventQueue(
-    TouchEventQueueClient* client,
+    PassthroughTouchEventQueueClient* client,
     const Config& config)
     : client_(client),
       has_handlers_(true),
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue.h b/content/browser/renderer_host/input/passthrough_touch_event_queue.h
index d89c373..65d881e 100644
--- a/content/browser/renderer_host/input/passthrough_touch_event_queue.h
+++ b/content/browser/renderer_host/input/passthrough_touch_event_queue.h
@@ -5,14 +5,36 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_PASSTHROUGH_TOUCH_EVENT_QUEUE_H_
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_PASSTHROUGH_TOUCH_EVENT_QUEUE_H_
 
-#include "content/browser/renderer_host/input/touch_event_queue.h"
-
 #include <set>
 
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/common/content_export.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
+
 namespace content {
 
 class TouchTimeoutHandler;
 
+// Interface with which PassthroughTouchEventQueue can forward touch events, and
+// dispatch touch event responses.
+class CONTENT_EXPORT PassthroughTouchEventQueueClient {
+ public:
+  virtual ~PassthroughTouchEventQueueClient() {}
+
+  virtual void SendTouchEventImmediately(
+      const TouchEventWithLatencyInfo& event) = 0;
+
+  virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
+                               InputEventAckSource ack_source,
+                               InputEventAckState ack_result) = 0;
+
+  virtual void OnFilteringTouchEvent(
+      const blink::WebTouchEvent& touch_event) = 0;
+};
+
 // A queue that processes a touch-event and forwards it on to the
 // renderer process immediately. This class assumes that queueing will
 // happen inside the renderer process. This class will hold onto the pending
@@ -21,51 +43,71 @@
 // model of the renderer it is possible that an ack for a touchend can
 // be sent before the corresponding ack for the touchstart. This class
 // corrects that state.
-class CONTENT_EXPORT PassthroughTouchEventQueue : public TouchEventQueue {
+class CONTENT_EXPORT PassthroughTouchEventQueue {
  public:
-  PassthroughTouchEventQueue(TouchEventQueueClient* client,
+  struct CONTENT_EXPORT Config {
+    Config()
+        : desktop_touch_ack_timeout_delay(
+              base::TimeDelta::FromMilliseconds(200)),
+          mobile_touch_ack_timeout_delay(
+              base::TimeDelta::FromMilliseconds(1000)),
+          touch_ack_timeout_supported(false) {}
+
+    // Touch ack timeout delay for desktop sites. If zero, timeout behavior
+    // is disabled for such sites. Defaults to 200ms.
+    base::TimeDelta desktop_touch_ack_timeout_delay;
+
+    // Touch ack timeout delay for mobile sites. If zero, timeout behavior
+    // is disabled for such sites. Defaults to 1000ms.
+    base::TimeDelta mobile_touch_ack_timeout_delay;
+
+    // Whether the platform supports touch ack timeout behavior.
+    // Defaults to false (disabled).
+    bool touch_ack_timeout_supported;
+  };
+
+  PassthroughTouchEventQueue(PassthroughTouchEventQueueClient* client,
                              const Config& config);
 
-  ~PassthroughTouchEventQueue() override;
+  ~PassthroughTouchEventQueue();
 
-  // TouchEventQueue overrides.
-  void QueueEvent(const TouchEventWithLatencyInfo& event) override;
+  void QueueEvent(const TouchEventWithLatencyInfo& event);
 
-  void PrependTouchScrollNotification() override;
+  void PrependTouchScrollNotification();
 
   void ProcessTouchAck(InputEventAckSource ack_source,
                        InputEventAckState ack_result,
                        const ui::LatencyInfo& latency_info,
-                       const uint32_t unique_touch_event_id) override;
-  void OnGestureScrollEvent(
-      const GestureEventWithLatencyInfo& gesture_event) override;
+                       const uint32_t unique_touch_event_id);
+  void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event);
 
   void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
-                         InputEventAckState ack_result) override;
+                         InputEventAckState ack_result);
 
-  void OnHasTouchEventHandlers(bool has_handlers) override;
+  void OnHasTouchEventHandlers(bool has_handlers);
 
-  bool IsPendingAckTouchStart() const override;
+  bool IsPendingAckTouchStart() const;
 
-  void SetAckTimeoutEnabled(bool enabled) override;
+  void SetAckTimeoutEnabled(bool enabled);
 
-  void SetIsMobileOptimizedSite(bool mobile_optimized_site) override;
+  void SetIsMobileOptimizedSite(bool mobile_optimized_site);
 
-  bool IsAckTimeoutEnabled() const override;
+  bool IsAckTimeoutEnabled() const;
 
-  bool Empty() const override;
+  bool Empty() const;
 
  protected:
   void SendTouchCancelEventForTouchEvent(
-      const TouchEventWithLatencyInfo& event_to_cancel) override;
+      const TouchEventWithLatencyInfo& event_to_cancel);
   void UpdateTouchConsumerStates(const blink::WebTouchEvent& event,
-                                 InputEventAckState ack_result) override;
+                                 InputEventAckState ack_result);
   // Empties the queue of touch events. This may result in any number of gesture
   // events being sent to the renderer.
-  void FlushQueue() override;
+  void FlushQueue();
 
  private:
   friend class PassthroughTouchEventQueueTest;
+  friend class TouchTimeoutHandler;
 
   class TouchEventWithLatencyInfoAndAckState
       : public TouchEventWithLatencyInfo {
@@ -107,7 +149,7 @@
   size_t SizeForTesting() const;
 
   // Handles touch event forwarding and ack'ed event dispatch.
-  TouchEventQueueClient* client_;
+  PassthroughTouchEventQueueClient* client_;
 
   // Whether the renderer has at least one touch handler.
   bool has_handlers_;
diff --git a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
index 93cf482..d5f982e3 100644
--- a/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -42,7 +42,7 @@
 }  // namespace
 
 class PassthroughTouchEventQueueTest : public testing::Test,
-                                       public TouchEventQueueClient {
+                                       public PassthroughTouchEventQueueClient {
  public:
   PassthroughTouchEventQueueTest()
       : scoped_task_environment_(
@@ -55,13 +55,13 @@
 
   // testing::Test
   void SetUp() override {
-    ResetQueueWithConfig(TouchEventQueue::Config());
+    ResetQueueWithConfig(PassthroughTouchEventQueue::Config());
     sent_events_ids_.clear();
   }
 
   void TearDown() override { queue_.reset(); }
 
-  // TouchEventQueueClient
+  // PassthroughTouchEventQueueClient
   void SendTouchEventImmediately(
       const TouchEventWithLatencyInfo& event) override {
     sent_events_.push_back(event.event);
@@ -102,7 +102,7 @@
 
   void SetUpForTimeoutTesting(base::TimeDelta desktop_timeout_delay,
                               base::TimeDelta mobile_timeout_delay) {
-    TouchEventQueue::Config config;
+    PassthroughTouchEventQueue::Config config;
     config.desktop_touch_ack_timeout_delay = desktop_timeout_delay;
     config.mobile_touch_ack_timeout_delay = mobile_timeout_delay;
     config.touch_ack_timeout_supported = true;
@@ -325,7 +325,7 @@
     touch_event_.ResetPoints();
   }
 
-  void ResetQueueWithConfig(const TouchEventQueue::Config& config) {
+  void ResetQueueWithConfig(const PassthroughTouchEventQueue::Config& config) {
     queue_.reset(new PassthroughTouchEventQueue(this, config));
     queue_->OnHasTouchEventHandlers(true);
   }
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index 1752b78..1a9ed9d7 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -15,7 +15,6 @@
 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
 #include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/web_contents/web_contents_impl.h"
diff --git a/content/browser/renderer_host/input/touch_event_queue.h b/content/browser/renderer_host/input/touch_event_queue.h
deleted file mode 100644
index a6a15a8..0000000
--- a/content/browser/renderer_host/input/touch_event_queue.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "content/browser/renderer_host/event_with_latency_info.h"
-#include "content/common/content_export.h"
-#include "content/public/common/input_event_ack_source.h"
-#include "content/public/common/input_event_ack_state.h"
-
-namespace content {
-
-// Interface with which TouchEventQueue can forward touch events, and dispatch
-// touch event responses.
-class CONTENT_EXPORT TouchEventQueueClient {
- public:
-  virtual ~TouchEventQueueClient() {}
-
-  virtual void SendTouchEventImmediately(
-      const TouchEventWithLatencyInfo& event) = 0;
-
-  virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
-                               InputEventAckSource ack_source,
-                               InputEventAckState ack_result) = 0;
-
-  virtual void OnFilteringTouchEvent(
-      const blink::WebTouchEvent& touch_event) = 0;
-};
-
-// A queue for throttling and coalescing touch-events.
-class CONTENT_EXPORT TouchEventQueue {
- public:
-  struct CONTENT_EXPORT Config {
-    Config()
-        : desktop_touch_ack_timeout_delay(
-              base::TimeDelta::FromMilliseconds(200)),
-          mobile_touch_ack_timeout_delay(
-              base::TimeDelta::FromMilliseconds(1000)),
-          touch_ack_timeout_supported(false) {}
-
-    // Touch ack timeout delay for desktop sites. If zero, timeout behavior
-    // is disabled for such sites. Defaults to 200ms.
-    base::TimeDelta desktop_touch_ack_timeout_delay;
-
-    // Touch ack timeout delay for mobile sites. If zero, timeout behavior
-    // is disabled for such sites. Defaults to 1000ms.
-    base::TimeDelta mobile_touch_ack_timeout_delay;
-
-    // Whether the platform supports touch ack timeout behavior.
-    // Defaults to false (disabled).
-    bool touch_ack_timeout_supported;
-  };
-
-  TouchEventQueue() {}
-
-  virtual ~TouchEventQueue() {}
-
-  // Adds an event to the queue. The event may be coalesced with previously
-  // queued events (e.g. consecutive touch-move events can be coalesced into a
-  // single touch-move event). The event may also be immediately forwarded to
-  // the renderer (e.g. when there are no other queued touch event).
-  virtual void QueueEvent(const TouchEventWithLatencyInfo& event) = 0;
-
-  // Insert a TouchScrollStarted event in the queue ahead of all not-in-flight
-  // events.
-  virtual void PrependTouchScrollNotification() = 0;
-
-  // Notifies the queue that a touch-event has been processed by the renderer.
-  // At this point, if the ack is for async touchmove, remove the uncancelable
-  // touchmove from the front of the queue and decide if it should dispatch the
-  // next pending async touch move event, otherwise the queue may send one or
-  // more gesture events and/or additional queued touch-events to the renderer.
-  virtual void ProcessTouchAck(InputEventAckSource ack_source,
-                               InputEventAckState ack_result,
-                               const ui::LatencyInfo& latency_info,
-                               const uint32_t unique_touch_event_id) = 0;
-
-  // When GestureScrollBegin is received, we send a touch cancel to renderer,
-  // route all the following touch events directly to client, and ignore the
-  // ack for the touch cancel. When Gesture{ScrollEnd,FlingStart} is received,
-  // resume the normal flow of sending touch events to the renderer.
-  virtual void OnGestureScrollEvent(
-      const GestureEventWithLatencyInfo& gesture_event) = 0;
-
-  virtual void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
-                                 InputEventAckState ack_result) = 0;
-
-  // Notifies the queue whether the renderer has at least one touch handler.
-  virtual void OnHasTouchEventHandlers(bool has_handlers) = 0;
-
-  // Returns whether the currently pending touch event (waiting ACK) is for
-  // a touch start event.
-  virtual bool IsPendingAckTouchStart() const = 0;
-
-  // Sets whether a delayed touch ack will cancel and flush the current
-  // touch sequence. Note that, if the timeout was previously disabled, enabling
-  // it will take effect only for the following touch sequence.
-  virtual void SetAckTimeoutEnabled(bool enabled) = 0;
-
-  // Sets whether the current site has a mobile friendly viewport. This
-  // determines which ack timeout delay will be used for *future* touch events.
-  // The default assumption is that the site is *not* mobile-optimized.
-  virtual void SetIsMobileOptimizedSite(bool mobile_optimized_site) = 0;
-
-  // Whether ack timeout behavior is supported and enabled for the current site.
-  virtual bool IsAckTimeoutEnabled() const = 0;
-
-  virtual bool Empty() const WARN_UNUSED_RESULT = 0;
-
- protected:
-  virtual void SendTouchCancelEventForTouchEvent(
-      const TouchEventWithLatencyInfo& event_to_cancel) = 0;
-
-  // Empties the queue of touch events. This may result in any number of gesture
-  // events being sent to the renderer.
-  virtual void FlushQueue() = 0;
-  virtual void UpdateTouchConsumerStates(const blink::WebTouchEvent& event,
-                                         InputEventAckState ack_result) = 0;
-
- private:
-  friend class TouchTimeoutHandler;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchEventQueue);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_
diff --git a/content/browser/renderer_host/input/touch_timeout_handler.cc b/content/browser/renderer_host/input/touch_timeout_handler.cc
index 216dfa0..2c95426a 100644
--- a/content/browser/renderer_host/input/touch_timeout_handler.cc
+++ b/content/browser/renderer_host/input/touch_timeout_handler.cc
@@ -11,7 +11,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/trace_event/trace_event.h"
-#include "content/browser/renderer_host/input/touch_event_queue.h"
+#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
 #include "content/common/input/web_touch_event_traits.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/gfx/geometry/point_f.h"
@@ -32,9 +32,10 @@
 
 }  // namespace
 
-TouchTimeoutHandler::TouchTimeoutHandler(TouchEventQueue* touch_queue,
-                                         base::TimeDelta desktop_timeout_delay,
-                                         base::TimeDelta mobile_timeout_delay)
+TouchTimeoutHandler::TouchTimeoutHandler(
+    PassthroughTouchEventQueue* touch_queue,
+    base::TimeDelta desktop_timeout_delay,
+    base::TimeDelta mobile_timeout_delay)
     : touch_queue_(touch_queue),
       desktop_timeout_delay_(desktop_timeout_delay),
       mobile_timeout_delay_(mobile_timeout_delay),
diff --git a/content/browser/renderer_host/input/touch_timeout_handler.h b/content/browser/renderer_host/input/touch_timeout_handler.h
index d8684db..641db79 100644
--- a/content/browser/renderer_host/input/touch_timeout_handler.h
+++ b/content/browser/renderer_host/input/touch_timeout_handler.h
@@ -16,11 +16,11 @@
 
 namespace content {
 
-class TouchEventQueue;
+class PassthroughTouchEventQueue;
 
 class TouchTimeoutHandler {
  public:
-  TouchTimeoutHandler(TouchEventQueue* touch_queue,
+  TouchTimeoutHandler(PassthroughTouchEventQueue* touch_queue,
                       base::TimeDelta desktop_timeout_delay,
                       base::TimeDelta mobile_timeout_delay);
 
@@ -52,7 +52,7 @@
   base::TimeDelta GetTimeoutDelay() const;
   bool HasTimeoutEvent() const;
 
-  TouchEventQueue* touch_queue_;
+  PassthroughTouchEventQueue* touch_queue_;
 
   // How long to wait on a touch ack before cancelling the touch sequence.
   const base::TimeDelta desktop_timeout_delay_;
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 676eb6a..1bebbc1 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -216,6 +216,8 @@
       return IDS_MEDIA_OVERFLOW_MENU_PAUSE;
     case WebLocalizedString::kOverflowMenuDownload:
       return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD;
+    case WebLocalizedString::kOverflowMenuPictureInPicture:
+      return IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE;
     case WebLocalizedString::kPlaceholderForDayOfMonthField:
       return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD;
     case WebLocalizedString::kPlaceholderForMonthField:
@@ -326,7 +328,7 @@
     blink::scheduler::WebThreadBase* thread) {
   base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                             base::WaitableEvent::InitialState::NOT_SIGNALED);
-  thread->GetTaskRunner()->PostTask(
+  thread->GetSingleThreadTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(&BlinkPlatformImpl::UpdateWebThreadTLS,
                      base::Unretained(this), base::Unretained(thread),
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index f8b8ff58..ae68a49e 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -411,8 +411,11 @@
   if (base::FeatureList::IsEnabled(features::kV8ContextSnapshot))
     WebRuntimeFeatures::EnableV8ContextSnapshot(true);
 
+  if (base::FeatureList::IsEnabled(features::kStopInBackground))
+    WebRuntimeFeatures::EnableStopInBackground(true);
+
   if (base::FeatureList::IsEnabled(features::kStopLoadingInBackground))
-    WebRuntimeFeatures::EnableStopLoadingInBackgroundAndroid(true);
+    WebRuntimeFeatures::EnableStopLoadingInBackground(true);
 
   WebRuntimeFeatures::EnablePWAFullCodeCache(
       base::FeatureList::IsEnabled(features::kPWAFullCodeCache));
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 5bb4fc4..7154497e 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -167,7 +167,6 @@
     "native_web_keyboard_event.h",
     "navigation_controller.cc",
     "navigation_controller.h",
-    "navigation_data.h",
     "navigation_details.cc",
     "navigation_details.h",
     "navigation_entry.h",
diff --git a/content/public/browser/navigation_data.h b/content/public/browser/navigation_data.h
deleted file mode 100644
index d0fccd6d..0000000
--- a/content/public/browser/navigation_data.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_
-#define CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_
-
-#include <memory>
-
-namespace content {
-
-// Copyable interface for embedders to pass opaque data to content/. It is
-// expected to be created on the IO thread, and content/ will transfer it to the
-// UI thread as a clone.
-class NavigationData {
- public:
-  virtual ~NavigationData(){};
-
-  // Creates a new NavigationData that is a deep copy of the original
-  virtual std::unique_ptr<NavigationData> Clone() const = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_NAVIGATION_DATA_H_
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h
index f73f0c3..ffcb64e0 100644
--- a/content/public/browser/navigation_handle.h
+++ b/content/public/browser/navigation_handle.h
@@ -21,13 +21,16 @@
 
 class GURL;
 
+namespace base {
+class Value;
+}  // namespace base
+
 namespace net {
 class HttpResponseHeaders;
 }  // namespace net
 
 namespace content {
 struct GlobalRequestID;
-class NavigationData;
 class NavigationThrottle;
 class RenderFrameHost;
 class SiteInstance;
@@ -313,7 +316,7 @@
   // The NavigationData that the embedder returned from
   // ResourceDispatcherHostDelegate::GetNavigationData during commit. This will
   // be a clone of the NavigationData.
-  virtual NavigationData* GetNavigationData() = 0;
+  virtual const base::Value& GetNavigationData() = 0;
 };
 
 }  // namespace content
diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc
index e51377e..5ceaa8f 100644
--- a/content/public/browser/resource_dispatcher_host_delegate.cc
+++ b/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -4,7 +4,7 @@
 
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 
-#include "content/public/browser/navigation_data.h"
+#include "base/values.h"
 #include "content/public/browser/resource_request_info.h"
 #include "content/public/browser/stream_info.h"
 #include "net/ssl/client_cert_store.h"
@@ -87,9 +87,9 @@
   return PREVIEWS_UNSPECIFIED;
 }
 
-NavigationData* ResourceDispatcherHostDelegate::GetNavigationData(
-    net::URLRequest* request) const {
-  return nullptr;
+base::Value ResourceDispatcherHostDelegate::GetNavigationData(
+    net::URLRequest* request) {
+  return base::Value();
 }
 
 std::unique_ptr<net::ClientCertStore>
diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h
index 3d24882..b26956a 100644
--- a/content/public/browser/resource_dispatcher_host_delegate.h
+++ b/content/public/browser/resource_dispatcher_host_delegate.h
@@ -18,6 +18,11 @@
 #include "ui/base/page_transition_types.h"
 
 class GURL;
+
+namespace base {
+class Value;
+}
+
 namespace net {
 class AuthChallengeInfo;
 class ClientCertStore;
@@ -27,7 +32,6 @@
 namespace content {
 
 class AppCacheService;
-class NavigationData;
 class ResourceContext;
 class ResourceDispatcherHostLoginDelegate;
 class ResourceThrottle;
@@ -131,7 +135,7 @@
 
   // Asks the embedder for NavigationData related to this request. It is only
   // called for navigation requests.
-  virtual NavigationData* GetNavigationData(net::URLRequest* request) const;
+  virtual base::Value GetNavigationData(net::URLRequest* request);
 
   // Get platform ClientCertStore. May return nullptr.
   virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index d599efb5..1cc5948 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -324,6 +324,16 @@
 const base::Feature kSlimmingPaintInvalidation{
     "SlimmingPaintInvalidation", base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Stop scheduler task queues in background after allowed grace time.
+const base::Feature kStopInBackground {
+  "stop-in-background",
+#if defined(OS_ANDROID)
+      base::FEATURE_ENABLED_BY_DEFAULT
+#else
+      base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
+
 // Stop loading tasks and loading of resources in background, on Android,
 // after allowed grace time. Launch bug: https://crbug.com/775761.
 const base::Feature kStopLoadingInBackground{"stop-loading-in-background",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index b87fdf0d..91d19b0 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -85,6 +85,7 @@
 CONTENT_EXPORT extern const base::Feature kSignInProcessIsolation;
 CONTENT_EXPORT extern const base::Feature kSitePerProcess;
 CONTENT_EXPORT extern const base::Feature kSlimmingPaintInvalidation;
+CONTENT_EXPORT extern const base::Feature kStopInBackground;
 CONTENT_EXPORT extern const base::Feature kStopLoadingInBackground;
 CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
 CONTENT_EXPORT extern const base::Feature kTopDocumentIsolation;
diff --git a/content/public/common/resource_response_info.cc b/content/public/common/resource_response_info.cc
index 0f01d5df..dff9f8e 100644
--- a/content/public/common/resource_response_info.cc
+++ b/content/public/common/resource_response_info.cc
@@ -29,7 +29,8 @@
       cert_status(0),
       ssl_connection_status(0),
       ssl_key_exchange_group(0),
-      did_service_worker_navigation_preload(false) {}
+      did_service_worker_navigation_preload(false),
+      blocked_cross_site_document(false) {}
 
 ResourceResponseInfo::ResourceResponseInfo(const ResourceResponseInfo& other) =
     default;
diff --git a/content/public/common/resource_response_info.h b/content/public/common/resource_response_info.h
index 9111e41..897243f 100644
--- a/content/public/common/resource_response_info.h
+++ b/content/public/common/resource_response_info.h
@@ -183,6 +183,11 @@
   // for this response.
   bool did_service_worker_navigation_preload;
 
+  // Is used to report that cross-site document request response was blocked
+  // from entering renderer. Corresponding message will be generated in devtools
+  // console if this flag is set to true.
+  bool blocked_cross_site_document;
+
   // NOTE: When adding or changing fields here, also update
   // ResourceResponse::DeepCopy in resource_response.cc.
 };
diff --git a/content/public/test/web_contents_tester.h b/content/public/test/web_contents_tester.h
index 5b64dca4..b73bec6b 100644
--- a/content/public/test/web_contents_tester.h
+++ b/content/public/test/web_contents_tester.h
@@ -15,6 +15,10 @@
 class GURL;
 class SkBitmap;
 
+namespace base {
+class Value;
+}
+
 namespace gfx {
 class Size;
 }
@@ -26,7 +30,6 @@
 namespace content {
 
 class BrowserContext;
-class NavigationData;
 class NavigationHandle;
 class RenderFrameHost;
 
@@ -99,9 +102,8 @@
                                ui::PageTransition transition) = 0;
 
   // Sets NavgationData on |navigation_handle|.
-  virtual void SetNavigationData(
-      NavigationHandle* navigation_handle,
-      std::unique_ptr<NavigationData> navigation_data) = 0;
+  virtual void SetNavigationData(NavigationHandle* navigation_handle,
+                                 base::Value navigation_data) = 0;
 
   // Sets HttpResponseData on |navigation_handle|.
   virtual void SetHttpResponseHeaders(
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index a95025da..3cf60a8 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -925,7 +925,8 @@
     } else {
       client_->DidFinishLoading(
           (status.completion_time - TimeTicks()).InSecondsF(),
-          total_transfer_size, encoded_body_size, status.decoded_body_length);
+          total_transfer_size, encoded_body_size, status.decoded_body_length,
+          status.blocked_cross_site_document);
     }
   }
 }
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc
index 2c5cf15..0173361 100644
--- a/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -227,7 +227,8 @@
   void DidFinishLoading(double finishTime,
                         int64_t totalEncodedDataLength,
                         int64_t totalEncodedBodyLength,
-                        int64_t totalDecodedBodyLength) override {
+                        int64_t totalDecodedBodyLength,
+                        bool blocked_cross_site_document) override {
     EXPECT_TRUE(loader_);
     EXPECT_TRUE(did_receive_response_);
     EXPECT_FALSE(did_finish_);
diff --git a/content/renderer/quota_dispatcher.cc b/content/renderer/quota_dispatcher.cc
index 94413c4..d3e17fc 100644
--- a/content/renderer/quota_dispatcher.cc
+++ b/content/renderer/quota_dispatcher.cc
@@ -21,7 +21,6 @@
 using blink::QuotaStatusCode;
 using blink::StorageType;
 using blink::WebStorageQuotaCallbacks;
-using blink::WebStorageQuotaError;
 
 namespace content {
 
@@ -30,30 +29,6 @@
 
 namespace {
 
-// QuotaDispatcher::Callback implementation for WebStorageQuotaCallbacks.
-class WebStorageQuotaDispatcherCallback : public QuotaDispatcher::Callback {
- public:
-  explicit WebStorageQuotaDispatcherCallback(
-      blink::WebStorageQuotaCallbacks callback)
-      : callbacks_(callback) {}
-  ~WebStorageQuotaDispatcherCallback() override {}
-
-  void DidQueryStorageUsageAndQuota(int64_t usage, int64_t quota) override {
-    callbacks_.DidQueryStorageUsageAndQuota(usage, quota);
-  }
-  void DidGrantStorageQuota(int64_t usage, int64_t granted_quota) override {
-    callbacks_.DidGrantStorageQuota(usage, granted_quota);
-  }
-  void DidFail(QuotaStatusCode error) override {
-    callbacks_.DidFail(static_cast<WebStorageQuotaError>(error));
-  }
-
- private:
-  blink::WebStorageQuotaCallbacks callbacks_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebStorageQuotaDispatcherCallback);
-};
-
 int CurrentWorkerId() {
   return WorkerThread::GetCurrentId();
 }
@@ -83,7 +58,7 @@
 }
 
 QuotaDispatcher::~QuotaDispatcher() {
-  base::IDMap<std::unique_ptr<Callback>>::iterator iter(
+  base::IDMap<std::unique_ptr<WebStorageQuotaCallbacks>>::iterator iter(
       &pending_quota_callbacks_);
   while (!iter.IsAtEnd()) {
     iter.GetCurrentValue()->DidFail(blink::QuotaStatusCode::kErrorAbort);
@@ -111,7 +86,7 @@
 void QuotaDispatcher::QueryStorageUsageAndQuota(
     const url::Origin& origin,
     StorageType type,
-    std::unique_ptr<Callback> callback) {
+    std::unique_ptr<WebStorageQuotaCallbacks> callback) {
   DCHECK(callback);
   int request_id = pending_quota_callbacks_.Add(std::move(callback));
   quota_host_->QueryStorageUsageAndQuota(
@@ -120,11 +95,12 @@
                      base::Unretained(this), request_id));
 }
 
-void QuotaDispatcher::RequestStorageQuota(int render_frame_id,
-                                          const url::Origin& origin,
-                                          StorageType type,
-                                          int64_t requested_size,
-                                          std::unique_ptr<Callback> callback) {
+void QuotaDispatcher::RequestStorageQuota(
+    int render_frame_id,
+    const url::Origin& origin,
+    StorageType type,
+    int64_t requested_size,
+    std::unique_ptr<WebStorageQuotaCallbacks> callback) {
   DCHECK(callback);
   DCHECK_EQ(CurrentWorkerId(), 0)
       << "Requests may show permission UI and are not allowed from workers.";
@@ -135,13 +111,6 @@
                      base::Unretained(this), request_id));
 }
 
-// static
-std::unique_ptr<QuotaDispatcher::Callback>
-QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(
-    blink::WebStorageQuotaCallbacks callbacks) {
-  return std::make_unique<WebStorageQuotaDispatcherCallback>(callbacks);
-}
-
 void QuotaDispatcher::DidGrantStorageQuota(int64_t request_id,
                                            QuotaStatusCode status,
                                            int64_t current_usage,
@@ -151,7 +120,8 @@
     return;
   }
 
-  Callback* callback = pending_quota_callbacks_.Lookup(request_id);
+  WebStorageQuotaCallbacks* callback =
+      pending_quota_callbacks_.Lookup(request_id);
   DCHECK(callback);
   callback->DidGrantStorageQuota(current_usage, granted_quota);
   pending_quota_callbacks_.Remove(request_id);
@@ -166,7 +136,8 @@
     return;
   }
 
-  Callback* callback = pending_quota_callbacks_.Lookup(request_id);
+  WebStorageQuotaCallbacks* callback =
+      pending_quota_callbacks_.Lookup(request_id);
   DCHECK(callback);
   callback->DidQueryStorageUsageAndQuota(current_usage, current_quota);
   pending_quota_callbacks_.Remove(request_id);
@@ -175,17 +146,11 @@
 void QuotaDispatcher::DidFail(
     int request_id,
     QuotaStatusCode error) {
-  Callback* callback = pending_quota_callbacks_.Lookup(request_id);
+  WebStorageQuotaCallbacks* callback =
+      pending_quota_callbacks_.Lookup(request_id);
   DCHECK(callback);
   callback->DidFail(error);
   pending_quota_callbacks_.Remove(request_id);
 }
 
-static_assert(int(blink::kWebStorageQuotaErrorNotSupported) ==
-                  int(blink::QuotaStatusCode::kErrorNotSupported),
-              "mismatching enums: kQuotaErrorNotSupported");
-static_assert(int(blink::kWebStorageQuotaErrorAbort) ==
-                  int(blink::QuotaStatusCode::kErrorAbort),
-              "mismatching enums: kQuotaErrorAbort");
-
 }  // namespace content
diff --git a/content/renderer/quota_dispatcher.h b/content/renderer/quota_dispatcher.h
index 2b3c82f..107cff2b 100644
--- a/content/renderer/quota_dispatcher.h
+++ b/content/renderer/quota_dispatcher.h
@@ -33,16 +33,6 @@
 // TODO(sashab): Change this to be per-execution context instead of per-process.
 class QuotaDispatcher : public WorkerThread::Observer {
  public:
-  // TODO(sashab): Remove this wrapper, using lambdas or just the web callback
-  // itself.
-  class Callback {
-   public:
-    virtual ~Callback() {}
-    virtual void DidQueryStorageUsageAndQuota(int64_t usage, int64_t quota) = 0;
-    virtual void DidGrantStorageQuota(int64_t usage, int64_t granted_quota) = 0;
-    virtual void DidFail(blink::QuotaStatusCode status) = 0;
-  };
-
   explicit QuotaDispatcher(
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
   ~QuotaDispatcher() override;
@@ -53,18 +43,16 @@
   // WorkerThread::Observer implementation.
   void WillStopCurrentWorkerThread() override;
 
-  void QueryStorageUsageAndQuota(const url::Origin& origin,
-                                 blink::StorageType type,
-                                 std::unique_ptr<Callback> callback);
-  void RequestStorageQuota(int render_frame_id,
-                           const url::Origin& origin,
-                           blink::StorageType type,
-                           int64_t requested_size,
-                           std::unique_ptr<Callback> callback);
-
-  // Creates a new Callback instance for WebStorageQuotaCallbacks.
-  static std::unique_ptr<Callback> CreateWebStorageQuotaCallbacksWrapper(
-      blink::WebStorageQuotaCallbacks callbacks);
+  void QueryStorageUsageAndQuota(
+      const url::Origin& origin,
+      blink::StorageType type,
+      std::unique_ptr<blink::WebStorageQuotaCallbacks> callback);
+  void RequestStorageQuota(
+      int render_frame_id,
+      const url::Origin& origin,
+      blink::StorageType type,
+      int64_t requested_size,
+      std::unique_ptr<blink::WebStorageQuotaCallbacks> callback);
 
  private:
   // Message handlers.
@@ -84,7 +72,8 @@
   // TODO(sashab, nverne): Once default callbacks are available for dropped mojo
   // callbacks (crbug.com/775358), use them to call DidFail for them in the
   // destructor and remove this.
-  base::IDMap<std::unique_ptr<Callback>> pending_quota_callbacks_;
+  base::IDMap<std::unique_ptr<blink::WebStorageQuotaCallbacks>>
+      pending_quota_callbacks_;
 
   DISALLOW_COPY_AND_ASSIGN(QuotaDispatcher);
 };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index a035583a..017b43df 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5116,12 +5116,12 @@
   WebSecurityOrigin origin = frame_->GetDocument().GetSecurityOrigin();
   if (origin.IsUnique()) {
     // Unique origins cannot store persistent state.
-    callbacks.DidFail(blink::kWebStorageQuotaErrorAbort);
+    callbacks.DidFail(blink::QuotaStatusCode::kErrorAbort);
     return;
   }
   RenderThreadImpl::current()->quota_dispatcher()->RequestStorageQuota(
       routing_id_, origin, type, requested_size,
-      QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
+      std::make_unique<blink::WebStorageQuotaCallbacks>(callbacks));
 }
 
 blink::WebPresentationClient* RenderFrameImpl::PresentationClient() {
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 186a82a0..fef03d7 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1167,7 +1167,7 @@
   compositor_thread_ =
       blink::scheduler::WebThreadBase::CreateCompositorThread(options);
   blink_platform_impl_->SetCompositorThread(compositor_thread_.get());
-  compositor_task_runner_ = compositor_thread_->GetTaskRunner();
+  compositor_task_runner_ = compositor_thread_->GetSingleThreadTaskRunner();
   compositor_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed),
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index f570eff..a3b1b02 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -236,7 +236,6 @@
 using blink::WebSettings;
 using blink::WebSize;
 using blink::WebStorageQuotaCallbacks;
-using blink::WebStorageQuotaError;
 using blink::WebString;
 using blink::WebTappedInfo;
 using blink::WebTextDirection;
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index ca0bdc5..0e7d9b48 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -1373,7 +1373,7 @@
   QuotaDispatcher::ThreadSpecificInstance(default_task_runner_)
       ->QueryStorageUsageAndQuota(
           storage_partition, type,
-          QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
+          std::make_unique<blink::WebStorageQuotaCallbacks>(callbacks));
 }
 
 //------------------------------------------------------------------------------
diff --git a/content/renderer/screen_orientation/screen_orientation_dispatcher.cc b/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
index 63f35a80b89..a3d479d 100644
--- a/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
+++ b/content/renderer/screen_orientation/screen_orientation_dispatcher.cc
@@ -26,42 +26,39 @@
 void ScreenOrientationDispatcher::OnLockOrientationResult(
     int request_id,
     ScreenOrientationLockResult result) {
-  blink::WebLockOrientationCallback* callback =
-      pending_callbacks_.Lookup(request_id);
-  if (!callback)
+  if (!pending_callback_ || request_id != request_id_)
     return;
 
   switch (result) {
     case ScreenOrientationLockResult::SCREEN_ORIENTATION_LOCK_RESULT_SUCCESS:
-      callback->OnSuccess();
+      pending_callback_->OnSuccess();
       break;
     case ScreenOrientationLockResult::
         SCREEN_ORIENTATION_LOCK_RESULT_ERROR_NOT_AVAILABLE:
-      callback->OnError(blink::kWebLockOrientationErrorNotAvailable);
+      pending_callback_->OnError(blink::kWebLockOrientationErrorNotAvailable);
       break;
     case ScreenOrientationLockResult::
         SCREEN_ORIENTATION_LOCK_RESULT_ERROR_FULLSCREEN_REQUIRED:
-      callback->OnError(blink::kWebLockOrientationErrorFullscreenRequired);
+      pending_callback_->OnError(
+          blink::kWebLockOrientationErrorFullscreenRequired);
       break;
     case ScreenOrientationLockResult::
         SCREEN_ORIENTATION_LOCK_RESULT_ERROR_CANCELED:
-      callback->OnError(blink::kWebLockOrientationErrorCanceled);
+      pending_callback_->OnError(blink::kWebLockOrientationErrorCanceled);
       break;
     default:
       NOTREACHED();
       break;
   }
 
-  pending_callbacks_.Remove(request_id);
+  pending_callback_.reset();
 }
 
 void ScreenOrientationDispatcher::CancelPendingLocks() {
-  for (CallbackMap::Iterator<blink::WebLockOrientationCallback>
-       iterator(&pending_callbacks_); !iterator.IsAtEnd(); iterator.Advance()) {
-    iterator.GetCurrentValue()->OnError(
-        blink::kWebLockOrientationErrorCanceled);
-    pending_callbacks_.Remove(iterator.GetCurrentKey());
-  }
+  if (!pending_callback_)
+    return;
+  pending_callback_->OnError(blink::kWebLockOrientationErrorCanceled);
+  pending_callback_.reset();
 }
 
 void ScreenOrientationDispatcher::LockOrientation(
@@ -69,12 +66,12 @@
     std::unique_ptr<blink::WebLockOrientationCallback> callback) {
   CancelPendingLocks();
 
-  int request_id = pending_callbacks_.Add(std::move(callback));
+  pending_callback_ = std::move(callback);
   EnsureScreenOrientationService();
   screen_orientation_->LockOrientation(
       orientation,
       base::BindOnce(&ScreenOrientationDispatcher::OnLockOrientationResult,
-                     base::Unretained(this), request_id));
+                     base::Unretained(this), ++request_id_));
 }
 
 void ScreenOrientationDispatcher::UnlockOrientation() {
@@ -83,6 +80,10 @@
   screen_orientation_->UnlockOrientation();
 }
 
+int ScreenOrientationDispatcher::GetRequestIdForTests() {
+  return pending_callback_ ? request_id_ : -1;
+}
+
 void ScreenOrientationDispatcher::EnsureScreenOrientationService() {
   if (!screen_orientation_) {
     render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
@@ -90,12 +91,4 @@
   }
 }
 
-int ScreenOrientationDispatcher::GetRequestIdForTests() {
-  if (pending_callbacks_.IsEmpty())
-    return -1;
-  CallbackMap::Iterator<blink::WebLockOrientationCallback> iterator(
-      &pending_callbacks_);
-  return iterator.GetCurrentKey();
-}
-
 }  // namespace content
diff --git a/content/renderer/screen_orientation/screen_orientation_dispatcher.h b/content/renderer/screen_orientation/screen_orientation_dispatcher.h
index 97b97080..3cf5598 100644
--- a/content/renderer/screen_orientation/screen_orientation_dispatcher.h
+++ b/content/renderer/screen_orientation/screen_orientation_dispatcher.h
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/compiler_specific.h"
-#include "base/containers/id_map.h"
 #include "base/macros.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "device/screen_orientation/public/interfaces/screen_orientation.mojom.h"
@@ -63,14 +62,8 @@
     screen_orientation_ = std::move(screen_orientation_for_tests);
   }
 
-  // The pending_callbacks_ map is mostly meant to have a unique ID to associate
-  // with every callback going trough the dispatcher. The map will own the
-  // pointer in the sense that it will destroy it when Remove() will be called.
-  // Furthermore, we only expect to have one callback at a time in this map,
-  // which is what IDMap was designed for.
-  using CallbackMap =
-      base::IDMap<std::unique_ptr<blink::WebLockOrientationCallback>>;
-  CallbackMap pending_callbacks_;
+  std::unique_ptr<blink::WebLockOrientationCallback> pending_callback_;
+  int request_id_ = 0;
 
   ScreenOrientationAssociatedPtr screen_orientation_;
 
diff --git a/content/test/test_navigation_url_loader.cc b/content/test/test_navigation_url_loader.cc
index 853cd74..2e262b39 100644
--- a/content/test/test_navigation_url_loader.cc
+++ b/content/test/test_navigation_url_loader.cc
@@ -6,10 +6,10 @@
 
 #include <utility>
 
+#include "base/values.h"
 #include "content/browser/loader/navigation_url_loader_delegate.h"
 #include "content/common/navigation_subresource_loader_params.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/ssl_status.h"
@@ -63,7 +63,7 @@
 void TestNavigationURLLoader::CallOnResponseStarted(
     const scoped_refptr<ResourceResponse>& response,
     std::unique_ptr<StreamHandle> body,
-    std::unique_ptr<NavigationData> navigation_data) {
+    base::Value navigation_data) {
   // Start the request_ids at 1000 to avoid collisions with request ids from
   // network resources (it should be rare to compare these in unit tests).
   static int request_id = 1000;
diff --git a/content/test/test_navigation_url_loader.h b/content/test/test_navigation_url_loader.h
index 8edcdfc..56bb0de 100644
--- a/content/test/test_navigation_url_loader.h
+++ b/content/test/test_navigation_url_loader.h
@@ -12,13 +12,16 @@
 #include "content/browser/loader/navigation_url_loader.h"
 #include "content/common/navigation_params.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 struct RedirectInfo;
 }
 
 namespace content {
 
-class NavigationData;
 class NavigationURLLoaderDelegate;
 class StreamHandle;
 struct ResourceResponse;
@@ -47,7 +50,7 @@
                                const scoped_refptr<ResourceResponse>& response);
   void CallOnResponseStarted(const scoped_refptr<ResourceResponse>& response,
                              std::unique_ptr<StreamHandle> body,
-                             std::unique_ptr<NavigationData> navigation_data);
+                             base::Value navigation_data);
 
   int redirect_count() { return redirect_count_; }
 
diff --git a/content/test/test_navigation_url_loader_delegate.cc b/content/test/test_navigation_url_loader_delegate.cc
index 19311a19..0b43d87 100644
--- a/content/test/test_navigation_url_loader_delegate.cc
+++ b/content/test/test_navigation_url_loader_delegate.cc
@@ -7,7 +7,6 @@
 #include "base/run_loop.h"
 #include "content/common/navigation_subresource_loader_params.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/stream_handle.h"
 #include "content/public/common/resource_response.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -62,7 +61,7 @@
     mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
     std::unique_ptr<StreamHandle> body,
     const net::SSLInfo& ssl_info,
-    std::unique_ptr<NavigationData> navigation_data,
+    base::Value navigation_data,
     const GlobalRequestID& request_id,
     bool is_download,
     bool is_stream,
diff --git a/content/test/test_navigation_url_loader_delegate.h b/content/test/test_navigation_url_loader_delegate.h
index e0a6941..346f119d 100644
--- a/content/test/test_navigation_url_loader_delegate.h
+++ b/content/test/test_navigation_url_loader_delegate.h
@@ -62,7 +62,7 @@
       mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
       std::unique_ptr<StreamHandle> body,
       const net::SSLInfo& ssl_info,
-      std::unique_ptr<NavigationData> navigation_data,
+      base::Value navigation_data,
       const GlobalRequestID& request_id,
       bool is_download,
       bool is_stream,
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index b900bc3..17d14c19 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -9,6 +9,7 @@
 
 #include "base/guid.h"
 #include "base/run_loop.h"
+#include "base/values.h"
 #include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/browser/frame_host/navigation_request.h"
@@ -586,7 +587,9 @@
   response->head.socket_address = socket_address;
   // TODO(carlosk): ideally with PlzNavigate it should be possible someday to
   // fully commit the navigation at this call to CallOnResponseStarted.
-  url_loader->CallOnResponseStarted(response, MakeEmptyStream(), nullptr);
+  url_loader->CallOnResponseStarted(
+      response, MakeEmptyStream(), base::Value()  // navigation_data
+      );
 }
 
 void TestRenderFrameHost::PrepareForCommitIfNecessary() {
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc
index 0b698b7..e20dcda 100644
--- a/content/test/test_web_contents.cc
+++ b/content/test/test_web_contents.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/values.h"
 #include "content/browser/browser_url_handler_impl.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
 #include "content/browser/frame_host/debug_urls.h"
@@ -20,7 +21,6 @@
 #include "content/common/frame_messages.h"
 #include "content/common/render_message_filter.mojom.h"
 #include "content/common/view_messages.h"
-#include "content/public/browser/navigation_data.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
@@ -328,9 +328,8 @@
   frame_tree_.root()->current_frame_host()->OnMessageReceived(msg);
 }
 
-void TestWebContents::SetNavigationData(
-    NavigationHandle* navigation_handle,
-    std::unique_ptr<NavigationData> navigation_data) {
+void TestWebContents::SetNavigationData(NavigationHandle* navigation_handle,
+                                        base::Value navigation_data) {
   static_cast<NavigationHandleImpl*>(navigation_handle)
       ->set_navigation_data(std::move(navigation_data));
 }
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h
index 9f54971..af13411 100644
--- a/content/test/test_web_contents.h
+++ b/content/test/test_web_contents.h
@@ -22,6 +22,10 @@
 class Referrer;
 class SkBitmap;
 
+namespace base {
+class Value;
+}
+
 namespace gfx {
 class Size;
 }
@@ -32,7 +36,6 @@
 
 namespace content {
 
-class NavigationData;
 class NavigationHandle;
 class RenderViewHost;
 class TestRenderViewHost;
@@ -134,9 +137,8 @@
                                 int error_code,
                                 const base::string16& error_description);
 
-  void SetNavigationData(
-      NavigationHandle* navigation_handle,
-      std::unique_ptr<NavigationData> navigation_data) override;
+  void SetNavigationData(NavigationHandle* navigation_handle,
+                         base::Value navigation_data) override;
 
   void SetHttpResponseHeaders(
       NavigationHandle* navigation_handle,
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn
index f02d81b..603e21b 100644
--- a/device/gamepad/BUILD.gn
+++ b/device/gamepad/BUILD.gn
@@ -15,6 +15,8 @@
   sources = [
     "abstract_haptic_gamepad.cc",
     "abstract_haptic_gamepad.h",
+    "dualshock4_controller_base.cc",
+    "dualshock4_controller_base.h",
     "game_controller_data_fetcher_mac.h",
     "game_controller_data_fetcher_mac.mm",
     "gamepad_consumer.cc",
diff --git a/device/gamepad/dualshock4_controller_base.cc b/device/gamepad/dualshock4_controller_base.cc
new file mode 100644
index 0000000..36ac47b4
--- /dev/null
+++ b/device/gamepad/dualshock4_controller_base.cc
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/gamepad/dualshock4_controller_base.h"
+
+namespace {
+const uint32_t kVendorSony = 0x054c;
+const uint32_t kProductDualshock4 = 0x05c4;
+const uint32_t kProductDualshock4Slim = 0x9cc;
+const uint8_t kRumbleMagnitudeMax = 0xff;
+
+enum ControllerType {
+  UNKNOWN_CONTROLLER,
+  DUALSHOCK4_CONTROLLER,
+  DUALSHOCK4_SLIM_CONTROLLER
+};
+
+ControllerType ControllerTypeFromDeviceIds(int vendor_id, int product_id) {
+  if (vendor_id == kVendorSony) {
+    switch (product_id) {
+      case kProductDualshock4:
+        return DUALSHOCK4_CONTROLLER;
+      case kProductDualshock4Slim:
+        return DUALSHOCK4_SLIM_CONTROLLER;
+      default:
+        break;
+    }
+  }
+  return UNKNOWN_CONTROLLER;
+}
+
+}  // namespace
+
+namespace device {
+
+Dualshock4ControllerBase::~Dualshock4ControllerBase() = default;
+
+// static
+bool Dualshock4ControllerBase::IsDualshock4(int vendor_id, int product_id) {
+  return ControllerTypeFromDeviceIds(vendor_id, product_id) !=
+         UNKNOWN_CONTROLLER;
+}
+
+void Dualshock4ControllerBase::SetVibration(double strong_magnitude,
+                                            double weak_magnitude) {
+  const size_t report_length = 32;
+  uint8_t control_report[report_length];
+  memset(control_report, 0, report_length);
+  control_report[0] = 0x05;  // report ID
+  control_report[1] = 0x01;  // motor only, don't update LEDs
+  control_report[4] =
+      static_cast<uint8_t>(weak_magnitude * kRumbleMagnitudeMax);
+  control_report[5] =
+      static_cast<uint8_t>(strong_magnitude * kRumbleMagnitudeMax);
+
+  WriteOutputReport(control_report, report_length);
+}
+
+}  // namespace device
diff --git a/device/gamepad/dualshock4_controller_base.h b/device/gamepad/dualshock4_controller_base.h
new file mode 100644
index 0000000..555eca7c
--- /dev/null
+++ b/device/gamepad/dualshock4_controller_base.h
@@ -0,0 +1,26 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_GAMEPAD_DUALSHOCK4_CONTROLLER_BASE_
+#define DEVICE_GAMEPAD_DUALSHOCK4_CONTROLLER_BASE_
+
+#include "device/gamepad/abstract_haptic_gamepad.h"
+
+namespace device {
+
+class Dualshock4ControllerBase : public AbstractHapticGamepad {
+ public:
+  Dualshock4ControllerBase() = default;
+  ~Dualshock4ControllerBase() override;
+
+  static bool IsDualshock4(int vendor_id, int product_id);
+
+ private:
+  void SetVibration(double strong_magnitude, double weak_magnitude) override;
+  virtual void WriteOutputReport(void* report, size_t report_length) {}
+};
+
+}  // namespace device
+
+#endif  // DEVICE_GAMEPAD_DUALSHOCK4_CONTROLLER_BASE_
diff --git a/docs/speed/perf_bot_sheriffing.md b/docs/speed/perf_bot_sheriffing.md
index f812b1537..303f5fc 100644
--- a/docs/speed/perf_bot_sheriffing.md
+++ b/docs/speed/perf_bot_sheriffing.md
@@ -335,6 +335,12 @@
 immediately, disable the story on the failing platforms.
 
 You can do this with [Expectations](https://cs.chromium.org/chromium/src/tools/perf/expectations.config).
+
+Disabling CLs can be TBR-ed to anyone in
+[tools/perf/OWNERS](https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/OWNERS).
+As long as the disabling CL touches only tools/perf/expectations.config, you can
+use TBR and NOTRY=true to submit the CL immediately.
+
 An expectation is a line in the expectations file in the following format:
 ```
 reason [ conditions ] benchmark/story [ Skip ]
@@ -385,10 +391,6 @@
 crbug.com/123456 [ CONDITIONS ] memory_benchmark/* [ Skip ]
 ```
 
-Disabling CLs can be TBR-ed to anyone in [tools/perf/OWNERS](https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/OWNERS),
-As long as a disabling CL touches only tools/perf/expectations.config, you can
-use TBR and NOTRY=true to submit the CL immediately.
-
 ### Disabling Other Tests
 
 Non-telemetry tests are configured in [chromium.perf.json](https://code.google.com/p/chromium/codesearch#chromium/src/testing/buildbot/chromium.perf.json) **But do not manually edit this file.**
diff --git a/headless/public/util/generic_url_request_job.cc b/headless/public/util/generic_url_request_job.cc
index e865fae..8095d94c 100644
--- a/headless/public/util/generic_url_request_job.cc
+++ b/headless/public/util/generic_url_request_job.cc
@@ -143,6 +143,34 @@
   body_size_ = body_size;
   load_timing_info_ = load_timing_info;
 
+  // Save any cookies from the response.
+  if (!(request_->load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES) &&
+      request_->context()->cookie_store()) {
+    net::CookieOptions options;
+    options.set_include_httponly();
+
+    base::Time response_date;
+    if (!response_headers_->GetDateValue(&response_date))
+      response_date = base::Time();
+    options.set_server_time(response_date);
+
+    // Set all cookies, without waiting for them to be set. Any subsequent read
+    // will see the combined result of all cookie operation.
+    const base::StringPiece name("Set-Cookie");
+    std::string cookie_line;
+    size_t iter = 0;
+    while (response_headers_->EnumerateHeader(&iter, name, &cookie_line)) {
+      std::unique_ptr<net::CanonicalCookie> cookie =
+          net::CanonicalCookie::Create(final_url, cookie_line,
+                                       base::Time::Now(), options);
+      if (!cookie || !CanSetCookie(*cookie, &options))
+        continue;
+      request_->context()->cookie_store()->SetCanonicalCookieAsync(
+          std::move(cookie), final_url.SchemeIsCryptographic(),
+          !options.exclude_httponly(), net::CookieStore::SetCookiesCallback());
+    }
+  }
+
   DispatchHeadersComplete();
 
   delegate_->OnResourceLoadComplete(this, final_url, response_headers_, body_,
diff --git a/headless/public/util/generic_url_request_job_test.cc b/headless/public/util/generic_url_request_job_test.cc
index f59c63b..d1188b54 100644
--- a/headless/public/util/generic_url_request_job_test.cc
+++ b/headless/public/util/generic_url_request_job_test.cc
@@ -27,7 +27,11 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using testing::AllOf;
+using testing::ElementsAre;
+using testing::Eq;
 using testing::NotNull;
+using testing::Property;
 using testing::_;
 
 std::ostream& operator<<(std::ostream& os, const base::DictionaryValue& value) {
@@ -519,6 +523,27 @@
   EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json));
 }
 
+TEST_F(GenericURLRequestJobTest, ResponseWithCookies) {
+  std::string reply = R"(
+      {
+        "url": "https://example.com",
+        "data": "Reply",
+        "headers": {
+          "Set-Cookie": "A=foobar; path=/; "
+        }
+      })";
+
+  std::unique_ptr<net::URLRequest> request(
+      CreateAndCompleteGetJob(GURL("https://example.com"), reply));
+
+  EXPECT_THAT(*cookie_store_.cookies(),
+              ElementsAre(AllOf(
+                  Property(&net::CanonicalCookie::Name, Eq("A")),
+                  Property(&net::CanonicalCookie::Value, Eq("foobar")),
+                  Property(&net::CanonicalCookie::Domain, Eq("example.com")),
+                  Property(&net::CanonicalCookie::Path, Eq("/")))));
+}
+
 TEST_F(GenericURLRequestJobTest, OnResourceLoadFailed) {
   EXPECT_CALL(job_delegate_,
               OnResourceLoadFailed(_, net::ERR_ADDRESS_UNREACHABLE));
diff --git a/headless/public/util/testing/generic_url_request_mocks.cc b/headless/public/util/testing/generic_url_request_mocks.cc
index 9c20668..7d4d2e7 100644
--- a/headless/public/util/testing/generic_url_request_mocks.cc
+++ b/headless/public/util/testing/generic_url_request_mocks.cc
@@ -50,7 +50,7 @@
     bool secure_source,
     bool can_modify_httponly,
     SetCookiesCallback callback) {
-  CHECK(false);
+  cookies_.push_back(std::move(*cookie));
 }
 
 void MockCookieStore::GetCookiesWithOptionsAsync(
diff --git a/ios/chrome/app/chrome_overlay_window.h b/ios/chrome/app/chrome_overlay_window.h
index 4ba7c79..70b2a558 100644
--- a/ios/chrome/app/chrome_overlay_window.h
+++ b/ios/chrome/app/chrome_overlay_window.h
@@ -7,8 +7,7 @@
 
 #import "ios/third_party/material_components_ios/src/components/OverlayWindow/src/MaterialOverlayWindow.h"
 
-// Tracks size classes changes and kTabModelTabDidFinishLoadingNotification
-// then reports to SizeClassRecorder and Breakpad.
+// Tracks size classes changes then reports to SizeClassRecorder and Breakpad.
 @interface ChromeOverlayWindow : MDCOverlayWindow
 @end
 
diff --git a/ios/chrome/app/chrome_overlay_window.mm b/ios/chrome/app/chrome_overlay_window.mm
index 16e0706b..869e50c 100644
--- a/ios/chrome/app/chrome_overlay_window.mm
+++ b/ios/chrome/app/chrome_overlay_window.mm
@@ -55,12 +55,6 @@
   if (IsIPadIdiom()) {
     _sizeClassRecorder = [[SizeClassRecorder alloc]
         initWithHorizontalSizeClass:self.traitCollection.horizontalSizeClass];
-    // Remove use of this notification.
-    [[NSNotificationCenter defaultCenter]
-        addObserver:self
-           selector:@selector(pageLoaded:)
-               name:kTabModelTabDidFinishLoadingNotification
-             object:nil];
   }
 }
 
@@ -85,14 +79,6 @@
   }
 }
 
-#pragma mark - Notification handler
-
-- (void)pageLoaded:(NSNotification*)notification {
-  [_sizeClassRecorder
-      pageLoadedWithHorizontalSizeClass:self.traitCollection
-                                            .horizontalSizeClass];
-}
-
 #pragma mark - Testing methods
 
 - (void)unsetSizeClassRecorder {
diff --git a/ios/chrome/app/spotlight/base_spotlight_manager.h b/ios/chrome/app/spotlight/base_spotlight_manager.h
index b9280d9..32ff1033 100644
--- a/ios/chrome/app/spotlight/base_spotlight_manager.h
+++ b/ios/chrome/app/spotlight/base_spotlight_manager.h
@@ -8,7 +8,6 @@
 #import <CoreSpotlight/CoreSpotlight.h>
 #import <UIKit/UIKit.h>
 
-#include "base/mac/scoped_nsobject.h"
 #include "ios/chrome/app/spotlight/spotlight_util.h"
 
 class GURL;
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index bcb9abc8..03a244b8 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -127,6 +127,7 @@
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/history:history_base_feature",
     "//ios/chrome/browser/ui/main:feature_flags",
+    "//ios/chrome/browser/ui/omnibox",
     "//ios/chrome/browser/ui/toolbar:feature",
     "//ios/chrome/browser/ui/toolbar/public:toolbar_base_feature",
     "//ios/chrome/common",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index f38d8d6..8dbd00e9 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -46,6 +46,7 @@
 #include "ios/chrome/browser/ui/fullscreen/fullscreen_features.h"
 #import "ios/chrome/browser/ui/history/history_base_feature.h"
 #include "ios/chrome/browser/ui/main/main_feature_flags.h"
+#import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -185,6 +186,9 @@
     {"clean-toolbar", flag_descriptions::kCleanToolbarName,
      flag_descriptions::kCleanToolbarDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kCleanToolbar)},
+    {"clipping-textfield", flag_descriptions::kClippingTextfieldName,
+     flag_descriptions::kClippingTextfieldDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(kClippingTextfield)},
     {"bookmark-new-edit-page", flag_descriptions::kBookmarkNewEditPageName,
      flag_descriptions::kBookmarkNewEditPageDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kBookmarkNewEditPage)},
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index a2d9890d..788a47d37 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -35,6 +35,11 @@
     "When enabled, the Clean Toolbar will be used instead of "
     "WebToolbarController.";
 
+const char kClippingTextfieldName[] = "Clipping Textfield";
+const char kClippingTextfieldDescription[] =
+    "When enabled, the new URL clipping implementation compatible with iOS 11 "
+    "is used.";
+
 const char kContextualSearch[] = "Contextual Search";
 const char kContextualSearchDescription[] =
     "Whether or not Contextual Search is enabled.";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 3554ac2..4b868893 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -29,6 +29,10 @@
 extern const char kCleanToolbarName[];
 extern const char kCleanToolbarDescription[];
 
+// Title and description for the flag to enable Omnibox Clipping.
+extern const char kClippingTextfieldName[];
+extern const char kClippingTextfieldDescription[];
+
 // Title and description for the flag to enable Contextual Search.
 extern const char kContextualSearch[];
 extern const char kContextualSearchDescription[];
diff --git a/ios/chrome/browser/metrics/size_class_recorder.h b/ios/chrome/browser/metrics/size_class_recorder.h
index fa5807d..1932ebb7d 100644
--- a/ios/chrome/browser/metrics/size_class_recorder.h
+++ b/ios/chrome/browser/metrics/size_class_recorder.h
@@ -21,7 +21,7 @@
 
 // Call this class method when a page has loaded to record the size class at
 // that time. It will be reported inder Tab.PageLoadInHorizontalSizeClass.
-- (void)pageLoadedWithHorizontalSizeClass:(UIUserInterfaceSizeClass)sizeClass;
++ (void)pageLoadedWithHorizontalSizeClass:(UIUserInterfaceSizeClass)sizeClass;
 
 @end
 
diff --git a/ios/chrome/browser/metrics/size_class_recorder.mm b/ios/chrome/browser/metrics/size_class_recorder.mm
index 70763f3f..de82926 100644
--- a/ios/chrome/browser/metrics/size_class_recorder.mm
+++ b/ios/chrome/browser/metrics/size_class_recorder.mm
@@ -79,15 +79,6 @@
   return self;
 }
 
-- (instancetype)init {
-  NOTREACHED();
-  return nil;
-}
-
-- (void)dealloc {
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
 - (void)horizontalSizeClassDidChange:(UIUserInterfaceSizeClass)newSizeClass {
   // iOS sometimes changes from Compact to Regular to Compact again when putting
   // the application in the background, to update the application screenshot.
@@ -97,7 +88,7 @@
   ReportHorizontalSizeClassUsed(newSizeClass);
 }
 
-- (void)pageLoadedWithHorizontalSizeClass:(UIUserInterfaceSizeClass)sizeClass {
++ (void)pageLoadedWithHorizontalSizeClass:(UIUserInterfaceSizeClass)sizeClass {
   SizeClassForReporting sizeClassForReporting =
       SizeClassForReporting(sizeClass);
   UMA_HISTOGRAM_ENUMERATION("Tab.PageLoadInHorizontalSizeClass",
diff --git a/ios/chrome/browser/metrics/size_class_recorder_unittest.mm b/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
index d4997d9..15bb216 100644
--- a/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
+++ b/ios/chrome/browser/metrics/size_class_recorder_unittest.mm
@@ -171,7 +171,7 @@
 
   recorder_ = [[SizeClassRecorder alloc]
       initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
-  [recorder_
+  [[recorder_ class]
       pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
@@ -187,7 +187,8 @@
 
   recorder_ = [[SizeClassRecorder alloc]
       initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
-  [recorder_ pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
+  [[recorder_ class]
+      pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
   histogram_tester_->ExpectUniqueSample(
@@ -202,7 +203,8 @@
 
   recorder_ = [[SizeClassRecorder alloc]
       initWithHorizontalSizeClass:UIUserInterfaceSizeClassUnspecified];
-  [recorder_ pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
+  [[recorder_ class]
+      pageLoadedWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
 
   histogram_tester_->ExpectTotalCount(kSizeClassUsedHistogramName, 0);
   histogram_tester_->ExpectUniqueSample(
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index a8734a3d..d4aad602 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -822,14 +822,6 @@
 
   [_parentTabModel notifyTabFinishedLoading:self success:loadSuccess];
 
-  if (_parentTabModel) {
-    // This notification is deprecated, and no further observers of it should
-    // be added.
-    [[NSNotificationCenter defaultCenter]
-        postNotificationName:kTabModelTabDidFinishLoadingNotification
-                      object:_parentTabModel];
-  }
-
   if (!self.isPrerenderTab) {
     [[OmniboxGeolocationController sharedInstance]
         finishPageLoadForTab:self
diff --git a/ios/chrome/browser/tabs/tab_model.h b/ios/chrome/browser/tabs/tab_model.h
index e1d3d7e..1dfbf21 100644
--- a/ios/chrome/browser/tabs/tab_model.h
+++ b/ios/chrome/browser/tabs/tab_model.h
@@ -32,20 +32,6 @@
 class WebState;
 }
 
-// When a tab finishes loading a URL, a notification with the following key is
-// sent. This notification is DEPRECATED and no further observers of it should
-// be added.
-// A tab finished loading a URL. The tab in question is in the userInfo under
-// kTabModelTabKey.
-extern NSString* const kTabModelTabDidFinishLoadingNotification;
-
-// All tabs have finished their shutdown sequences.
-// NOTE: This notification is not sent when closing a single tab that happens
-// to be the last tab.
-extern NSString* const kTabModelAllTabsDidCloseNotification;
-
-// ---------------------------------------------------------------------------
-
 namespace TabModelConstants {
 
 // Position the tab automatically. This value is used as index parameter in
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
index 16432ee85..95e6881 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -67,11 +67,6 @@
 #error "This file requires ARC support."
 #endif
 
-NSString* const kTabModelTabDidFinishLoadingNotification =
-    @"kTabModelTabDidFinishLoadingNotification";
-NSString* const kTabModelAllTabsDidCloseNotification =
-    @"kTabModelAllTabsDidCloseNotification";
-
 namespace {
 
 // Updates CRWSessionCertificatePolicyManager's certificate policy cache.
@@ -472,9 +467,7 @@
 
 - (void)closeAllTabs {
   _webStateList->CloseAllWebStates(WebStateList::CLOSE_USER_ACTION);
-  [[NSNotificationCenter defaultCenter]
-      postNotificationName:kTabModelAllTabsDidCloseNotification
-                    object:self];
+  [_observers tabModelClosedAllTabs:self];
 }
 
 - (void)haltAllTabs {
diff --git a/ios/chrome/browser/tabs/tab_model_observer.h b/ios/chrome/browser/tabs/tab_model_observer.h
index 40cc02ac5..ac970a1 100644
--- a/ios/chrome/browser/tabs/tab_model_observer.h
+++ b/ios/chrome/browser/tabs/tab_model_observer.h
@@ -24,6 +24,9 @@
 // The given tab will be removed.
 - (void)tabModel:(TabModel*)model willRemoveTab:(Tab*)tab;
 
+// All tabs in the model will close.
+- (void)tabModelClosedAllTabs:(TabModel*)model;
+
 // A tab was removed at the given index.
 - (void)tabModel:(TabModel*)model
     didRemoveTab:(Tab*)tab
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 429b04ba..81ba938 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -78,6 +78,7 @@
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/language/url_language_histogram_factory.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
+#import "ios/chrome/browser/metrics/size_class_recorder.h"
 #include "ios/chrome/browser/metrics/tab_usage_recorder.h"
 #import "ios/chrome/browser/passwords/password_controller.h"
 #include "ios/chrome/browser/passwords/password_tab_helper.h"
@@ -4711,6 +4712,11 @@
     didFinishLoadingTab:(Tab*)tab
                 success:(BOOL)success {
   [self tabLoadComplete:tab withSuccess:success];
+  if (IsIPadIdiom()) {
+    UIUserInterfaceSizeClass sizeClass =
+        self.view.window.traitCollection.horizontalSizeClass;
+    [SizeClassRecorder pageLoadedWithHorizontalSizeClass:sizeClass];
+  }
 }
 
 - (void)tabModel:(TabModel*)model
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view.mm b/ios/chrome/browser/ui/location_bar/location_bar_view.mm
index 65e99eb..e0bb2a24 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_view.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_view.mm
@@ -5,6 +5,8 @@
 #import "ios/chrome/browser/ui/location_bar/location_bar_view.h"
 
 #import "ios/chrome/browser/ui/animation_util.h"
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield_container.h"
+#import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h"
 #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
 #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -60,6 +62,10 @@
 // When the |leadingButton| is not hidden, this is a constraint that links the
 // leading edge of the button to self leading edge. Used for animations.
 @property(nonatomic, strong) NSLayoutConstraint* leadingButtonLeadingConstraint;
+// The textfield container. The |textField| is contained in it, and its frame
+// should not be managed directly, instead the location bar uses this container.
+// This is required to achieve desired text clipping of long URLs.
+@property(nonatomic, strong) ClippingTextFieldContainer* textFieldContainer;
 @end
 
 @implementation LocationBarView
@@ -68,6 +74,7 @@
 @synthesize leadingTextfieldConstraint = _leadingTextfieldConstraint;
 @synthesize incognito = _incognito;
 @synthesize leadingButtonLeadingConstraint = _leadingButtonLeadingConstraint;
+@synthesize textFieldContainer = _textFieldContainer;
 
 #pragma mark - Public properties
 
@@ -98,20 +105,55 @@
                                                        font:font
                                                   textColor:textColor
                                                   tintColor:tintColor];
-    [self addSubview:_textField];
 
-    _leadingTextfieldConstraint = [_textField.leadingAnchor
-        constraintEqualToAnchor:self.leadingAnchor
-                       constant:kTextFieldLeadingOffsetNoImage];
+    if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+      // When clipping is enabled, the text field is put into a container.
 
-    [NSLayoutConstraint activateConstraints:@[
-      [_textField.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
-      [_textField.topAnchor constraintEqualToAnchor:self.topAnchor],
-      [_textField.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
-      _leadingTextfieldConstraint,
-    ]];
+      // TODO(crbug.com/789968): remove these insets when the location bar
+      // background is managed by this view and not toolbar controller. These
+      // insets allow the gradient masking of the omnibox to not extend beyond
+      // the omnibox background's visible frame.
+      self.layoutMargins = UIEdgeInsetsMake(3, 3, 3, 3);
 
-    _textField.translatesAutoresizingMaskIntoConstraints = NO;
+      _textFieldContainer = [[ClippingTextFieldContainer alloc]
+          initWithClippingTextField:_textField];
+      [self addSubview:_textFieldContainer];
+
+      _leadingTextfieldConstraint = [_textFieldContainer.leadingAnchor
+          constraintEqualToAnchor:self.leadingAnchor
+                         constant:kTextFieldLeadingOffsetNoImage];
+
+      [NSLayoutConstraint activateConstraints:@[
+        [_textFieldContainer.trailingAnchor
+            constraintEqualToAnchor:self.layoutMarginsGuide.trailingAnchor],
+        [_textFieldContainer.topAnchor
+            constraintEqualToAnchor:self.layoutMarginsGuide.topAnchor],
+        [_textFieldContainer.bottomAnchor
+            constraintEqualToAnchor:self.layoutMarginsGuide.bottomAnchor],
+        _leadingTextfieldConstraint,
+      ]];
+
+      _textFieldContainer.translatesAutoresizingMaskIntoConstraints = NO;
+      [_textFieldContainer
+          setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
+                                          forAxis:
+                                              UILayoutConstraintAxisHorizontal];
+    } else {
+      // Contain the text field directly, with no clipping container.
+      [self addSubview:_textField];
+      _leadingTextfieldConstraint = [_textField.leadingAnchor
+          constraintEqualToAnchor:self.leadingAnchor
+                         constant:kTextFieldLeadingOffsetNoImage];
+
+      [NSLayoutConstraint activateConstraints:@[
+        [_textField.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+        [_textField.topAnchor constraintEqualToAnchor:self.topAnchor],
+        [_textField.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
+        _leadingTextfieldConstraint,
+      ]];
+
+      _textField.translatesAutoresizingMaskIntoConstraints = NO;
+    }
   }
   return self;
 }
@@ -127,15 +169,26 @@
   } else {
     [self addSubview:_leadingButton];
     self.leadingTextfieldConstraint.active = NO;
-    self.leadingButtonLeadingConstraint = [self.leadingAnchor
+    self.leadingButtonLeadingConstraint = [self.layoutMarginsGuide.leadingAnchor
         constraintEqualToAnchor:self.leadingButton.leadingAnchor
                        constant:-kLeadingButtonEdgeOffset];
-    [NSLayoutConstraint activateConstraints:@[
-      [_leadingButton.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
-      self.leadingButtonLeadingConstraint,
-      [self.leadingButton.trailingAnchor
+
+    NSLayoutConstraint* leadingButtonToTextField = nil;
+    if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+      leadingButtonToTextField = [self.leadingButton.trailingAnchor
+          constraintEqualToAnchor:self.textFieldContainer.leadingAnchor
+                         constant:-kTextFieldLeadingOffsetImage];
+    } else {
+      leadingButtonToTextField = [self.leadingButton.trailingAnchor
           constraintEqualToAnchor:self.textField.leadingAnchor
-                         constant:-kTextFieldLeadingOffsetImage],
+                         constant:-kTextFieldLeadingOffsetImage];
+    }
+
+    [NSLayoutConstraint activateConstraints:@[
+      [_leadingButton.centerYAnchor
+          constraintEqualToAnchor:self.layoutMarginsGuide.centerYAnchor],
+      self.leadingButtonLeadingConstraint,
+      leadingButtonToTextField,
     ]];
   }
 }
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm
index 553c8b3c..7c0eb02 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm
@@ -251,4 +251,9 @@
   [self.delegate updateNtpBarShadowForPanelController:self];
 }
 
+- (void)refreshSessionsViewRecentTabsTableViewController:
+    (RecentTabsTableViewController*)controller {
+  [self refreshSessionsView];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
index 05f131e..dbdae87 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
@@ -29,6 +29,10 @@
 @protocol RecentTabsTableViewControllerDelegate<NSObject>
 // Tells the delegate when the table view content scrolled or changed size.
 - (void)recentTabsTableViewContentMoved:(UITableView*)tableView;
+
+// Tells the delegate to refresh the session view.
+- (void)refreshSessionsViewRecentTabsTableViewController:
+    (RecentTabsTableViewController*)controller;
 @end
 
 // Controls the content of a UITableView.
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
index 20a65f9..8f44bcb 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
@@ -525,9 +525,10 @@
 #pragma mark - Distant Sessions helpers
 
 - (void)refreshUserState:(SessionsSyncUserState)newSessionState {
-  if (newSessionState == _sessionState &&
-      _sessionState !=
-          SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS) {
+  if ((newSessionState == _sessionState &&
+       _sessionState !=
+           SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS) ||
+      _signinPromoViewMediator.isSigninInProgress) {
     // No need to refresh the sections.
     return;
   }
@@ -1030,6 +1031,10 @@
   [configurator configureSigninPromoView:signinPromoView];
 }
 
+- (void)signinDidFinish {
+  [self.delegate refreshSessionsViewRecentTabsTableViewController:self];
+}
+
 #pragma mark - SyncPresenter
 
 - (void)showReauthenticateSignin {
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn
index 0481967..f060a1e9 100644
--- a/ios/chrome/browser/ui/omnibox/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -7,6 +7,8 @@
     "location_bar_controller.cc",
     "location_bar_controller.h",
     "location_bar_delegate.h",
+    "omnibox_clipping_feature.h",
+    "omnibox_clipping_feature.mm",
     "web_omnibox_edit_controller.cc",
     "web_omnibox_edit_controller.h",
   ]
@@ -39,6 +41,12 @@
     "autocomplete_suggestion.h",
     "chrome_omnibox_client_ios.h",
     "chrome_omnibox_client_ios.mm",
+    "clipping_mask_view.h",
+    "clipping_mask_view.mm",
+    "clipping_textfield.h",
+    "clipping_textfield.mm",
+    "clipping_textfield_container.h",
+    "clipping_textfield_container.mm",
     "image_retriever.h",
     "location_bar_controller_impl.h",
     "location_bar_controller_impl.mm",
@@ -128,9 +136,11 @@
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
   sources = [
+    "clipping_textfield_container_unittest.mm",
     "omnibox_text_field_ios_unittest.mm",
   ]
   deps = [
+    ":omnibox",
     ":omnibox_internal",
     ":resources_unit_tests",
     "//base",
diff --git a/ios/chrome/browser/ui/omnibox/clipping_mask_view.h b/ios/chrome/browser/ui/omnibox/clipping_mask_view.h
new file mode 100644
index 0000000..1ff342a
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_mask_view.h
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_MASK_VIEW_H_
+#define IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_MASK_VIEW_H_
+
+#import <UIKit/UIKit.h>
+
+// The view used as a mask when the omnibox textfield is being clipped.
+// Displays an opaque rectangle with left, right, or both edges being
+// faded out with transparent gradient.
+@interface ClippingMaskView : UIView
+
+// Whether the left edge is faded.
+@property(nonatomic, assign) BOOL fadeLeft;
+// Whether the right edge is faded.
+@property(nonatomic, assign) BOOL fadeRight;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_MASK_VIEW_H_
diff --git a/ios/chrome/browser/ui/omnibox/clipping_mask_view.mm b/ios/chrome/browser/ui/omnibox/clipping_mask_view.mm
new file mode 100644
index 0000000..49ad300
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_mask_view.mm
@@ -0,0 +1,141 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/omnibox/clipping_mask_view.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#pragma mark - GradientView
+
+namespace {
+
+enum GradientViewDirection {
+  GRADIENT_LEFT_TO_RIGHT,
+  GRADIENT_RIGHT_TO_LEFT,
+};
+
+}  // namespace
+
+// The gradient view is a view that displays a simple horizontal gradient, from
+// black to transparent.
+@interface GradientView : UIView
+// Sets the gradient's direction. You have to call this at least once to
+// configure the gradient.
+@property(nonatomic, assign) GradientViewDirection direction;
+@end
+
+@implementation GradientView
+@synthesize direction = _direction;
+
++ (Class)layerClass {
+  return [CAGradientLayer class];
+}
+
+- (void)setDirection:(GradientViewDirection)direction {
+  _direction = direction;
+
+  CAGradientLayer* layer = static_cast<CAGradientLayer*>(self.layer);
+  layer.colors = @[
+    static_cast<id>([[UIColor clearColor] CGColor]),
+    static_cast<id>([[UIColor blackColor] CGColor])
+  ];
+
+  if (direction == GRADIENT_LEFT_TO_RIGHT) {
+    layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 0, 1);
+  } else {
+    layer.transform = CATransform3DMakeRotation(-M_PI_2, 0, 0, 1);
+  }
+
+  [self setNeedsDisplay];
+}
+
+@end
+
+#pragma mark - ClippingMaskView
+
+@interface ClippingMaskView ()
+// The left gradient view.
+@property(nonatomic, strong) GradientView* leftGradientView;
+// The right gradient view.
+@property(nonatomic, strong) GradientView* rightGradientView;
+// The middle view. Used to paint everything not covered by the gradients with
+// opaque color.
+@property(nonatomic, strong) UIView* middleView;
+@end
+
+@implementation ClippingMaskView
+@synthesize fadeLeft = _fadeLeft;
+@synthesize fadeRight = _fadeRight;
+@synthesize middleView = _middleView;
+@synthesize leftGradientView = _leftGradientView;
+@synthesize rightGradientView = _rightGradientView;
+
+- (instancetype)initWithFrame:(CGRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) {
+    _leftGradientView = [[GradientView alloc] init];
+    [_leftGradientView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    _leftGradientView.direction = GRADIENT_RIGHT_TO_LEFT;
+
+    _rightGradientView = [[GradientView alloc] init];
+    [_rightGradientView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    _rightGradientView.direction = GRADIENT_LEFT_TO_RIGHT;
+
+    _middleView = [[UIView alloc] init];
+    [_middleView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    _middleView.backgroundColor = [UIColor blackColor];
+
+    [self addSubview:_leftGradientView];
+    [self addSubview:_middleView];
+    [self addSubview:_rightGradientView];
+  }
+  return self;
+}
+
+- (void)setFadeLeft:(BOOL)fadeLeft {
+  _fadeLeft = fadeLeft;
+  self.leftGradientView.hidden = !fadeLeft;
+  [self setNeedsLayout];
+}
+
+- (void)setFadeRight:(BOOL)fadeRight {
+  _fadeRight = fadeRight;
+  self.rightGradientView.hidden = !fadeRight;
+  [self setNeedsLayout];
+}
+
+// Since this view is intended to be used as a maskView of another UIView, and
+// maskViews are not in the view hierarchy, autolayout is not supported.
+// Luckily, the desired layout is easy:
+// |[leftGradientView][middleView][rightGradientView]|,
+// where the grad views are sometimes hidden (and then the middle view is
+// extended to that side). The gradients' widths are equal to the height of this
+// view.
+- (void)layoutSubviews {
+  [super layoutSubviews];
+  CGFloat height = self.bounds.size.height;
+  CGFloat gradientWidth = height;
+  CGFloat xOffset = 0;
+  if (self.fadeLeft) {
+    self.leftGradientView.frame = CGRectMake(0, 0, gradientWidth, height);
+    xOffset += gradientWidth;
+  }
+
+  CGFloat midWidth = self.bounds.size.width - xOffset;
+  if (self.fadeRight) {
+    midWidth -= gradientWidth;
+  }
+
+  self.middleView.frame = CGRectMake(xOffset, 0, midWidth, height);
+  xOffset += midWidth;
+
+  if (self.fadeRight) {
+    self.rightGradientView.frame =
+        CGRectMake(xOffset, 0, gradientWidth, height);
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/ui/omnibox/clipping_textfield.h b/ios/chrome/browser/ui/omnibox/clipping_textfield.h
new file mode 100644
index 0000000..94d34efa
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_textfield.h
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_H_
+#define IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_H_
+
+#import <UIKit/UIKit.h>
+
+@protocol ClippingTextFieldDelegate;
+
+// This textfield subclass is designed to be paired with
+// ClippingTextFieldContainer. It notifies its delegate about changes of text
+// and becoming/resigning first responder.
+@interface ClippingTextField : UITextField
+
+@property(nonatomic, weak) id<ClippingTextFieldDelegate>
+    clippingTextfieldDelegate;
+
+@end
+
+@protocol ClippingTextFieldDelegate
+
+// Called when setText: or setAttributedText: was called. Not called when the
+// textfield is being typed into.
+- (void)textFieldTextChanged:(UITextField*)sender;
+- (void)textFieldBecameFirstResponder:(UITextField*)sender;
+- (void)textFieldResignedFirstResponder:(UITextField*)sender;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_H_
diff --git a/ios/chrome/browser/ui/omnibox/clipping_textfield.mm b/ios/chrome/browser/ui/omnibox/clipping_textfield.mm
new file mode 100644
index 0000000..1942edd
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_textfield.mm
@@ -0,0 +1,38 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation ClippingTextField
+@synthesize clippingTextfieldDelegate = _clippingTextfieldDelegate;
+
+- (void)setText:(NSString*)setText {
+  [super setText:setText];
+  [self.clippingTextfieldDelegate textFieldTextChanged:self];
+}
+
+- (void)setAttributedText:(NSAttributedString*)attributedText {
+  [super setAttributedText:attributedText];
+  [self.clippingTextfieldDelegate textFieldTextChanged:self];
+}
+
+- (BOOL)becomeFirstResponder {
+  BOOL didBecomeFirstResponder = [super becomeFirstResponder];
+  [self.clippingTextfieldDelegate textFieldBecameFirstResponder:self];
+  return didBecomeFirstResponder;
+}
+
+- (BOOL)resignFirstResponder {
+  BOOL didResignFirstResponder = [super resignFirstResponder];
+  if (didResignFirstResponder) {
+    [self.clippingTextfieldDelegate textFieldResignedFirstResponder:self];
+  }
+  return didResignFirstResponder;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/omnibox/clipping_textfield_container.h b/ios/chrome/browser/ui/omnibox/clipping_textfield_container.h
new file mode 100644
index 0000000..b2328c3a
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_textfield_container.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_CONTAINER_H_
+#define IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_CONTAINER_H_
+
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield.h"
+
+// A container for the textfield that manages clipping it appropriately.
+// It will size the textfield to fit precisely when the textfield is first
+// responder. Otherwise, it will clip the textfield to its own bounds in the
+// best way to fit the most significant part of the URL, like this:
+//
+//                     --------------------
+// www.somereallyreally|longdomainname.com|/path/gets/clipped
+//                     --------------------
+// {  clipped prefix  } {  visible text  } { clipped suffix }
+//
+// The clipped parts will also be masked with a gradient fade effect on the
+// clipped ends.
+@interface ClippingTextFieldContainer : UIView<ClippingTextFieldDelegate>
+
+// The only available initializer. This will immediately add |textField| as its
+// subview and set |self| as textField's clipping delegate.
+- (instancetype)initWithClippingTextField:(ClippingTextField*)textField
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
+- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
+
+// Managed textfield.
+@property(nonatomic, strong, readonly) ClippingTextField* textField;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_OMNIBOX_CLIPPING_TEXTFIELD_CONTAINER_H_
diff --git a/ios/chrome/browser/ui/omnibox/clipping_textfield_container.mm b/ios/chrome/browser/ui/omnibox/clipping_textfield_container.mm
new file mode 100644
index 0000000..6d0ce430
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_textfield_container.mm
@@ -0,0 +1,166 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield_container.h"
+
+#include "base/strings/sys_string_conversions.h"
+#include "components/omnibox/browser/autocomplete_input.h"
+#include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/ui/omnibox/clipping_mask_view.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface ClippingTextFieldContainer ()
+
+@property(nonatomic, strong) NSLayoutConstraint* leftConstraint;
+@property(nonatomic, strong) NSLayoutConstraint* rightConstraint;
+@property(nonatomic, strong) ClippingMaskView* gradientMaskView;
+@property(nonatomic, assign, getter=isClipping) BOOL clipping;
+
+@end
+
+@implementation ClippingTextFieldContainer
+@synthesize textField = _textField;
+@synthesize leftConstraint = _leftConstraint;
+@synthesize rightConstraint = _rightConstraint;
+@synthesize gradientMaskView = _gradientMaskView;
+@synthesize clipping = _clipping;
+
+- (instancetype)initWithClippingTextField:(ClippingTextField*)textField {
+  self = [super initWithFrame:CGRectZero];
+  if (self) {
+    _textField = textField;
+    textField.clippingTextfieldDelegate = self;
+    [self addSubview:textField];
+
+    _gradientMaskView = [[ClippingMaskView alloc] init];
+    self.maskView = _gradientMaskView;
+
+    // Configure layout.
+    // Left and Right are used instead of Leading and Trailing because the
+    // clipping only ever applies to URLs that are always displayed in LTR.
+    _leftConstraint =
+        [self.textField.leftAnchor constraintEqualToAnchor:self.leftAnchor];
+    _rightConstraint =
+        [self.textField.rightAnchor constraintEqualToAnchor:self.rightAnchor];
+    [NSLayoutConstraint activateConstraints:@[
+      [textField.topAnchor constraintEqualToAnchor:self.topAnchor],
+      [textField.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
+      _leftConstraint,
+      _rightConstraint,
+    ]];
+    textField.translatesAutoresizingMaskIntoConstraints = NO;
+    self.clipsToBounds = YES;
+    _clipping = NO;
+  }
+  return self;
+}
+
+- (void)layoutSubviews {
+  if ([self isClipping]) {
+    [self applyClipping];
+  }
+  [super layoutSubviews];
+  self.gradientMaskView.frame = self.bounds;
+}
+
+- (void)startClipping {
+  self.clipping = YES;
+  [self applyClipping];
+  [self setNeedsLayout];
+  [self layoutIfNeeded];
+}
+
+- (void)applyClipping {
+  CGFloat suffixWidth = 0;
+  CGFloat prefixWidth =
+      -[self leftConstantWithAttributedText:self.textField.attributedText
+                              rightConstant:&suffixWidth];
+
+  [self applyGradientsToPrefix:(prefixWidth < 0) suffix:(suffixWidth > 0)];
+
+  self.leftConstraint.constant = prefixWidth;
+  self.rightConstraint.constant = suffixWidth;
+}
+
+- (void)stopClipping {
+  if (![self isClipping]) {
+    return;
+  }
+  self.clipping = NO;
+  self.leftConstraint.constant = 0;
+  self.rightConstraint.constant = 0;
+  [self removeGradient];
+}
+
+// Fade the beginning and/or end of the visible string to indicate to the user
+// that the URL has been clipped.
+- (void)applyGradientsToPrefix:(BOOL)shouldApplyToPrefix
+                        suffix:(BOOL)shouldApplyToSuffix {
+  self.gradientMaskView.fadeLeft = shouldApplyToPrefix;
+  self.gradientMaskView.fadeRight = shouldApplyToSuffix;
+}
+
+- (void)removeGradient {
+  [self applyGradientsToPrefix:NO suffix:NO];
+}
+
+#pragma mark calculate clipping
+
+// Calculates the length (in pts) of the clipped text on the left and
+// right sides of the omnibox in order to show the most significant part of
+// the hostname.
+- (CGFloat)leftConstantWithAttributedText:(NSAttributedString*)attributedText
+                            rightConstant:(out CGFloat*)right {
+  // The goal is to always show the most significant part of the hostname
+  // (i.e. the end of the TLD).
+  //
+  //                     --------------------
+  // www.somereallyreally|longdomainname.com|/path/gets/clipped
+  //                     --------------------
+  // {  clipped prefix  } {  visible text  } { clipped suffix }
+
+  // First find how much (if any) of the scheme/host needs to be clipped so that
+  // the end of the TLD fits in bounds.
+
+  CGFloat widthOfClippedPrefix = 0;
+  url::Component scheme, host;
+  AutocompleteInput::ParseForEmphasizeComponents(
+      base::SysNSStringToUTF16(attributedText.string),
+      AutocompleteSchemeClassifierImpl(), &scheme, &host);
+  if (host.len < 0) {
+    return 0;
+  }
+  NSRange hostRange = NSMakeRange(0, host.begin + host.len);
+  NSAttributedString* hostString =
+      [attributedText attributedSubstringFromRange:hostRange];
+  CGFloat widthOfHost = ceil(hostString.size.width);
+  widthOfClippedPrefix = MAX(widthOfHost - self.bounds.size.width, 0);
+
+  // Now determine if there is any text that will need to be truncated because
+  // there's not enough room.
+  int textWidth = ceil(attributedText.size.width);
+  CGFloat widthOfClippedSuffix =
+      MAX(textWidth - self.bounds.size.width - widthOfClippedPrefix, 0);
+  *right = widthOfClippedSuffix;
+  return widthOfClippedPrefix;
+}
+
+#pragma mark - ClippingTextFieldDelegate
+
+- (void)textFieldTextChanged:(UITextField*)sender {
+  [self startClipping];
+}
+
+- (void)textFieldBecameFirstResponder:(UITextField*)sender {
+  [self stopClipping];
+}
+
+- (void)textFieldResignedFirstResponder:(UITextField*)sender {
+  [self startClipping];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/omnibox/clipping_textfield_container_unittest.mm b/ios/chrome/browser/ui/omnibox/clipping_textfield_container_unittest.mm
new file mode 100644
index 0000000..e99a4066
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/clipping_textfield_container_unittest.mm
@@ -0,0 +1,200 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield_container.h"
+
+#include "testing/platform_test.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+class ClippingTextFieldContainerTest : public PlatformTest {
+ protected:
+  void SetUp() override {
+    PlatformTest::SetUp();
+    textField_ = [[ClippingTextField alloc] init];
+    container_ = [[ClippingTextFieldContainer alloc]
+        initWithClippingTextField:textField_];
+
+    [[[UIApplication sharedApplication] keyWindow] addSubview:container_];
+    // Width of 200 is enough to fit "http://www.google.com" and is
+    // in the same ballpark as iPhone omnibox.
+    container_.frame = CGRectMake(0, 0, 200, 20);
+  };
+
+  void TearDown() override { [container_ removeFromSuperview]; }
+
+  ClippingTextFieldContainer* container_;
+  ClippingTextField* textField_;
+
+  UIView* LeftDecorationView() {
+    // The decoration container contains the decoration views covering the
+    // tail and the head.
+    UIView* decorationContainer = container_.maskView;
+    CGPoint leftMidPoint = CGPointMake(0, container_.bounds.size.height / 2);
+    for (UIView* decorationView in decorationContainer.subviews) {
+      if (CGRectContainsPoint(decorationView.frame, leftMidPoint) &&
+          [decorationView.layer class] == [CAGradientLayer class]) {
+        return decorationView;
+      }
+    }
+    return nil;
+  }
+
+  UIView* RightDecorationView() {
+    // The decoration container contains the decoration views covering the
+    // tail and the head.
+    UIView* decorationContainer = container_.maskView;
+    // Substract 0.5pt from x coordinate because CGRectContainsPoint
+    // returns NO for points on the maximum X edge.
+    CGPoint rightMidPoint = CGPointMake(container_.bounds.size.width - 0.5,
+                                        container_.bounds.size.height / 2);
+    for (UIView* decorationView in decorationContainer.subviews) {
+      if (CGRectContainsPoint(decorationView.frame, rightMidPoint) &&
+          [decorationView.layer class] == [CAGradientLayer class]) {
+        return decorationView;
+      }
+    }
+    return nil;
+  }
+};
+
+TEST_F(ClippingTextFieldContainerTest, DoesntClipWhenEntireURLFits) {
+  NSString* text = @"http://www.google.com";
+  [textField_ setText:text];
+
+  // The textfield fits in the container.
+  EXPECT_LE(textField_.frame.size.width, container_.frame.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, ClipsLongPrefix) {
+  NSString* text = @"http://verylongprefixwaymorethan200pts.google.com";
+  [textField_ setText:text];
+
+  // The left edge is clipped, so the textfield is shifted left.
+  EXPECT_TRUE(textField_.frame.origin.x < 0);
+  // The amount it's shifted left by is just enough to fit the URL.
+  EXPECT_EQ(textField_.frame.origin.x + textField_.frame.size.width,
+            container_.frame.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, ClipsLongSuffix) {
+  NSString* text = @"http://www.google.com/verylongsuffixwaymorethan200pts";
+  [textField_ setText:text];
+
+  // The left edge is not clipped.
+  EXPECT_EQ(textField_.frame.origin.x, 0);
+  // The right edge is clipped.
+  EXPECT_GE(textField_.frame.size.width, container_.frame.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, ClipsPrefixAndSuffix) {
+  NSString* text =
+      @"http://verylongprefixwaymorethan200pts.google.com/"
+      @"verylongsuffixwaymorethan200pts";
+  [textField_ setText:text];
+  CGSize textSize = [[textField_ attributedText] size];
+
+  // The left edge is clipped.
+  EXPECT_TRUE(textField_.frame.origin.x < 0);
+  // The right edge is clipped.
+  EXPECT_GE(textField_.frame.size.width + textField_.frame.origin.x,
+            container_.frame.size.width);
+  // The textfield expands to fit the text.
+  EXPECT_EQ(textField_.frame.size.width, ceil(textSize.width));
+}
+
+TEST_F(ClippingTextFieldContainerTest, NoScheme) {
+  NSString* text = @"www.google.com";
+  [textField_ setText:text];
+
+  // The textfield fits in the container.
+  EXPECT_LE(textField_.frame.size.width, container_.frame.size.width);
+  // The left edge is not clipped.
+  EXPECT_EQ(textField_.frame.origin.x, 0);
+
+  // Textfield's size is equal to container size and greater than text.
+  CGSize textSize = [[textField_ attributedText] size];
+  textSize.width = ceil(textSize.width);
+  textSize.height = ceil(textSize.height);
+  EXPECT_EQ(textField_.frame.size.width, container_.bounds.size.width);
+  EXPECT_LE(textSize.width, textField_.bounds.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, NoHost) {
+  NSString* text = @"http://";
+  [textField_ setText:text];
+
+  // The textfield fits in the container.
+  EXPECT_LE(textField_.frame.size.width, container_.frame.size.width);
+  // The left edge is not clipped.
+  EXPECT_EQ(textField_.frame.origin.x, 0);
+
+  // Textfield's size is equal to container size and greater than text.
+  CGSize textSize = [[textField_ attributedText] size];
+  textSize.width = ceil(textSize.width);
+  textSize.height = ceil(textSize.height);
+  EXPECT_EQ(textField_.frame.size.width, container_.bounds.size.width);
+  EXPECT_LE(textSize.width, textField_.bounds.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, DoesntClipWhenFocused) {
+  NSString* text =
+      @"http://verylongprefixwaymorethan200pts.google.com/"
+      @"verylongsuffixwaymorethan200pts";
+  [textField_ setText:text];
+
+  // The left edge is clipped.
+  EXPECT_TRUE(textField_.frame.origin.x < 0);
+  // The right edge is clipped.
+  EXPECT_GE(textField_.frame.size.width + textField_.frame.origin.x,
+            container_.frame.size.width);
+
+  [textField_ becomeFirstResponder];
+  [container_ layoutIfNeeded];
+
+  // When focused, the textfield should take the container's space and
+  // not be clipped.
+  EXPECT_EQ(textField_.frame.origin.x, 0);
+  EXPECT_EQ(textField_.frame.size.width, container_.frame.size.width);
+
+  [textField_ resignFirstResponder];
+  [container_ layoutIfNeeded];
+
+  // The left edge is clipped.
+  EXPECT_TRUE(textField_.frame.origin.x < 0);
+  // The right edge is clipped.
+  EXPECT_GE(textField_.frame.size.width + textField_.frame.origin.x,
+            container_.frame.size.width);
+}
+
+TEST_F(ClippingTextFieldContainerTest, ShowsDecorationsWhenClipping) {
+  NSString* text =
+      @"http://verylongprefixwaymorethan200pts.google.com/"
+      @"verylongsuffixwaymorethan200pts";
+  [textField_ setText:text];
+
+  // Tail and head are masked when the ends are clipped.
+  EXPECT_FALSE(LeftDecorationView().hidden);
+  EXPECT_FALSE(RightDecorationView().hidden);
+
+  [textField_ becomeFirstResponder];
+  [container_ layoutIfNeeded];
+
+  // Even for long strings, the masks are disabled while editing.
+  EXPECT_TRUE(LeftDecorationView().hidden);
+  EXPECT_TRUE(RightDecorationView().hidden);
+
+  [textField_ resignFirstResponder];
+  [container_ layoutIfNeeded];
+
+  // Deselecting textfield with a long string remasks the ends.
+  EXPECT_FALSE(LeftDecorationView().hidden);
+  EXPECT_FALSE(RightDecorationView().hidden);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h b/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h
new file mode 100644
index 0000000..e3ea34c
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h
@@ -0,0 +1,13 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_CLIPPING_FEATURE_H_
+#define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_CLIPPING_FEATURE_H_
+
+#include "base/feature_list.h"
+
+// Feature to choose whether to use the iOS 11-compatible textfield clipping.
+extern const base::Feature kClippingTextfield;
+
+#endif  // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_CLIPPING_FEATURE_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.mm b/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.mm
new file mode 100644
index 0000000..c7a759a
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.mm
@@ -0,0 +1,8 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h"
+
+const base::Feature kClippingTextfield{"kClippingTextfield",
+                                       base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_popup_view_controller.mm
index e77d736b5..508e0f0 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_popup_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_popup_view_controller.mm
@@ -153,6 +153,13 @@
   [self layoutRows];
 }
 
+#pragma mark - Properties accessors
+
+- (void)setIncognito:(BOOL)incognito {
+  DCHECK(!self.viewLoaded);
+  _incognito = incognito;
+}
+
 #pragma mark - AutocompleteResultConsumer
 
 - (void)updateMatches:(NSArray<id<AutocompleteSuggestion>>*)result
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h
index d1f1103..a93cb28 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_TEXT_FIELD_IOS_H_
 #define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_TEXT_FIELD_IOS_H_
 
-#import <UIKit/UIKit.h>
+#import "ios/chrome/browser/ui/omnibox/clipping_textfield.h"
 
 #include "base/strings/string16.h"
 #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_delegate.h"
@@ -17,7 +17,7 @@
 } OmniboxTextFieldFadeStyle;
 
 // UITextField subclass to allow for adjusting borders.
-@interface OmniboxTextFieldIOS : UITextField
+@interface OmniboxTextFieldIOS : ClippingTextField
 
 // Initialize the omnibox with the given frame, font, text color, and tint
 // color.
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
index 0360925..33efcb0 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -18,6 +18,7 @@
 #include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
 #include "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/ui/animation_util.h"
+#import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h"
 #include "ios/chrome/browser/ui/omnibox/omnibox_util.h"
 #import "ios/chrome/browser/ui/reversed_animation.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
@@ -533,6 +534,12 @@
 
 // Enumerate url components (host, path) and draw each one in different rect.
 - (void)drawTextInRect:(CGRect)rect {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // With the new clipping logic, this override is unnecessary.
+    [super drawTextInRect:rect];
+    return;
+  }
+
   if (base::ios::IsRunningOnOrLater(11, 1, 0)) {
     // -[UITextField drawTextInRect:] ignores the argument, so we can't do
     // anything on 11.1 and up.
@@ -839,6 +846,11 @@
 }
 
 - (CGRect)rectForDrawTextInRect:(CGRect)rect {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // With the new clipping logic, this override is unnecessary.
+    return rect;
+  }
+
   // The goal is to always show the most significant part of the hostname
   // (i.e. the end of the TLD).
   //
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios_unittest.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios_unittest.mm
index bb9bacb..a4c9a3ca 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios_unittest.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios_unittest.mm
@@ -11,6 +11,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/sys_string_conversions.h"
 #include "ios/chrome/browser/chrome_paths.h"
+#import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -143,6 +144,12 @@
 }
 
 TEST_F(OmniboxTextFieldTest, rectForDrawTextInRect_entireURLFits) {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // This test is expected to not work with new text field clipping because
+    // the code to implement clipping will be removed.
+    return;
+  }
+
   NSString* text = @"http://www.google.com";
   [textfield_ setText:text];
   CGSize textSize = [[textfield_ attributedText] size];
@@ -154,6 +161,12 @@
 }
 
 TEST_F(OmniboxTextFieldTest, rectForDrawTextInRect_clippedPrefix) {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // This test is expected to not work with new text field clipping because
+    // the code to implement clipping will be removed.
+    return;
+  }
+
   NSString* text = @"http://www.google.com";
   [textfield_ setText:text];
   CGSize textSize = [[textfield_ attributedText] size];
@@ -168,6 +181,12 @@
 }
 
 TEST_F(OmniboxTextFieldTest, rectForDrawTextInRect_clippedSuffix) {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // This test is expected to not work with new text field clipping because
+    // the code to implement clipping will be removed.
+    return;
+  }
+
   NSString* text = @"http://www.google.com/somelongpath";
   [textfield_ setText:text];
   CGSize textSize = [[textfield_ attributedText] size];
@@ -180,6 +199,12 @@
 }
 
 TEST_F(OmniboxTextFieldTest, rectForDrawTextInRect_noScheme) {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // This test is expected to not work with new text field clipping because
+    // the code to implement clipping will be removed.
+    return;
+  }
+
   NSString* text = @"www.google.com";
   [textfield_ setText:text];
   CGSize textSize = [[textfield_ attributedText] size];
@@ -192,6 +217,12 @@
 // When the text doesn't contain a host the method bails early and returns
 // the |rect| passed in.
 TEST_F(OmniboxTextFieldTest, rectForDrawTextInRect_noHost) {
+  if (base::FeatureList::IsEnabled(kClippingTextfield)) {
+    // This test is expected to not work with new text field clipping because
+    // the code to implement clipping will be removed.
+    return;
+  }
+
   NSString* text = @"http://";
   [textfield_ setText:text];
   CGSize textSize = [[textfield_ attributedText] size];
diff --git a/ios/chrome/browser/ui/stack_view/card_set.h b/ios/chrome/browser/ui/stack_view/card_set.h
index 8280ac7..b59cb954 100644
--- a/ios/chrome/browser/ui/stack_view/card_set.h
+++ b/ios/chrome/browser/ui/stack_view/card_set.h
@@ -20,6 +20,9 @@
 // Observer delegate for clients interested in changes to cards in a CardSet.
 @protocol CardSetObserver
 
+// |cardSet| closed all of its tabs.
+- (void)cardSetDidCloseAllTabs:(CardSet*)cardSet;
+
 // |newCard| has been added to |cardSet|.
 - (void)cardSet:(CardSet*)cardSet didAddCard:(StackCard*)newCard;
 
diff --git a/ios/chrome/browser/ui/stack_view/card_set.mm b/ios/chrome/browser/ui/stack_view/card_set.mm
index c6041bc..10caf7d 100644
--- a/ios/chrome/browser/ui/stack_view/card_set.mm
+++ b/ios/chrome/browser/ui/stack_view/card_set.mm
@@ -535,6 +535,11 @@
   [self removeCardAtIndex:index];
 }
 
+// All tabs were closed in the model
+- (void)tabModelClosedAllTabs:(TabModel*)model {
+  [self.observer cardSetDidCloseAllTabs:self];
+}
+
 - (CGFloat)maximumStackLength {
   return [stackModel_ maximumStackLength];
 }
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
index 23667eb..f97bce3 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
@@ -222,8 +222,6 @@
 // scroll to one of its boundaries without also having reached the
 // corresponding boundary of the stack being scrolled.
 - (void)updateScrollViewContentSize;
-// Deregisters for the notifications |registerForNotifications| specifies.
-- (void)deregisterForNotifications;
 // Eliminates the ability for the user to perform any further interactions
 // with the stack view. Should be called when the stack view starts being
 // dismissed.
@@ -404,10 +402,6 @@
 // so this should *not* be called frequently.
 - (StackCard*)cardForView:(CardView*)view;
 
-// All local tab state is cleared, and |currentlyClosingAllTabs_| is set to
-// |NO|.
-- (void)allModelTabsHaveClosed:(NSNotification*)notify;
-
 // Updates the display views so that they are aligned to the scroll view's
 // viewport. Should be called any time the scroll view's content offset
 // changes.
@@ -669,11 +663,6 @@
   [[_mainCardSet displayView] removeFromSuperview];
   [[_otrCardSet displayView] removeFromSuperview];
 
-  // Only deregister from the specific notifications for which this class
-  // registered. Do not use the blanket |removeObserver|, otherwise the low
-  // memory notification is not received and the view is never unloaded.
-  [self deregisterForNotifications];
-
   [_mainCardSet disconnect];
   _mainCardSet = nil;
 
@@ -752,8 +741,6 @@
             ? UIInterfaceOrientationPortrait
             : UIInterfaceOrientationLandscapeRight;
   }
-  [self registerForNotifications];
-
   // TODO(blundell): Why isn't this recognizer initialized with the
   // pinch and mode switch recognizers?
   UIPanGestureRecognizer* panGestureRecognizer =
@@ -1035,21 +1022,6 @@
                    completion:nil];
 }
 
-- (void)registerForNotifications {
-  NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter addObserver:self
-                    selector:@selector(allModelTabsHaveClosed:)
-                        name:kTabModelAllTabsDidCloseNotification
-                      object:nil];
-}
-
-- (void)deregisterForNotifications {
-  NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter removeObserver:self
-                           name:kTabModelAllTabsDidCloseNotification
-                         object:nil];
-}
-
 - (void)prepareForDismissal {
   UIView* activeView = [_activeCardSet displayView];
   [activeView removeGestureRecognizer:_pinchRecognizer];
@@ -1169,6 +1141,7 @@
       void (^toDoWhenDone)(void) = NULL;
       if (card == lastVisibleCard) {
         toDoWhenDone = ^{
+          [cardSet setIgnoresTabModelChanges:NO];
           [cardSet.tabModel closeAllTabs];
         };
       }
@@ -2922,27 +2895,17 @@
 
 #pragma mark Notification Handlers
 
-- (void)allModelTabsHaveClosed:(NSNotification*)notify {
+- (void)cardSetDidCloseAllTabs:(CardSet*)cardSet {
   // Early return if the stack view is not active.  This can sometimes occur if
   // |clearInternalState| triggers the deletion of a tab model.
   if (!_isActive)
     return;
 
-  CardSet* closedSet =
-      (notify.object == [_mainCardSet tabModel]) ? _mainCardSet : _otrCardSet;
-
-  // If the tabModel that send the notification is not one handled by one of
-  // the two card sets, just return. This will happen when the otr tab model is
-  // deleted because the incognito profile is deleted.
-  if (notify.object != [closedSet tabModel])
-    return;
-
-  if (closedSet == _activeCardSet)
+  if (cardSet == _activeCardSet)
     [self activeCardCountChanged];
-  for (UIView* card in [closedSet.displayView subviews]) {
+  for (UIView* card in [cardSet.displayView subviews]) {
     [card removeFromSuperview];
   }
-  [closedSet setIgnoresTabModelChanges:NO];
   // No need to re-sync with the card set here, since the tab model (and thus
   // the card set) is known to be empty.
 
@@ -2951,8 +2914,8 @@
   // finishes closing while the main set is still animating (in the case of
   // closing all cards at once) wait until the main set finishes before updating
   // the display (necessary so the state is right if a new tab is opened).
-  if ((closedSet == _otrCardSet && ![_mainCardSet ignoresTabModelChanges]) ||
-      (closedSet == _mainCardSet && [[_otrCardSet cards] count] == 0)) {
+  if ((cardSet == _otrCardSet && ![_mainCardSet ignoresTabModelChanges]) ||
+      (cardSet == _mainCardSet && [[_otrCardSet cards] count] == 0)) {
     [self displayMainCardSetOnly];
   }
 
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller_private.h b/ios/chrome/browser/ui/stack_view/stack_view_controller_private.h
index 5245754a..76df9f0 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_controller_private.h
+++ b/ios/chrome/browser/ui/stack_view/stack_view_controller_private.h
@@ -42,9 +42,6 @@
 // attaching to the card sets.
 - (void)setUpDisplayViews;
 
-// Registers listeners for the appropriate notifications.
-- (void)registerForNotifications;
-
 // Used during |-dealloc| and |-didReceiveMemoryWaring| to clear any references
 // to the cards and removes |self| as an observer to any notifications.
 - (void)cleanUpViewsAndNotifications;
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index 012570b..f72d79a 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -268,6 +268,9 @@
   _keyboardDelegate = [[ToolbarAssistiveKeyboardDelegateImpl alloc] init];
   _keyboardDelegate.dispatcher = dispatcher;
   _keyboardDelegate.omniboxTextField = _locationBarView.textField;
+  [_locationBarView
+      setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
+                                      forAxis:UILayoutConstraintAxisHorizontal];
 
   // Disable default drop interactions on the omnibox.
   // TODO(crbug.com/739903): Handle drop events once Chrome iOS is built with
diff --git a/ios/chrome/browser/ui/webui/web_ui_egtest.mm b/ios/chrome/browser/ui/webui/web_ui_egtest.mm
index f14eca43..fd547ec 100644
--- a/ios/chrome/browser/ui/webui/web_ui_egtest.mm
+++ b/ios/chrome/browser/ui/webui/web_ui_egtest.mm
@@ -104,7 +104,7 @@
 
   // Verify that the resulting page is chrome://terms.
   [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://terms")]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
   const std::string kTermsText = "Google Chrome Terms of Service";
   [ChromeEarlGrey waitForWebViewContainingText:kTermsText];
 }
@@ -119,7 +119,7 @@
 
   // Verify that the resulting page is chrome://version.
   [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
   [ChromeEarlGrey waitForWebViewContainingText:"The Chromium Authors"];
 
   // Tap the back button in the toolbar and verify that the resulting page is
@@ -127,7 +127,7 @@
   [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
   [[EarlGrey
       selectElementWithMatcher:WaitForOmniboxText("chrome://chrome-urls")]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
   [ChromeEarlGrey waitForWebViewContainingText:"List of Chrome URLs"];
 }
 
@@ -144,14 +144,14 @@
   // corresponds to the first URL chrome://version that was loaded.
   [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
 
   // Tap the forward button in the toolbar and verify that the resulting page's
   // URL corresponds the second URL chrome://flags that was loaded.
   [[EarlGrey selectElementWithMatcher:ForwardButton()]
       performAction:grey_tap()];
   [[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://flags")]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
 }
 
 // Tests that all URLs on chrome://chrome-urls page load without error.
@@ -170,7 +170,7 @@
     const std::string chrome_url_path =
         url::SchemeHostPort(kChromeUIScheme, kChromeHostURLs[i], 0).Serialize();
     [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(chrome_url_path)]
-        assertWithMatcher:grey_sufficientlyVisible()];
+        assertWithMatcher:grey_notNil()];
   }
 }
 
@@ -182,7 +182,7 @@
 
   // Verify that the resulting page is an error page.
   [[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeInvalidURL)]
-      assertWithMatcher:grey_sufficientlyVisible()];
+      assertWithMatcher:grey_notNil()];
   NSString* kError =
       l10n_util::GetNSString(IDS_ERRORPAGES_HEADING_NOT_AVAILABLE);
   id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:kError];
diff --git a/ios/net/cookies/cookie_store_ios.h b/ios/net/cookies/cookie_store_ios.h
index 7afcce87..9a7f919 100644
--- a/ios/net/cookies/cookie_store_ios.h
+++ b/ios/net/cookies/cookie_store_ios.h
@@ -15,7 +15,6 @@
 
 #include "base/callback.h"
 #include "base/cancelable_callback.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
diff --git a/ios/net/crn_http_protocol_handler.h b/ios/net/crn_http_protocol_handler.h
index 576a8ec8..1545533 100644
--- a/ios/net/crn_http_protocol_handler.h
+++ b/ios/net/crn_http_protocol_handler.h
@@ -7,7 +7,6 @@
 
 #import <Foundation/Foundation.h>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "net/base/load_timing_info.h"
 #include "net/http/http_response_info.h"
@@ -46,7 +45,7 @@
     Metrics();
     ~Metrics();
 
-    base::scoped_nsobject<NSURLSessionTask> task;
+    NSURLSessionTask* task;
     LoadTimingInfo load_timing_info;
     HttpResponseInfo response_info;
     base::Time response_end_time;
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm
index e0f33e8..5cf1ffd1 100644
--- a/ios/net/crn_http_protocol_handler.mm
+++ b/ios/net/crn_http_protocol_handler.mm
@@ -747,7 +747,7 @@
     auto metrics = std::make_unique<net::MetricsDelegate::Metrics>();
 
     metrics->response_end_time = base::Time::Now();
-    metrics->task.reset(task_);
+    metrics->task = task_;
     metrics->response_info = net_request_->response_info();
     net_request_->GetLoadTimingInfo(&metrics->load_timing_info);
 
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
index c6b7338..1a1d7660 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h
@@ -7,7 +7,6 @@
 
 #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h"
 
-#include "base/mac/scoped_nsobject.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 @class NSMutableArray;
@@ -82,7 +81,7 @@
   void SetFakeMDMError(bool fakeMDMError);
 
  private:
-  base::scoped_nsobject<NSMutableArray> identities_;
+  NSMutableArray* identities_;
 
   // If true, call to GetAccessToken() fakes a MDM error.
   bool _fakeMDMError;
diff --git a/ios/public/provider/chrome/browser/signin/test_signin_resources_provider.h b/ios/public/provider/chrome/browser/signin/test_signin_resources_provider.h
index 40dfc9a..8f3638ee 100644
--- a/ios/public/provider/chrome/browser/signin/test_signin_resources_provider.h
+++ b/ios/public/provider/chrome/browser/signin/test_signin_resources_provider.h
@@ -7,7 +7,6 @@
 
 #include "ios/public/provider/chrome/browser/signin/signin_resources_provider.h"
 
-#include "base/mac/scoped_nsobject.h"
 
 @class UIImage;
 
@@ -20,7 +19,7 @@
   NSString* GetLocalizedString(ios::SigninStringID string_id) override;
 
  private:
-  base::scoped_nsobject<UIImage> default_avatar_;
+  UIImage* default_avatar_;
 
   DISALLOW_COPY_AND_ASSIGN(TestSigninResourcesProvider);
 };
diff --git a/ios/web/interstitials/html_web_interstitial_impl.h b/ios/web/interstitials/html_web_interstitial_impl.h
index 9dccfd4..63b73a9 100644
--- a/ios/web/interstitials/html_web_interstitial_impl.h
+++ b/ios/web/interstitials/html_web_interstitial_impl.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 #import "ios/web/interstitials/web_interstitial_impl.h"
 
 namespace web {
@@ -47,12 +46,12 @@
   std::unique_ptr<HtmlWebInterstitialDelegate> delegate_;
   // The |web_view_|'s delegate.  Used to forward JavaScript commands
   // resulting from user interaction with the interstitial content.
-  base::scoped_nsprotocol<id<WKNavigationDelegate>> web_view_delegate_;
+  id<WKNavigationDelegate> web_view_delegate_;
   // The web view used to show the content. View needs to be resized by the
   // caller.
   WKWebView* web_view_;  // strong
   // The CRWContentView used to display |web_view_controller_|'s view.
-  base::scoped_nsobject<CRWContentView> content_view_;
+  CRWContentView* content_view_;
 };
 
 }  // namespace web
diff --git a/ios/web/interstitials/html_web_interstitial_impl.mm b/ios/web/interstitials/html_web_interstitial_impl.mm
index 93192ca..e28d53d 100644
--- a/ios/web/interstitials/html_web_interstitial_impl.mm
+++ b/ios/web/interstitials/html_web_interstitial_impl.mm
@@ -104,13 +104,13 @@
 }
 
 CRWContentView* HtmlWebInterstitialImpl::GetContentView() const {
-  return content_view_.get();
+  return content_view_;
 }
 
 void HtmlWebInterstitialImpl::PrepareForDisplay() {
   if (!content_view_) {
-    web_view_delegate_.reset([[CRWWebInterstitialImplWKWebViewDelegate alloc]
-        initWithInterstitial:this]);
+    web_view_delegate_ = [[CRWWebInterstitialImplWKWebViewDelegate alloc]
+        initWithInterstitial:this];
     web_view_ =
         web::BuildWKWebView(CGRectZero, GetWebStateImpl()->GetBrowserState());
     [web_view_ setNavigationDelegate:web_view_delegate_];
@@ -118,9 +118,9 @@
                                     UIViewAutoresizingFlexibleHeight)];
     NSString* html = base::SysUTF8ToNSString(delegate_->GetHtmlContents());
     [web_view_ loadHTMLString:html baseURL:net::NSURLWithGURL(GetUrl())];
-    content_view_.reset([[CRWWebViewContentView alloc]
-        initWithWebView:web_view_
-             scrollView:[web_view_ scrollView]]);
+    content_view_ =
+        [[CRWWebViewContentView alloc] initWithWebView:web_view_
+                                            scrollView:[web_view_ scrollView]];
   }
 }
 
diff --git a/ios/web/interstitials/native_web_interstitial_impl.h b/ios/web/interstitials/native_web_interstitial_impl.h
index 8b850d4..3d62eca 100644
--- a/ios/web/interstitials/native_web_interstitial_impl.h
+++ b/ios/web/interstitials/native_web_interstitial_impl.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 
 namespace web {
 
@@ -40,7 +39,7 @@
   // The native interstitial delegate.
   std::unique_ptr<NativeWebInterstitialDelegate> delegate_;
   // The transient content view containing interstitial content.
-  base::scoped_nsobject<CRWContentView> content_view_;
+  CRWContentView* content_view_;
 };
 
 }  // namespace web
diff --git a/ios/web/interstitials/native_web_interstitial_impl.mm b/ios/web/interstitials/native_web_interstitial_impl.mm
index fbceff67..b78e268f 100644
--- a/ios/web/interstitials/native_web_interstitial_impl.mm
+++ b/ios/web/interstitials/native_web_interstitial_impl.mm
@@ -43,13 +43,13 @@
 }
 
 CRWContentView* NativeWebInterstitialImpl::GetContentView() const {
-  return content_view_.get();
+  return content_view_;
 }
 
 void NativeWebInterstitialImpl::PrepareForDisplay() {
   if (!content_view_) {
-    content_view_.reset([[CRWGenericContentView alloc]
-        initWithView:delegate_->GetContentView()]);
+    content_view_ = [[CRWGenericContentView alloc]
+        initWithView:delegate_->GetContentView()];
   }
 }
 
diff --git a/ios/web/navigation/legacy_navigation_manager_impl.h b/ios/web/navigation/legacy_navigation_manager_impl.h
index 5a178456..070590b 100644
--- a/ios/web/navigation/legacy_navigation_manager_impl.h
+++ b/ios/web/navigation/legacy_navigation_manager_impl.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <vector>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
 #import "ios/web/public/navigation_item_list.h"
@@ -96,7 +95,7 @@
 
   // CRWSessionController that backs this instance.
   // TODO(stuartmorgan): Fold CRWSessionController into this class.
-  base::scoped_nsobject<CRWSessionController> session_controller_;
+  CRWSessionController* session_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(LegacyNavigationManagerImpl);
 };
diff --git a/ios/web/navigation/legacy_navigation_manager_impl.mm b/ios/web/navigation/legacy_navigation_manager_impl.mm
index a4bf9c5..9188c6f2 100644
--- a/ios/web/navigation/legacy_navigation_manager_impl.mm
+++ b/ios/web/navigation/legacy_navigation_manager_impl.mm
@@ -40,7 +40,7 @@
 
 void LegacyNavigationManagerImpl::SetSessionController(
     CRWSessionController* session_controller) {
-  session_controller_.reset(session_controller);
+  session_controller_ = session_controller;
   [session_controller_ setNavigationManager:this];
 }
 
diff --git a/ios/web/navigation/navigation_item_impl.h b/ios/web/navigation/navigation_item_impl.h
index ab5ad99..e279565 100644
--- a/ios/web/navigation/navigation_item_impl.h
+++ b/ios/web/navigation/navigation_item_impl.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/strings/string16.h"
 #include "ios/web/public/favicon_status.h"
 #import "ios/web/public/navigation_item.h"
@@ -136,14 +135,14 @@
   SSLStatus ssl_;
   base::Time timestamp_;
   UserAgentType user_agent_type_;
-  base::scoped_nsobject<NSMutableDictionary> http_request_headers_;
+  NSMutableDictionary* http_request_headers_;
 
-  base::scoped_nsobject<NSString> serialized_state_object_;
+  NSString* serialized_state_object_;
   bool is_created_from_push_state_;
   bool has_state_been_replaced_;
   bool is_created_from_hash_change_;
   bool should_skip_repost_form_confirmation_;
-  base::scoped_nsobject<NSData> post_data_;
+  NSData* post_data_;
 
   // The navigation initiation type of the item.  This decides whether the URL
   // should be displayed before the navigation commits.  It is cleared in
diff --git a/ios/web/navigation/navigation_item_impl.mm b/ios/web/navigation/navigation_item_impl.mm
index 15d02506..e273e3da 100644
--- a/ios/web/navigation/navigation_item_impl.mm
+++ b/ios/web/navigation/navigation_item_impl.mm
@@ -193,7 +193,7 @@
 }
 
 bool NavigationItemImpl::HasPostData() const {
-  return post_data_.get() != nil;
+  return post_data_ != nil;
 }
 
 NSDictionary* NavigationItemImpl::GetHttpRequestHeaders() const {
@@ -208,16 +208,16 @@
   if (http_request_headers_)
     [http_request_headers_ addEntriesFromDictionary:additional_headers];
   else
-    http_request_headers_.reset([additional_headers mutableCopy]);
+    http_request_headers_ = [additional_headers mutableCopy];
 }
 
 void NavigationItemImpl::SetSerializedStateObject(
     NSString* serialized_state_object) {
-  serialized_state_object_.reset(serialized_state_object);
+  serialized_state_object_ = serialized_state_object;
 }
 
 NSString* NavigationItemImpl::GetSerializedStateObject() const {
-  return serialized_state_object_.get();
+  return serialized_state_object_;
 }
 
 void NavigationItemImpl::SetIsCreatedFromPushState(bool push_state) {
@@ -263,22 +263,22 @@
 }
 
 void NavigationItemImpl::SetPostData(NSData* post_data) {
-  post_data_.reset(post_data);
+  post_data_ = post_data;
 }
 
 NSData* NavigationItemImpl::GetPostData() const {
-  return post_data_.get();
+  return post_data_;
 }
 
 void NavigationItemImpl::RemoveHttpRequestHeaderForKey(NSString* key) {
   DCHECK(key);
   [http_request_headers_ removeObjectForKey:key];
   if (![http_request_headers_ count])
-    http_request_headers_.reset();
+    http_request_headers_ = nil;
 }
 
 void NavigationItemImpl::ResetHttpRequestHeaders() {
-  http_request_headers_.reset();
+  http_request_headers_ = nil;
 }
 
 void NavigationItemImpl::ResetForCommit() {
diff --git a/ios/web/navigation/navigation_item_storage_builder.mm b/ios/web/navigation/navigation_item_storage_builder.mm
index 0f3df37e..6a24f7e4 100644
--- a/ios/web/navigation/navigation_item_storage_builder.mm
+++ b/ios/web/navigation/navigation_item_storage_builder.mm
@@ -47,9 +47,9 @@
   item->should_skip_repost_form_confirmation_ =
       navigation_item_storage.shouldSkipRepostFormConfirmation;
   item->user_agent_type_ = navigation_item_storage.userAgentType;
-  item->post_data_.reset(navigation_item_storage.POSTData);
-  item->http_request_headers_.reset(
-      [navigation_item_storage.HTTPRequestHeaders mutableCopy]);
+  item->post_data_ = navigation_item_storage.POSTData;
+  item->http_request_headers_ =
+      [navigation_item_storage.HTTPRequestHeaders mutableCopy];
   return item;
 }
 
diff --git a/ios/web/navigation/navigation_manager_impl.h b/ios/web/navigation/navigation_manager_impl.h
index 9d7154d..de7c6e74 100644
--- a/ios/web/navigation/navigation_manager_impl.h
+++ b/ios/web/navigation/navigation_manager_impl.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <vector>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/public/navigation_item_list.h"
diff --git a/ios/web/navigation/serializable_user_data_manager_impl.h b/ios/web/navigation/serializable_user_data_manager_impl.h
index f002e90..9c62d8b 100644
--- a/ios/web/navigation/serializable_user_data_manager_impl.h
+++ b/ios/web/navigation/serializable_user_data_manager_impl.h
@@ -5,7 +5,6 @@
 #ifndef IOS_WEB_NAVIGATION_SERIALIZABLE_USER_DATA_MANAGER_IMPL_H_
 #define IOS_WEB_NAVIGATION_SERIALIZABLE_USER_DATA_MANAGER_IMPL_H_
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #import "ios/web/public/serializable_user_data_manager.h"
 
@@ -42,7 +41,7 @@
 
   // The dictionary passed on initialization.  After calling Decode(), this will
   // contain the data that is decoded from the NSCoder.
-  base::scoped_nsobject<NSDictionary<NSString*, id<NSCoding>>> data_;
+  NSDictionary<NSString*, id<NSCoding>>* data_;
 
   DISALLOW_COPY_AND_ASSIGN(SerializableUserDataImpl);
 };
@@ -61,7 +60,7 @@
 
  private:
   // The dictionary that stores serializable user data.
-  base::scoped_nsobject<NSMutableDictionary<NSString*, id<NSCoding>>> data_;
+  NSMutableDictionary<NSString*, id<NSCoding>>* data_;
 
   DISALLOW_COPY_AND_ASSIGN(SerializableUserDataManagerImpl);
 };
diff --git a/ios/web/navigation/serializable_user_data_manager_impl.mm b/ios/web/navigation/serializable_user_data_manager_impl.mm
index a53fae5..d503b47 100644
--- a/ios/web/navigation/serializable_user_data_manager_impl.mm
+++ b/ios/web/navigation/serializable_user_data_manager_impl.mm
@@ -82,7 +82,7 @@
     data = [NSMutableDictionary dictionary];
   }
   [data addEntriesFromDictionary:GetDecodedLegacyValues(coder)];
-  data_.reset([data copy]);
+  data_ = [data copy];
   DCHECK(data_);
 }
 
@@ -146,7 +146,7 @@
   if (data) {
     SerializableUserDataImpl* data_impl =
         static_cast<SerializableUserDataImpl*>(data);
-    data_.reset([data_impl->data() mutableCopy]);
+    data_ = [data_impl->data() mutableCopy];
     DCHECK(data_);
   }
 }
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.h b/ios/web/navigation/wk_based_navigation_manager_impl.h
index 8042d0d9..16fb922d 100644
--- a/ios/web/navigation/wk_based_navigation_manager_impl.h
+++ b/ios/web/navigation/wk_based_navigation_manager_impl.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <vector>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
diff --git a/ios/web/net/cookie_notification_bridge.h b/ios/web/net/cookie_notification_bridge.h
index 8e6273e..5a90ff73 100644
--- a/ios/web/net/cookie_notification_bridge.h
+++ b/ios/web/net/cookie_notification_bridge.h
@@ -5,7 +5,6 @@
 #ifndef IOS_WEB_NET_COOKIE_NOTIFICATION_BRIDGE_H_
 #define IOS_WEB_NET_COOKIE_NOTIFICATION_BRIDGE_H_
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 
 @class NSNotification;
@@ -22,7 +21,7 @@
 
  private:
   static void OnNotificationReceived(NSNotification* notification);
-  base::scoped_nsprotocol<id> observer_;
+  id observer_;
 
   DISALLOW_COPY_AND_ASSIGN(CookieNotificationBridge);
 };
diff --git a/ios/web/net/cookie_notification_bridge.mm b/ios/web/net/cookie_notification_bridge.mm
index 4ab27e0e..0b6cdddac 100644
--- a/ios/web/net/cookie_notification_bridge.mm
+++ b/ios/web/net/cookie_notification_bridge.mm
@@ -25,7 +25,7 @@
               usingBlock:^(NSNotification* notification) {
                 OnNotificationReceived(notification);
               }];
-  observer_.reset(observer);
+  observer_ = observer;
 }
 
 CookieNotificationBridge::~CookieNotificationBridge() {
diff --git a/ios/web/net/request_tracker_factory_impl.h b/ios/web/net/request_tracker_factory_impl.h
index 9cdb3e7..3ac0e37 100644
--- a/ios/web/net/request_tracker_factory_impl.h
+++ b/ios/web/net/request_tracker_factory_impl.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#import "base/mac/scoped_nsobject.h"
 #import "ios/net/request_tracker.h"
 
 namespace web {
@@ -23,7 +22,7 @@
   bool GetRequestTracker(NSURLRequest* request,
                          base::WeakPtr<net::RequestTracker>* tracker) override;
 
-  base::scoped_nsobject<NSString> application_scheme_;
+  NSString* application_scheme_;
 };
 
 }  // namespace web
diff --git a/ios/web/net/request_tracker_factory_impl.mm b/ios/web/net/request_tracker_factory_impl.mm
index a1ee474..74b36f4 100644
--- a/ios/web/net/request_tracker_factory_impl.mm
+++ b/ios/web/net/request_tracker_factory_impl.mm
@@ -19,8 +19,7 @@
 RequestTrackerFactoryImpl::RequestTrackerFactoryImpl(
     const std::string& application_scheme) {
   if (!application_scheme.empty()) {
-    application_scheme_.reset(
-        [base::SysUTF8ToNSString(application_scheme) copy]);
+    application_scheme_ = [base::SysUTF8ToNSString(application_scheme) copy];
     DCHECK(application_scheme_);
   }
 }
diff --git a/ios/web/web_state/navigation_context_impl.h b/ios/web/web_state/navigation_context_impl.h
index 3faeeff..a223bc4 100644
--- a/ios/web/web_state/navigation_context_impl.h
+++ b/ios/web/web_state/navigation_context_impl.h
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #import "ios/web/public/web_state/navigation_context.h"
@@ -71,7 +70,7 @@
   const ui::PageTransition page_transition_;
   bool is_same_document_ = false;
   bool is_post_ = false;
-  base::scoped_nsobject<NSError> error_;
+  NSError* error_;
   scoped_refptr<net::HttpResponseHeaders> response_headers_;
   bool is_renderer_initiated_ = false;
   int navigation_item_unique_id_ = -1;
diff --git a/ios/web/web_state/navigation_context_impl.mm b/ios/web/web_state/navigation_context_impl.mm
index 361e20e..d8a04fe6 100644
--- a/ios/web/web_state/navigation_context_impl.mm
+++ b/ios/web/web_state/navigation_context_impl.mm
@@ -29,11 +29,11 @@
 
 #ifndef NDEBUG
 NSString* NavigationContextImpl::GetDescription() const {
-  return [NSString
-      stringWithFormat:@"web::WebState: %ld, url: %s, "
+  return [NSString stringWithFormat:
+                       @"web::WebState: %ld, url: %s, "
                         "is_same_document: %@, error: %@",
                        reinterpret_cast<long>(web_state_), url_.spec().c_str(),
-                       is_same_document_ ? @"true" : @"false", error_.get()];
+                       is_same_document_ ? @"true" : @"false", error_];
 }
 #endif  // NDEBUG
 
@@ -78,7 +78,7 @@
 }
 
 void NavigationContextImpl::SetError(NSError* error) {
-  error_.reset(error);
+  error_ = error;
 }
 
 void NavigationContextImpl::SetResponseHeaders(
diff --git a/ios/web/web_state/session_certificate_policy_cache_impl.h b/ios/web/web_state/session_certificate_policy_cache_impl.h
index fb78639..86d1d11f 100644
--- a/ios/web/web_state/session_certificate_policy_cache_impl.h
+++ b/ios/web/web_state/session_certificate_policy_cache_impl.h
@@ -7,7 +7,6 @@
 
 #import <Foundation/Foundation.h>
 
-#import "base/mac/scoped_nsobject.h"
 #include "ios/web/public/web_state/session_certificate_policy_cache.h"
 
 namespace web {
@@ -33,7 +32,7 @@
 
  private:
   // An set of CRWSessionCertificateStorages representing allowed certs.
-  base::scoped_nsobject<NSMutableSet> allowed_certs_;
+  NSMutableSet* allowed_certs_;
 
   DISALLOW_COPY_AND_ASSIGN(SessionCertificatePolicyCacheImpl);
 };
diff --git a/ios/web/web_state/session_certificate_policy_cache_impl.mm b/ios/web/web_state/session_certificate_policy_cache_impl.mm
index ece14cd00..fc4e5b4 100644
--- a/ios/web/web_state/session_certificate_policy_cache_impl.mm
+++ b/ios/web/web_state/session_certificate_policy_cache_impl.mm
@@ -81,11 +81,11 @@
 }
 
 void SessionCertificatePolicyCacheImpl::SetAllowedCerts(NSSet* allowed_certs) {
-  allowed_certs_.reset([allowed_certs mutableCopy]);
+  allowed_certs_ = [allowed_certs mutableCopy];
 }
 
 NSSet* SessionCertificatePolicyCacheImpl::GetAllowedCerts() const {
-  return allowed_certs_.get();
+  return allowed_certs_;
 }
 
 }  // namespace web
diff --git a/ios/web/web_state/ui/wk_back_forward_list_item_holder.h b/ios/web/web_state/ui/wk_back_forward_list_item_holder.h
index fb941141..390d781 100644
--- a/ios/web/web_state/ui/wk_back_forward_list_item_holder.h
+++ b/ios/web/web_state/ui/wk_back_forward_list_item_holder.h
@@ -7,7 +7,6 @@
 
 #import <WebKit/WebKit.h>
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/supports_user_data.h"
 
@@ -42,16 +41,14 @@
   void set_navigation_type(WKNavigationType type) { navigation_type_ = type; }
 
   // Gets/sets HTTP request method for this item.
-  NSString* http_method() const { return http_method_.get(); }
+  NSString* http_method() const { return http_method_; }
   void set_http_method(NSString* http_method) {
-    http_method_.reset([http_method copy]);
+    http_method_ = [http_method copy];
   }
 
   // Gets/sets the MIME type of the page corresponding to this item.
-  NSString* mime_type() const { return mime_type_.get(); }
-  void set_mime_type(NSString* mime_type) {
-    mime_type_.reset([mime_type copy]);
-  }
+  NSString* mime_type() const { return mime_type_; }
+  void set_mime_type(NSString* mime_type) { mime_type_ = [mime_type copy]; }
 
  private:
   WKBackForwardListItemHolder();
@@ -64,10 +61,10 @@
   WKNavigationType navigation_type_;
 
   // HTTP request method.
-  base::scoped_nsobject<NSString> http_method_;
+  NSString* http_method_;
 
   // The MIME type of the page content.
-  base::scoped_nsobject<NSString> mime_type_;
+  NSString* mime_type_;
 
   DISALLOW_COPY_AND_ASSIGN(WKBackForwardListItemHolder);
 };
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.h b/ios/web/web_state/ui/wk_web_view_configuration_provider.h
index dd8de96..810d4659 100644
--- a/ios/web/web_state/ui/wk_web_view_configuration_provider.h
+++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.h
@@ -5,7 +5,6 @@
 #ifndef IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_
 #define IOS_WEB_WEB_STATE_UI_WK_WEB_VIEW_CONFIGURATION_PROVIDER_H_
 
-#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/supports_user_data.h"
 
@@ -50,8 +49,8 @@
   explicit WKWebViewConfigurationProvider(BrowserState* browser_state);
   WKWebViewConfigurationProvider() = delete;
 
-  base::scoped_nsobject<WKWebViewConfiguration> configuration_;
-  base::scoped_nsobject<CRWWKScriptMessageRouter> router_;
+  WKWebViewConfiguration* configuration_;
+  CRWWKScriptMessageRouter* router_;
   BrowserState* browser_state_;
 
   DISALLOW_COPY_AND_ASSIGN(WKWebViewConfigurationProvider);
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
index 147a0be8..705aee3 100644
--- a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
+++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
@@ -70,7 +70,7 @@
 WKWebViewConfigurationProvider::GetWebViewConfiguration() {
   DCHECK([NSThread isMainThread]);
   if (!configuration_) {
-    configuration_.reset([[WKWebViewConfiguration alloc] init]);
+    configuration_ = [[WKWebViewConfiguration alloc] init];
     if (browser_state_->IsOffTheRecord()) {
       [configuration_
           setWebsiteDataStore:[WKWebsiteDataStore nonPersistentDataStore]];
@@ -95,16 +95,16 @@
   if (!router_) {
     WKUserContentController* userContentController =
         [GetWebViewConfiguration() userContentController];
-    router_.reset([[CRWWKScriptMessageRouter alloc]
-        initWithUserContentController:userContentController]);
+    router_ = [[CRWWKScriptMessageRouter alloc]
+        initWithUserContentController:userContentController];
   }
   return router_;
 }
 
 void WKWebViewConfigurationProvider::Purge() {
   DCHECK([NSThread isMainThread]);
-  configuration_.reset();
-  router_.reset();
+  configuration_ = nil;
+  router_ = nil;
 }
 
 }  // namespace web
diff --git a/ios/web_view/internal/web_view_early_page_script_provider.h b/ios/web_view/internal/web_view_early_page_script_provider.h
index 272ad84..0c598ef 100644
--- a/ios/web_view/internal/web_view_early_page_script_provider.h
+++ b/ios/web_view/internal/web_view_early_page_script_provider.h
@@ -7,7 +7,6 @@
 
 #include <Foundation/Foundation.h>
 
-#include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/supports_user_data.h"
 
@@ -32,14 +31,14 @@
       web::BrowserState* _Nonnull browser_state);
 
   // Getter and Setter for the JavaScript source code.
-  NSString* _Nonnull GetScript() { return script_.get(); }
+  NSString* _Nonnull GetScript() { return script_; }
   void SetScript(NSString* _Nonnull script);
 
  private:
   WebViewEarlyPageScriptProvider();
 
   // The JavaScript source code.
-  base::scoped_nsobject<NSString> script_;
+  NSString* _Nonnull script_;
 
   DISALLOW_COPY_AND_ASSIGN(WebViewEarlyPageScriptProvider);
 };
diff --git a/ios/web_view/internal/web_view_early_page_script_provider.mm b/ios/web_view/internal/web_view_early_page_script_provider.mm
index 89d94c14..f23fa61 100644
--- a/ios/web_view/internal/web_view_early_page_script_provider.mm
+++ b/ios/web_view/internal/web_view_early_page_script_provider.mm
@@ -40,7 +40,7 @@
 WebViewEarlyPageScriptProvider::~WebViewEarlyPageScriptProvider() = default;
 
 void WebViewEarlyPageScriptProvider::SetScript(NSString* _Nonnull script) {
-  script_.reset([script copy]);
+  script_ = [script copy];
 }
 
 WebViewEarlyPageScriptProvider::WebViewEarlyPageScriptProvider()
diff --git a/ios/web_view/test/web_view_int_test.h b/ios/web_view/test/web_view_int_test.h
index 8318fa6..5a83253 100644
--- a/ios/web_view/test/web_view_int_test.h
+++ b/ios/web_view/test/web_view_int_test.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#import "base/mac/scoped_nsobject.h"
 #include "testing/platform_test.h"
 
 namespace net {
@@ -47,7 +46,7 @@
 
   // CWVWebView created with default configuration and frame equal to screen
   // bounds.
-  base::scoped_nsobject<CWVWebView> web_view_;
+  CWVWebView* web_view_;
 
   // Embedded server for handling requests sent to the URLs returned by the
   // GetURL* methods.
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index b77d6cf..6eaa321 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -900,6 +900,9 @@
   ExpectCTState state;
   if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
       GetDynamicExpectCTState(hostname, &state)) {
+    UMA_HISTOGRAM_ENUMERATION(
+        "Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup",
+        policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX);
     if (!complies && expect_ct_reporter_ && !state.report_uri.is_empty() &&
         report_status == ENABLE_EXPECT_CT_REPORTS) {
       MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri, state.expiry,
@@ -1515,6 +1518,9 @@
   // public root or did not comply with CT policy.
   if (!ssl_info.is_issued_by_known_root)
     return;
+  UMA_HISTOGRAM_ENUMERATION(
+      "Net.ExpectCTHeader.PolicyComplianceOnHeaderProcessing",
+      ssl_info.ct_policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX);
   if (ssl_info.ct_policy_compliance !=
       ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) {
     // If an Expect-CT header is observed over a non-compliant connection, the
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc
index efe45716..e133b7b 100644
--- a/net/log/net_log_util.cc
+++ b/net/log/net_log_util.cc
@@ -460,7 +460,7 @@
     context->AssertCalledOnValidThread();
     // Contexts should all be using the same NetLog.
     DCHECK_EQ((*contexts.begin())->net_log(), context->net_log());
-    for (auto* request : context->url_requests()) {
+    for (auto* request : *context->url_requests()) {
       requests.push_back(request);
     }
   }
diff --git a/net/nqe/network_qualities_prefs_manager.cc b/net/nqe/network_qualities_prefs_manager.cc
index f66b8bc..be39015 100644
--- a/net/nqe/network_qualities_prefs_manager.cc
+++ b/net/nqe/network_qualities_prefs_manager.cc
@@ -139,6 +139,11 @@
     // No need to cache the network quality since the default network quality
     // (synthesized using the platform APIs) matches the observed network
     // quality.
+    if (!prefs_->RemoveKey(network_id_string)) {
+      // Return early since the prefs was unchanged.
+      return;
+    }
+    pref_delegate_->SetDictionaryValue(*prefs_);
     return;
   }
 
diff --git a/net/nqe/network_qualities_prefs_manager_unittest.cc b/net/nqe/network_qualities_prefs_manager_unittest.cc
index ea5b433..44b228c 100644
--- a/net/nqe/network_qualities_prefs_manager_unittest.cc
+++ b/net/nqe/network_qualities_prefs_manager_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/values.h"
 #include "net/base/network_change_notifier.h"
 #include "net/nqe/effective_connection_type.h"
+#include "net/nqe/network_id.h"
 #include "net/nqe/network_quality_estimator_test_util.h"
 #include "net/nqe/network_quality_store.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -118,6 +119,70 @@
   manager.ShutdownOnPrefSequence();
 }
 
+TEST(NetworkQualitiesPrefManager, WriteWhenMatchingExpectedECT) {
+  // Force set the ECT to Slow 2G so that the ECT does not match the default
+  // ECT for the current connection type. This forces the prefs to be written
+  // for the current connection.
+  std::map<std::string, std::string> variation_params;
+  variation_params["force_effective_connection_type"] = "Slow-2G";
+  TestNetworkQualityEstimator estimator(variation_params);
+
+  std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
+  TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
+
+  NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
+  manager.InitializeOnNetworkThread(&estimator);
+  base::RunLoop().RunUntilIdle();
+
+  // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
+  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());
+
+  const nqe::internal::NetworkID network_id(
+      NetworkChangeNotifier::ConnectionType::CONNECTION_4G, "test", INT32_MIN);
+
+  estimator.SimulateNetworkChange(network_id.type, network_id.id);
+  EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
+  // Network quality generated from the default observation must be written.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
+
+  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
+  // Run a request so that effective connection type is recomputed, and
+  // observers are notified of change in the network quality.
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(4u, prefs_delegate_ptr->write_count());
+
+  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
+  // Run a request so that effective connection type is recomputed, and
+  // observers are notified of change in the network quality..
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(5u, prefs_delegate_ptr->write_count());
+
+  // Prefs should not be read again.
+  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());
+
+  EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
+  EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_3G,
+            manager.ForceReadPrefsForTesting()
+                .find(network_id)
+                ->second.effective_connection_type());
+
+  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_4G);
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+
+  // Cached network quality for |network_id| should be deleted from the prefs
+  // since the expected network quality for |network_id| matches the observed
+  // network quality.
+  EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
+  EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().count(network_id));
+  EXPECT_EQ(6u, prefs_delegate_ptr->write_count());
+
+  manager.ShutdownOnPrefSequence();
+}
+
 TEST(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
   static const size_t kMaxCacheSize = 20u;
 
diff --git a/net/nqe/network_quality_store.cc b/net/nqe/network_quality_store.cc
index c2f7a23..6d85622 100644
--- a/net/nqe/network_quality_store.cc
+++ b/net/nqe/network_quality_store.cc
@@ -19,8 +19,8 @@
                 "Size of the network quality cache must be > 0");
   // This limit should not be increased unless the logic for removing the
   // oldest cache entry is rewritten to use a doubly-linked-list LRU queue.
-  static_assert(kMaximumNetworkQualityCacheSize <= 10,
-                "Size of the network quality cache must <= 10");
+  static_assert(kMaximumNetworkQualityCacheSize <= 20,
+                "Size of the network quality cache must <= 20");
 }
 
 NetworkQualityStore::~NetworkQualityStore() {
diff --git a/net/nqe/network_quality_store.h b/net/nqe/network_quality_store.h
index f26566a..77b7e38 100644
--- a/net/nqe/network_quality_store.h
+++ b/net/nqe/network_quality_store.h
@@ -76,7 +76,7 @@
   // Maximum size of the store that holds network quality estimates.
   // A smaller size may reduce the cache hit rate due to frequent evictions.
   // A larger size may affect performance.
-  static const size_t kMaximumNetworkQualityCacheSize = 10;
+  static const size_t kMaximumNetworkQualityCacheSize = 20;
 
   // Notifies |observer| of the current effective connection type if |observer|
   // is still registered as an observer.
diff --git a/net/nqe/network_quality_store_unittest.cc b/net/nqe/network_quality_store_unittest.cc
index 4ad7a26..12928c5 100644
--- a/net/nqe/network_quality_store_unittest.cc
+++ b/net/nqe/network_quality_store_unittest.cc
@@ -234,7 +234,7 @@
   base::SimpleTestTickClock tick_clock;
 
   // Add more networks than the maximum size of the cache.
-  const size_t network_count = 11;
+  const size_t network_count = 21;
 
   nqe::internal::CachedNetworkQuality read_network_quality(
       tick_clock.NowTicks(),
diff --git a/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc b/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
index 03ed2c9..b7e407c9 100644
--- a/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
+++ b/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
@@ -674,7 +674,7 @@
 
   client.ResetTestState();
   EXPECT_THAT(client.RunTestThatMayFailSync(), IsError(ERR_CONTEXT_SHUT_DOWN));
-  EXPECT_EQ(0u, context.url_requests().size());
+  EXPECT_EQ(0u, context.url_requests()->size());
 }
 
 }  // namespace
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc
index c8d1045..5390c5495 100644
--- a/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -551,15 +551,15 @@
   int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
                                  callback.callback());
   EXPECT_THAT(result, IsError(ERR_IO_PENDING));
-  EXPECT_EQ(1u, context_.url_requests().size());
+  EXPECT_EQ(1u, context_.url_requests()->size());
 
   pac_fetcher.OnShutdown();
-  EXPECT_EQ(0u, context_.url_requests().size());
+  EXPECT_EQ(0u, context_.url_requests()->size());
   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONTEXT_SHUT_DOWN));
 
   // Make sure there's no asynchronous completion notification.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(0u, context_.url_requests().size());
+  EXPECT_EQ(0u, context_.url_requests()->size());
   EXPECT_FALSE(callback.have_result());
 
   result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
@@ -578,7 +578,7 @@
   int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
                                  callback.callback());
   EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
-  EXPECT_EQ(0u, context_.url_requests().size());
+  EXPECT_EQ(0u, context_.url_requests()->size());
 }
 
 }  // namespace
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 3b76938..34c173c 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -192,7 +192,8 @@
   // on UserData associated with |this| and poke at it during teardown.
   job_.reset();
 
-  context_->RemoveURLRequest(this);
+  DCHECK_EQ(1u, context_->url_requests()->count(this));
+  context_->url_requests()->erase(this);
 
   int net_error = OK;
   // Log error only on failure, not cancellation, as even successful requests
@@ -579,7 +580,7 @@
   // Sanity check out environment.
   DCHECK(base::ThreadTaskRunnerHandle::IsSet());
 
-  context->InsertURLRequest(this);
+  context->url_requests()->insert(this);
   net_log_.BeginEvent(
       NetLogEventType::REQUEST_ALIVE,
       base::Bind(&NetLogURLRequestConstructorCallback, &url, priority_));
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index a413081..8c27640 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -50,10 +50,10 @@
       reporting_service_(nullptr),
       network_error_logging_delegate_(nullptr),
 #endif  // BUILDFLAG(ENABLE_REPORTING)
+      url_requests_(std::make_unique<std::set<const URLRequest*>>()),
       enable_brotli_(false),
       check_cleartext_permitted_(false),
-      name_("unknown"),
-      largest_outstanding_requests_count_seen_(0) {
+      name_("unknown") {
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
       this, "URLRequestContext", base::ThreadTaskRunnerHandle::Get());
 }
@@ -135,29 +135,13 @@
   cookie_store_ = cookie_store;
 }
 
-void URLRequestContext::InsertURLRequest(const URLRequest* request) const {
-  url_requests_.insert(request);
-  if (url_requests_.size() > largest_outstanding_requests_count_seen_) {
-    largest_outstanding_requests_count_seen_ = url_requests_.size();
-    UMA_HISTOGRAM_COUNTS_1M("Net.URLRequestContext.OutstandingRequests",
-                            largest_outstanding_requests_count_seen_);
-    base::UmaHistogramSparse("Net.URLRequestContext.OutstandingRequests.Type",
-                             request->traffic_annotation().unique_id_hash_code);
-  }
-}
-
-void URLRequestContext::RemoveURLRequest(const URLRequest* request) const {
-  DCHECK_EQ(1u, url_requests_.count(request));
-  url_requests_.erase(request);
-}
-
 void URLRequestContext::AssertNoURLRequests() const {
-  int num_requests = url_requests_.size();
+  int num_requests = url_requests_->size();
   if (num_requests != 0) {
     // We're leaking URLRequests :( Dump the URL of the first one and record how
     // many we leaked so we have an idea of how bad it is.
     char url_buf[128];
-    const URLRequest* request = *url_requests_.begin();
+    const URLRequest* request = *url_requests_->begin();
     base::strlcpy(url_buf, request->url().spec().c_str(), arraysize(url_buf));
     int load_flags = request->load_flags();
     base::debug::Alias(url_buf);
@@ -180,7 +164,7 @@
       pmd->CreateAllocatorDump(dump_name);
   dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
                   base::trace_event::MemoryAllocatorDump::kUnitsObjects,
-                  url_requests_.size());
+                  url_requests_->size());
   HttpTransactionFactory* transaction_factory = http_transaction_factory();
   if (transaction_factory) {
     HttpNetworkSession* network_session = transaction_factory->GetSession();
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index c498ad2..30fc9851a 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -215,14 +215,10 @@
 
   // Gets the URLRequest objects that hold a reference to this
   // URLRequestContext.
-  const std::set<const URLRequest*>& url_requests() const {
-    return url_requests_;
+  std::set<const URLRequest*>* url_requests() const {
+    return url_requests_.get();
   }
 
-  void InsertURLRequest(const URLRequest* request) const;
-
-  void RemoveURLRequest(const URLRequest* request) const;
-
   // CHECKs that no URLRequests using this context remain. Subclasses should
   // additionally call AssertNoURLRequests() within their own destructor,
   // prior to implicit destruction of subclass-owned state.
@@ -328,7 +324,7 @@
   // be added to CopyFrom.
   // ---------------------------------------------------------------------------
 
-  mutable std::set<const URLRequest*> url_requests_;
+  std::unique_ptr<std::set<const URLRequest*>> url_requests_;
 
   // Enables Brotli Content-Encoding support.
   bool enable_brotli_;
@@ -341,10 +337,6 @@
   // to be unique.
   std::string name_;
 
-  // The largest number of outstanding URLRequests that have been created by
-  // |this| and are not yet destroyed. This doesn't need to be in CopyFrom.
-  mutable size_t largest_outstanding_requests_count_seen_;
-
   THREAD_CHECKER(thread_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(URLRequestContext);
diff --git a/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc b/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc
index 749e707..77dbaf5 100644
--- a/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc
+++ b/services/identity/public/cpp/primary_account_access_token_fetcher_unittest.cc
@@ -38,7 +38,9 @@
 
 namespace identity {
 
-class PrimaryAccountAccessTokenFetcherTest : public testing::Test {
+class PrimaryAccountAccessTokenFetcherTest
+    : public testing::Test,
+      public OAuth2TokenService::DiagnosticsObserver {
  public:
   using TestTokenCallback =
       StrictMock<MockCallback<PrimaryAccountAccessTokenFetcher::TokenCallback>>;
@@ -68,9 +70,12 @@
         &signin_client_, &token_service_, account_tracker_.get(),
         /*cookie_manager_service=*/nullptr);
 #endif  // OS_CHROMEOS
+    token_service_.AddDiagnosticsObserver(this);
   }
 
-  ~PrimaryAccountAccessTokenFetcherTest() override {}
+  ~PrimaryAccountAccessTokenFetcherTest() override {
+    token_service_.RemoveDiagnosticsObserver(this);
+  }
 
   std::unique_ptr<PrimaryAccountAccessTokenFetcher> CreateFetcher(
       PrimaryAccountAccessTokenFetcher::TokenCallback callback) {
@@ -91,18 +96,36 @@
 #endif  // OS_CHROMEOS
   }
 
+  void set_on_access_token_request_callback(base::OnceClosure callback) {
+    on_access_token_request_callback_ = std::move(callback);
+  }
+
  private:
+  // OAuth2TokenService::DiagnosticsObserver:
+  void OnAccessTokenRequested(
+      const std::string& account_id,
+      const std::string& consumer_id,
+      const OAuth2TokenService::ScopeSet& scopes) override {
+    if (on_access_token_request_callback_)
+      std::move(on_access_token_request_callback_).Run();
+  }
+
+  base::MessageLoop message_loop_;
   TestingPrefServiceSyncable pref_service_;
   TestSigninClient signin_client_;
   FakeProfileOAuth2TokenService token_service_;
 
   std::unique_ptr<AccountTrackerService> account_tracker_;
   std::unique_ptr<SigninManagerForTest> signin_manager_;
+  base::OnceClosure on_access_token_request_callback_;
 };
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldReturnAccessToken) {
   TestTokenCallback callback;
 
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   SignIn("account");
   token_service()->GetDelegate()->UpdateCredentials("account", "refresh token");
 
@@ -110,6 +133,8 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
   // Once the access token request is fulfilled, we should get called back with
   // the access token.
   EXPECT_CALL(callback,
@@ -122,6 +147,9 @@
 TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldNotReplyIfDestroyed) {
   TestTokenCallback callback;
 
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   SignIn("account");
   token_service()->GetDelegate()->UpdateCredentials("account", "refresh token");
 
@@ -129,6 +157,8 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
   // Destroy the fetcher before the access token request is fulfilled.
   fetcher.reset();
 
@@ -151,14 +181,20 @@
 #if !defined(OS_CHROMEOS)
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForSignIn) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   // Not signed in, so this should wait for a sign-in to complete.
   auto fetcher = CreateFetcher(callback.Get());
 
   SignIn("account");
+
   token_service()->GetDelegate()->UpdateCredentials("account", "refresh token");
 
+  run_loop.Run();
+
   // Once the access token request is fulfilled, we should get called back with
   // the access token.
   EXPECT_CALL(callback,
@@ -169,6 +205,9 @@
 }
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForSignInInProgress) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   signin_manager()->set_auth_in_progress("account");
@@ -180,6 +219,8 @@
   SignIn("account");
   token_service()->GetDelegate()->UpdateCredentials("account", "refresh token");
 
+  run_loop.Run();
+
   // Once the access token request is fulfilled, we should get called back with
   // the access token.
   EXPECT_CALL(callback,
@@ -212,6 +253,9 @@
 #endif  // !OS_CHROMEOS
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForRefreshToken) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -223,6 +267,8 @@
   // Getting a refresh token should result in a request for an access token.
   token_service()->GetDelegate()->UpdateCredentials("account", "refresh token");
 
+  run_loop.Run();
+
   // Once the access token request is fulfilled, we should get called back with
   // the access token.
   EXPECT_CALL(callback,
@@ -262,11 +308,6 @@
   token_service()->GetDelegate()->UpdateCredentials("different account",
                                                     "refresh token");
 
-  // The OAuth2TokenService posts a task to the current thread when we try to
-  // get an access token for an account without a refresh token, so we need a
-  // MessageLoop in this test to not crash.
-  base::MessageLoop message_loop;
-
   // When all refresh tokens have been loaded by the token service, but the one
   // for our account wasn't among them, we should get called back with an empty
   // access token.
@@ -279,6 +320,9 @@
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest,
        ShouldRetryCanceledAccessTokenRequest) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -288,11 +332,19 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
+  // Before cancelling the first request, set up to wait for the second request.
+  base::RunLoop run_loop2;
+  set_on_access_token_request_callback(run_loop2.QuitClosure());
+
   // A canceled access token request should get retried once.
   token_service()->IssueErrorForAllPendingRequestsForAccount(
       "account",
       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
 
+  run_loop2.Run();
+
   // Once the access token request is fulfilled, we should get called back with
   // the access token.
   EXPECT_CALL(callback,
@@ -304,6 +356,9 @@
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest,
        ShouldRetryCanceledAccessTokenRequestOnlyOnce) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -313,11 +368,19 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
+  // Before cancelling the first request, set up to wait for the second request.
+  base::RunLoop run_loop2;
+  set_on_access_token_request_callback(run_loop2.QuitClosure());
+
   // A canceled access token request should get retried once.
   token_service()->IssueErrorForAllPendingRequestsForAccount(
       "account",
       GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
 
+  run_loop2.Run();
+
   // On the second failure, we should get called back with an empty access
   // token.
   EXPECT_CALL(
@@ -333,6 +396,9 @@
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest,
        ShouldNotRetryCanceledAccessTokenRequestIfSignedOut) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -342,6 +408,8 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
   // Simulate the user signing out while the access token request is pending.
   // In this case, the pending request gets canceled, and the fetcher should
   // *not* retry.
@@ -359,6 +427,9 @@
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest,
        ShouldNotRetryCanceledAccessTokenRequestIfRefreshTokenRevoked) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -368,6 +439,8 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
   // Simulate the refresh token getting invalidated. In this case, pending
   // access token requests get canceled, and the fetcher should *not* retry.
   token_service()->GetDelegate()->RevokeCredentials("account");
@@ -382,6 +455,9 @@
 
 TEST_F(PrimaryAccountAccessTokenFetcherTest,
        ShouldNotRetryFailedAccessTokenRequest) {
+  base::RunLoop run_loop;
+  set_on_access_token_request_callback(run_loop.QuitClosure());
+
   TestTokenCallback callback;
 
   SignIn("account");
@@ -391,6 +467,8 @@
   // request for an access token.
   auto fetcher = CreateFetcher(callback.Get());
 
+  run_loop.Run();
+
   // An access token failure other than "canceled" should not be retried; we
   // should immediately get called back with an empty access token.
   EXPECT_CALL(
diff --git a/services/network/public/cpp/network_param_ipc_traits.h b/services/network/public/cpp/network_param_ipc_traits.h
index 7204a73..5711ffc 100644
--- a/services/network/public/cpp/network_param_ipc_traits.h
+++ b/services/network/public/cpp/network_param_ipc_traits.h
@@ -151,6 +151,7 @@
   IPC_STRUCT_TRAITS_MEMBER(decoded_body_length)
   IPC_STRUCT_TRAITS_MEMBER(cors_error_status)
   IPC_STRUCT_TRAITS_MEMBER(ssl_info)
+  IPC_STRUCT_TRAITS_MEMBER(blocked_cross_site_document)
 IPC_STRUCT_TRAITS_END()
 
 #endif  // SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_IPC_TRAITS_H_
diff --git a/services/network/public/cpp/url_loader_completion_status.cc b/services/network/public/cpp/url_loader_completion_status.cc
index 8183d5b..b7792fa 100644
--- a/services/network/public/cpp/url_loader_completion_status.cc
+++ b/services/network/public/cpp/url_loader_completion_status.cc
@@ -31,7 +31,8 @@
          encoded_data_length == rhs.encoded_data_length &&
          encoded_body_length == rhs.encoded_body_length &&
          decoded_body_length == rhs.decoded_body_length &&
-         cors_error_status == rhs.cors_error_status;
+         cors_error_status == rhs.cors_error_status &&
+         blocked_cross_site_document == rhs.blocked_cross_site_document;
 }
 
 }  // namespace network
diff --git a/services/network/public/cpp/url_loader_completion_status.h b/services/network/public/cpp/url_loader_completion_status.h
index 0b804bf9..9cc4049 100644
--- a/services/network/public/cpp/url_loader_completion_status.h
+++ b/services/network/public/cpp/url_loader_completion_status.h
@@ -55,6 +55,9 @@
 
   // Optional SSL certificate info.
   base::Optional<net::SSLInfo> ssl_info;
+
+  // Set when response was blocked due to being cross-site document load.
+  bool blocked_cross_site_document = false;
 };
 
 }  // namespace network
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 8d5f864..bbcdd90 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -2389,6 +2389,9 @@
         "test": "components_policy_junit_tests"
       },
       {
+        "test": "components_signin_junit_tests"
+      },
+      {
         "test": "components_variations_junit_tests"
       },
       {
@@ -4066,6 +4069,9 @@
         "test": "components_policy_junit_tests"
       },
       {
+        "test": "components_signin_junit_tests"
+      },
+      {
         "test": "components_variations_junit_tests"
       },
       {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index bc0b521..0b04d48 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -4220,18 +4220,6 @@
       },
       {
         "args": [
-          "--xvfb"
-        ],
-        "isolate_name": "telemetry_perf_unittests_viz",
-        "name": "telemetry_perf_unittests_viz",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "hard_timeout": 960,
-          "shards": 12
-        }
-      },
-      {
-        "args": [
           "--extra-browser-args=--enable-viz",
           "--skip=telemetry.internal.actions.scroll_unittest.ScrollActionTest.testWheelScrollDistanceWhileZoomed",
           "--skip=telemetry.internal.backends.chrome_inspector.inspector_page_unittest.InspectorPageTest.testCaptureScreenshot",
diff --git a/testing/buildbot/filters/viz.browser_tests.filter b/testing/buildbot/filters/viz.browser_tests.filter
index a074ced..29fac6a5 100644
--- a/testing/buildbot/filters/viz.browser_tests.filter
+++ b/testing/buildbot/filters/viz.browser_tests.filter
@@ -11,6 +11,10 @@
 # PictureLayerTilingSet::ComputeSkewport crash crbug.com/796594
 -LoginFeedbackTest.Basic
 
+# RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedderImpl crash
+# crbug.com/797801
+-HostedAppProcessModelTest.IframeNavigationsInsideHostedApp/1
+
 # Tab Capture is still in development: crbug.com/754864
 -CastStreamingApiTestWithPixelOutput.EndToEnd
 -ChromeScreenshotGrabberBrowserTest.TakeScreenshot
@@ -68,13 +72,7 @@
 -BrowserTest.ShouldShowLocationBar
 -CaptivePortalBrowserTest.*
 -CastStreamingApiTestWithPixelOutput.EndToEnd
--CertificateReportingServiceBrowserTest.Delayed_Reset/0
--CertificateReportingServiceBrowserTest.DisableSafebrowsing/0
--CertificateReportingServiceBrowserTest.DontSendOldReports/0
--CertificateReportingServiceBrowserTest.DropOldReportsFromQueue/0
--CertificateReportingServiceBrowserTest.DropOldReportsFromQueue/1
--CertificateReportingServiceBrowserTest.OptedIn_ShouldQueueFailedReport/0
--CertificateReportingServiceBrowserTest.OptedOut_ThenOptedIn_ThenOptedOut/0
+-CertificateReportingServiceBrowserTest.*
 -ClipboardApiTest.Extension
 -ClipboardApiTest.ExtensionNoPermission
 -CloudPrintPolicyTest.NormalPassedFlag
@@ -86,7 +84,7 @@
 -ContextMenuBrowserTest.OpenLinkInProfile
 -CrossOriginXHR.AllURLs
 -CrossOriginXHR.ContentScript
--DidChangeVisibleSecurityStateTest.DidChangeVisibleSecurityStateObserver
+-DidChangeVisibleSecurityStateTest.*
 -DomainReliabilityBrowserTest.UploadAtShutdown
 -DownloadTest.DownloadCrossDomainReferrerPolicy
 -ExecuteScriptApiTest.ExecuteScriptBadEncoding
@@ -100,8 +98,7 @@
 -ExtensionApiNewTabTest.Tabs
 -ExtensionApiTabTest.TabConnect
 -ExtensionBrowserTest.PromptToReEnableExtensionsOnNavigation
--ExtensionTabsTest.GetAllWindows
--ExtensionTabsTest.GetAllWindowsAllTypes
+-ExtensionTabsTest.*
 -GeolocationBrowserTest.CancelPermissionForFrame
 -GeolocationBrowserTest.IFramesWithCachedPosition
 -GeolocationBrowserTest.IFramesWithFreshPosition
@@ -129,7 +126,8 @@
 -PageLoadMetricsBrowserTest.*
 -PasswordManagerBrowserTestBase.SlowPageFill
 -PaymentRequestModifiersTest.*
--Pepper/ECKEncryptedMediaTest.OutputProtectionTest/0
+-PaymentRequestPaymentAppTest.*
+-Pepper/ECKEncryptedMediaTest.*
 -PlatformAppBrowserTest.Isolation
 -PolicyTest.CertificateTransparencyEnforcementDisabledForUrls
 -PolicyTest.SSLErrorOverridingAllowed
@@ -143,6 +141,7 @@
 -ReferrerPolicyTest.MiddleClickRedirect
 -ReferrerPolicyTest.MiddleClickTargetBlankRedirect
 -ResourcePrefetchPredictorBrowserTest.SubresourceFcpOrder
+-SSLNetworkTimeBrowserTest.TimeoutExpiresBeforeFetchCompletes/0
 -SSLUICaptivePortalListResourceBundleTest.Enabled_DynamicUpdate/0
 -SSLUITest*
 -SSLUIWorkerFetchTest.*
@@ -163,6 +162,7 @@
 -ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.BackgroundPageIsWokenIfAsleep/0
 -ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.FetchArbitraryPaths/0
 -ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.ServiceWorkerSuspensionOnExtensionUnload/0
+-SRC_ExternalClearKey/EncryptedMediaTest.Playback_VideoAudio_WebM/0
 -SubresourceFilterPopupBrowserTest.BlockOpenURLFromTab
 -SuperfishSSLUITest.NoSuperfishRecorded/0
 -SuperfishSSLUITest.SuperfishRecorded/0
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 893e1c1..fed3cae 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -359,6 +359,10 @@
     "label": "//components/policy/android:components_policy_junit_tests",
     "type": "junit_test",
   },
+  "components_signin_junit_tests": {
+    "label": "//components/signin/core/browser/android:components_signin_junit_tests",
+    "type": "junit_test",
+  },
   "components_unittests": {
     "label": "//components:components_unittests",
     "type": "windowed_test_launcher",
@@ -957,17 +961,6 @@
       "-v",
     ],
   },
-  "telemetry_perf_unittests_viz": {
-    "label": "//chrome/test:telemetry_perf_unittests",
-    "type": "script",
-    "executable": "telemetry_perf_tests",
-    "script": "//testing/scripts/run_telemetry_as_googletest.py",
-    "args": [
-      "../../tools/perf/run_tests",
-      "-v",
-      '--extra-browser-args=--enable-viz',
-    ],
-  },
   "telemetry_perf_tests": {
     "label": "//chrome/test:telemetry_perf_tests",
     "type": "script",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index bd2873c..e55c16d 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -441,6 +441,7 @@
     'components_gcm_driver_junit_tests': {},
     'components_invalidation_impl_junit_tests': {},
     'components_policy_junit_tests': {},
+    'components_signin_junit_tests': {},
     'components_web_restrictions_junit_tests': {},
     'components_variations_junit_tests': {},
     'content_junit_tests': {},
@@ -976,15 +977,6 @@
         'shards': 12,
       },
     },
-    'telemetry_perf_unittests_viz': {
-      'args': [
-        "--xvfb",
-      ],
-      'swarming': {
-        'hard_timeout': 960,
-        'shards': 12,
-      },
-    },
     'telemetry_unittests': {
       'args': [
         '--extra-browser-args=--enable-viz',
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
index b8f9cc8..0617278a 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -12,6 +12,8 @@
 crbug.com/417782 fast/loader/scroll-position-restored-on-reload-at-load-event.html [ Failure ]
 crbug.com/417782 fast/overflow/overflow-clamp-after-visible-rect-resize.html [ Failure ]
 crbug.com/417782 fast/overflow/scrollRevealButton.html [ Failure ]
+crbug.com/417782 fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html [ Failure ]
+crbug.com/417782 fast/spatial-navigation/snav-use-visual-viewport.html [ Failure ]
 crbug.com/417782 html/dialog/form-method-dialog.html [ Crash ]
 crbug.com/417782 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/417782 http/tests/devtools/tracing/timeline-paint/layer-tree.js [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index 9e9ef4b..5c291508 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -44,6 +44,7 @@
 crbug.com/780386 external/wpt/html/dom/reflection-grouping.html [ Leak Pass ]
 crbug.com/796944 [ Linux ] synthetic_gestures/synthetic-pinch-zoom-gesture.html [ Leak Pass ]
 crbug.com/667560 [ Linux ] http/tests/devtools/console/console-search.js [ Leak Pass ]
+crbug.com/798735 [ Linux ] fast/events/drop-handler-should-not-stop-navigate.html [ Leak Pass ]
 
 # -----------------------------------------------------------------
 # Not revert suspected CL as jam@ request, expected to be fixed soon.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 8abdb6cb..b9eb7e7 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -741,9 +741,6 @@
 
 crbug.com/788110 [ Linux ] inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.js [ Pass Failure ]
 
-# Sheriff 2017-12-21
-crbug.com/796926 [ Win10 ] inspector-protocol/layout-fonts/fallback-pua-last-resort.js [ Pass Failure ]
-
 # Run these tests with under virtual/scalefactor... only.
 crbug.com/567837 fast/hidpi/static [ Skip ]
 
@@ -3012,7 +3009,7 @@
 crbug.com/736255 [ Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-item-vert-001b.html [ Skip ]
 crbug.com/736732 virtual/enable_wasm/external/wpt/wasm/wasm_local_iframe_test.html [ Timeout Pass ]
 
-crbug.com/798116 [ Linux ] fast/forms/select/listbox-in-multi-column.html [ Failure Pass ]
+crbug.com/798116 [ Linux Win7 ] fast/forms/select/listbox-in-multi-column.html [ Failure Pass ]
 
 # These imported tests exercise tens of thousands of code points and generate large results. Marked slow, but still timeout.
 crbug.com/736056 [ Mac ] external/wpt/encoding/legacy-mb-japanese [ Timeout Pass ]
@@ -3572,4 +3569,4 @@
 
 # Sheriff failures 2018-01-02
 crbug.com/798527 [ Linux ] virtual/spv175/compositing/gestures/gesture-tapHighlight-with-box-shadow.html [ Pass Failure ]
-crbug.com/798592 [ Win7 ] virtual/threaded/http/tests/devtools/tracing/timeline-style/timeline-recalculate-styles.js [ Pass Failure ]
\ No newline at end of file
+crbug.com/798592 [ Win7 ] virtual/threaded/http/tests/devtools/tracing/timeline-style/timeline-recalculate-styles.js [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index b1c5547..aaf0528 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -133,6 +133,15 @@
              "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"]
   },
   {
+    "prefix": "android",
+    "base": "url-bar",
+    "args": ["--enable-features=OverlayScrollbar", "--enable-threaded-compositing",
+             "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text",
+             "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch",
+             "--force-overlay-fullscreen-video", "--enable-overscroll-notifications",
+             "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"]
+  },
+  {
     "prefix": "media-gpu-accelerated",
     "base": "http/tests/media/media-source",
     "args": ["--use-gpu-in-tests"]
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/webkit-column-gap-interpolation.html b/third_party/WebKit/LayoutTests/animations/interpolation/column-gap-interpolation.html
similarity index 61%
rename from third_party/WebKit/LayoutTests/animations/interpolation/webkit-column-gap-interpolation.html
rename to third_party/WebKit/LayoutTests/animations/interpolation/column-gap-interpolation.html
index 43c2520f..c50e5b9 100644
--- a/third_party/WebKit/LayoutTests/animations/interpolation/webkit-column-gap-interpolation.html
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/column-gap-interpolation.html
@@ -2,11 +2,11 @@
 <meta charset="UTF-8">
 <style>
 .parent {
-  -webkit-column-gap: 90px;
+  column-gap: 90px;
 }
 .target {
-  -webkit-column-count: 2;
-  -webkit-column-gap: 10px;
+  column-count: 2;
+  column-gap: 10px;
 }
 .expected div {
   opacity: 0.7;
@@ -26,7 +26,7 @@
 <script src='resources/interpolation-test.js'></script>
 <script>
 assertInterpolation({
-  property: '-webkit-column-gap',
+  property: 'column-gap',
   from: neutralKeyframe,
   to: '40px',
 }, [
@@ -38,21 +38,14 @@
   {at: 1.5, is: '55px'},
 ]);
 
-assertInterpolation({
-  property: '-webkit-column-gap',
+assertNoInterpolation({
+  property: 'column-gap',
   from: 'initial',
   to: '20px',
-}, [
-  {at: -0.3, is: '0px'},
-  {at: 0, is: '0px'},
-  {at: 0.3, is: '6px'},
-  {at: 0.6, is: '12px'},
-  {at: 1, is: '20px'},
-  {at: 1.5, is: '30px'},
-]);
+});
 
 assertInterpolation({
-  property: '-webkit-column-gap',
+  property: 'column-gap',
   from: 'inherit',
   to: '20px',
 }, [
@@ -64,25 +57,24 @@
   {at: 1.5, is: '0px'},
 ]);
 
-assertInterpolation({
-  property: '-webkit-column-gap',
+assertNoInterpolation({
+  property: 'column-gap',
   from: 'unset',
   to: '20px',
-}, [
-  {at: -0.3, is: '0px'},
-  {at: 0, is: '0px'},
-  {at: 0.3, is: '6px'},
-  {at: 0.6, is: '12px'},
-  {at: 1, is: '20px'},
-  {at: 1.5, is: '30px'},
-]);
+});
+
+assertNoInterpolation({
+  property: 'column-gap',
+  from: 'normal',
+  to: '20px',
+});
 
 assertInterpolation({
-  property: '-webkit-column-gap',
+  property: 'column-gap',
   from: '0px',
   to: '100px'
 }, [
-  {at: -0.3, is: '0'}, // -webkit-column-gap can't be negative.
+  {at: -0.3, is: '0'}, // column-gap can't be negative.
   {at: 0, is: '0'},
   {at: 0.3, is: '30px'},
   {at: 0.6, is: '60px'},
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-animation-003-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-animation-003-expected.txt
deleted file mode 100644
index 479213d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-animation-003-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Default column-gap is not interpolable assert_equals: expected "100px" but got "80.2414px"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/hr-time/performance-tojson.html b/third_party/WebKit/LayoutTests/external/wpt/hr-time/performance-tojson.html
new file mode 100644
index 0000000..fd8049c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/hr-time/performance-tojson.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+test(() => {
+  // Check Performance attributes.
+  assert_equals(typeof(performance.toJSON), 'function');
+  const json = performance.toJSON();
+  assert_equals(typeof(json), 'object');
+  assert_equals(json.timeOrigin, performance.timeOrigin,
+    'performance.toJSON().timeOrigin should match performance.timeOrigin');
+
+  // Check PerformanceTiming toJSON.
+  const jsonTiming = json.timing;
+  const timing = performance.timing;
+  assert_equals(typeof(timing.toJSON), 'function');
+  const timingJSON = timing.toJSON();
+  assert_equals(typeof(timingJSON), 'object');
+  // Check PerformanceTiming attributes, from both:
+  // 1) |jsonTiming| from  Performance.
+  // 2) |timingJSON| from PerformanceTiming.
+  const performanceTimingKeys = [
+    'navigationStart',
+    'unloadEventStart',
+    'unloadEventEnd',
+    'redirectStart',
+    'redirectEnd',
+    'fetchStart',
+    'domainLookupStart',
+    'domainLookupEnd',
+    'connectStart',
+    'connectEnd',
+    'secureConnectionStart',
+    'requestStart',
+    'responseStart',
+    'responseEnd',
+    'domLoading',
+    'domInteractive',
+    'domContentLoadedEventStart',
+    'domContentLoadedEventEnd',
+    'domComplete',
+    'loadEventStart',
+    'loadEventEnd'
+  ];
+  for (const key of performanceTimingKeys) {
+    assert_equals(jsonTiming[key], timing[key],
+      `performance.toJSON().timing.${key} should match performance.timing.${key}`);
+    assert_equals(timingJSON[key], timing[key],
+      `performance.timing.toJSON().${key} should match performance.timing.${key}`);
+  }
+
+  // Check PerformanceNavigation toJSON.
+  const jsonNavigation = json.navigation;
+  const navigation = performance.navigation;
+  assert_equals(typeof(navigation.toJSON), 'function');
+  const navigationJSON = navigation.toJSON();
+  assert_equals(typeof(navigationJSON), 'object');
+  // Check PerformanceNavigation attributes, from both:
+  // 1) |jsonNavigation| from  Performance.
+  // 2) |navigationJSON| from PerformanceNavigation.
+  let performanceNavigationKeys = ['type', 'redirectCount'];
+  for (const key of performanceNavigationKeys) {
+    assert_equals(jsonNavigation[key], navigation[key],
+      `performance.toJSON().navigation.${key} should match performance.navigation.${key}`);
+    assert_equals(navigationJSON[key], navigation[key],
+      `performance.navigation.toJSON().${key} should match performance.navigation.${key}`);
+  }
+}, 'Test performance.toJSON()');
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/longtask-tojson.html b/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/longtask-tojson.html
new file mode 100644
index 0000000..bbe0d662
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/longtask-timing/longtask-tojson.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+  async_test(function (t) {
+    const observer = new PerformanceObserver(
+      t.step_func(function (entryList) {
+        const entries = entryList.getEntries();
+        assert_greater_than_equal(entries.length, 1);
+        const entry = entries[0];
+        assert_equals(typeof(entry.toJSON), 'function');
+        const entryJSON = entry.toJSON();
+        assert_equals(typeof(entryJSON), 'object');
+        // Check attributes inheritted from PerformanceEntry.
+        const performanceEntryKeys = [
+            'name',
+            'entryType',
+            'startTime',
+            'duration'
+        ];
+        for (const key of performanceEntryKeys) {
+            assert_equals(entryJSON[key], entry[key],
+                `entry.toJSON().${key} should match entry.${key}`);
+        }
+
+        // Check PerformanceLongTaskTiming specific entries.
+        assert_equals(typeof(entryJSON.attribution), 'object');
+        const entryJsonAttribution = entryJSON.attribution[0];
+        assert_equals(typeof(entryJsonAttribution), 'object');
+        assert_equals(entryJSON.attribution.length, entry.attribution.length);
+
+        // Check TaskAttributionTiming toJSON.
+        const entryAttribution = entry.attribution[0];
+        assert_equals(typeof(entryAttribution.toJSON), 'function');
+        const entryAttributionJSON = entryAttribution.toJSON();
+        assert_equals(typeof(entryAttributionJSON), 'object');
+        // Check TaskAttributionTiming attributes, from both:
+        // 1) |entryJsonAttribution| from  PerformanceLongTaskTiming.
+        // 2) |entryAttributionJSON| from TaskAttributionTiming.
+        const taskAttributionTimingKeys = [
+            'name',
+            'entryType',
+            'startTime',
+            'duration',
+            'containerType',
+            'containerSrc',
+            'containerId',
+            'containerName'
+        ];
+        for (const key of taskAttributionTimingKeys) {
+            assert_equals(entryAttributionJSON[key], entryAttribution[key],
+                `attribution.toJSON().${key} should match attribution.${key}`);
+            assert_equals(entryJsonAttribution[key], entryAttribution[key],
+                `entry.toJSON().attribution[0].${key} should match attribution.${key}`);
+        }
+        t.done();
+      })
+    );
+    observer.observe({entryTypes: ['longtask']});
+
+    // Trigger a long task.
+    const begin = window.performance.now();
+    while (window.performance.now() < begin + 51);
+  }, 'Test toJSON() in PerformanceLongTaskTiming and TaskAttributionTiming');
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/performanceentry-tojson.html b/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/performanceentry-tojson.html
new file mode 100644
index 0000000..8576872
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/performance-timeline/performanceentry-tojson.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+test(() => {
+  performance.mark('markName');
+  performance.measure('measureName');
+
+  const entries = performance.getEntries();
+  const performanceEntryKeys = [
+    'name',
+    'entryType',
+    'startTime',
+    'duration'
+  ];
+  for (let i = 0; i < entries.length; ++i) {
+    assert_equals(typeof(entries[i].toJSON), 'function');
+    const json = entries[i].toJSON();
+    assert_equals(typeof(json), 'object');
+    for (const key of performanceEntryKeys) {
+      assert_equals(json[key], entries[i][key],
+        `entries[${i}].toJSON().${key} should match entries[${i}].${key}`);
+    }
+  }
+}, 'Test toJSON() in PerformanceEntry');
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resource-timing/resource-timing-tojson.html b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/resource-timing-tojson.html
new file mode 100644
index 0000000..77094f4b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/resource-timing/resource-timing-tojson.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+  const img_url = "resources/blue.png";
+  const img = document.createElement("img");
+  img.src = img_url;
+  window.onload = function() {
+    test(() => {
+      const entries = performance.getEntriesByType('resource');
+      assert_greater_than_equal(entries.length, 1);
+      const entry = entries[0];
+      assert_equals(typeof(entry.toJSON), 'function');
+      const json = entry.toJSON();
+      assert_equals(typeof(json), 'object');
+
+      const performanceResourceTimingKeys = [
+        'name',
+        'entryType',
+        'startTime',
+        'duration',
+        'initiatorType',
+        'nextHopProtocol',
+        'workerStart',
+        'redirectStart',
+        'fetchStart',
+        'domainLookupStart',
+        'domainLookupEnd',
+        'connectStart',
+        'connectEnd',
+        'secureConnectionStart',
+        'requestStart',
+        'responseStart',
+        'responseEnd',
+        'transferSize',
+        'encodedBodySize',
+        'decodedBodySize'
+      ];
+      for (const key of performanceResourceTimingKeys) {
+        assert_equals(json[key], entry[key],
+          `entry.toJSON().${key} should match entry.${key}`);
+      }
+    }, 'Test toJSON() in PerformanceResourceTiming');
+  };
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/uievents/mouse/layout_change_should_fire_mouseover-manual.html b/third_party/WebKit/LayoutTests/external/wpt/uievents/mouse/layout_change_should_fire_mouseover-manual.html
new file mode 100644
index 0000000..f36fadb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/uievents/mouse/layout_change_should_fire_mouseover-manual.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+    <head>
+        <title>Mouseover/enter is sent on layout change</title>
+        <meta name="viewport" content="width=device-width">
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+        <style>
+            #spacer {
+                height: 100px;
+                width: 100px;
+            }
+            #red {
+                background-color: rgb(255, 0, 0);
+                position: absolute;
+                z-index: 0;
+                left: 0px;
+                top: 0px;
+                height: 100px;
+                width: 100px;
+            }
+            #blue {
+                background-color: rgb(0, 0, 255);
+                position: absolute;
+                z-index: 1;
+                left: 0px;
+                top: 0px;
+                height: 100px;
+                width: 100px;
+            }
+            #blue:hover {
+                background-color: rgb(255, 255, 0);
+            }
+        </style>
+    </head>
+    <body onload="run();">
+        <div id="spacer"></div>
+        <div id="red"></div>
+        <h4>Test Description: Tests that the mouseover event is fired and the element has a hover effect when the element underneath the mouse cursor is changed.
+            <ol>
+                <li>Put your mouse over the red rectangle</li>
+                <li>Click the primary mouse button</li>
+            </ol>
+        </h4>
+        <script type="text/javascript">
+            var testMouseOver = async_test('Tests that the mouseover event is fired and the element has a hover effect when the element underneath the mouse cursor is changed.');
+
+            var eventList = [];
+            function addBlue() {
+                document.body.innerHTML += '<div id="blue"></div>';
+                var blue = document.getElementById("blue");
+                var events = ['mouseover', 'mousemove', 'mouseout', 'mouseenter', 'mouseleave'];
+                events.forEach(function (event) {
+                    blue.addEventListener(event, checkHoverEffect);
+                });
+                testMouseOver.step_timeout(function () {
+                   checkEventSequence();
+                }, 2500);
+            }
+
+            function checkEventSequence() {
+                var result = eventList.join();
+                assert_true(result == 'mouseover,mouseenter');
+                testMouseOver.done();
+            }
+
+            function run() {
+                document.addEventListener('click', addBlue);
+            }
+
+            function checkHoverEffect(event) {
+                eventList.push(event.type);
+                testMouseOver.step(function () {
+                  assert_equals(event.target.id, "blue");
+                  assert_equals(getComputedStyle(event.target).backgroundColor, "rgb(255, 255, 0)");
+                  if (event.type == "mouseenter") {
+                      checkEventSequence();
+                  }
+              });
+            }
+        </script>
+    </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt_automation/uievents/mouse/layout_change_should_fire_mouseover-manual-automation.js b/third_party/WebKit/LayoutTests/external/wpt_automation/uievents/mouse/layout_change_should_fire_mouseover-manual-automation.js
new file mode 100644
index 0000000..3b05bdf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt_automation/uievents/mouse/layout_change_should_fire_mouseover-manual-automation.js
@@ -0,0 +1,5 @@
+importAutomationScript('/pointerevents/pointerevent_common_input.js');
+
+function inject_input() {
+  return mouseClickInTarget('#red');
+}
diff --git a/third_party/WebKit/LayoutTests/fast/events/layout-change-should-fire-mouseover.html b/third_party/WebKit/LayoutTests/fast/events/layout-change-should-fire-mouseover.html
deleted file mode 100644
index 80fe658..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/layout-change-should-fire-mouseover.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<script src='../../resources/testharness.js'></script>
-<script src='../../resources/testharnessreport.js'></script>
-<style type="text/css">
-#blue {
-    background-color: rgb(0, 0, 255);
-    position: absolute;
-    left: 75px;
-    top: 75px;
-    height: 100px;
-    width: 100px;
-}
-#blue:hover {
-    background-color: rgb(255, 255, 0);
-}
-</style>
-
-<body onload="loaded();">
-
-<script type="text/javascript">
-var eventList = [];
-var x = 100;
-var y = 100;
-
-function addBlue() {
-    document.body.innerHTML += '<div id="blue"></div>';
-    var blue = document.getElementById("blue");
-    var events = ['mouseover', 'mousemove', 'mouseout', 'mouseenter', 'mouseleave'];
-    events.forEach(function (event) {
-        blue.addEventListener(event, validMouseEventsResult);
-    });
-}
-
-function loaded() {
-    document.addEventListener('click', addBlue);
-}
-
-function validMouseEventsResult(event) {
-    eventList.push(event.type);
-    testMouseOver.step(function () {
-        assert_equals(event.target.id, "blue");
-        assert_equals(getComputedStyle(event.target).backgroundColor, "rgb(255, 255, 0)");
-        if (event.type == "mouseenter") {
-            var result = eventList.join();
-            assert_true(result == 'mouseover,mouseenter');
-            testMouseOver.done();
-        }
-    });
-
-}
-
-function testMouseOverAddElement() {
-    if (window.chrome && chrome.gpuBenchmarking) {
-        var pointerActions =
-            [{source: "mouse",
-              actions: [
-                { name: "pointerDown", x: x, y: y },
-                { name: "pointerUp" }]}];
-        chrome.gpuBenchmarking.pointerActionSequence(pointerActions);
-    }
-}
-
-var testMouseOver = async_test('Tests that the mouseover event is fired and the element has a hover effect when the element underneath the mouse cursor is changed.');
-testMouseOverAddElement();
-
-</script>
-</body>
-
-
diff --git a/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-use-visual-viewport.html b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-use-visual-viewport.html
new file mode 100644
index 0000000..78132fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/spatial-navigation/snav-use-visual-viewport.html
@@ -0,0 +1,39 @@
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<style>
+  a {font-size: 200px;}
+</style>
+
+<a href="#" id="a">a</a><br>
+<a href="#" id="b">b</a><br>
+<a href="#" id="c">c</a><br>
+<a href="#" id="d">d</a><br>
+<a href="#" id="e">e</a><br>
+<a href="#" id="f">f</a>
+
+<script>
+  if (window.testRunner) {
+    testRunner.overridePreference('WebKitTabToLinksPreferenceKey', 1);
+    testRunner.overridePreference('WebKitSpatialNavigationEnabled', 1);
+    testRunner.waitUntilDone();
+  }
+
+  test(() => {
+    assert_equals(document.activeElement, document.body);
+    eventSender.keyDown('ArrowDown');
+    assert_equals(document.activeElement, a);
+  }, "Spatnav picks the visual viewport's topmost element (a).");
+
+  test(() => {
+    c.scrollIntoView(true);
+    eventSender.keyDown('ArrowDown');
+    assert_equals(document.activeElement, c);
+  }, "Spatnav picks the visual viewport's topmost element (c).");
+
+  test(() => {
+    f.scrollIntoView(false);
+    eventSender.keyDown('ArrowUp');
+    assert_equals(document.activeElement, f);
+  }, "Spatnav picks the visual viewport's bottommost element (f).");
+</script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/site-per-process/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/site-per-process/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt
new file mode 100644
index 0000000..84f89b4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/site-per-process/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt
@@ -0,0 +1,6 @@
+Tests the blockedCrossSiteDocumentLoad bit available as a part of the loading finished signal.
+Blocking cross-site document at http://127.0.0.1:8000/inspector-protocol/network/resources/nosniff.pl: false
+Blocking cross-site document at http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html: false
+Blocking cross-site document at http://devtools.oopif.test:8000/inspector-protocol/network/resources/nosniff.pl: true
+Blocking cross-site document at http://devtools.oopif.test:8000/inspector-protocol/network/resources/simple-iframe.html: true
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt
index a9eecab..d31abdf 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry-expected.txt
@@ -6,16 +6,16 @@
             Index: index1
 Dumping ObjectStore data:
     Object store: objectStore1
-            Key = testKey1, value = {"injectedScriptId":2,"id":1}
-            Key = testKey2, value = {"injectedScriptId":2,"id":2}
+            Key = testKey1, value = [{"name":"test","type":"string","value":"testKey1"},{"name":"testValue","type":"string","value":"testValue"}]
+            Key = testKey2, value = [{"name":"test","type":"string","value":"testKey2"},{"name":"testValue","type":"string","value":"testValue"}]
             Index: index1
-                Key = testKey1, value = {"injectedScriptId":2,"id":3}
-                Key = testKey2, value = {"injectedScriptId":2,"id":4}
+                Key = testKey1, value = [{"name":"test","type":"string","value":"testKey1"},{"name":"testValue","type":"string","value":"testValue"}]
+                Key = testKey2, value = [{"name":"test","type":"string","value":"testKey2"},{"name":"testValue","type":"string","value":"testValue"}]
 Dumping ObjectStore data:
     Object store: objectStore1
-            Key = testKey2, value = {"injectedScriptId":2,"id":5}
+            Key = testKey2, value = [{"name":"test","type":"string","value":"testKey2"},{"name":"testValue","type":"string","value":"testValue"}]
             Index: index1
-                Key = testKey2, value = {"injectedScriptId":2,"id":6}
+                Key = testKey2, value = [{"name":"test","type":"string","value":"testKey2"},{"name":"testValue","type":"string","value":"testValue"}]
 Dumping ObjectStore data:
     Object store: objectStore1
             Index: index1
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js
index 11f6380..4b452af 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/indexeddb/delete-entry.js
@@ -12,7 +12,7 @@
     TestRunner.addResult(`            Index: ${treeElement.title}`);
     treeElement.select();
     for (var entry of treeElement._view._entries)
-      TestRunner.addResult(`                Key = ${entry.primaryKey.value}, value = ${entry.value.objectId}`);
+      TestRunner.addResult(`                Key = ${entry.primaryKey.value}, value = ${JSON.stringify(entry.value.preview.properties)}`);
   }
 
   function dumpObjectStores() {
@@ -22,7 +22,7 @@
       objectStoreTreeElement.select();
       TestRunner.addResult(`    Object store: ${objectStoreTreeElement.title}`);
       for (var entry of objectStoreTreeElement._view._entries)
-        TestRunner.addResult(`            Key = ${entry.key.value}, value = ${entry.value.objectId}`);
+        TestRunner.addResult(`            Key = ${entry.key.value}, value = ${JSON.stringify(entry.value.preview.properties)}`);
       for (var treeElement of objectStoreTreeElement.children())
         dumpObjectStore(treeElement);
     }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt
new file mode 100644
index 0000000..42f43df
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load-expected.txt
@@ -0,0 +1,6 @@
+Tests the blockedCrossSiteDocumentLoad bit available as a part of the loading finished signal.
+Blocking cross-site document at http://127.0.0.1:8000/inspector-protocol/network/resources/nosniff.pl: false
+Blocking cross-site document at http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html: false
+Blocking cross-site document at http://devtools.oopif.test:8000/inspector-protocol/network/resources/nosniff.pl: false
+Blocking cross-site document at http://devtools.oopif.test:8000/inspector-protocol/network/resources/simple-iframe.html: false
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load.js
new file mode 100644
index 0000000..a97c76d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/block_cross_site_document_load.js
@@ -0,0 +1,21 @@
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startURL(
+      '../resources/test-page.html',
+      `Tests the blockedCrossSiteDocumentLoad bit available as a part of the loading finished signal.`);
+
+  const responses = new Map();
+  await dp.Network.enable();
+
+  let urls = [
+    'http://127.0.0.1:8000/inspector-protocol/network/resources/nosniff.pl',
+    'http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html',
+    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/nosniff.pl',
+    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/simple-iframe.html',
+  ];
+  for (const url of urls) {
+    session.evaluate(`new Image().src = '${url}';`);
+    const response = await dp.Network.onceLoadingFinished();
+    testRunner.log(`Blocking cross-site document at ${url}: ${response.params.blockedCrossSiteDocument}`);
+  }
+  testRunner.completeTest();
+})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/nosniff.pl b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/nosniff.pl
new file mode 100755
index 0000000..58d79f7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/nosniff.pl
@@ -0,0 +1,5 @@
+#!/usr/bin/perl
+
+print "Status: 200 OK\r\n";
+print "Content-Type: text/html\r\n";
+print "X-Content-Type-Options: nosniff\r\n\r\n";
diff --git a/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt
new file mode 100644
index 0000000..7c3bace
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt
@@ -0,0 +1,7 @@
+Test passes if the fallback font selected for the Unicode Private Use Area test text matches known last resort fonts on each platform.
+󰀀󺪪󿿿􀀀􊪪􏿿
+#pua_test_run:
+"DejaVu Sans" : 11
+
+PASS
+
diff --git a/third_party/WebKit/LayoutTests/platform/win7/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt b/third_party/WebKit/LayoutTests/platform/win/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/platform/win7/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt
rename to third_party/WebKit/LayoutTests/platform/win/inspector-protocol/layout-fonts/fallback-pua-last-resort-expected.txt
diff --git a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
index 9ce129d..4ea0ee43 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
+++ b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
@@ -60,6 +60,12 @@
     case 'CSSMatrixComponent':
       assert_matrix_approx_equals(a.matrix, b.matrix, 1e-6);
       break;
+    case 'CSSURLImageValue':
+      assert_equals(a.instrinsicWidth, b.instrinsicWidth);
+      assert_equals(a.instrinsicHeight, b.instrinsicHeight);
+      assert_equals(a.instrinsicRatio, b.instrinsicRatio);
+      assert_equals(a.url, b.url);
+      break;
     default:
       assert_equals(a, b);
       break;
@@ -107,3 +113,17 @@
 function createComputedStyleMap(test, cssText) {
   return createDivWithStyle(test, cssText).computedStyleMap();
 }
+
+// Creates a new element with background image set to |imageValue|
+// and returns a new Image element that can be used to attach
+// event listeners regarding the image.
+function loadImageResource(test, imageValue) {
+  // Set a CSSURLImageValue on an element so it can be loaded.
+  let styleMap = createInlineStyleMap(test, '');
+  styleMap.set('background-image', imageValue);
+
+  // add a new Image element to know if the image resource has been loaded
+  let image = new Image();
+  image.src = imageValue.url;
+  return image;
+}
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource-expected.txt
new file mode 100644
index 0000000..ecd43b21
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+PASS Normalizing a valid <url> returns a CSSURLImageValue that eventually loads
+PASS Normalizing a bad <url> returns a CSSURLImageValue in error state
+FAIL Normalizing a <gradient> returns a CSSImageValue assert_equals: expected "CSSImageValue" but got "CSSStyleValue"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource.html b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource.html
new file mode 100644
index 0000000..0c00fa3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-normalization/normalize-resource.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSSResourceValue normalization tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#resourcevalue-normalization">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+const gTestUrl = '../resources/1x1-green.png';
+const gBadTestUrl = document.location.href;
+
+async_test(t => {
+  const result = CSSStyleValue.parse('background-image', 'url("' + gTestUrl + '")');
+  assert_equals(result.constructor.name, 'CSSURLImageValue');
+  assert_equals(result.intrinsicWidth, null);
+  assert_equals(result.intrinsicHeight, null);
+  assert_equals(result.intrinsicRatio, null);
+  assert_equals(result.state, 'unloaded');
+
+  let image = loadImageResource(t, result);
+  image.addEventListener('load', t.step_func_done(() => {
+    assert_equals(result.url, gTestUrl);
+    assert_equals(result.state, 'loaded');
+    assert_equals(result.intrinsicWidth, 1);
+    assert_equals(result.intrinsicHeight, 1);
+    assert_equals(result.intrinsicRatio, 1);
+  }));
+}, 'Normalizing a valid <url> returns a CSSURLImageValue that eventually loads');
+
+async_test(t => {
+  const result = CSSStyleValue.parse('background-image', 'url("' + gBadTestUrl + '")');
+  assert_equals(result.constructor.name, 'CSSURLImageValue');
+
+  let image = loadImageResource(t, result);
+  image.addEventListener('error', t.step_func_done(() => {
+      assert_equals(result.url, gBadTestUrl);
+      assert_equals(result.state, 'error');
+      assert_equals(result.intrinsicWidth, null);
+      assert_equals(result.intrinsicHeight, null);
+      assert_equals(result.intrinsicRatio, null);
+  }));
+}, 'Normalizing a bad <url> returns a CSSURLImageValue in error state');
+
+test(t => {
+  const result = CSSStyleValue.parse('background-image', 'linear-gradient(red, orange)');
+  assert_equals(result.constructor.name, 'CSSImageValue');
+  assert_equals(result.state, 'loaded');
+  assert_equals(result.intrinsicWidth, null);
+  assert_equals(result.intrinsicHeight, null);
+  assert_equals(result.intrinsicRatio, null);
+}, 'Normalizing a <gradient> returns a CSSImageValue');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-objects/parse-relative-url.html b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-objects/parse-relative-url.html
index 4cbbd70..388a12b2 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-objects/parse-relative-url.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-objects/parse-relative-url.html
@@ -11,17 +11,6 @@
 
 const gTestUrl = '../resources/1x1-green.png';
 
-function loadImageResource(test, imageValue) {
-  // Set a CSSURLImageValue on an element so it can be loaded.
-  let target = createDivWithStyle(test, '');
-  target.attributeStyleMap.set('background-image', imageValue);
-
-  // add a new Image element to know if the image resource has been loaded
-  let image = new Image();
-  image.src = imageValue.url;
-  return image;
-}
-
 async_test(t => {
   const result = CSSStyleValue.parse('background-image', 'url('+gTestUrl+')');
   let image = loadImageResource(t, result);
diff --git a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssUrlImageValue.html b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssUrlImageValue.html
index 2d8a3e1f..904b7d1 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssUrlImageValue.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/stylevalue-subclasses/cssUrlImageValue.html
@@ -9,17 +9,6 @@
 <script>
 'use strict';
 
-function loadImageResource(test, imageValue) {
-  // Set a CSSURLImageValue on an element so it can be loaded.
-  let target = createDivWithStyle(test);
-  target.attributeStyleMap.set('background-image', imageValue);
-
-  // add a new Image element to know if the image resource has been loaded
-  let image = new Image();
-  image.src = imageValue.url;
-  return image;
-}
-
 const gTestUrl = '../resources/1x1-green.png';
 const gBase64TestUrl = 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=';
 const gBadTestUrl = document.location.href;
diff --git a/third_party/WebKit/LayoutTests/virtual/android/url-bar/README.txt b/third_party/WebKit/LayoutTests/virtual/android/url-bar/README.txt
new file mode 100644
index 0000000..8418509c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/android/url-bar/README.txt
@@ -0,0 +1,2 @@
+# This suite runs the tests in url-bar with additional flags.
+# See the virtual_test_suites() method in Tools/Scripts/webkitpy/layout_tests/port/base.py.
diff --git a/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar-expected.html b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar-expected.html
new file mode 100644
index 0000000..c028f2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar-expected.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, user-scalable=no" />
+<style>
+  html, body {
+    height: 100%;
+    width: 100%;
+    margin: 0;
+  }
+  #cover {
+    width: 100%;
+    height: 500px;
+    background-color: palegreen;
+  }
+  #bottom {
+    position: fixed;
+    left: 50px;
+    right: 50px;
+    height: 20px;
+    bottom: 100px;
+    background-color: coral;
+  }
+</style>
+
+<div id="cover">
+    Test passes if the orange bar is visible at the bottom of the green box.
+    The green box should be 100px from the screen bottom.
+</div>
+<div id="bottom"></div>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar.html b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar.html
new file mode 100644
index 0000000..c30ba3f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-fixed-adjusted-when-showing-url-bar.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, user-scalable=no" />
+<script>
+  // NOTE: It is important that this test be run with the Android viewport
+  // flags turned on.
+  // Set the browser controls to be 100px and start off hidden. Bring them in
+  // fully without causing a resize. i.e. as if the user dragged them into view
+  // but hasn't lifted their finger.
+  if (window.internals) {
+    window.internals.setBrowserControlsShownRatio(0);
+    window.internals.setBrowserControlsState(100, 0, false);
+    window.internals.setBrowserControlsShownRatio(1);
+    window.internals.settings.setHideScrollbars(true);
+  }
+</script>
+<style>
+  html, body {
+    height: 100%;
+    width: 100%;
+    margin: 0;
+  }
+  #cover {
+    width: 100%;
+    /* Must be scrollable to force fixed elements to get a transform node. */
+    height: 200%;
+    background-color: palegreen;
+  }
+  #bottom {
+    position: fixed;
+    left: 50px;
+    right: 50px;
+    height: 20px;
+    bottom: 0px;
+    background-color: coral;
+  }
+</style>
+
+<div id="cover">
+    Test passes if the orange bar is visible at the bottom of the green box.
+    The green box should be 100px from the screen bottom.
+</div>
+<div id="bottom"></div>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp
index bca33d6f..c7bd2626 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp
@@ -103,7 +103,7 @@
   }
 
   void Finish() {
-    GetResource()->Loader()->DidFinishLoading(0.0, 0, 0, 0);
+    GetResource()->Loader()->DidFinishLoading(0.0, 0, 0, 0, false);
     GetResource()->SetStatus(ResourceStatus::kCached);
   }
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 6a07d04..c0b2b8b3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -641,8 +641,9 @@
 #endif  // USE_V8_CONTEXT_SNAPSHOT
 
   v8::Isolate* isolate = V8PerIsolateData::Initialize(
-      scheduler ? scheduler->V8TaskRunner()
-                : Platform::Current()->CurrentThread()->GetWebTaskRunner(),
+      scheduler
+          ? scheduler->V8TaskRunner()
+          : Platform::Current()->CurrentThread()->GetSingleThreadTaskRunner(),
       v8_context_snapshot_mode);
 
   InitializeV8Common(isolate);
diff --git a/third_party/WebKit/Source/core/animation/ElementAnimations.cpp b/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
index 5819c0c5..ba7a521 100644
--- a/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
@@ -120,13 +120,13 @@
 }
 
 bool ElementAnimations::IsAnimationStyleChange() const {
-  // TODO(rune@opera.com): The FontFaceCache version number may be increased
-  // without forcing a style recalc (see crbug.com/471079). ComputedStyle
-  // objects created with different cache versions will not be considered equal
-  // as Font::operator== will compare versions, hence ComputedStyle::operator==
-  // will return false. We avoid using baseComputedStyle (the check for
-  // isFallbackValid()) in that case to avoid triggering the ComputedStyle
-  // comparison ASSERT in updateBaseComputedStyle.
+  // TODO(futhark@chromium.org): The FontFaceCache version number may be
+  // increased without forcing a style recalc (see crbug.com/471079).
+  // ComputedStyle objects created with different cache versions will not be
+  // considered equal as Font::operator== will compare versions, hence
+  // ComputedStyle::operator== will return false. We avoid using
+  // base_computed_style (the check for IsFallbackValid()) in that case to avoid
+  // triggering the ComputedStyle comparison DCHECK in UpdateBaseComputedStyle.
   return animation_style_change_ &&
          (!base_computed_style_ ||
           base_computed_style_->GetFont().IsFallbackValid());
diff --git a/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp b/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
index ab4bda75..7f3a7e8 100644
--- a/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
+++ b/third_party/WebKit/Source/core/animation/LengthPropertyFunctions.cpp
@@ -256,6 +256,8 @@
       result = Length(style.VerticalBorderSpacing(), kFixed);
       return true;
     case CSSPropertyColumnGap:
+      if (style.HasNormalColumnGap())
+        return false;
       result = Length(style.ColumnGap(), kFixed);
       return true;
     case CSSPropertyColumnRuleWidth:
diff --git a/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h b/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h
index 34e8e33..fad426b 100644
--- a/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h
+++ b/third_party/WebKit/Source/core/css/CSSGlobalRuleSet.h
@@ -18,9 +18,9 @@
 // in the whole Document as well as UA stylesheets and watched selectors which
 // apply to elements in all TreeScopes.
 //
-// TODO(rune@opera.com): We would like to move as much of this data as possible
-// to the ScopedStyleResolver as possible to avoid full reconstruction of these
-// rulesets on shadow tree changes. See https://crbug.com/401359
+// TODO(futhark@chromium.org): We would like to move as much of this data as
+// possible to the ScopedStyleResolver as possible to avoid full reconstruction
+// of these rulesets on shadow tree changes. See https://crbug.com/401359
 
 class CSSGlobalRuleSet : public GarbageCollectedFinalized<CSSGlobalRuleSet> {
  public:
diff --git a/third_party/WebKit/Source/core/css/CSSVariableReferenceValue.h b/third_party/WebKit/Source/core/css/CSSVariableReferenceValue.h
index c2a7ba7..7fc25030 100644
--- a/third_party/WebKit/Source/core/css/CSSVariableReferenceValue.h
+++ b/third_party/WebKit/Source/core/css/CSSVariableReferenceValue.h
@@ -14,6 +14,10 @@
 
 class CSSVariableReferenceValue : public CSSValue {
  public:
+  static CSSVariableReferenceValue* Create(
+      scoped_refptr<CSSVariableData> data) {
+    return new CSSVariableReferenceValue(std::move(data));
+  }
   static CSSVariableReferenceValue* Create(scoped_refptr<CSSVariableData> data,
                                            const CSSParserContext& context) {
     return new CSSVariableReferenceValue(std::move(data), context);
@@ -21,6 +25,7 @@
 
   CSSVariableData* VariableDataValue() const { return data_.get(); }
   const CSSParserContext* ParserContext() const {
+    DCHECK(parser_context_);
     return parser_context_.Get();
   }
 
@@ -32,12 +37,16 @@
   void TraceAfterDispatch(blink::Visitor*);
 
  private:
+  CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data)
+      : CSSValue(kVariableReferenceClass),
+        data_(std::move(data)),
+        parser_context_(nullptr) {}
+
   CSSVariableReferenceValue(scoped_refptr<CSSVariableData> data,
                             const CSSParserContext& context)
       : CSSValue(kVariableReferenceClass),
         data_(std::move(data)),
         parser_context_(context) {
-    DCHECK(parser_context_);
   }
 
   scoped_refptr<CSSVariableData> data_;
diff --git a/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp b/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
index 12ccf5c..92409374 100644
--- a/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
+++ b/third_party/WebKit/Source/core/css/RuleFeatureSet.cpp
@@ -224,7 +224,7 @@
     // Note that we also construct a DescendantInvalidationSet instead of using
     // the SelfInvalidationSet() when we create a SiblingInvalidationSet. We may
     // be able to let SiblingInvalidationSets reference the singleton set for
-    // descendants as well. TODO(rune@opera.com)
+    // descendants as well. TODO(futhark@chromium.org)
     invalidation_set = DescendantInvalidationSet::Create();
     invalidation_set->SetInvalidatesSelf();
   }
diff --git a/third_party/WebKit/Source/core/css/StyleEngine.cpp b/third_party/WebKit/Source/core/css/StyleEngine.cpp
index fca0d074..7c8dab0a 100644
--- a/third_party/WebKit/Source/core/css/StyleEngine.cpp
+++ b/third_party/WebKit/Source/core/css/StyleEngine.cpp
@@ -181,8 +181,8 @@
       StyleSheetContents::Create(CSSParserContext::Create(*document_));
   inspector_style_sheet_ = CSSStyleSheet::Create(contents, *document_);
   MarkDocumentDirty();
-  // TODO(rune@opera.com): Making the active stylesheets up-to-date here is
-  // required by some inspector tests, at least. I theory this should not be
+  // TODO(futhark@chromium.org): Making the active stylesheets up-to-date here
+  // is required by some inspector tests, at least. I theory this should not be
   // necessary. Need to investigate to figure out if/why.
   UpdateActiveStyle();
   return *inspector_style_sheet_;
@@ -283,7 +283,7 @@
   DCHECK(IsMaster());
   DCHECK(global_rule_set_);
   global_rule_set_->InitWatchedSelectorsRuleSet(GetDocument());
-  // TODO(rune@opera.com): Should be able to use RuleSetInvalidation here.
+  // TODO(futhark@chromium.org): Should be able to use RuleSetInvalidation here.
   GetDocument().SetNeedsStyleRecalc(
       kSubtreeStyleChange, StyleChangeReasonForTracing::Create(
                                StyleChangeReason::kDeclarativeContent));
@@ -1050,8 +1050,8 @@
   if (!preferred_stylesheet_set_name_.IsEmpty())
     return;
   preferred_stylesheet_set_name_ = name;
-  // TODO(rune@opera.com): Setting the selected set here is wrong if the set
-  // has been previously set by through Document.selectedStylesheetSet. Our
+  // TODO(futhark@chromium.org): Setting the selected set here is wrong if the
+  // set has been previously set by through Document.selectedStylesheetSet. Our
   // current implementation ignores the effect of Document.selectedStylesheetSet
   // and either only collects persistent style, or additionally preferred
   // style when present.
@@ -1061,9 +1061,9 @@
 
 void StyleEngine::SetSelectedStylesheetSetName(const String& name) {
   selected_stylesheet_set_name_ = name;
-  // TODO(rune@opera.com): Setting Document.selectedStylesheetSet currently
-  // has no other effect than the ability to read back the set value using
-  // the same api. If it did have an effect, we should have marked the
+  // TODO(futhark@chromium.org): Setting Document.selectedStylesheetSet
+  // currently has no other effect than the ability to read back the set value
+  // using the same api. If it did have an effect, we should have marked the
   // document scope dirty and triggered an update of the active stylesheets
   // from here.
 }
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp
index 3e61637..23436b60 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.cpp
@@ -72,7 +72,7 @@
   return CssValueKeywordID(keyword_value_);
 }
 
-const CSSValue* CSSKeywordValue::ToCSSValue(SecureContextMode) const {
+const CSSValue* CSSKeywordValue::ToCSSValue() const {
   CSSValueID keyword_id = KeywordValueID();
   switch (keyword_id) {
     case (CSSValueInherit):
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h
index d516c4a..dd727f9 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSKeywordValue.h
@@ -28,7 +28,7 @@
   void setValue(const String& keyword, ExceptionState&);
   CSSValueID KeywordValueID() const;
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override;
+  const CSSValue* ToCSSValue() const override;
 
  private:
   explicit CSSKeywordValue(const String& keyword) : keyword_value_(keyword) {}
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSMathValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSMathValue.cpp
index 2d5b9b3..634a468 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSMathValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSMathValue.cpp
@@ -8,7 +8,7 @@
 
 namespace blink {
 
-const CSSValue* CSSMathValue::ToCSSValue(SecureContextMode) const {
+const CSSValue* CSSMathValue::ToCSSValue() const {
   CSSCalcExpressionNode* node = ToCalcExpressionNode();
   if (!node)
     return nullptr;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSMathValue.h b/third_party/WebKit/Source/core/css/cssom/CSSMathValue.h
index f479d5e2..c3924edd 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSMathValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSMathValue.h
@@ -27,7 +27,7 @@
     return false;
   }
 
-  const CSSValue* ToCSSValue(SecureContextMode) const final;
+  const CSSValue* ToCSSValue() const final;
 
  protected:
   CSSMathValue(const CSSNumericValueType& type) : CSSNumericValue(type) {}
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.cpp b/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.cpp
index 90810702..14623bad 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.cpp
@@ -51,8 +51,7 @@
       CSSMatrixComponentOptions());
 }
 
-const CSSFunctionValue* CSSMatrixComponent::ToCSSValue(
-    SecureContextMode) const {
+const CSSFunctionValue* CSSMatrixComponent::ToCSSValue() const {
   CSSFunctionValue* result =
       CSSFunctionValue::Create(is2D() ? CSSValueMatrix : CSSValueMatrix3d);
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.h b/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.h
index 4e76024..4b91e35 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSMatrixComponent.h
@@ -35,7 +35,7 @@
   // Internal methods - from CSSTransformComponent.
   TransformComponentType GetType() const final { return kMatrixType; }
   const DOMMatrix* AsMatrix(ExceptionState&) const final;
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const final;
+  const CSSFunctionValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(matrix_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
index cfcc992..cf415d6 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.cpp
@@ -63,14 +63,13 @@
   return matrix;
 }
 
-const CSSFunctionValue* CSSPerspective::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
+const CSSFunctionValue* CSSPerspective::ToCSSValue() const {
   if (length_->IsUnitValue() && ToCSSUnitValue(length_)->value() < 0) {
     // Negative values are invalid.
     // https://github.com/w3c/css-houdini-drafts/issues/420
     return nullptr;
   }
-  const CSSValue* length = length_->ToCSSValue(secure_context_mode);
+  const CSSValue* length = length_->ToCSSValue();
   if (!length)
     return nullptr;
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.h b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.h
index d2d811e..31479e4a 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSPerspective.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSPerspective.h
@@ -40,7 +40,7 @@
   // Internal methods - from CSSTransformComponent.
   TransformComponentType GetType() const final { return kPerspectiveType; }
   const DOMMatrix* AsMatrix(ExceptionState&) const final;
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const final;
+  const CSSFunctionValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(length_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.cpp
index d5a72060..15c8a1e 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.cpp
@@ -128,10 +128,9 @@
   y_ = y;
 }
 
-const CSSValue* CSSPositionValue::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
-  const CSSValue* x = x_->ToCSSValue(secure_context_mode);
-  const CSSValue* y = y_->ToCSSValue(secure_context_mode);
+const CSSValue* CSSPositionValue::ToCSSValue() const {
+  const CSSValue* x = x_->ToCSSValue();
+  const CSSValue* y = y_->ToCSSValue();
   if (!x || !y)
     return nullptr;
   return CSSValuePair::Create(x, y, CSSValuePair::kKeepIdenticalValues);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.h b/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.h
index e97e377..88d53d7c9 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSPositionValue.h
@@ -38,7 +38,7 @@
   // Internal methods - from CSSStyleValue.
   StyleValueType GetType() const final { return kPositionType; }
 
-  const CSSValue* ToCSSValue(SecureContextMode) const final;
+  const CSSValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(x_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSResourceValueTest.cpp b/third_party/WebKit/Source/core/css/cssom/CSSResourceValueTest.cpp
index e5ef9f49..f6ee2ce5 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSResourceValueTest.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSResourceValueTest.cpp
@@ -15,10 +15,8 @@
   FakeCSSResourceValue(ResourceStatus status) : status_(status) {}
   ResourceStatus Status() const override { return status_; }
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override {
-    return nullptr;
-  }
-  StyleValueType GetType() const override { return kUnknownType; }
+  const CSSValue* ToCSSValue() const final { return nullptr; }
+  StyleValueType GetType() const final { return kUnknownType; }
 
  private:
   ResourceStatus status_;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSRotation.cpp b/third_party/WebKit/Source/core/css/cssom/CSSRotation.cpp
index dfa4886..4ecbe724 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSRotation.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSRotation.cpp
@@ -161,8 +161,7 @@
   return matrix;
 }
 
-const CSSFunctionValue* CSSRotation::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
+const CSSFunctionValue* CSSRotation::ToCSSValue() const {
   DCHECK(x_->to(CSSPrimitiveValue::UnitType::kNumber));
   DCHECK(y_->to(CSSPrimitiveValue::UnitType::kNumber));
   DCHECK(z_->to(CSSPrimitiveValue::UnitType::kNumber));
@@ -171,9 +170,9 @@
   CSSFunctionValue* result =
       CSSFunctionValue::Create(is2D() ? CSSValueRotate : CSSValueRotate3d);
   if (!is2D()) {
-    const CSSValue* x = x_->ToCSSValue(secure_context_mode);
-    const CSSValue* y = y_->ToCSSValue(secure_context_mode);
-    const CSSValue* z = z_->ToCSSValue(secure_context_mode);
+    const CSSValue* x = x_->ToCSSValue();
+    const CSSValue* y = y_->ToCSSValue();
+    const CSSValue* z = z_->ToCSSValue();
     if (!x || !y || !z)
       return nullptr;
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSRotation.h b/third_party/WebKit/Source/core/css/cssom/CSSRotation.h
index 30dae25..3ebf02c 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSRotation.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSRotation.h
@@ -51,7 +51,7 @@
   // Internal methods - from CSSTransformComponent.
   TransformComponentType GetType() const final { return kRotationType; }
   const DOMMatrix* AsMatrix(ExceptionState&) const final;
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const final;
+  const CSSFunctionValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(angle_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSScale.cpp b/third_party/WebKit/Source/core/css/cssom/CSSScale.cpp
index c52f6efe..061bb4e 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSScale.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSScale.cpp
@@ -157,10 +157,9 @@
   return result->scaleSelf(x->value(), y->value(), z->value());
 }
 
-const CSSFunctionValue* CSSScale::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
-  const CSSValue* x = x_->ToCSSValue(secure_context_mode);
-  const CSSValue* y = y_->ToCSSValue(secure_context_mode);
+const CSSFunctionValue* CSSScale::ToCSSValue() const {
+  const CSSValue* x = x_->ToCSSValue();
+  const CSSValue* y = y_->ToCSSValue();
   if (!x || !y)
     return nullptr;
 
@@ -169,7 +168,7 @@
   result->Append(*x);
   result->Append(*y);
   if (!is2D()) {
-    const CSSValue* z = z_->ToCSSValue(secure_context_mode);
+    const CSSValue* z = z_->ToCSSValue();
     if (!z)
       return nullptr;
     result->Append(*z);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSScale.h b/third_party/WebKit/Source/core/css/cssom/CSSScale.h
index 35b4db3..1acacfe 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSScale.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSScale.h
@@ -53,7 +53,7 @@
   // Internal methods - from CSSTransformComponent.
   TransformComponentType GetType() const final { return kScaleType; }
   const DOMMatrix* AsMatrix(ExceptionState&) const final;
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const final;
+  const CSSFunctionValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(x_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp b/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp
index 6960888..d539457e 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSSkew.cpp
@@ -87,7 +87,7 @@
   return result;
 }
 
-const CSSFunctionValue* CSSSkew::ToCSSValue(SecureContextMode) const {
+const CSSFunctionValue* CSSSkew::ToCSSValue() const {
   // TDOO(meade): Handle calc angles here.
   CSSUnitValue* ax = ToCSSUnitValue(ax_);
   CSSUnitValue* ay = ToCSSUnitValue(ay_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSSkew.h b/third_party/WebKit/Source/core/css/cssom/CSSSkew.h
index 54c44841..dfc6c7d 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSSkew.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSSkew.h
@@ -44,7 +44,7 @@
   // Internal methods - from CSSTransformComponent.
   const DOMMatrix* AsMatrix(ExceptionState&) const override;
   TransformComponentType GetType() const override { return kSkewType; }
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const override;
+  const CSSFunctionValue* ToCSSValue() const override;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(ax_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp
index 68ad7ea3..4613d19 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp
@@ -19,19 +19,17 @@
         cache_pending_(cache_pending),
         size_(size) {}
 
-  bool IsCachePending() const override { return cache_pending_; }
-  IntSize ImageSize() const override { return size_; }
+  bool IsCachePending() const final { return cache_pending_; }
+  IntSize ImageSize() const final { return size_; }
 
-  ResourceStatus Status() const override {
+  ResourceStatus Status() const final {
     if (IsCachePending())
       return ResourceStatus::kNotStarted;
     return ResourceStatus::kCached;
   }
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override {
-    return nullptr;
-  }
-  StyleValueType GetType() const override { return kUnknownType; }
+  const CSSValue* ToCSSValue() const final { return nullptr; }
+  StyleValueType GetType() const final { return kUnknownType; }
 
  private:
   bool cache_pending_;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.cpp
index 3b3049eca..478ffa4f 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.cpp
@@ -74,10 +74,8 @@
   return style_value_vector;
 }
 
-String CSSStyleValue::toString(
-    const ExecutionContext* execution_context) const {
-  const CSSValue* result =
-      ToCSSValue(execution_context->GetSecureContextMode());
+String CSSStyleValue::toString() const {
+  const CSSValue* result = ToCSSValue();
   // TODO(crbug.com/782103): Remove this once all CSSStyleValues
   // support toCSSValue().
   return result ? result->CssText() : "";
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
index ebf1ffb..5e01552f 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
@@ -66,13 +66,11 @@
   virtual StyleValueType GetType() const = 0;
   virtual bool ContainsPercent() const { return false; }
 
-  virtual const CSSValue* ToCSSValue(SecureContextMode) const = 0;
-  virtual const CSSValue* ToCSSValueWithProperty(
-      CSSPropertyID,
-      SecureContextMode secure_context_mode) const {
-    return ToCSSValue(secure_context_mode);
+  virtual const CSSValue* ToCSSValue() const = 0;
+  virtual const CSSValue* ToCSSValueWithProperty(CSSPropertyID) const {
+    return ToCSSValue();
   }
-  virtual String toString(const ExecutionContext*) const;
+  virtual String toString() const;
 
  protected:
   static String StyleValueTypeToString(StyleValueType);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
index 072b230..8fe50596 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
+++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.idl
@@ -9,7 +9,7 @@
 [
   Exposed(Window CSSTypedOM, PaintWorklet CSSPaintAPI)
 ] interface CSSStyleValue {
-  [CallWith=ExecutionContext] stringifier;
+  stringifier;
   // Putting Exposed=Window in the next line makes |parse| not exposed to PaintWorklet.
   [RaisesException, Exposed=Window, CallWith=ExecutionContext] static CSSStyleValue? parse(DOMString property, DOMString cssText);
   [RaisesException, Exposed=Window, CallWith=ExecutionContext] static sequence<CSSStyleValue>? parseAll(DOMString property, DOMString cssText);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp
index 2c99d12e..766d787 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.cpp
@@ -52,12 +52,8 @@
   }
 }
 
-String CSSTransformComponent::toString(
-    const ExecutionContext* execution_context) const {
-  const CSSValue* result =
-      ToCSSValue(execution_context->GetSecureContextMode());
-  // TODO(meade): Remove this once all the number and length types are
-  // rewritten.
+String CSSTransformComponent::toString() const {
+  const CSSValue* result = ToCSSValue();
   return result ? result->CssText() : "";
 }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h
index 4fae47f..0f4a590 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.h
@@ -15,8 +15,6 @@
 
 class DOMMatrix;
 class ExceptionState;
-class ExecutionContext;
-enum class SecureContextMode;
 
 // CSSTransformComponent is the base class used for the representations of
 // the individual CSS transforms. They are combined in a CSSTransformValue
@@ -43,11 +41,11 @@
   // Getters and setters for attributes defined in the IDL.
   bool is2D() const { return is2D_; }
   virtual void setIs2D(bool is2D) { is2D_ = is2D; }
-  virtual String toString(const ExecutionContext*) const;
+  String toString() const;
 
   // Internal methods.
   virtual TransformComponentType GetType() const = 0;
-  virtual const CSSFunctionValue* ToCSSValue(SecureContextMode) const = 0;
+  virtual const CSSFunctionValue* ToCSSValue() const = 0;
   virtual const DOMMatrix* AsMatrix(ExceptionState&) const = 0;
 
  protected:
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.idl b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.idl
index c9ccdc0..ec592a2 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.idl
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformComponent.idl
@@ -10,6 +10,6 @@
     Exposed=(Window,PaintWorklet),
     RuntimeEnabled=CSSTypedOM
 ] interface CSSTransformComponent {
-    [CallWith=ExecutionContext] stringifier;
+    stringifier;
     attribute boolean is2D;
 };
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.cpp
index 0f7ac23..112f75c 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.cpp
@@ -62,12 +62,10 @@
   return matrix;
 }
 
-const CSSValue* CSSTransformValue::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
+const CSSValue* CSSTransformValue::ToCSSValue() const {
   CSSValueList* transform_css_value = CSSValueList::CreateSpaceSeparated();
   for (size_t i = 0; i < transform_components_.size(); i++) {
-    const CSSValue* component =
-        transform_components_[i]->ToCSSValue(secure_context_mode);
+    const CSSValue* component = transform_components_[i]->ToCSSValue();
     // TODO(meade): Remove this check once numbers and lengths are rewritten.
     if (!component)
       return nullptr;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.h b/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.h
index 6d1667c..55cd81c 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTransformValue.h
@@ -34,7 +34,7 @@
 
   DOMMatrix* toMatrix(ExceptionState&) const;
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override;
+  const CSSValue* ToCSSValue() const override;
 
   StyleValueType GetType() const override { return kTransformType; }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
index 8d0f95f..9bdd0d6 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.cpp
@@ -180,17 +180,16 @@
   return matrix->translate(x->value(), y->value(), z->value());
 }
 
-const CSSFunctionValue* CSSTranslation::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
-  const CSSValue* x = x_->ToCSSValue(secure_context_mode);
-  const CSSValue* y = y_->ToCSSValue(secure_context_mode);
+const CSSFunctionValue* CSSTranslation::ToCSSValue() const {
+  const CSSValue* x = x_->ToCSSValue();
+  const CSSValue* y = y_->ToCSSValue();
 
   CSSFunctionValue* result = CSSFunctionValue::Create(
       is2D() ? CSSValueTranslate : CSSValueTranslate3d);
   result->Append(*x);
   result->Append(*y);
   if (!is2D()) {
-    const CSSValue* z = z_->ToCSSValue(secure_context_mode);
+    const CSSValue* z = z_->ToCSSValue();
     result->Append(*z);
   }
   return result;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.h b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.h
index 3a026c64..51766be 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSTranslation.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSTranslation.h
@@ -51,7 +51,7 @@
   // Internal methods - from CSSTransformComponent.
   TransformComponentType GetType() const final { return kTranslationType; }
   const DOMMatrix* AsMatrix(ExceptionState&) const final;
-  const CSSFunctionValue* ToCSSValue(SecureContextMode) const final;
+  const CSSFunctionValue* ToCSSValue() const final;
 
   virtual void Trace(blink::Visitor* visitor) {
     visitor->Trace(x_);
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.h b/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.h
index a6cf846..6cd216d 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSURLImageValue.h
@@ -36,9 +36,7 @@
 
   StyleValueType GetType() const override { return kURLImageType; }
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override {
-    return CssImageValue();
-  }
+  const CSSValue* ToCSSValue() const override { return CssImageValue(); }
 
   const String& url() const { return CssImageValue()->RelativeUrl(); }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
index 5bb88b5..79549e01 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.cpp
@@ -140,7 +140,7 @@
   return value_ == other_unit_value.value_ && unit_ == other_unit_value.unit_;
 }
 
-const CSSPrimitiveValue* CSSUnitValue::ToCSSValue(SecureContextMode) const {
+const CSSPrimitiveValue* CSSUnitValue::ToCSSValue() const {
   return CSSPrimitiveValue::Create(value_, unit_);
 }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
index e46617d..f59d8fcf 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnitValue.h
@@ -50,7 +50,7 @@
     return unit_ == CSSPrimitiveValue::UnitType::kPercentage;
   }
 
-  const CSSPrimitiveValue* ToCSSValue(SecureContextMode) const final;
+  const CSSPrimitiveValue* ToCSSValue() const final;
   CSSCalcExpressionNode* ToCalcExpressionNode() const final;
 
  private:
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.cpp
index 42ec3c8..71a3f18 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.cpp
@@ -76,17 +76,12 @@
   return CSSUnparsedValue::Create(ParserTokenRangeToTokens(value.TokenRange()));
 }
 
-const CSSValue* CSSUnparsedValue::ToCSSValue(
-    SecureContextMode secure_context_mode) const {
+const CSSValue* CSSUnparsedValue::ToCSSValue() const {
   CSSTokenizer tokenizer(ToString());
   const auto tokens = tokenizer.TokenizeToEOF();
-  // TODO(alancutter): This should be using a real parser context instead of
-  // StrictCSSParserContext.
-  return CSSVariableReferenceValue::Create(
-      CSSVariableData::Create(CSSParserTokenRange(tokens),
-                              false /* isAnimationTainted */,
-                              true /* needsVariableResolution */),
-      *StrictCSSParserContext(secure_context_mode));
+  return CSSVariableReferenceValue::Create(CSSVariableData::Create(
+      CSSParserTokenRange(tokens), false /* isAnimationTainted */,
+      false /* needsVariableResolution */));
 }
 
 String CSSUnparsedValue::ToString() const {
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.h b/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.h
index 8eb0dc3..42cb87b 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnparsedValue.h
@@ -27,7 +27,7 @@
   static CSSUnparsedValue* FromCSSValue(const CSSVariableReferenceValue&);
   static CSSUnparsedValue* FromCSSValue(const CSSVariableData&);
 
-  const CSSValue* ToCSSValue(SecureContextMode) const override;
+  const CSSValue* ToCSSValue() const override;
 
   StyleValueType GetType() const override { return kUnparsedType; }
 
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.cpp
index 8de98bf..cb4c7d53e 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.cpp
@@ -9,16 +9,8 @@
 
 namespace blink {
 
-const CSSValue* CSSUnsupportedStyleValue::ToCSSValue(SecureContextMode) const {
-  NOTREACHED();
-  return nullptr;
-}
-
-const CSSValue* CSSUnsupportedStyleValue::ToCSSValueWithProperty(
-    CSSPropertyID property_id,
-    SecureContextMode secure_context_mode) const {
-  return CSSParser::ParseSingleValue(
-      property_id, css_text_, StrictCSSParserContext(secure_context_mode));
+const CSSValue* CSSUnsupportedStyleValue::ToCSSValue() const {
+  return css_value_.Get();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
index fa88870..bd429049 100644
--- a/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
+++ b/third_party/WebKit/Source/core/css/cssom/CSSUnsupportedStyleValue.h
@@ -15,22 +15,24 @@
 // for a given CSS Value.
 class CORE_EXPORT CSSUnsupportedStyleValue final : public CSSStyleValue {
  public:
-  static CSSUnsupportedStyleValue* Create(const String& css_text) {
-    return new CSSUnsupportedStyleValue(css_text);
+  static CSSUnsupportedStyleValue* Create(const CSSValue& css_value) {
+    return new CSSUnsupportedStyleValue(css_value);
   }
 
   StyleValueType GetType() const override {
     return StyleValueType::kUnknownType;
   }
-  const CSSValue* ToCSSValue(SecureContextMode) const override;
-  const CSSValue* ToCSSValueWithProperty(CSSPropertyID,
-                                         SecureContextMode) const override;
-  String toString(const ExecutionContext*) const override { return css_text_; }
+  const CSSValue* ToCSSValue() const override;
+
+  virtual void Trace(blink::Visitor* visitor) {
+    visitor->Trace(css_value_);
+    CSSStyleValue::Trace(visitor);
+  }
 
  private:
-  CSSUnsupportedStyleValue(const String& css_text) : css_text_(css_text) {}
+  CSSUnsupportedStyleValue(const CSSValue& css_value) : css_value_(css_value) {}
 
-  String css_text_;
+  Member<const CSSValue> css_value_;
   DISALLOW_COPY_AND_ASSIGN(CSSUnsupportedStyleValue);
 };
 
diff --git a/third_party/WebKit/Source/core/css/cssom/StylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/StylePropertyMap.cpp
index 27d6314..72d77838c 100644
--- a/third_party/WebKit/Source/core/css/cssom/StylePropertyMap.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/StylePropertyMap.cpp
@@ -33,12 +33,11 @@
 }
 
 const CSSValue* StyleValueToCSSValue(const CSSProperty& property,
-                                     const CSSStyleValue& style_value,
-                                     SecureContextMode secure_context_mode) {
+                                     const CSSStyleValue& style_value) {
   const CSSPropertyID property_id = property.PropertyID();
   if (!CSSOMTypes::PropertyCanTake(property_id, style_value))
     return nullptr;
-  return style_value.ToCSSValueWithProperty(property_id, secure_context_mode);
+  return style_value.ToCSSValueWithProperty(property_id);
 }
 
 const CSSValue* CoerceStyleValueOrString(
@@ -51,8 +50,7 @@
     if (!value.GetAsCSSStyleValue())
       return nullptr;
 
-    return StyleValueToCSSValue(property, *value.GetAsCSSStyleValue(),
-                                execution_context.GetSecureContextMode());
+    return StyleValueToCSSValue(property, *value.GetAsCSSStyleValue());
   } else {
     DCHECK(value.IsString());
     const auto values = StyleValueFactory::FromString(
@@ -61,8 +59,7 @@
     if (values.size() != 1U)
       return nullptr;
 
-    return StyleValueToCSSValue(property, *values[0],
-                                execution_context.GetSecureContextMode());
+    return StyleValueToCSSValue(property, *values[0]);
   }
 }
 
@@ -83,8 +80,7 @@
         return nullptr;
 
       css_values.push_back(
-          StyleValueToCSSValue(property, *value.GetAsCSSStyleValue(),
-                               execution_context.GetSecureContextMode()));
+          StyleValueToCSSValue(property, *value.GetAsCSSStyleValue()));
     } else {
       DCHECK(value.IsString());
       if (!parser_context)
@@ -97,8 +93,7 @@
 
       for (const auto& subvalue : subvalues) {
         DCHECK(subvalue);
-        css_values.push_back(StyleValueToCSSValue(
-            property, *subvalue, execution_context.GetSecureContextMode()));
+        css_values.push_back(StyleValueToCSSValue(property, *subvalue));
       }
     }
   }
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
index 19014b9..4ee361cc 100644
--- a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
@@ -72,8 +72,7 @@
 
 CSSStyleValueVector UnsupportedCSSValue(const CSSValue& value) {
   CSSStyleValueVector style_value_vector;
-  style_value_vector.push_back(
-      CSSUnsupportedStyleValue::Create(value.CssText()));
+  style_value_vector.push_back(CSSUnsupportedStyleValue::Create(value));
   return style_value_vector;
 }
 
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
index 7106cae8..c6317d19 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -142,7 +142,7 @@
     return kHasContentPseudoElement;
   if (simple_selector.GetPseudoType() == CSSSelector::kPseudoShadow)
     return 0;
-  // TODO(rune@opera.com): crbug.com/578131
+  // TODO(futhark@chromium.org): crbug.com/578131
   // The UASheetMode check is a work-around to allow this selector in
   // mediaControls(New).css:
   // input[type="range" i]::-webkit-media-slider-container > div {
@@ -298,7 +298,7 @@
 
   while (std::unique_ptr<CSSParserSelector> simple_selector =
              ConsumeSimpleSelector(range)) {
-    // TODO(rune@opera.com): crbug.com/578131
+    // TODO(futhark@chromium.org): crbug.com/578131
     // The UASheetMode check is a work-around to allow this selector in
     // mediaControls(New).css:
     // video::-webkit-media-text-track-region-container.scrolling
@@ -330,7 +330,7 @@
     return CSSParserSelector::Create(
         QualifiedName(namespace_prefix, element_name, namespace_uri));
   }
-  // TODO(rune@opera.com): Prepending a type selector to the compound is
+  // TODO(futhark@chromium.org): Prepending a type selector to the compound is
   // unnecessary if this compound is an argument to a pseudo selector like
   // :not(), since a type selector will be prepended at the top level of the
   // selector if necessary. We need to propagate that context information here
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index b4e42878..18ee0c7 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -1577,7 +1577,7 @@
           ? ToElement(node_before_change)
           : ElementTraversal::PreviousSibling(*node_before_change);
 
-  // TODO(rune@opera.com): move this code into StyleEngine and collect the
+  // TODO(futhark@chromium.org): move this code into StyleEngine and collect the
   // various invalidation sets into a single InvalidationLists object and
   // schedule with a single scheduleInvalidationSetsForNode for efficiency.
 
diff --git a/third_party/WebKit/Source/core/dom/DOMTokenList.idl b/third_party/WebKit/Source/core/dom/DOMTokenList.idl
index 23275a09..a389b0674 100644
--- a/third_party/WebKit/Source/core/dom/DOMTokenList.idl
+++ b/third_party/WebKit/Source/core/dom/DOMTokenList.idl
@@ -25,7 +25,9 @@
 
 // https://dom.spec.whatwg.org/#interface-domtokenlist
 
-interface DOMTokenList {
+[
+    Exposed=Window
+] interface DOMTokenList {
     readonly attribute unsigned long length;
     getter DOMString? item(unsigned long index);
     boolean contains(DOMString token);
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index b2883a8e6739..bddbbca 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2221,7 +2221,7 @@
 
   NthIndexCache nth_index_cache(*this);
 
-  // TODO(rune@opera.com): Cannot access the EnsureStyleResolver() before
+  // TODO(futhark@chromium.org): Cannot access the EnsureStyleResolver() before
   // calling StyleForViewport() below because apparently the StyleResolver's
   // constructor has side effects. We should fix it. See
   // printing/setPrinting.html, printing/width-overflow.html though they only
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.idl b/third_party/WebKit/Source/core/dom/MutationObserver.idl
index 514741c7..370a5a0 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.idl
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.idl
@@ -36,7 +36,8 @@
 [
     ConstructorCallWith=ScriptState,
     Constructor(MutationCallback callback),
-    ActiveScriptWrappable
+    ActiveScriptWrappable,
+    Exposed=Window
 ] interface MutationObserver {
     [RaisesException] void observe(Node target, optional MutationObserverInit options);
     void disconnect();
diff --git a/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp b/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp
index 5b7cf26..80d2e31 100644
--- a/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/ime/InputMethodControllerTest.cpp
@@ -2502,4 +2502,30 @@
                              Position(div, PositionAnchorType::kAfterAnchor))));
 }
 
+TEST_F(InputMethodControllerTest, SetCompositionTamilVirama) {
+  Element* div =
+      InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
+
+  // Commit TAMIL LETTER CA (U+0B9A) followed by TAMIL SIGN VIRAMA (U+U0BCD)
+  Controller().CommitText(String::FromUTF8("\xE0\xAE\x9A\xE0\xAF\x8D"),
+                          Vector<ImeTextSpan>(), 0);
+
+  // Open composition with TAMIL LETTER CA (U+0B9A) followed by
+  // TAMIL SIGN VIRAMA (U+U0BCD)
+  Controller().SetComposition(String::FromUTF8("\xE0\xAE\x9A\xE0\xAF\x8D"),
+                              Vector<ImeTextSpan>(), 2, 2);
+  // Remove the TAMIL SIGN VIRAMA from the end of the composition
+  Controller().SetComposition(String::FromUTF8("\xE0\xAE\x9A"),
+                              Vector<ImeTextSpan>(), 1, 1);
+
+  EXPECT_EQ(1u, div->CountChildren());
+  Text* text = ToText(div->firstChild());
+  EXPECT_STREQ("\xE0\xAE\x9A\xE0\xAF\x8D\xE0\xAE\x9A",
+               text->data().Utf8().data());
+
+  Range* range = Controller().CompositionRange();
+  EXPECT_EQ(2u, range->startOffset());
+  EXPECT_EQ(3u, range->endOffset());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtil.cpp b/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtil.cpp
index 61d69e7a..7855883 100644
--- a/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtil.cpp
+++ b/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtil.cpp
@@ -27,9 +27,11 @@
 // Must be sorted.
 // See http://www.unicode.org/Public/9.0.0/ucd/IndicSyllabicCategory-9.0.0d2.txt
 const uint32_t kIndicSyllabicCategoryViramaList[] = {
-    0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0BCD,  0x0C4D,  0x0CCD,
-    0x0D4D,  0x0DCA,  0x1B44,  0xA8C4,  0xA9C0,  0x11046, 0x110B9, 0x111C0,
-    0x11235, 0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F, 0x116B6, 0x11C3F,
+    // Do not include 0+0BCD TAMIL SIGN VIRAMA as Tamil works differently from
+    // other Indic languages. See crbug.com/693687.
+    0x094D,  0x09CD,  0x0A4D,  0x0ACD,  0x0B4D,  0x0C4D,  0x0CCD,  0x0D4D,
+    0x0DCA,  0x1B44,  0xA8C4,  0xA9C0,  0x11046, 0x110B9, 0x111C0, 0x11235,
+    0x1134D, 0x11442, 0x114C2, 0x115BF, 0x1163F, 0x116B6, 0x11C3F,
 };
 
 // Returns true if the code point has Indic_Syllabic_Category=Virama property.
diff --git a/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtilTest.cpp b/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtilTest.cpp
index f2e7a0aa..45b6b1c9 100644
--- a/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtilTest.cpp
+++ b/third_party/WebKit/Source/core/editing/state_machines/StateMachineUtilTest.cpp
@@ -160,6 +160,10 @@
   // Do not break after character having Indic_Syllabic_Category=Virama
   // property if following character has General_Category=C(Other) property.
   EXPECT_FALSE(IsGraphemeBreak(kVirama, kDevangariKa));
+
+  // Tamil virama is an exception (crbug.com/693697).
+  const UChar32 kTamilVirama = 0x0BCD;
+  EXPECT_TRUE(IsGraphemeBreak(kTamilVirama, kDevangariKa));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5
index cfb30eb..c11d244d6 100644
--- a/third_party/WebKit/Source/core/frame/Settings.json5
+++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -871,6 +871,7 @@
     {
       name: "hideScrollbars",
       initial: false,
+      invalidate: "ViewportScrollbar",
     },
 
     // Spellchecking is enabled by default for elements that do not specify it explicitly
diff --git a/third_party/WebKit/Source/core/frame/SettingsDelegate.h b/third_party/WebKit/Source/core/frame/SettingsDelegate.h
index eb6552a..a82b2f4 100644
--- a/third_party/WebKit/Source/core/frame/SettingsDelegate.h
+++ b/third_party/WebKit/Source/core/frame/SettingsDelegate.h
@@ -54,6 +54,7 @@
     kStyleChange,
     kViewportDescriptionChange,
     kViewportRuleChange,
+    kViewportScrollbarChange,
     kDNSPrefetchingChange,
     kImageLoadingChange,
     kTextAutosizingChange,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
index 89f161dd..9c2f2be8 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -450,15 +450,18 @@
         BuildObjectForTiming(*response.GetResourceLoadTiming()));
 
   if (response.GetResourceLoadInfo()) {
-    if (!response.GetResourceLoadInfo()->response_headers_text.IsEmpty())
+    if (!response.GetResourceLoadInfo()->response_headers_text.IsEmpty()) {
       response_object->setHeadersText(
           response.GetResourceLoadInfo()->response_headers_text);
-    if (response.GetResourceLoadInfo()->request_headers.size())
+    }
+    if (response.GetResourceLoadInfo()->request_headers.size()) {
       response_object->setRequestHeaders(BuildObjectForHeaders(
           response.GetResourceLoadInfo()->request_headers));
-    if (!response.GetResourceLoadInfo()->request_headers_text.IsEmpty())
+    }
+    if (!response.GetResourceLoadInfo()->request_headers_text.IsEmpty()) {
       response_object->setRequestHeadersText(
           response.GetResourceLoadInfo()->request_headers_text);
+    }
   }
 
   String remote_ip_address = response.RemoteIPAddress();
@@ -850,7 +853,8 @@
                                              DocumentLoader*,
                                              double monotonic_finish_time,
                                              int64_t encoded_data_length,
-                                             int64_t decoded_body_length) {
+                                             int64_t decoded_body_length,
+                                             bool blocked_cross_site_document) {
   String request_id = IdentifiersFactory::RequestId(identifier);
   NetworkResourcesData::ResourceData const* resource_data =
       resources_data_->Data(request_id);
@@ -873,8 +877,10 @@
   resources_data_->MaybeDecodeDataToContent(request_id);
   if (!monotonic_finish_time)
     monotonic_finish_time = CurrentTimeTicksInSeconds();
+
   GetFrontend()->loadingFinished(request_id, monotonic_finish_time,
-                                 encoded_data_length);
+                                 encoded_data_length,
+                                 blocked_cross_site_document);
 }
 
 void InspectorNetworkAgent::DidReceiveCORSRedirectResponse(
@@ -885,7 +891,7 @@
   // Update the response and finish loading
   DidReceiveResourceResponse(identifier, loader, response, resource);
   DidFinishLoading(identifier, loader, 0,
-                   WebURLLoaderClient::kUnknownEncodedDataLength, 0);
+                   WebURLLoaderClient::kUnknownEncodedDataLength, 0, false);
 }
 
 void InspectorNetworkAgent::DidFailLoading(unsigned long identifier,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
index 6b7663e..0025e77f 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.h
@@ -106,7 +106,8 @@
                         DocumentLoader*,
                         double monotonic_finish_time,
                         int64_t encoded_data_length,
-                        int64_t decoded_body_length);
+                        int64_t decoded_body_length,
+                        bool blocked_cross_site_document);
   void DidReceiveCORSRedirectResponse(unsigned long identifier,
                                       DocumentLoader*,
                                       const ResourceResponse&,
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
index ad1914e..4206b46 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -138,7 +138,8 @@
                                             DocumentLoader* loader,
                                             double finish_time,
                                             int64_t encoded_data_length,
-                                            int64_t decoded_body_length) {
+                                            int64_t decoded_body_length,
+                                            bool blocked_cross_site_document) {
   LocalFrame* frame = loader ? loader->GetFrame() : nullptr;
   TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish",
                        TRACE_EVENT_SCOPE_THREAD, "data",
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
index b91ca9f1..8efa73b6 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -93,7 +93,8 @@
                         DocumentLoader*,
                         double monotonic_finish_time,
                         int64_t encoded_data_length,
-                        int64_t decoded_body_length);
+                        int64_t decoded_body_length,
+                        bool blocked_cross_site_document);
   void DidFailLoading(unsigned long identifier,
                       DocumentLoader*,
                       const ResourceError&);
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index b09afda5..7022175 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -8261,6 +8261,12 @@
                             "name": "encodedDataLength",
                             "description": "Total number of bytes received for this request.",
                             "type": "number"
+                        },
+                        {
+                            "name": "blockedCrossSiteDocument",
+                            "description": "Set when response was blocked due to being cross-site document response.",
+                            "optional": true,
+                            "type": "boolean"
                         }
                     ]
                 },
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
index b647a936..9723adb 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
@@ -3768,6 +3768,8 @@
       MonotonicTime timestamp
       # Total number of bytes received for this request.
       number encodedDataLength
+      # Set when response was blocked due to being cross-site document response.
+      optional boolean blockedCrossSiteDocument
 
   # Details of an intercepted HTTP request, which must be either allowed, blocked, modified or
   # mocked.
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index dbc2e83..37d8d30 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -582,17 +582,20 @@
                                      encoded_data_length);
 }
 
-void FrameFetchContext::DispatchDidFinishLoading(unsigned long identifier,
-                                                 double finish_time,
-                                                 int64_t encoded_data_length,
-                                                 int64_t decoded_body_length) {
+void FrameFetchContext::DispatchDidFinishLoading(
+    unsigned long identifier,
+    double finish_time,
+    int64_t encoded_data_length,
+    int64_t decoded_body_length,
+    bool blocked_cross_site_document) {
   if (IsDetached())
     return;
 
   GetFrame()->Loader().Progress().CompleteProgress(identifier);
   probe::didFinishLoading(GetFrame()->GetDocument(), identifier,
                           MasterDocumentLoader(), finish_time,
-                          encoded_data_length, decoded_body_length);
+                          encoded_data_length, decoded_body_length,
+                          blocked_cross_site_document);
   if (document_) {
     InteractiveDetector* interactive_detector(
         InteractiveDetector::From(*document_));
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
index c8833a8..bd78b02 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.h
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -112,7 +112,8 @@
   void DispatchDidFinishLoading(unsigned long identifier,
                                 double finish_time,
                                 int64_t encoded_data_length,
-                                int64_t decoded_body_length) override;
+                                int64_t decoded_body_length,
+                                bool blocked_cross_site_document) override;
   void DispatchDidFail(unsigned long identifier,
                        const ResourceError&,
                        int64_t encoded_data_length,
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
index 2fdba90..53035249 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
@@ -1178,7 +1178,7 @@
 TEST_F(FrameFetchContextTest, DispatchDidFinishLoadingWhenDetached) {
   dummy_page_holder = nullptr;
 
-  fetch_context->DispatchDidFinishLoading(4, 0.3, 8, 10);
+  fetch_context->DispatchDidFinishLoading(4, 0.3, 8, 10, false);
   // Should not crash.
 }
 
diff --git a/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp b/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp
index ee4c802..48d09aa 100644
--- a/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/WorkerFetchContext.cpp
@@ -305,12 +305,15 @@
                                      encoded_data_length);
 }
 
-void WorkerFetchContext::DispatchDidFinishLoading(unsigned long identifier,
-                                                  double finish_time,
-                                                  int64_t encoded_data_length,
-                                                  int64_t decoded_body_length) {
+void WorkerFetchContext::DispatchDidFinishLoading(
+    unsigned long identifier,
+    double finish_time,
+    int64_t encoded_data_length,
+    int64_t decoded_body_length,
+    bool blocked_cross_site_document) {
   probe::didFinishLoading(global_scope_, identifier, nullptr, finish_time,
-                          encoded_data_length, decoded_body_length);
+                          encoded_data_length, decoded_body_length,
+                          blocked_cross_site_document);
 }
 
 void WorkerFetchContext::DispatchDidFail(unsigned long identifier,
diff --git a/third_party/WebKit/Source/core/loader/WorkerFetchContext.h b/third_party/WebKit/Source/core/loader/WorkerFetchContext.h
index 1ada8ea..cf1f63e 100644
--- a/third_party/WebKit/Source/core/loader/WorkerFetchContext.h
+++ b/third_party/WebKit/Source/core/loader/WorkerFetchContext.h
@@ -88,14 +88,15 @@
                               const char* data,
                               int dataLength) override;
   void DispatchDidReceiveEncodedData(unsigned long identifier,
-                                     int encodedDataLength) override;
+                                     int encoded_data_length) override;
   void DispatchDidFinishLoading(unsigned long identifier,
-                                double finishTime,
-                                int64_t encodedDataLength,
-                                int64_t decodedBodyLength) override;
+                                double finish_time,
+                                int64_t encoded_data_length,
+                                int64_t decoded_body_length,
+                                bool blocked_cross_site_document) override;
   void DispatchDidFail(unsigned long identifier,
                        const ResourceError&,
-                       int64_t encodedDataLength,
+                       int64_t encoded_data_length,
                        bool isInternalRequest) override;
   void AddResourceTiming(const ResourceTimingInfo&) override;
   void PopulateResourceRequest(Resource::Type,
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
index 9999878..eaa2c91 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -396,7 +396,8 @@
   if (!all_data_received && Loader()) {
     // Observers are notified via ImageResource::finish().
     // TODO(hiroshige): Do not call didFinishLoading() directly.
-    Loader()->DidFinishLoading(CurrentTimeTicksInSeconds(), size, size, size);
+    Loader()->DidFinishLoading(CurrentTimeTicksInSeconds(), size, size, size,
+                               false);
   } else {
     auto result = GetContent()->UpdateImage(
         nullptr, GetStatus(),
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
index 074f4e4..09ae215 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
@@ -226,7 +226,7 @@
       ResourceResponse(test_url, "image/jpeg", kDataLength)));
   image_resource->Loader()->DidReceiveData(data, kDataLength);
   image_resource->Loader()->DidFinishLoading(0.0, kDataLength, kDataLength,
-                                             kDataLength);
+                                             kDataLength, false);
 
   // Checks |imageResource|'s status after reloading.
   EXPECT_EQ(ResourceStatus::kCached, image_resource->GetStatus());
@@ -282,7 +282,7 @@
   image_resource->Loader()->DidFinishLoading(
       0.0, kJpegImageSubrangeWithDimensionsLength,
       kJpegImageSubrangeWithDimensionsLength,
-      kJpegImageSubrangeWithDimensionsLength);
+      kJpegImageSubrangeWithDimensionsLength, false);
 
   // Checks that |imageResource| is successfully loaded, showing a placeholder.
   EXPECT_EQ(ResourceStatus::kCached, image_resource->GetStatus());
@@ -320,7 +320,7 @@
   image_resource->Loader()->DidReceiveData(
       reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage));
   image_resource->Loader()->DidFinishLoading(
-      0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage));
+      0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage), false);
 
   // Checks that |imageResource| is successfully loaded,
   // showing a non-placeholder image.
@@ -413,7 +413,7 @@
 
   // This part finishes. The image is created, callbacks are sent, and the data
   // buffer is cleared.
-  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0);
+  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0, false);
   EXPECT_TRUE(image_resource->ResourceBuffer());
   EXPECT_FALSE(image_resource->ErrorOccurred());
   ASSERT_TRUE(image_resource->GetContent()->HasImage());
@@ -455,7 +455,7 @@
   image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage),
                              sizeof(kJpegImage));
   image_resource->AppendData(kBoundary, strlen(kBoundary));
-  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0);
+  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0, false);
   EXPECT_TRUE(image_resource->GetContent()->HasImage());
   EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
   EXPECT_TRUE(image_resource->GetContent()
@@ -796,7 +796,7 @@
   image_resource->Loader()->DidReceiveData(
       reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage));
   image_resource->Loader()->DidFinishLoading(
-      0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage));
+      0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage), false);
 
   EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
   EXPECT_EQ(image_resource, fetcher->CachedResource(test_url));
@@ -1295,7 +1295,7 @@
   EXPECT_FALSE(observer->ImageNotifyFinishedCalled());
   EXPECT_EQ(0, observer->ImageChangedCount());
 
-  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0);
+  image_resource->Loader()->DidFinishLoading(0.0, 0, 0, 0, false);
 
   EXPECT_EQ(ResourceStatus::kDecodeError, image_resource->GetStatus());
   EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
@@ -1340,7 +1340,7 @@
   image_resource->Loader()->DidFinishLoading(
       0.0, kJpegImageSubrangeWithoutDimensionsLength,
       kJpegImageSubrangeWithoutDimensionsLength,
-      kJpegImageSubrangeWithoutDimensionsLength);
+      kJpegImageSubrangeWithoutDimensionsLength, false);
 
   EXPECT_EQ(ResourceStatus::kDecodeError, image_resource->GetStatus());
   EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
@@ -1568,7 +1568,7 @@
     image_resource->Loader()->DidFinishLoading(
         0.0, kJpegImageSubrangeWithoutDimensionsLength,
         kJpegImageSubrangeWithoutDimensionsLength,
-        kJpegImageSubrangeWithoutDimensionsLength);
+        kJpegImageSubrangeWithoutDimensionsLength, false);
 
     EXPECT_FALSE(observer->ImageNotifyFinishedCalled());
     EXPECT_EQ(2, observer->ImageChangedCount());
@@ -1706,7 +1706,7 @@
     image_resource->Loader()->DidReceiveData(
         reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage));
     image_resource->Loader()->DidFinishLoading(
-        0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage));
+        0.0, sizeof(kJpegImage), sizeof(kJpegImage), sizeof(kJpegImage), false);
 
     EXPECT_EQ(ResourceStatus::kCached, image_resource->GetStatus());
     EXPECT_EQ(sizeof(kJpegImage), image_resource->EncodedSize());
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp
index 46ca2fb..4ffc93c 100644
--- a/third_party/WebKit/Source/core/page/Page.cpp
+++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -510,6 +510,9 @@
           text_autosizer->UpdatePageInfoInAllFrames();
       }
       break;
+    case SettingsDelegate::kViewportScrollbarChange:
+      GetVisualViewport().InitializeScrollbars();
+      break;
     case SettingsDelegate::kDNSPrefetchingChange:
       for (Frame* frame = MainFrame(); frame;
            frame = frame->Tree().TraverseNext()) {
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index 48cb088..8780199d 100644
--- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -436,11 +436,10 @@
 }
 
 LayoutRect FrameRectInAbsoluteCoordinates(LocalFrame* frame) {
-  ScrollableArea* scrollable_area =
-      frame->View()->LayoutViewportScrollableArea();
-  LayoutRect content_rect(scrollable_area->VisibleContentRect());
-  return LayoutRect(frame->View()->ContentsToRootFrame(LayoutPoint()),
-                    content_rect.Size());
+  return RectToAbsoluteCoordinates(
+      frame,
+      LayoutRect(
+          frame->View()->LayoutViewportScrollableArea()->VisibleContentRect()));
 }
 
 // This method calculates the exitPoint from the startingRect and the entryPoint
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
index e68edb0..5a8f719 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -2631,12 +2631,15 @@
 
   scrolling_coordinator->UpdateLayerPositionConstraint(&owning_layer_);
 
-  // Page scale is applied as a transform on the root layout view layer. Because
-  // the scroll layer is further up in the hierarchy, we need to avoid marking
-  // the root layout view layer as a container.
+  // In non-RLS mode, the fixed container will actually be the special viewport
+  // scrolling layers, higher up in the hierarchy, above the LayoutView "root
+  // layer". So avoid marking the LayoutView's layer a container in that case.
+  // The layout viewport scrolling layer will be correctly marked as such by
+  // PaintLayerCompositor.
   bool is_container =
       owning_layer_.GetLayoutObject().CanContainFixedPositionObjects() &&
-      !owning_layer_.IsRootLayer();
+      (!owning_layer_.IsRootLayer() ||
+       RuntimeEnabledFeatures::RootLayerScrollingEnabled());
   scrolling_coordinator->SetLayerIsContainerForFixedPositionLayers(
       graphics_layer_.get(), is_container);
   // Fixed-pos descendants inherits the space that has all CSS property applied,
diff --git a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
index c092096..ae85d59 100644
--- a/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/PaintLayerCompositor.cpp
@@ -532,23 +532,24 @@
     }
   }
 
-  if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-    bool is_root_scroller_ancestor = IsRootScrollerAncestor();
+  CompositedLayerMapping* clm = RootLayer()->GetCompositedLayerMapping();
+  GraphicsLayer* scroll_layer =
+      RuntimeEnabledFeatures::RootLayerScrollingEnabled() && clm
+          ? clm->ScrollingContentsLayer()
+          : scroll_layer_.get();
 
-    if (scroll_layer_)
-      scroll_layer_->SetIsResizedByBrowserControls(is_root_scroller_ancestor);
+  bool is_root_scroller_ancestor = IsRootScrollerAncestor();
 
-    // Clip a frame's overflow controls layer only if it's not an ancestor of
-    // the root scroller. If it is an ancestor, then it's guaranteed to be
-    // viewport sized and so will be appropriately clipped by the visual
-    // viewport. We don't want to clip here in this case so that URL bar
-    // expansion doesn't need to resize the clip.
+  if (scroll_layer)
+    scroll_layer->SetIsResizedByBrowserControls(is_root_scroller_ancestor);
 
-    if (overflow_controls_host_layer_) {
-      overflow_controls_host_layer_->SetMasksToBounds(
-          !is_root_scroller_ancestor);
-    }
-  }
+  // Clip a frame's overflow controls layer only if it's not an ancestor of
+  // the root scroller. If it is an ancestor, then it's guaranteed to be
+  // viewport sized and so will be appropriately clipped by the visual
+  // viewport. We don't want to clip here in this case so that URL bar
+  // expansion doesn't need to resize the clip.
+  if (overflow_controls_host_layer_)
+    overflow_controls_host_layer_->SetMasksToBounds(!is_root_scroller_ancestor);
 
   // Inform the inspector that the layer tree has changed.
   if (IsMainFrame())
diff --git a/third_party/WebKit/Source/core/probe/CoreProbes.pidl b/third_party/WebKit/Source/core/probe/CoreProbes.pidl
index 44e66b5..044cd8d6 100644
--- a/third_party/WebKit/Source/core/probe/CoreProbes.pidl
+++ b/third_party/WebKit/Source/core/probe/CoreProbes.pidl
@@ -95,7 +95,7 @@
   void didReceiveResourceResponse(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, Resource*);
   void didReceiveData(ExecutionContext*, unsigned long identifier, DocumentLoader*, const char* data, int dataLength);
   void didReceiveEncodedDataLength(ExecutionContext*, unsigned long identifier, int encodedDataLength);
-  void didFinishLoading(ExecutionContext*, unsigned long identifier, DocumentLoader*, double finishTime, int64_t encodedDataLength, int64_t decodedBodyLength);
+  void didFinishLoading(ExecutionContext*, unsigned long identifier, DocumentLoader*, double finishTime, int64_t encoded_data_length, int64_t decodedBodyLength, bool blocked_cross_site_document);
   void didReceiveCORSRedirectResponse(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, Resource*);
   void didFailLoading(ExecutionContext*, unsigned long identifier, DocumentLoader*, const ResourceError&);
   void documentThreadableLoaderStartedLoadingForClient(ExecutionContext*, unsigned long identifier, ThreadableLoaderClient* client);
diff --git a/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp b/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
index f4af264e..1855758 100644
--- a/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
+++ b/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
@@ -15,8 +15,8 @@
 #include "public/web/WebView.h"
 
 namespace blink {
+namespace virtual_time_test {
 
-namespace {
 class ScriptExecutionCallbackHelper : public WebScriptExecutionCallback {
  public:
   const String Result() const { return result_; }
@@ -30,7 +30,6 @@
 
   String result_;
 };
-}  // namespace
 
 class VirtualTimeTest : public SimTest {
  protected:
@@ -252,4 +251,5 @@
 #undef MAYBE_AllowVirtualTimeToAdvance
 #undef MAYBE_VirtualTimeNotAllowedToAdvanceWhileResourcesLoading
 #undef MAYBE_DOMTimersSuspended
+}  // namespace virtual_time_test
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/sim/SimNetwork.cpp b/third_party/WebKit/Source/core/testing/sim/SimNetwork.cpp
index f4c5c93b..0edcee5c 100644
--- a/third_party/WebKit/Source/core/testing/sim/SimNetwork.cpp
+++ b/third_party/WebKit/Source/core/testing/sim/SimNetwork.cpp
@@ -79,7 +79,7 @@
   if (!current_request_) {
     client->DidFinishLoading(finish_time, total_encoded_data_length,
                              total_encoded_body_length,
-                             total_decoded_body_length);
+                             total_decoded_body_length, false);
     return;
   }
   current_request_ = nullptr;
diff --git a/third_party/WebKit/Source/core/testing/sim/SimRequest.cpp b/third_party/WebKit/Source/core/testing/sim/SimRequest.cpp
index 8a559fa..5a68e88cd 100644
--- a/third_party/WebKit/Source/core/testing/sim/SimRequest.cpp
+++ b/third_party/WebKit/Source/core/testing/sim/SimRequest.cpp
@@ -70,7 +70,7 @@
     // TODO(esprehn): Is claiming a request time of 0 okay for tests?
     client_->DidFinishLoading(0, total_encoded_data_length_,
                               total_encoded_data_length_,
-                              total_encoded_data_length_);
+                              total_encoded_data_length_, false);
   }
   Reset();
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
index 22bef1ed..0b24190 100644
--- a/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
+++ b/third_party/WebKit/Source/devtools/front_end/application_test_runner/IndexedDBTestRunner.js
@@ -175,11 +175,6 @@
       'addIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\', \'' + value + '\')');
 };
 
-ApplicationTestRunner.addIDBValueAsync = function(databaseName, objectStoreName, key, value) {
-  return TestRunner.evaluateInPageAsync(
-      'addIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\', \'' + value + '\')');
-};
-
 ApplicationTestRunner.deleteIDBValueAsync = function(databaseName, objectStoreName, key) {
   return TestRunner.evaluateInPageAsync(
       'deleteIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\')');
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
index 26d3b643..d8d31ab4 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
@@ -506,12 +506,13 @@
    * @param {!Protocol.Network.RequestId} requestId
    * @param {!Protocol.Network.MonotonicTime} finishTime
    * @param {number} encodedDataLength
+   * @param {boolean=} blockedCrossSiteDocument
    */
-  loadingFinished(requestId, finishTime, encodedDataLength) {
+  loadingFinished(requestId, finishTime, encodedDataLength, blockedCrossSiteDocument) {
     var networkRequest = this._inflightRequestsById[requestId];
     if (!networkRequest)
       return;
-    this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength);
+    this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument);
   }
 
   /**
@@ -740,8 +741,9 @@
    * @param {!SDK.NetworkRequest} networkRequest
    * @param {!Protocol.Network.MonotonicTime} finishTime
    * @param {number} encodedDataLength
+   * @param {boolean=} blockedCrossSiteDocument
    */
-  _finishNetworkRequest(networkRequest, finishTime, encodedDataLength) {
+  _finishNetworkRequest(networkRequest, finishTime, encodedDataLength, blockedCrossSiteDocument) {
     networkRequest.endTime = finishTime;
     networkRequest.finished = true;
     if (encodedDataLength >= 0)
@@ -750,6 +752,15 @@
     delete this._inflightRequestsById[networkRequest.requestId()];
     delete this._inflightRequestsByURL[networkRequest.url()];
 
+    if (blockedCrossSiteDocument) {
+      var message = Common.UIString(
+          `Blocked current origin from receiving cross-site document at %s with MIME type %s.`, networkRequest.url(),
+          networkRequest.mimeType);
+      this._manager.dispatchEventToListeners(
+          SDK.NetworkManager.Events.MessageGenerated,
+          {message: message, requestId: networkRequest.requestId(), warning: true});
+    }
+
     if (Common.moduleSetting('monitoringXHREnabled').get() &&
         networkRequest.resourceType().category() === Common.resourceCategories.XHR) {
       var message = Common.UIString(
diff --git a/third_party/WebKit/Source/modules/media_controls/BUILD.gn b/third_party/WebKit/Source/modules/media_controls/BUILD.gn
index 72e7b40..c17a537e 100644
--- a/third_party/WebKit/Source/modules/media_controls/BUILD.gn
+++ b/third_party/WebKit/Source/modules/media_controls/BUILD.gn
@@ -58,6 +58,8 @@
     "elements/MediaControlPanelElement.h",
     "elements/MediaControlPanelEnclosureElement.cpp",
     "elements/MediaControlPanelEnclosureElement.h",
+    "elements/MediaControlPictureInPictureButtonElement.cpp",
+    "elements/MediaControlPictureInPictureButtonElement.h",
     "elements/MediaControlPlayButtonElement.cpp",
     "elements/MediaControlPlayButtonElement.h",
     "elements/MediaControlRemainingTimeDisplayElement.cpp",
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
index 52fbda2..7c3cc1a 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -70,6 +70,7 @@
 #include "modules/media_controls/elements/MediaControlOverlayPlayButtonElement.h"
 #include "modules/media_controls/elements/MediaControlPanelElement.h"
 #include "modules/media_controls/elements/MediaControlPanelEnclosureElement.h"
+#include "modules/media_controls/elements/MediaControlPictureInPictureButtonElement.h"
 #include "modules/media_controls/elements/MediaControlPlayButtonElement.h"
 #include "modules/media_controls/elements/MediaControlRemainingTimeDisplayElement.h"
 #include "modules/media_controls/elements/MediaControlTextTrackListElement.h"
@@ -302,6 +303,7 @@
       overflow_list_(nullptr),
       media_button_panel_(nullptr),
       loading_panel_(nullptr),
+      picture_in_picture_button_(nullptr),
       cast_button_(nullptr),
       fullscreen_button_(nullptr),
       download_button_(nullptr),
@@ -407,6 +409,8 @@
 //     |  |    (-webkit-media-controls-mute-button)
 //     |  +-MediaControlVolumeSliderElement
 //     |  |    (-webkit-media-controls-volume-slider)
+//     |  +-MediaControlPictureInPictureButtonElement
+//     |  |   (-webkit-media-controls-picture-in-picture-button)
 //     |  +-MediaControlFullscreenButtonElement
 //     |  |    (-webkit-media-controls-fullscreen-button)
 //     |  +-MediaControlDownloadButtonElement
@@ -492,6 +496,13 @@
   if (PreferHiddenVolumeControls(GetDocument()))
     volume_slider_->SetIsWanted(false);
 
+  // TODO(apacible): Enable for modern controls when SVG is added.
+  if (RuntimeEnabledFeatures::PictureInPictureEnabled() && !IsModern() &&
+      MediaElement().IsHTMLVideoElement()) {
+    picture_in_picture_button_ =
+        new MediaControlPictureInPictureButtonElement(*this);
+    button_panel->AppendChild(picture_in_picture_button_);
+  }
   fullscreen_button_ = new MediaControlFullscreenButtonElement(*this);
   button_panel->AppendChild(fullscreen_button_);
 
@@ -524,6 +535,11 @@
   // overflow menu.
   overflow_list_->AppendChild(play_button_->CreateOverflowElement(
       new MediaControlPlayButtonElement(*this)));
+  if (RuntimeEnabledFeatures::PictureInPictureEnabled() && !IsModern()) {
+    overflow_list_->AppendChild(
+        picture_in_picture_button_->CreateOverflowElement(
+            new MediaControlPictureInPictureButtonElement(*this)));
+  }
   overflow_list_->AppendChild(fullscreen_button_->CreateOverflowElement(
       new MediaControlFullscreenButtonElement(*this)));
   overflow_list_->AppendChild(download_button_->CreateOverflowElement(
@@ -924,6 +940,9 @@
       std::make_pair(fullscreen_button_.Get(), true),
       std::make_pair(current_time_display_.Get(), true),
       std::make_pair(duration_display_.Get(), true),
+      picture_in_picture_button_.Get()
+          ? std::make_pair(picture_in_picture_button_.Get(), false)
+          : std::make_pair(nullptr, false),
       std::make_pair(cast_button_.Get(), false),
       std::make_pair(download_button_.Get(), false),
       std::make_pair(toggle_closed_captions_button_.Get(), false),
@@ -969,6 +988,8 @@
   bool overflow_wanted = false;
   for (std::pair<MediaControlElementBase*, bool> pair : row_elements) {
     MediaControlElementBase* element = pair.first;
+    if (!element)
+      continue;
 
     // If the element is wanted then it should take up space, otherwise skip it.
     element->SetOverflowElementIsWanted(false);
@@ -1370,6 +1391,8 @@
       mute_button_.Get(),
       volume_slider_.Get(),
       toggle_closed_captions_button_.Get(),
+      picture_in_picture_button_.Get() ? picture_in_picture_button_.Get()
+                                       : nullptr,
       cast_button_.Get(),
       current_time_display_.Get(),
       duration_display_.Get(),
@@ -1492,6 +1515,8 @@
       mute_button_.Get(),
       volume_slider_.Get(),
       toggle_closed_captions_button_.Get(),
+      picture_in_picture_button_.Get() ? picture_in_picture_button_.Get()
+                                       : nullptr,
       cast_button_.Get(),
       current_time_display_.Get(),
       duration_display_.Get(),
@@ -1637,6 +1662,7 @@
   visitor->Trace(timeline_);
   visitor->Trace(mute_button_);
   visitor->Trace(volume_slider_);
+  visitor->Trace(picture_in_picture_button_);
   visitor->Trace(toggle_closed_captions_button_);
   visitor->Trace(fullscreen_button_);
   visitor->Trace(download_button_);
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
index 1fc0da3..663a3efe 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.h
@@ -54,6 +54,7 @@
 class MediaControlOverlayPlayButtonElement;
 class MediaControlPanelElement;
 class MediaControlPanelEnclosureElement;
+class MediaControlPictureInPictureButtonElement;
 class MediaControlPlayButtonElement;
 class MediaControlRemainingTimeDisplayElement;
 class MediaControlTextTrackListElement;
@@ -293,6 +294,7 @@
   Member<MediaControlOverflowMenuListElement> overflow_list_;
   Member<MediaControlButtonPanelElement> media_button_panel_;
   Member<MediaControlLoadingPanelElement> loading_panel_;
+  Member<MediaControlPictureInPictureButtonElement> picture_in_picture_button_;
 
   Member<MediaControlCastButtonElement> cast_button_;
   Member<MediaControlFullscreenButtonElement> fullscreen_button_;
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.cpp
new file mode 100644
index 0000000..d1004314
--- /dev/null
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.cpp
@@ -0,0 +1,50 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/media_controls/elements/MediaControlPictureInPictureButtonElement.h"
+
+#include "core/dom/events/Event.h"
+#include "core/html/media/HTMLMediaElement.h"
+#include "core/html/media/HTMLMediaSource.h"
+#include "core/input_type_names.h"
+#include "modules/media_controls/MediaControlsImpl.h"
+#include "public/platform/Platform.h"
+
+namespace blink {
+
+MediaControlPictureInPictureButtonElement::
+    MediaControlPictureInPictureButtonElement(MediaControlsImpl& media_controls)
+    : MediaControlInputElement(media_controls, kMediaPlayButton) {
+  setType(InputTypeNames::button);
+  SetShadowPseudoId(
+      AtomicString("-internal-media-controls-picture-in-picture-button"));
+}
+
+bool MediaControlPictureInPictureButtonElement::
+    WillRespondToMouseClickEvents() {
+  return true;
+}
+
+WebLocalizedString::Name
+MediaControlPictureInPictureButtonElement::GetOverflowStringName() const {
+  return WebLocalizedString::kOverflowMenuPictureInPicture;
+}
+
+bool MediaControlPictureInPictureButtonElement::HasOverflowButton() const {
+  return true;
+}
+
+const char* MediaControlPictureInPictureButtonElement::GetNameForHistograms()
+    const {
+  return IsOverflowElement() ? "PictureInPictureOverflowButton"
+                             : "PictureInPictureButton";
+}
+
+void MediaControlPictureInPictureButtonElement::DefaultEventHandler(
+    Event* event) {
+  // TODO(apacible): On click, trigger picture in picture.
+  MediaControlInputElement::DefaultEventHandler(event);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.h
new file mode 100644
index 0000000..ccebfaef
--- /dev/null
+++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlPictureInPictureButtonElement.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaControlPictureInPictureButtonElement_h
+#define MediaControlPictureInPictureButtonElement_h
+
+#include "modules/media_controls/elements/MediaControlInputElement.h"
+
+namespace blink {
+
+class Event;
+class MediaControlsImpl;
+
+class MediaControlPictureInPictureButtonElement final
+    : public MediaControlInputElement {
+ public:
+  explicit MediaControlPictureInPictureButtonElement(MediaControlsImpl&);
+
+  // MediaControlInputElement:
+  bool WillRespondToMouseClickEvents() override;
+  WebLocalizedString::Name GetOverflowStringName() const override;
+  bool HasOverflowButton() const override;
+
+  void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(event); }
+
+ protected:
+  const char* GetNameForHistograms() const override;
+
+ private:
+  void DefaultEventHandler(Event*) override;
+};
+
+}  // namespace blink
+
+#endif  // MediaControlPictureInPictureButtonElement_h
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/default_100_percent/legacy/mediaplayer_pictureinpicture.png b/third_party/WebKit/Source/modules/media_controls/resources/default_100_percent/legacy/mediaplayer_pictureinpicture.png
new file mode 100644
index 0000000..75a85d0
--- /dev/null
+++ b/third_party/WebKit/Source/modules/media_controls/resources/default_100_percent/legacy/mediaplayer_pictureinpicture.png
Binary files differ
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/legacyMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/legacyMediaControls.css
index 858d72b6..d9aba6a 100644
--- a/third_party/WebKit/Source/modules/media_controls/resources/legacyMediaControls.css
+++ b/third_party/WebKit/Source/modules/media_controls/resources/legacyMediaControls.css
@@ -267,7 +267,7 @@
       url(default_100_percent/legacy/mediaplayer_overlay_cast_on.png) 1x);
 }
 
-audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
+video::-internal-media-controls-picture-in-picture-button, audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
     -webkit-appearance: -internal-media-control;
     background-image: -webkit-image-set(
       url(default_100_percent/legacy/mediaplayer_pause.png) 1x);
@@ -291,6 +291,11 @@
       url(default_100_percent/legacy/mediaplayer_play.png) 1x);
 }
 
+video::-internal-media-controls-picture-in-picture-button {
+  background-image: -webkit-image-set(
+      url(default_100_percent/legacy/mediaplayer_pictureinpicture.png) 1x);
+}
+
 audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container {
     -webkit-appearance: media-controls-background;
     display: flex;
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
index c919a5b..e86707b 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
@@ -70,7 +70,7 @@
     quota_callback_->InvokeAndReportException(nullptr, granted_quota_in_bytes);
 }
 
-void DeprecatedStorageQuotaCallbacksImpl::DidFail(WebStorageQuotaError error) {
+void DeprecatedStorageQuotaCallbacksImpl::DidFail(QuotaStatusCode error) {
   if (error_callback_) {
     error_callback_->InvokeAndReportException(
         nullptr, DOMError::Create(static_cast<ExceptionCode>(error)));
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
index 1773fb7..241b8ac 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
@@ -62,7 +62,7 @@
                                     unsigned long long quota_in_bytes) override;
   void DidGrantStorageQuota(unsigned long long usage_in_bytes,
                             unsigned long long granted_quota_in_bytes) override;
-  void DidFail(WebStorageQuotaError) override;
+  void DidFail(QuotaStatusCode) override;
 
  private:
   DeprecatedStorageQuotaCallbacksImpl(V8StorageUsageCallback*,
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.cpp b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
index ee589cf..bd07f4d 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
@@ -18,7 +18,7 @@
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Functional.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebStorageQuotaError.h"
+#include "third_party/WebKit/common/quota/quota_status_code.h"
 #include "third_party/WebKit/common/quota/storage_type.h"
 
 namespace blink {
@@ -50,7 +50,9 @@
     resolver_->Resolve(estimate);
   }
 
-  void DidFail(WebStorageQuotaError error) override {
+  void DidFail(QuotaStatusCode error) override {
+    // TODO(sashab): Replace this with a switch statement, and remove the enum
+    // values from QuotaStatusCode.
     resolver_->Reject(DOMException::Create(static_cast<ExceptionCode>(error)));
   }
 
@@ -154,10 +156,10 @@
   resolver->Resolve(status == PermissionStatus::GRANTED);
 }
 
-STATIC_ASSERT_ENUM(kWebStorageQuotaErrorNotSupported, kNotSupportedError);
-STATIC_ASSERT_ENUM(kWebStorageQuotaErrorInvalidModification,
+STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorNotSupported, kNotSupportedError);
+STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorInvalidModification,
                    kInvalidModificationError);
-STATIC_ASSERT_ENUM(kWebStorageQuotaErrorInvalidAccess, kInvalidAccessError);
-STATIC_ASSERT_ENUM(kWebStorageQuotaErrorAbort, kAbortError);
+STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorInvalidAccess, kInvalidAccessError);
+STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorAbort, kAbortError);
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h b/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
index 1b362d4..55eff8a 100644
--- a/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
+++ b/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
@@ -35,7 +35,7 @@
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Noncopyable.h"
-#include "public/platform/WebStorageQuotaError.h"
+#include "third_party/WebKit/common/quota/quota_status_code.h"
 
 namespace blink {
 
@@ -56,7 +56,7 @@
                                     unsigned long long granted_quota_in_bytes) {
     NOTREACHED();
   }
-  virtual void DidFail(WebStorageQuotaError) { NOTREACHED(); }
+  virtual void DidFail(QuotaStatusCode) { NOTREACHED(); }
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/WebThread.cpp b/third_party/WebKit/Source/platform/WebThread.cpp
index b8b1eb7..da63a2a 100644
--- a/third_party/WebKit/Source/platform/WebThread.cpp
+++ b/third_party/WebKit/Source/platform/WebThread.cpp
@@ -28,7 +28,7 @@
 #endif
 
 scoped_refptr<base::SingleThreadTaskRunner>
-WebThread::GetSingleThreadTaskRunner() {
+WebThread::GetSingleThreadTaskRunner() const {
   return GetWebTaskRunner();
 }
 
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
index 58e59e1..e18cbd0b 100644
--- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
@@ -27,7 +27,6 @@
 
 #include <memory>
 
-#include "platform/WebTaskRunner.h"
 #include "platform/bindings/DOMDataStore.h"
 #include "platform/bindings/ScriptForbiddenScope.h"
 #include "platform/bindings/V8Binding.h"
@@ -59,7 +58,7 @@
 }
 
 V8PerIsolateData::V8PerIsolateData(
-    WebTaskRunner* task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     V8ContextSnapshotMode v8_context_snapshot_mode)
     : v8_context_snapshot_mode_(v8_context_snapshot_mode),
       isolate_holder_(
@@ -119,8 +118,9 @@
   return g_main_thread_per_isolate_data->GetIsolate();
 }
 
-v8::Isolate* V8PerIsolateData::Initialize(WebTaskRunner* task_runner,
-                                          V8ContextSnapshotMode context_mode) {
+v8::Isolate* V8PerIsolateData::Initialize(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    V8ContextSnapshotMode context_mode) {
   V8PerIsolateData* data = nullptr;
   if (context_mode == V8ContextSnapshotMode::kTakeSnapshot) {
     data = new V8PerIsolateData();
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
index b897089..2696918 100644
--- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
+++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
@@ -49,7 +49,6 @@
 class DOMDataStore;
 class StringCache;
 class V8PrivateProperty;
-class WebTaskRunner;
 struct WrapperTypeInfo;
 
 typedef WTF::Vector<DOMDataStore*> DOMDataStoreList;
@@ -100,7 +99,7 @@
     virtual ~Data() = default;
   };
 
-  static v8::Isolate* Initialize(WebTaskRunner*,
+  static v8::Isolate* Initialize(scoped_refptr<base::SingleThreadTaskRunner>,
                                  V8ContextSnapshotMode);
 
   static V8PerIsolateData* From(v8::Isolate* isolate) {
@@ -235,7 +234,7 @@
   }
 
  private:
-  V8PerIsolateData(WebTaskRunner*,
+  V8PerIsolateData(scoped_refptr<base::SingleThreadTaskRunner>,
                    V8ContextSnapshotMode);
   V8PerIsolateData();
   ~V8PerIsolateData();
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
index c9ee2d44..90fa9c2 100644
--- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -486,8 +486,16 @@
   RuntimeEnabledFeatures::SetWorkStealingInScriptRunnerEnabled(enable);
 }
 
-void WebRuntimeFeatures::EnableStopLoadingInBackgroundAndroid(bool enable) {
-  RuntimeEnabledFeatures::SetStopLoadingInBackgroundAndroidEnabled(enable);
+void WebRuntimeFeatures::EnableStopInBackground(bool enable) {
+  RuntimeEnabledFeatures::SetStopInBackgroundEnabled(enable);
+}
+
+void WebRuntimeFeatures::EnableStopLoadingInBackground(bool enable) {
+  RuntimeEnabledFeatures::SetStopLoadingInBackgroundEnabled(enable);
+}
+
+void WebRuntimeFeatures::EnableStopNonTimersInBackground(bool enable) {
+  RuntimeEnabledFeatures::SetStopNonTimersInBackgroundEnabled(enable);
 }
 
 void WebRuntimeFeatures::EnablePWAFullCodeCache(bool enable) {
diff --git a/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp b/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
index 3768068..688e7ab 100644
--- a/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
@@ -36,7 +36,7 @@
   private_.Reset();
 }
 
-void WebStorageQuotaCallbacks::DidFail(WebStorageQuotaError error) {
+void WebStorageQuotaCallbacks::DidFail(QuotaStatusCode error) {
   DCHECK(!private_.IsNull());
   private_->DidFail(error);
   private_.Reset();
diff --git a/third_party/WebKit/Source/platform/exported/WebURLLoaderTestDelegate.cpp b/third_party/WebKit/Source/platform/exported/WebURLLoaderTestDelegate.cpp
index adef4fe..67b9c96 100644
--- a/third_party/WebKit/Source/platform/exported/WebURLLoaderTestDelegate.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebURLLoaderTestDelegate.cpp
@@ -46,7 +46,7 @@
     int64_t total_decoded_body_length) {
   original_client->DidFinishLoading(finish_time, total_encoded_data_length,
                                     total_encoded_body_length,
-                                    total_decoded_body_length);
+                                    total_decoded_body_length, false);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
index 32cf15d..e74ac2b 100644
--- a/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/IncrementalMarkingTest.cpp
@@ -78,6 +78,9 @@
       CallbackStack::Item* item = marking_stack_->Pop();
       T* obj = reinterpret_cast<T*>(item->Object());
       auto pos = std::find(objects_.begin(), objects_.end(), obj);
+      // The following check makes sure that there are no unexpected objects on
+      // the marking stack. If it fails then the write barrier fired for an
+      // unexpected object.
       EXPECT_NE(objects_.end(), pos);
       objects_.erase(pos);
     }
@@ -852,6 +855,88 @@
   }
 }
 
+// =============================================================================
+// HeapHashMap support. ========================================================
+// =============================================================================
+
+TEST(IncrementalMarkingTest, HeapHashMapInsertMember) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map;
+  {
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2});
+    map.insert(obj1, obj2);
+  }
+}
+
+TEST(IncrementalMarkingTest, HeapHashMapSetMember) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map;
+  {
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2});
+    map.Set(obj1, obj2);
+  }
+}
+
+TEST(IncrementalMarkingTest, HeapHashMapSetMemberOnlyValue) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  Object* obj3 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map;
+  map.insert(obj1, obj2);
+  {
+    // Only |obj3| is newly added to |map|, so we only expect the barrier to
+    // fire on this one.
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3});
+    map.Set(obj1, obj3);
+    EXPECT_FALSE(HeapObjectHeader::FromPayload(obj1)->IsMarked());
+    EXPECT_FALSE(HeapObjectHeader::FromPayload(obj2)->IsMarked());
+  }
+}
+
+TEST(IncrementalMarkingTest, HeapHashMapIteratorChangeKey) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  Object* obj3 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map;
+  map.insert(obj1, obj2);
+  {
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3});
+    auto it = map.find(obj1);
+    EXPECT_NE(map.end(), it);
+    it->key = obj3;
+  }
+}
+
+TEST(IncrementalMarkingTest, HeapHashMapIteratorChangeValue) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  Object* obj3 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map;
+  map.insert(obj1, obj2);
+  {
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3});
+    auto it = map.find(obj1);
+    EXPECT_NE(map.end(), it);
+    it->value = obj3;
+  }
+}
+
+TEST(IncrementalMarkingTest, HeapHashMapCopyMember) {
+  Object* obj1 = Object::Create();
+  Object* obj2 = Object::Create();
+  HeapHashMap<Member<Object>, Member<Object>> map1;
+  map1.insert(obj1, obj2);
+  {
+    ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2});
+    EXPECT_TRUE(map1.Contains(obj1));
+    HeapHashMap<Member<Object>, Member<Object>> map2(map1);
+    EXPECT_TRUE(map1.Contains(obj1));
+    EXPECT_TRUE(map2.Contains(obj1));
+  }
+}
+
 }  // namespace incremental_marking_test
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/platform/heap/Member.h b/third_party/WebKit/Source/platform/heap/Member.h
index 250b979..754cadd6 100644
--- a/third_party/WebKit/Source/platform/heap/Member.h
+++ b/third_party/WebKit/Source/platform/heap/Member.h
@@ -13,7 +13,7 @@
 #include "platform/wtf/HashTraits.h"
 
 namespace WTF {
-template <typename P, typename Allocator>
+template <typename P, typename Traits, typename Allocator>
 class ConstructTraits;
 }  // namespace WTF
 
@@ -268,7 +268,7 @@
 #endif  // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING)
   }
 
-  template <typename P, typename Allocator>
+  template <typename P, typename Traits, typename Allocator>
   friend class WTF::ConstructTraits;
 };
 
@@ -582,8 +582,8 @@
   static const bool value = true;
 };
 
-template <typename T, typename Allocator>
-class ConstructTraits<blink::Member<T>, Allocator> {
+template <typename T, typename Traits, typename Allocator>
+class ConstructTraits<blink::Member<T>, Traits, Allocator> {
   STATIC_ONLY(ConstructTraits);
 
  public:
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.cpp b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.cpp
index 66ce5af..156a779 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.cpp
@@ -93,7 +93,8 @@
 void FetchContext::DispatchDidFinishLoading(unsigned long,
                                             double,
                                             int64_t,
-                                            int64_t) {}
+                                            int64_t,
+                                            bool) {}
 
 void FetchContext::DispatchDidFail(unsigned long,
                                    const ResourceError&,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
index 3aa3a83..a1b748d1 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
@@ -151,7 +151,8 @@
   virtual void DispatchDidFinishLoading(unsigned long identifier,
                                         double finish_time,
                                         int64_t encoded_data_length,
-                                        int64_t decoded_body_length);
+                                        int64_t decoded_body_length,
+                                        bool blocked_cross_site_document);
   virtual void DispatchDidFail(unsigned long identifier,
                                const ResourceError&,
                                int64_t encoded_data_length,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
index dc04eab..7dd62ea 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -384,7 +384,7 @@
   }
 
   Context().DispatchDidFinishLoading(
-      identifier, 0, 0, resource->GetResponse().DecodedBodyLength());
+      identifier, 0, 0, resource->GetResponse().DecodedBodyLength(), false);
 }
 
 static std::unique_ptr<TracedValue> UrlForTraceEvent(const KURL& url) {
@@ -1361,7 +1361,8 @@
 void ResourceFetcher::HandleLoaderFinish(Resource* resource,
                                          double finish_time,
                                          LoaderFinishType type,
-                                         uint32_t inflight_keepalive_bytes) {
+                                         uint32_t inflight_keepalive_bytes,
+                                         bool blocked_cross_site_document) {
   DCHECK(resource);
 
   DCHECK_LE(inflight_keepalive_bytes, inflight_keepalive_bytes_);
@@ -1416,7 +1417,7 @@
   resource->VirtualTimePauser().PauseVirtualTime(false);
   Context().DispatchDidFinishLoading(
       resource->Identifier(), finish_time, encoded_data_length,
-      resource->GetResponse().DecodedBodyLength());
+      resource->GetResponse().DecodedBodyLength(), blocked_cross_site_document);
 
   if (type == kDidFinishLoading)
     resource->Finish(finish_time, Context().GetLoadingTaskRunner().get());
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h
index 8d09171..0643df6 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.h
@@ -132,7 +132,8 @@
   void HandleLoaderFinish(Resource*,
                           double finish_time,
                           LoaderFinishType,
-                          uint32_t inflight_keepalive_bytes);
+                          uint32_t inflight_keepalive_bytes,
+                          bool blocked_cross_site_document);
   void HandleLoaderError(Resource*,
                          const ResourceError&,
                          uint32_t inflight_keepalive_bytes);
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
index 6759023b..3d9ac694 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
@@ -188,7 +188,7 @@
       fetcher->GetNavigationTimingInfo();
   ASSERT_TRUE(navigation_timing_info);
   long long encoded_data_length = 123;
-  resource->Loader()->DidFinishLoading(0.0, encoded_data_length, 0, 0);
+  resource->Loader()->DidFinishLoading(0.0, encoded_data_length, 0, 0, false);
   EXPECT_EQ(navigation_timing_info->TransferSize(), encoded_data_length);
 
   // When there are redirects.
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
index 1b4b053..154f787 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
@@ -629,14 +629,16 @@
       resource_->Identifier(),
       network_instrumentation::RequestOutcome::kSuccess);
 
-  fetcher_->HandleLoaderFinish(
-      resource_.Get(), 0, ResourceFetcher::kDidFinishFirstPartInMultipart, 0);
+  fetcher_->HandleLoaderFinish(resource_.Get(), 0,
+                               ResourceFetcher::kDidFinishFirstPartInMultipart,
+                               0, false);
 }
 
 void ResourceLoader::DidFinishLoading(double finish_time,
                                       int64_t encoded_data_length,
                                       int64_t encoded_body_length,
-                                      int64_t decoded_body_length) {
+                                      int64_t decoded_body_length,
+                                      bool blocked_cross_site_document) {
   resource_->SetEncodedDataLength(encoded_data_length);
   resource_->SetEncodedBodyLength(encoded_body_length);
   resource_->SetDecodedBodyLength(decoded_body_length);
@@ -650,9 +652,9 @@
       resource_->Identifier(),
       network_instrumentation::RequestOutcome::kSuccess);
 
-  fetcher_->HandleLoaderFinish(resource_.Get(), finish_time,
-                               ResourceFetcher::kDidFinishLoading,
-                               inflight_keepalive_bytes_);
+  fetcher_->HandleLoaderFinish(
+      resource_.Get(), finish_time, ResourceFetcher::kDidFinishLoading,
+      inflight_keepalive_bytes_, blocked_cross_site_document);
 }
 
 void ResourceLoader::DidFail(const WebURLError& error,
@@ -729,7 +731,7 @@
     resource_->SetResourceBuffer(data_out);
   }
   DidFinishLoading(CurrentTimeTicksInSeconds(), encoded_data_length,
-                   encoded_body_length, decoded_body_length);
+                   encoded_body_length, decoded_body_length, false);
 }
 
 void ResourceLoader::Dispose() {
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h
index 5385610..2ce0c68a 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.h
@@ -117,7 +117,8 @@
   void DidFinishLoading(double finish_time,
                         int64_t encoded_data_length,
                         int64_t encoded_body_length,
-                        int64_t decoded_body_length) override;
+                        int64_t decoded_body_length,
+                        bool blocked_cross_site_document) override;
   void DidFail(const WebURLError&,
                int64_t encoded_data_length,
                int64_t encoded_body_length,
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index e174f92..714cda7f 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -1002,7 +1002,15 @@
       status: "experimental",
     },
     {
-      name: "StopLoadingInBackgroundAndroid",
+      name: "StopInBackground",
+      status: "test",
+    },
+    {
+      name: "StopLoadingInBackground",
+      status: "test",
+    },
+    {
+      name: "StopNonTimersInBackground",
       status: "test",
     },
     {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
index fdff86d..188abee 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_base.cc
@@ -67,6 +67,12 @@
   task_observer_map_.erase(iter);
 }
 
+scoped_refptr<base::SingleThreadTaskRunner>
+WebThreadBase::GetSingleThreadTaskRunner() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 void WebThreadBase::AddTaskTimeObserver(TaskTimeObserver* task_time_observer) {
   AddTaskTimeObserverInternal(task_time_observer);
 }
@@ -100,7 +106,7 @@
 }
 
 bool WebThreadBase::IsCurrentThread() const {
-  return GetTaskRunner()->BelongsToCurrentThread();
+  return GetSingleThreadTaskRunner()->BelongsToCurrentThread();
 }
 
 namespace {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
index 830779f0..342d0d17 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -107,8 +107,8 @@
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
-WebThreadImplForWorkerScheduler::GetTaskRunner() const {
-  return task_queue_;
+WebThreadImplForWorkerScheduler::GetSingleThreadTaskRunner() const {
+  return web_task_runner_.Get();
 }
 
 SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::GetIdleTaskRunner()
@@ -116,7 +116,8 @@
   return idle_task_runner_.get();
 }
 
-blink::WebTaskRunner* WebThreadImplForWorkerScheduler::GetWebTaskRunner() {
+blink::WebTaskRunner* WebThreadImplForWorkerScheduler::GetWebTaskRunner()
+    const {
   return web_task_runner_.Get();
 }
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
index 1a3a447..6359231 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -39,10 +39,11 @@
   // WebThread implementation.
   WebScheduler* Scheduler() const override;
   PlatformThreadId ThreadId() const override;
-  WebTaskRunner* GetWebTaskRunner() override;
+  WebTaskRunner* GetWebTaskRunner() const override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner()
+      const override;
 
   // WebThreadBase implementation.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override;
   scheduler::SingleThreadIdleTaskRunner* GetIdleTaskRunner() const override;
   void Init() override;
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index 69ad1912..2f28e5d 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -83,7 +83,7 @@
     base::WaitableEvent completion(
         base::WaitableEvent::ResetPolicy::AUTOMATIC,
         base::WaitableEvent::InitialState::NOT_SIGNALED);
-    thread_->GetTaskRunner()->PostTask(
+    thread_->GetSingleThreadTaskRunner()->PostTask(
         from_here,
         base::Bind(&WebThreadImplForWorkerSchedulerTest::RunOnWorkerThreadTask,
                    base::Unretained(this), task, &completion));
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
index 6ee65f4..44bfd51 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -112,6 +112,10 @@
   return "";  // MSVC needs that.
 }
 
+bool StopLoadingInBackgroundEnabled() {
+  return RuntimeEnabledFeatures::StopLoadingInBackgroundEnabled();
+}
+
 }  // namespace
 
 RendererSchedulerImpl::RendererSchedulerImpl(
@@ -528,7 +532,7 @@
   return NewTaskQueue(
       MainThreadTaskQueue::QueueCreationParams(queue_type)
           .SetCanBePaused(true)
-          .SetCanBeStopped(true)
+          .SetCanBeStopped(StopLoadingInBackgroundEnabled())
           .SetCanBeDeferred(true)
           .SetUsedForControlTasks(
               queue_type ==
@@ -1343,7 +1347,7 @@
 
   if (main_thread_only().stopped_when_backgrounded) {
     new_policy.timer_queue_policy().is_stopped = true;
-    if (RuntimeEnabledFeatures::StopLoadingInBackgroundAndroidEnabled())
+    if (StopLoadingInBackgroundEnabled())
       new_policy.loading_queue_policy().is_stopped = true;
   }
   if (main_thread_only().renderer_pause_count != 0) {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
index 1663d197..ef5bead 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -2553,7 +2553,7 @@
 }
 
 TEST_F(RendererSchedulerImplTest, TestRendererBackgroundedLoadingSuspension) {
-  ScopedStopLoadingInBackgroundAndroidForTest stop_loading_enabler(true);
+  ScopedStopLoadingInBackgroundForTest stop_loading_enabler(true);
 
   scheduler_->SetStoppingWhenBackgroundedEnabled(true);
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
index 1e42413..c2dc9ba 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -56,6 +56,10 @@
   }
 }
 
+bool StopNonTimersInBackgroundEnabled() {
+  return RuntimeEnabledFeatures::StopNonTimersInBackgroundEnabled();
+}
+
 }  // namespace
 
 WebFrameSchedulerImpl::ActiveConnectionHandleImpl::ActiveConnectionHandleImpl(
@@ -338,6 +342,7 @@
             MainThreadTaskQueue::QueueType::kFrameThrottleable)
             .SetShouldReportWhenExecutionBlocked(true)
             .SetCanBeDeferred(true)
+            .SetCanBeStopped(StopNonTimersInBackgroundEnabled())
             .SetCanBePaused(true));
     deferrable_task_queue_->SetBlameContext(blame_context_);
     deferrable_task_queue_->SetFrameScheduler(this);
@@ -355,6 +360,7 @@
         MainThreadTaskQueue::QueueCreationParams(
             MainThreadTaskQueue::QueueType::kFramePausable)
             .SetShouldReportWhenExecutionBlocked(true)
+            .SetCanBeStopped(StopNonTimersInBackgroundEnabled())
             .SetCanBePaused(true));
     pausable_task_queue_->SetBlameContext(blame_context_);
     pausable_task_queue_->SetFrameScheduler(this);
@@ -507,7 +513,7 @@
 
 WebFrameScheduler::ThrottlingState
 WebFrameSchedulerImpl::CalculateThrottlingState() const {
-  if (RuntimeEnabledFeatures::StopLoadingInBackgroundAndroidEnabled() &&
+  if (RuntimeEnabledFeatures::StopLoadingInBackgroundEnabled() &&
       page_stopped_) {
     DCHECK(!page_visible_);
     return WebFrameScheduler::ThrottlingState::kStopped;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
index 242efd14..629b857 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc
@@ -34,7 +34,7 @@
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
-WebThreadImplForRendererScheduler::GetTaskRunner() const {
+WebThreadImplForRendererScheduler::GetSingleThreadTaskRunner() const {
   return task_runner_;
 }
 
@@ -43,7 +43,8 @@
   return idle_task_runner_.get();
 }
 
-blink::WebTaskRunner* WebThreadImplForRendererScheduler::GetWebTaskRunner() {
+blink::WebTaskRunner* WebThreadImplForRendererScheduler::GetWebTaskRunner()
+    const {
   return web_task_runner_.get();
 }
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
index 6a1d860..c5525c0 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h
@@ -28,10 +28,11 @@
   // WebThread implementation.
   WebScheduler* Scheduler() const override;
   PlatformThreadId ThreadId() const override;
-  WebTaskRunner* GetWebTaskRunner() override;
+  WebTaskRunner* GetWebTaskRunner() const override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner()
+      const override;
 
   // WebThreadBase implementation.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override;
   SingleThreadIdleTaskRunner* GetIdleTaskRunner() const override;
   void Init() override;
 
diff --git a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.cc b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.cc
index a5db34f..177f420c 100644
--- a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.cc
+++ b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.cc
@@ -25,7 +25,7 @@
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
-WebThreadImplForUtilityThread::GetTaskRunner() const {
+WebThreadImplForUtilityThread::GetSingleThreadTaskRunner() const {
   return task_runner_;
 }
 
diff --git a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h
index 02b413d..79a08f9 100644
--- a/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h
+++ b/third_party/WebKit/Source/platform/scheduler/utility/webthread_impl_for_utility_thread.h
@@ -22,9 +22,10 @@
   // WebThread implementation.
   WebScheduler* Scheduler() const override;
   PlatformThreadId ThreadId() const override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner()
+      const override;
 
   // WebThreadBase implementation.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override;
   scheduler::SingleThreadIdleTaskRunner* GetIdleTaskRunner() const override;
   void Init() override;
 
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
index 9742b02..4cb64cd 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
@@ -68,7 +68,7 @@
                                                    base::Thread::Options());
   thread->Init();
   WaitableEvent event;
-  thread->GetTaskRunner()->PostTask(
+  thread->GetSingleThreadTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(PrepareCurrentThread, base::Unretained(&event),
                                 base::Unretained(thread.get())));
   event.Wait();
diff --git a/third_party/WebKit/Source/platform/wtf/ConstructTraits.h b/third_party/WebKit/Source/platform/wtf/ConstructTraits.h
index 556705b..e3a3bad 100644
--- a/third_party/WebKit/Source/platform/wtf/ConstructTraits.h
+++ b/third_party/WebKit/Source/platform/wtf/ConstructTraits.h
@@ -14,7 +14,7 @@
 // ConstructTraits is used to construct elements in WTF collections. All
 // in-place constructions that may assign Oilpan objects must be dispatched
 // through ConstructAndNotifyElement.
-template <typename T, typename Allocator>
+template <typename T, typename Traits, typename Allocator>
 class ConstructTraits {
   STATIC_ONLY(ConstructTraits);
 
@@ -24,14 +24,14 @@
   template <typename... Args>
   static T* ConstructAndNotifyElement(void* location, Args&&... args) {
     T* object = new (NotNull, location) T(std::forward<Args>(args)...);
-    Allocator::template NotifyNewObject<T, VectorTraits<T>>(object);
+    Allocator::template NotifyNewObject<T, Traits>(object);
     return object;
   }
 
   // After constructing elements using memcopy or memmove (or similar)
   // |NotifyNewElements| needs to be called to propagate that information.
   static void NotifyNewElements(T* array, size_t len) {
-    Allocator::template NotifyNewObjects<T, VectorTraits<T>>(array, len);
+    Allocator::template NotifyNewObjects<T, Traits>(array, len);
   }
 };
 
diff --git a/third_party/WebKit/Source/platform/wtf/Deque.h b/third_party/WebKit/Source/platform/wtf/Deque.h
index cad6e69..b8f158c 100644
--- a/third_party/WebKit/Source/platform/wtf/Deque.h
+++ b/third_party/WebKit/Source/platform/wtf/Deque.h
@@ -499,7 +499,7 @@
     end_ = 0;
   else
     ++end_;
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       new_element, std::forward<U>(value));
 }
 
@@ -511,7 +511,7 @@
     start_ = buffer_.capacity() - 1;
   else
     --start_;
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       &buffer_.Buffer()[start_], std::forward<U>(value));
 }
 
@@ -524,7 +524,7 @@
     end_ = 0;
   else
     ++end_;
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       new_element, std::forward<Args>(args)...);
 }
 
@@ -536,7 +536,7 @@
     start_ = buffer_.capacity() - 1;
   else
     --start_;
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       &buffer_.Buffer()[start_], std::forward<Args>(args)...);
 }
 
diff --git a/third_party/WebKit/Source/platform/wtf/HashMap.h b/third_party/WebKit/Source/platform/wtf/HashMap.h
index fad82873..b014528 100644
--- a/third_party/WebKit/Source/platform/wtf/HashMap.h
+++ b/third_party/WebKit/Source/platform/wtf/HashMap.h
@@ -21,9 +21,10 @@
 #ifndef WTF_HashMap_h
 #define WTF_HashMap_h
 
+#include <initializer_list>
+#include "platform/wtf/ConstructTraits.h"
 #include "platform/wtf/HashTable.h"
 #include "platform/wtf/allocator/PartitionAllocator.h"
-#include <initializer_list>
 
 namespace WTF {
 
@@ -310,7 +311,7 @@
   }
 };
 
-template <typename ValueTraits, typename HashFunctions>
+template <typename ValueTraits, typename HashFunctions, typename Allocator>
 struct HashMapTranslator {
   STATIC_ONLY(HashMapTranslator);
   template <typename T>
@@ -523,12 +524,13 @@
           typename V,
           typename W,
           typename X,
-          typename Y>
+          typename Allocator>
 template <typename IncomingKeyType, typename IncomingMappedType>
-typename HashMap<T, U, V, W, X, Y>::AddResult
-HashMap<T, U, V, W, X, Y>::InlineAdd(IncomingKeyType&& key,
-                                     IncomingMappedType&& mapped) {
-  return impl_.template insert<HashMapTranslator<ValueTraits, HashFunctions>>(
+typename HashMap<T, U, V, W, X, Allocator>::AddResult
+HashMap<T, U, V, W, X, Allocator>::InlineAdd(IncomingKeyType&& key,
+                                             IncomingMappedType&& mapped) {
+  return impl_.template insert<
+      HashMapTranslator<ValueTraits, HashFunctions, Allocator>>(
       std::forward<IncomingKeyType>(key),
       std::forward<IncomingMappedType>(mapped));
 }
diff --git a/third_party/WebKit/Source/platform/wtf/HashTable.h b/third_party/WebKit/Source/platform/wtf/HashTable.h
index 855ea16..cc6bd7f 100644
--- a/third_party/WebKit/Source/platform/wtf/HashTable.h
+++ b/third_party/WebKit/Source/platform/wtf/HashTable.h
@@ -523,29 +523,32 @@
 
 using std::swap;
 
-template <typename T, typename Allocator, bool enterGCForbiddenScope>
+template <typename T,
+          typename Allocator,
+          typename Traits,
+          bool enterGCForbiddenScope>
 struct Mover {
   STATIC_ONLY(Mover);
   static void Move(T&& from, T& to) {
     to.~T();
-    ConstructTraits<T, Allocator>::ConstructAndNotifyElement(&to,
-                                                             std::move(from));
+    ConstructTraits<T, Traits, Allocator>::ConstructAndNotifyElement(
+        &to, std::move(from));
   }
 };
 
-template <typename T, typename Allocator>
-struct Mover<T, Allocator, true> {
+template <typename T, typename Allocator, typename Traits>
+struct Mover<T, Allocator, Traits, true> {
   STATIC_ONLY(Mover);
   static void Move(T&& from, T& to) {
     to.~T();
     Allocator::EnterGCForbiddenScope();
-    ConstructTraits<T, Allocator>::ConstructAndNotifyElement(&to,
-                                                             std::move(from));
+    ConstructTraits<T, Traits, Allocator>::ConstructAndNotifyElement(
+        &to, std::move(from));
     Allocator::LeaveGCForbiddenScope();
   }
 };
 
-template <typename HashFunctions, typename Allocator>
+template <typename HashFunctions, typename Traits, typename Allocator>
 class IdentityHashTranslator {
   STATIC_ONLY(IdentityHashTranslator);
 
@@ -561,7 +564,7 @@
   template <typename T, typename U, typename V>
   static void Translate(T& location, U&&, V&& value) {
     location = std::forward<V>(value);
-    ConstructTraits<T, Allocator>::NotifyNewElements(&location, 1);
+    ConstructTraits<T, Traits, Allocator>::NotifyNewElements(&location, 1);
   }
 };
 
@@ -685,7 +688,7 @@
   typedef Value ValueType;
   typedef Extractor ExtractorType;
   typedef KeyTraits KeyTraitsType;
-  typedef IdentityHashTranslator<HashFunctions, Allocator>
+  typedef IdentityHashTranslator<HashFunctions, Traits, Allocator>
       IdentityTranslatorType;
   typedef HashTableAddResult<HashTable, ValueType> AddResult;
 
@@ -1199,7 +1202,7 @@
   STATIC_ONLY(HashTableBucketInitializer);
   template <typename Traits, typename Allocator, typename Value>
   static void Initialize(Value& bucket) {
-    ConstructTraits<Value, Allocator>::ConstructAndNotifyElement(
+    ConstructTraits<Value, Traits, Allocator>::ConstructAndNotifyElement(
         &bucket, Traits::EmptyValue());
   }
 };
@@ -1398,7 +1401,7 @@
   ++stats_->numReinserts;
 #endif
   Value* new_entry = LookupForWriting(Extractor::Extract(entry)).first;
-  Mover<ValueType, Allocator,
+  Mover<ValueType, Allocator, Traits,
         Traits::template NeedsToForbidGCOnMove<>::value>::Move(std::move(entry),
                                                                *new_entry);
 
@@ -1682,7 +1685,7 @@
         InitializeBucket(temporary_table[i]);
       }
     } else {
-      Mover<ValueType, Allocator,
+      Mover<ValueType, Allocator, Traits,
             Traits::template NeedsToForbidGCOnMove<>::value>::
           Move(std::move(table_[i]), temporary_table[i]);
       table_[i].~ValueType();
@@ -1917,12 +1920,12 @@
 #endif
 
   if (table_) {
-    ConstructTraits<ValueType, Allocator>::NotifyNewElements(table_,
-                                                             table_size_);
+    ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(
+        table_, table_size_);
   }
   if (other.table_) {
-    ConstructTraits<ValueType, Allocator>::NotifyNewElements(other.table_,
-                                                             other.table_size_);
+    ConstructTraits<ValueType, Traits, Allocator>::NotifyNewElements(
+        other.table_, other.table_size_);
   }
 }
 
diff --git a/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h b/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
index b663c371..a0e239e 100644
--- a/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
+++ b/third_party/WebKit/Source/platform/wtf/TerminatedArrayBuilder.h
@@ -45,7 +45,8 @@
     CHECK_LT(count_, capacity_);
     DCHECK(!item.IsLastInArray());
     array_->at(count_++) = item;
-    ConstructTraits<T, typename ArrayType<T>::Allocator::BackendAllocator>::
+    ConstructTraits<T, VectorTraits<T>,
+                    typename ArrayType<T>::Allocator::BackendAllocator>::
         NotifyNewElements(&array_->at(count_ - 1), 1);
     if (count_ == capacity_)
       array_->at(capacity_ - 1).SetLastInArray(true);
diff --git a/third_party/WebKit/Source/platform/wtf/Vector.h b/third_party/WebKit/Source/platform/wtf/Vector.h
index c844238..c8a7677 100644
--- a/third_party/WebKit/Source/platform/wtf/Vector.h
+++ b/third_party/WebKit/Source/platform/wtf/Vector.h
@@ -153,8 +153,8 @@
   STATIC_ONLY(VectorMover);
   static void Move(T* src, T* src_end, T* dst) {
     while (src != src_end) {
-      ConstructTraits<T, Allocator>::ConstructAndNotifyElement(dst,
-                                                               std::move(*src));
+      ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
+          dst, std::move(*src));
       src->~T();
       ++dst;
       ++src;
@@ -168,8 +168,10 @@
       while (src != src_end) {
         --src_end;
         --dst_end;
-        ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
-            dst_end, std::move(*src_end));
+        ConstructTraits<T, VectorTraits<T>,
+                        Allocator>::ConstructAndNotifyElement(dst_end,
+                                                              std::move(
+                                                                  *src_end));
         src_end->~T();
       }
     }
@@ -177,8 +179,8 @@
   static void Swap(T* src, T* src_end, T* dst) {
     std::swap_ranges(src, src_end, dst);
     const size_t len = src_end - src;
-    ConstructTraits<T, Allocator>::NotifyNewElements(src, len);
-    ConstructTraits<T, Allocator>::NotifyNewElements(dst, len);
+    ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(src, len);
+    ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(dst, len);
   }
 };
 
@@ -190,7 +192,8 @@
       memcpy(dst, src,
              reinterpret_cast<const char*>(src_end) -
                  reinterpret_cast<const char*>(src));
-      ConstructTraits<T, Allocator>::NotifyNewElements(dst, src_end - src);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+          dst, src_end - src);
     }
   }
   static void MoveOverlapping(const T* src, const T* src_end, T* dst) {
@@ -198,7 +201,8 @@
       memmove(dst, src,
               reinterpret_cast<const char*>(src_end) -
                   reinterpret_cast<const char*>(src));
-      ConstructTraits<T, Allocator>::NotifyNewElements(dst, src_end - src);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+          dst, src_end - src);
     }
   }
   static void Swap(T* src, T* src_end, T* dst) {
@@ -206,8 +210,8 @@
                      reinterpret_cast<char*>(src_end),
                      reinterpret_cast<char*>(dst));
     const size_t len = src_end - src;
-    ConstructTraits<T, Allocator>::NotifyNewElements(src, len);
-    ConstructTraits<T, Allocator>::NotifyNewElements(dst, len);
+    ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(src, len);
+    ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(dst, len);
   }
 };
 
@@ -220,7 +224,8 @@
   template <typename U>
   static void UninitializedCopy(const U* src, const U* src_end, T* dst) {
     while (src != src_end) {
-      ConstructTraits<T, Allocator>::ConstructAndNotifyElement(dst, *src);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
+          dst, *src);
       ++dst;
       ++src;
     }
@@ -235,7 +240,8 @@
       memcpy(dst, src,
              reinterpret_cast<const char*>(src_end) -
                  reinterpret_cast<const char*>(src));
-      ConstructTraits<T, Allocator>::NotifyNewElements(dst, src_end - src);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+          dst, src_end - src);
     }
   }
   template <typename U>
@@ -252,7 +258,8 @@
   STATIC_ONLY(VectorFiller);
   static void UninitializedFill(T* dst, T* dst_end, const T& val) {
     while (dst != dst_end) {
-      ConstructTraits<T, Allocator>::ConstructAndNotifyElement(dst, T(val));
+      ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
+          dst, T(val));
       ++dst;
     }
   }
@@ -534,11 +541,12 @@
     std::swap(capacity_, other.capacity_);
     std::swap(size_, other.size_);
     if (buffer_) {
-      ConstructTraits<T, Allocator>::NotifyNewElements(buffer_, size_);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(buffer_,
+                                                                        size_);
     }
     if (other.buffer_) {
-      ConstructTraits<T, Allocator>::NotifyNewElements(other.buffer_,
-                                                       other.size_);
+      ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+          other.buffer_, other.size_);
     }
   }
 
@@ -686,11 +694,12 @@
       std::swap(capacity_, other.capacity_);
       std::swap(size_, other.size_);
       if (buffer_) {
-        ConstructTraits<T, Allocator>::NotifyNewElements(buffer_, size_);
+        ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+            buffer_, size_);
       }
       if (other.buffer_) {
-        ConstructTraits<T, Allocator>::NotifyNewElements(other.buffer_,
-                                                         other.size_);
+        ConstructTraits<T, VectorTraits<T>, Allocator>::NotifyNewElements(
+            other.buffer_, other.size_);
       }
       return;
     }
@@ -1721,7 +1730,7 @@
   DCHECK(Allocator::IsAllocationAllowed());
   if (LIKELY(size() != capacity())) {
     ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
-    ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+    ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
         end(), std::forward<U>(val));
     ++size_;
     return;
@@ -1739,8 +1748,9 @@
     ExpandCapacity(size() + 1);
 
   ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
-  T* t = ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
-      end(), std::forward<Args>(args)...);
+  T* t =
+      ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
+          end(), std::forward<Args>(args)...);
   ++size_;
   return *t;
 }
@@ -1774,7 +1784,7 @@
   DCHECK(begin());
 
   ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       end(), std::forward<U>(*ptr));
   ++size_;
 }
@@ -1805,7 +1815,7 @@
   push_back(std::forward<U>(val));
 #else
   DCHECK_LT(size(), capacity());
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       end(), std::forward<U>(val));
   ++size_;
 #endif
@@ -1825,7 +1835,7 @@
   ANNOTATE_CHANGE_SIZE(begin(), capacity(), size_, size_ + 1);
   T* spot = begin() + position;
   TypeOperations::MoveOverlapping(spot, end(), spot + 1);
-  ConstructTraits<T, Allocator>::ConstructAndNotifyElement(
+  ConstructTraits<T, VectorTraits<T>, Allocator>::ConstructAndNotifyElement(
       spot, std::forward<U>(*data));
   ++size_;
 }
diff --git a/third_party/WebKit/common/quota/quota_status_code.h b/third_party/WebKit/common/quota/quota_status_code.h
index efef901..76a1aef 100644
--- a/third_party/WebKit/common/quota/quota_status_code.h
+++ b/third_party/WebKit/common/quota/quota_status_code.h
@@ -7,8 +7,7 @@
 
 namespace blink {
 
-// These values are used by WebStorageQuotaError and need to match
-// dom/ExceptionState.h.
+// These values need to match dom/ExceptionState.h.
 // TODO(sashab): Remove this and use mojom::storage::QuotaStatusCode instead.
 enum class QuotaStatusCode {
   kOk = 0,
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index ab92178b..93fe9be 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -333,7 +333,6 @@
     "platform/WebStorageArea.h",
     "platform/WebStorageNamespace.h",
     "platform/WebStorageQuotaCallbacks.h",
-    "platform/WebStorageQuotaError.h",
     "platform/WebString.h",
     "platform/WebSurfaceLayerBridge.h",
     "platform/WebTextInputInfo.h",
diff --git a/third_party/WebKit/public/platform/WebLocalizedString.h b/third_party/WebKit/public/platform/WebLocalizedString.h
index e3870a4..e40d6508 100644
--- a/third_party/WebKit/public/platform/WebLocalizedString.h
+++ b/third_party/WebKit/public/platform/WebLocalizedString.h
@@ -109,6 +109,7 @@
     kOverflowMenuPlay,
     kOverflowMenuPause,
     kOverflowMenuDownload,
+    kOverflowMenuPictureInPicture,
     // kPlaceholderForDayOfMonthField is for day placeholder text, e.g.
     // "dd", for date field used in multiple fields "date", "datetime", and
     // "datetime-local" input UI instead of "--".
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
index a76b897..9b5a573 100644
--- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -183,7 +183,9 @@
   BLINK_PLATFORM_EXPORT static void EnableV8ContextSnapshot(bool);
   BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool);
   BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool);
-  BLINK_PLATFORM_EXPORT static void EnableStopLoadingInBackgroundAndroid(bool);
+  BLINK_PLATFORM_EXPORT static void EnableStopInBackground(bool);
+  BLINK_PLATFORM_EXPORT static void EnableStopLoadingInBackground(bool);
+  BLINK_PLATFORM_EXPORT static void EnableStopNonTimersInBackground(bool);
   BLINK_PLATFORM_EXPORT static void EnablePWAFullCodeCache(bool);
   BLINK_PLATFORM_EXPORT static void EnableDoubleTapToJumpOnVideo(bool);
 
diff --git a/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h b/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
index f73dab2..69a26c23 100644
--- a/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
+++ b/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
@@ -33,7 +33,7 @@
 
 #include "WebCommon.h"
 #include "WebPrivatePtr.h"
-#include "WebStorageQuotaError.h"
+#include "third_party/WebKit/common/quota/quota_status_code.h"
 
 namespace blink {
 
@@ -67,7 +67,7 @@
       unsigned long long usage_in_bytes,
       unsigned long long granted_quota_in_bytes);
 
-  BLINK_PLATFORM_EXPORT void DidFail(WebStorageQuotaError);
+  BLINK_PLATFORM_EXPORT void DidFail(QuotaStatusCode);
 
  private:
   WebPrivatePtr<StorageQuotaCallbacks> private_;
diff --git a/third_party/WebKit/public/platform/WebStorageQuotaError.h b/third_party/WebKit/public/platform/WebStorageQuotaError.h
deleted file mode 100644
index 47080799..0000000
--- a/third_party/WebKit/public/platform/WebStorageQuotaError.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebStorageQuotaError_h
-#define WebStorageQuotaError_h
-
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-
-namespace blink {
-
-// The error code used for WebStorageQuota. Values must match QuotaStatusCode.
-// TODO(sashab): Remove this class and update callers to use
-// blink::QuotaStatusCode instead.
-enum WebStorageQuotaError {
-  kWebStorageQuotaErrorNotSupported = 7,
-  kWebStorageQuotaErrorInvalidModification = 11,
-  kWebStorageQuotaErrorInvalidAccess = 13,
-  kWebStorageQuotaErrorAbort = 17,
-};
-
-static_assert(
-    static_cast<int>(kWebStorageQuotaErrorNotSupported) ==
-        static_cast<int>(QuotaStatusCode::kErrorNotSupported),
-    "WebStorageQuotaError and QuotaStatusCode enum values must match");
-static_assert(
-    static_cast<int>(kWebStorageQuotaErrorInvalidModification) ==
-        static_cast<int>(QuotaStatusCode::kErrorInvalidModification),
-    "WebStorageQuotaError and QuotaStatusCode enum values must match");
-static_assert(
-    static_cast<int>(kWebStorageQuotaErrorInvalidAccess) ==
-        static_cast<int>(QuotaStatusCode::kErrorInvalidAccess),
-    "WebStorageQuotaError and QuotaStatusCode enum values must match");
-static_assert(
-    static_cast<int>(kWebStorageQuotaErrorAbort) ==
-        static_cast<int>(QuotaStatusCode::kErrorAbort),
-    "WebStorageQuotaError and QuotaStatusCode enum values must match");
-
-}  // namespace blink
-
-#endif  // WebStorageQuotaError_h
diff --git a/third_party/WebKit/public/platform/WebThread.h b/third_party/WebKit/public/platform/WebThread.h
index 8fb35d6c..c983c13a 100644
--- a/third_party/WebKit/public/platform/WebThread.h
+++ b/third_party/WebKit/public/platform/WebThread.h
@@ -69,8 +69,9 @@
   // Default scheduler task queue does not give scheduler enough freedom to
   // manage task priorities and should not be used.
   // Use TaskRunnerHelper::Get instead (crbug.com/624696).
-  virtual WebTaskRunner* GetWebTaskRunner() { return nullptr; }
-  scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner();
+  virtual WebTaskRunner* GetWebTaskRunner() const { return nullptr; }
+  virtual scoped_refptr<base::SingleThreadTaskRunner>
+  GetSingleThreadTaskRunner() const;
 
   virtual bool IsCurrentThread() const = 0;
   virtual PlatformThreadId ThreadId() const { return 0; }
diff --git a/third_party/WebKit/public/platform/WebURLLoaderClient.h b/third_party/WebKit/public/platform/WebURLLoaderClient.h
index 429c84c9..53a2ca5 100644
--- a/third_party/WebKit/public/platform/WebURLLoaderClient.h
+++ b/third_party/WebKit/public/platform/WebURLLoaderClient.h
@@ -99,10 +99,16 @@
 
   // Called when the load completes successfully.
   // |total_encoded_data_length| may be equal to kUnknownEncodedDataLength.
+  // |blocked_cross_site_document| is used to report that cross-site document
+  // request response was blocked from entering renderer. Corresponding message
+  // will be generated in devtools console if this flag is set to true.
+  // TODO(crbug.com/798625): use different callback for subresources
+  // with responses blocked due to document protection.
   virtual void DidFinishLoading(double finish_time,
                                 int64_t total_encoded_data_length,
                                 int64_t total_encoded_body_length,
-                                int64_t total_decoded_body_length) {}
+                                int64_t total_decoded_body_length,
+                                bool blocked_cross_site_document) {}
 
   // Called when the load completes with an error.
   // |total_encoded_data_length| may be equal to kUnknownEncodedDataLength.
diff --git a/third_party/WebKit/public/platform/scheduler/child/webthread_base.h b/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
index 4fcb76c2..3720b65 100644
--- a/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
+++ b/third_party/WebKit/public/platform/scheduler/child/webthread_base.h
@@ -47,7 +47,8 @@
 
   // Returns the base::Bind-compatible task runner for posting tasks to this
   // thread. Can be called from any thread.
-  virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const = 0;
+  virtual scoped_refptr<base::SingleThreadTaskRunner>
+  GetSingleThreadTaskRunner() const override;
 
   // Returns the base::Bind-compatible task runner for posting idle tasks to
   // this thread. Can be called from any thread.
diff --git a/tools/binary_size/libsupersize/demangle.py b/tools/binary_size/libsupersize/demangle.py
index e1280765..748bf7b3 100644
--- a/tools/binary_size/libsupersize/demangle.py
+++ b/tools/binary_size/libsupersize/demangle.py
@@ -16,7 +16,12 @@
                           stdin=subprocess.PIPE, stdout=subprocess.PIPE)
   stdout = proc.communicate('\n'.join(names))[0]
   assert proc.returncode == 0
-  return stdout.splitlines()
+  ret = stdout.splitlines()
+  if logging.getLogger().isEnabledFor(logging.INFO):
+    fail_count = sum(1 for s in ret if s.startswith('_Z'))
+    if fail_count:
+      logging.info('* Failed to demangle %d/%d items', fail_count, len(ret))
+  return ret
 
 
 def DemangleRemainingSymbols(raw_symbols, tool_prefix):
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8e14e159..6362cc2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -18290,6 +18290,9 @@
   <int value="9" label="RecordHistogramSnapshotsFromSource"/>
   <int value="10" label="ProvideIndependentMetrics"/>
   <int value="11" label="ScheduleSourcesCheck Failed"/>
+  <int value="12" label="Old DeleteFile Failed"/>
+  <int value="13" label="Over DeleteFile Failed"/>
+  <int value="14" label="Async DeleteFile Failed"/>
 </enum>
 
 <enum name="FileReaderSyncWorkerType">
@@ -24955,6 +24958,7 @@
   <int value="-1490298774" label="enable-captive-portal-bypass-proxy-option"/>
   <int value="-1488744539" label="QuickUnlockFingerprint:enabled"/>
   <int value="-1487243228" label="NewUsbBackend:disabled"/>
+  <int value="-1482730792" label="stop-in-background:enabled"/>
   <int value="-1482685863" label="enable-request-tablet-site"/>
   <int value="-1480926949" label="MaterialDesignBookmarks:enabled"/>
   <int value="-1480866718" label="ash-disable-login-dim-and-blur"/>
@@ -24985,6 +24989,7 @@
   <int value="-1433087548" label="enable-app-install-alerts"/>
   <int value="-1431563697" label="WebPaymentsMethodSectionOrderV2:enabled"/>
   <int value="-1426817842" label="BlockTabUnders:enabled"/>
+  <int value="-1426150007" label="ignore-previews-blacklist"/>
   <int value="-1426034869" label="NoCreditCardAbort:enabled"/>
   <int value="-1419788257" label="enable-experimental-hotwording"/>
   <int value="-1417122729"
@@ -26180,6 +26185,7 @@
   <int value="1827369558" label="AndroidPayIntegrationV1:disabled"/>
   <int value="1828660283" label="enable-webfonts-intervention-trigger"/>
   <int value="1830460973" label="disable-network-settings-config"/>
+  <int value="1831593339" label="stop-in-background:disabled"/>
   <int value="1831835753" label="MaterialDesignIncognitoNTP:enabled"/>
   <int value="1835523483" label="OmniboxUIExperimentSwapTitleAndUrl:enabled"/>
   <int value="1838990777" label="V8Future:enabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 22a7cbc0..712a99e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -42948,6 +42948,31 @@
   </summary>
 </histogram>
 
+<histogram name="Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup"
+    enum="CTComplianceStatus">
+  <owner>estark@chromium.org</owner>
+  <summary>
+    Sites can send an Expect-CT header to Chrome to indicate that they intend
+    their sites to comply with Chrome's Certificate Transparency policy. This
+    histogram is recorded on connection setup, whenever Chrome connects to an
+    Expect-CT site using a publicly trusted root. The histogram records the CT
+    policy compliance status of the connection.
+  </summary>
+</histogram>
+
+<histogram name="Net.ExpectCTHeader.PolicyComplianceOnHeaderProcessing"
+    enum="CTComplianceStatus">
+  <owner>estark@chromium.org</owner>
+  <summary>
+    Sites can send an Expect-CT header to Chrome to indicate that they intend
+    their sites to comply with Chrome's Certificate Transparency policy. This
+    histogram is recorded whenever an Expect-CT header is successfully parsed on
+    a connection that chains to a publicly trusted root. The histogram records
+    the CT policy compliance status of the connection on which the header was
+    received.
+  </summary>
+</histogram>
+
 <histogram name="Net.ExpectCTHeaderResult" enum="ExpectCTHeaderResult">
   <obsolete>
     Deprecated 04/2017.
@@ -48147,7 +48172,9 @@
 </histogram>
 
 <histogram name="Net.URLRequestContext.OutstandingRequests" units="count">
-  <owner>xunjieli@chromium.org</owner>
+  <obsolete>
+    Deprecated 1/1/2018. No longer tracked.
+  </obsolete>
   <summary>
     Indicates the number of URLRequests that are handed out by a
     URLRequestContext and are not yet destroyed.
@@ -48156,7 +48183,9 @@
 
 <histogram name="Net.URLRequestContext.OutstandingRequests.Type"
     enum="URLRequestAnnotationType">
-  <owner>xunjieli@chromium.org</owner>
+  <obsolete>
+    Deprecated 1/1/2018. No longer tracked.
+  </obsolete>
   <summary>
     Records the annotation type of the URLRequest that is handed out by a
     URLRequestContext when Net.URLRequestContext.OutstandingRequests is
@@ -104032,6 +104061,9 @@
   <suffix name="MuteButton" label="Mute button"/>
   <suffix name="MuteOverflowButton" label="Mute overflow button"/>
   <suffix name="OverflowButton" label="Overflow button"/>
+  <suffix name="PictureInPictureButton" label="Picture in picture button"/>
+  <suffix name="PictureInPictureOverflowButton"
+      label="Picture in picture overflow button"/>
   <suffix name="PlayOverlayButton" label="Play overlay button"/>
   <suffix name="PlayPauseButton" label="Play/pause button"/>
   <suffix name="PlayPauseOverflowButton" label="Play/pause overflow button"/>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 59e72573..bd19245 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -221,7 +221,7 @@
 crbug.com/780779 [ Nexus_5 ] system_health.memory_mobile/browse:social:facebook [ Skip ]
 crbug.com/738854 [ Nexus_5X ] system_health.memory_mobile/load:tools:drive [ Skip ]
 crbug.com/738854 [ Android_Webview ] system_health.memory_mobile/load:tools:drive [ Skip ]
-crbug.com/797261 [ Android_Webview ] system_health.common_mobile/load:games:spychase [ Skip ]
+crbug.com/797261 [ Android_Webview ] system_health.memory_mobile/load:games:spychase [ Skip ]
 
 # Benchmark: tab_switching.typical_25
 crbug.com/747026 [ Mac ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ]
diff --git a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
index 1e26f2c..d4ae219 100644
--- a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
+++ b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
@@ -21,7 +21,7 @@
  public:
   bool IsCurrentThread() const override { return true; }
   blink::WebScheduler* Scheduler() const override { return nullptr; }
-  blink::WebTaskRunner* GetWebTaskRunner() override { return nullptr; }
+  blink::WebTaskRunner* GetWebTaskRunner() const override { return nullptr; }
 };
 
 class SnapshotPlatform final : public blink::Platform {
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn
index 43756d3..0499533 100644
--- a/ui/app_list/BUILD.gn
+++ b/ui/app_list/BUILD.gn
@@ -38,9 +38,6 @@
     "search_controller.h",
     "search_provider.cc",
     "search_provider.h",
-    "speech_ui_model.cc",
-    "speech_ui_model.h",
-    "speech_ui_model_observer.h",
     "views/app_list_drag_and_drop_host.h",
     "views/app_list_folder_view.cc",
     "views/app_list_folder_view.h",
@@ -142,6 +139,7 @@
   public_deps = [
     "//ash/app_list/model:app_list_model",
     "//ash/app_list/model:search_model",
+    "//ash/app_list/model:speech_ui_model",
   ]
 }
 
diff --git a/ui/app_list/search_controller.h b/ui/app_list/search_controller.h
index 80242920..f308fc23 100644
--- a/ui/app_list/search_controller.h
+++ b/ui/app_list/search_controller.h
@@ -11,10 +11,10 @@
 #include <vector>
 
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "ui/app_list/app_list_export.h"
 #include "ui/app_list/search/mixer.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 
 namespace app_list {
 
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h
index 28d2658..91ba720 100644
--- a/ui/app_list/test/app_list_test_view_delegate.h
+++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -13,11 +13,11 @@
 #include <vector>
 
 #include "ash/app_list/model/search/search_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/callback_forward.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "ui/app_list/app_list_view_delegate.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/app_list/test/app_list_test_model.h"
 
 namespace app_list {
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 9aec45d..5344d96a 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
@@ -24,7 +25,6 @@
 #include "ui/app_list/app_list_features.h"
 #include "ui/app_list/app_list_util.h"
 #include "ui/app_list/app_list_view_delegate.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/app_list/views/app_list_folder_view.h"
 #include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/apps_container_view.h"
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h
index 9a365217..b6461d8 100644
--- a/ui/app_list/views/app_list_view.h
+++ b/ui/app_list/views/app_list_view.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "ash/app_list/model/app_list_view_state.h"
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/scoped_observer.h"
@@ -16,7 +17,6 @@
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_export.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 #include "ui/display/display_observer.h"
 #include "ui/views/bubble/bubble_dialog_delegate.h"
 #include "ui/views/widget/widget.h"
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc
index 259297b..c209fd9c 100644
--- a/ui/app_list/views/search_box_view.cc
+++ b/ui/app_list/views/search_box_view.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "ash/app_list/model/search/search_box_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "build/build_config.h"
@@ -19,7 +20,6 @@
 #include "ui/app_list/app_list_util.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/resources/grit/app_list_resources.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/app_list/vector_icons/vector_icons.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/app_list/views/contents_view.h"
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h
index 31be1bf2..6387de30 100644
--- a/ui/app_list/views/search_box_view.h
+++ b/ui/app_list/views/search_box_view.h
@@ -11,10 +11,10 @@
 #include "ash/app_list/model/app_list_model.h"
 #include "ash/app_list/model/search/search_box_model_observer.h"
 #include "ash/app_list/model/search/search_model.h"
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 #include "ui/gfx/shadow_value.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
diff --git a/ui/app_list/views/speech_view.cc b/ui/app_list/views/speech_view.cc
index a2d9772..0edd2efb 100644
--- a/ui/app_list/views/speech_view.cc
+++ b/ui/app_list/views/speech_view.cc
@@ -9,13 +9,13 @@
 #include <limits>
 
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/resources/grit/app_list_resources.h"
-#include "ui/app_list/speech_ui_model.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
diff --git a/ui/app_list/views/speech_view.h b/ui/app_list/views/speech_view.h
index a40de4cc..3f706d48 100644
--- a/ui/app_list/views/speech_view.h
+++ b/ui/app_list/views/speech_view.h
@@ -7,9 +7,9 @@
 
 #include <stdint.h>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "ui/app_list/app_list_export.h"
-#include "ui/app_list/speech_ui_model_observer.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
 
diff --git a/ui/base/base_window.h b/ui/base/base_window.h
index 5ba8480d..f6af762c 100644
--- a/ui/base/base_window.h
+++ b/ui/base/base_window.h
@@ -6,9 +6,19 @@
 #define UI_BASE_BASE_WINDOW_H_
 
 #include "base/compiler_specific.h"
+#include "build/build_config.h"
 #include "ui/base/ui_base_types.h"  // WindowShowState
 #include "ui/gfx/native_widget_types.h"
 
+#if defined(OS_WIN)
+// Names used in this class are also windows.h macros. That the names
+// are the same as in the Windows API is no coincidence but for now we
+// don't want the Windows macros to interfere so we undef them.
+#undef IsMinimized
+#undef IsMaximized
+#undef IsRestored
+#endif  // OS_WIN
+
 namespace gfx {
 class Rect;
 }
diff --git a/ui/webui/resources/js/BUILD.gn b/ui/webui/resources/js/BUILD.gn
index 77876bf..75cf392f 100644
--- a/ui/webui/resources/js/BUILD.gn
+++ b/ui/webui/resources/js/BUILD.gn
@@ -56,6 +56,7 @@
 js_library("load_time_data") {
   deps = [
     ":assert",
+    ":parse_html_subset",
     "//third_party/jstemplate:jstemplate",
   ]
 }