diff --git a/AUTHORS b/AUTHORS
index a8b297c..c82c75f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -225,6 +225,7 @@
 Donna Wu <donna.wu@intel.com>
 Douglas F. Turner <doug.turner@gmail.com>
 Dustin Doloff <doloffd@amazon.com>
+Ebrahim Byagowi <ebrahim@gnu.org>
 Ebrahim Byagowi <ebraminio@gmail.com>
 Eden Wang <nedenwang@tencent.com>
 Eduardo Lima (Etrunko) <eblima@gmail.com>
diff --git a/DEPS b/DEPS
index 2ca7e5b..9ab0e1e 100644
--- a/DEPS
+++ b/DEPS
@@ -106,7 +106,7 @@
   # 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': 'c33acf2ab821e8c36da115ccebf7228784eced9f',
+  'v8_revision': '77fbb59f326019340db3592edacfeaa8024f4e69',
   # 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.
@@ -114,7 +114,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': '86ce210a675952554c1d84c4464b1a992162866c',
+  'angle_revision': '46bcea50feeb22aaeaf09859fd8d3f8ecdd7f478',
   # 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.
@@ -162,7 +162,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': 'c36ea24906979ce68061a752f350f7a2b52d62f8',
+  'catapult_revision': 'b48f5b49150fee6571e073e435926cadb8d50487',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -504,7 +504,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '80ebf9cc82d2c044543630a482a2c61010a2ee91',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ffe9e609259998c874d405c29d5dae2c2f1c9ace',
       'condition': 'checkout_linux',
   },
 
@@ -529,7 +529,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cf4aced37e993525b9e21856c0d1acec682edab1',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0ae14e9aad83c1387df8dd565cce3748fce3dec7',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
index f0fafb61..3155fe8 100644
--- a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
+++ b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
@@ -768,7 +768,6 @@
     method createProcessingInstruction
     method createRange
     method createTextNode
-    method createTouchList
     method createTreeWalker
     method elementFromPoint
     method elementsFromPoint
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index a891e04..92807bc4 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -116,10 +116,12 @@
     "assistant/ui/dialog_plate/dialog_plate.h",
     "assistant/ui/logo_view/base_logo_view.cc",
     "assistant/ui/logo_view/base_logo_view.h",
+    "assistant/ui/main_stage/assistant_text_element_view.cc",
+    "assistant/ui/main_stage/assistant_text_element_view.h",
+    "assistant/ui/main_stage/ui_element_container_view.cc",
+    "assistant/ui/main_stage/ui_element_container_view.h",
     "assistant/ui/suggestion_container_view.cc",
     "assistant/ui/suggestion_container_view.h",
-    "assistant/ui/ui_element_container_view.cc",
-    "assistant/ui/ui_element_container_view.h",
     "autoclick/autoclick_controller.cc",
     "autoclick/autoclick_controller.h",
     "cancel_mode.cc",
@@ -575,6 +577,8 @@
     "system/bluetooth/tray_bluetooth.h",
     "system/bluetooth/tray_bluetooth_helper.cc",
     "system/bluetooth/tray_bluetooth_helper.h",
+    "system/bluetooth/unified_bluetooth_detailed_view_controller.cc",
+    "system/bluetooth/unified_bluetooth_detailed_view_controller.h",
     "system/brightness/brightness_controller_chromeos.cc",
     "system/brightness/brightness_controller_chromeos.h",
     "system/brightness/tray_brightness.cc",
@@ -1071,8 +1075,6 @@
     "wm/native_cursor_manager_ash.h",
     "wm/native_cursor_manager_ash_classic.cc",
     "wm/native_cursor_manager_ash_classic.h",
-    "wm/native_cursor_manager_ash_mus.cc",
-    "wm/native_cursor_manager_ash_mus.h",
     "wm/non_client_frame_controller.cc",
     "wm/non_client_frame_controller.h",
     "wm/overlay_event_filter.cc",
diff --git a/ash/assistant/ui/assistant_bubble_view.cc b/ash/assistant/ui/assistant_bubble_view.cc
index cb7e71f..e56d9c4 100644
--- a/ash/assistant/ui/assistant_bubble_view.cc
+++ b/ash/assistant/ui/assistant_bubble_view.cc
@@ -12,8 +12,8 @@
 #include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/assistant/ui/caption_bar.h"
 #include "ash/assistant/ui/dialog_plate/dialog_plate.h"
+#include "ash/assistant/ui/main_stage/ui_element_container_view.h"
 #include "ash/assistant/ui/suggestion_container_view.h"
-#include "ash/assistant/ui/ui_element_container_view.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/gfx/paint_vector_icon.h"
diff --git a/ash/assistant/ui/assistant_ui_constants.h b/ash/assistant/ui/assistant_ui_constants.h
index 1edb7aa..c84703f 100644
--- a/ash/assistant/ui/assistant_ui_constants.h
+++ b/ash/assistant/ui/assistant_ui_constants.h
@@ -6,6 +6,7 @@
 #define ASH_ASSISTANT_UI_ASSISTANT_UI_CONSTANTS_H_
 
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/color_palette.h"
 
 namespace ash {
 
@@ -15,8 +16,8 @@
 constexpr int kSpacingDip = 8;
 
 // Typography.
-constexpr SkColor kTextColorHint = SkColorSetA(SK_ColorBLACK, 0x42);
-constexpr SkColor kTextColorPrimary = SkColorSetA(SK_ColorBLACK, 0xDE);
+constexpr SkColor kTextColorHint = gfx::kGoogleGrey500;
+constexpr SkColor kTextColorPrimary = gfx::kGoogleGrey900;
 
 }  // namespace ash
 
diff --git a/ash/assistant/ui/main_stage/assistant_text_element_view.cc b/ash/assistant/ui/main_stage/assistant_text_element_view.cc
new file mode 100644
index 0000000..11e91db
--- /dev/null
+++ b/ash/assistant/ui/main_stage/assistant_text_element_view.cc
@@ -0,0 +1,120 @@
+// 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 "ash/assistant/ui/main_stage/assistant_text_element_view.h"
+
+#include "ash/assistant/model/assistant_ui_element.h"
+#include "ash/assistant/ui/assistant_ui_constants.h"
+#include "ash/resources/vector_icons/vector_icons.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+
+namespace ash {
+
+// Appearance.
+constexpr int kIconSizeDip = 32;
+constexpr SkColor kLabelContainerBackgroundColor = SK_ColorWHITE;
+constexpr int kLabelContainerBackgroundCornerRadiusDip = 16;
+constexpr SkColor kLabelContainerBackgroundStrokeColor =
+    SkColorSetA(gfx::kGoogleGrey900, 0x24);
+constexpr int kLabelContainerBackgroundStrokeWidthDip = 1;
+constexpr int kLabelContainerPaddingHorizontalDip = 16;
+constexpr int kLabelContainerPaddingVerticalDip = 6;
+
+namespace {
+
+// LabelContainerBackground ----------------------------------------------------
+
+class LabelContainerBackground : public views::Background {
+ public:
+  LabelContainerBackground() = default;
+
+  ~LabelContainerBackground() override = default;
+
+  // views::Background:
+  void Paint(gfx::Canvas* canvas, views::View* view) const override {
+    cc::PaintFlags flags;
+    flags.setAntiAlias(true);
+
+    gfx::Rect bounds = view->GetContentsBounds();
+
+    // Background.
+    flags.setColor(kLabelContainerBackgroundColor);
+    canvas->DrawRoundRect(bounds, kLabelContainerBackgroundCornerRadiusDip,
+                          flags);
+
+    // Stroke should be drawn within our contents bounds.
+    bounds.Inset(gfx::Insets(kLabelContainerBackgroundStrokeWidthDip));
+
+    // Stroke.
+    flags.setColor(kLabelContainerBackgroundStrokeColor);
+    flags.setStrokeWidth(kLabelContainerBackgroundStrokeWidthDip);
+    flags.setStyle(cc::PaintFlags::Style::kStroke_Style);
+    canvas->DrawRoundRect(bounds, kLabelContainerBackgroundCornerRadiusDip,
+                          flags);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LabelContainerBackground);
+};
+
+}  // namespace
+
+// AssistantTextElementView ----------------------------------------------------
+
+AssistantTextElementView::AssistantTextElementView(
+    const AssistantTextElement* text_element) {
+  InitLayout(text_element);
+}
+
+AssistantTextElementView::~AssistantTextElementView() = default;
+
+void AssistantTextElementView::ChildPreferredSizeChanged(views::View* child) {
+  PreferredSizeChanged();
+}
+
+void AssistantTextElementView::InitLayout(
+    const AssistantTextElement* text_element) {
+  views::BoxLayout* layout_manager =
+      SetLayoutManager(std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
+          2 * kSpacingDip));
+
+  layout_manager->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_START);
+
+  // Icon.
+  views::ImageView* icon = new views::ImageView();
+  icon->SetImage(gfx::CreateVectorIcon(kAssistantIcon, kIconSizeDip));
+  icon->SetImageSize(gfx::Size(kIconSizeDip, kIconSizeDip));
+  icon->SetPreferredSize(gfx::Size(kIconSizeDip, kIconSizeDip));
+  AddChildView(icon);
+
+  // Label Container.
+  views::View* label_container = new views::View();
+  label_container->SetBackground(std::make_unique<LabelContainerBackground>());
+  label_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kHorizontal,
+      gfx::Insets(kLabelContainerPaddingVerticalDip,
+                  kLabelContainerPaddingHorizontalDip)));
+  AddChildView(label_container);
+
+  // Label.
+  views::Label* label =
+      new views::Label(base::UTF8ToUTF16(text_element->text()));
+  label->SetAutoColorReadabilityEnabled(false);
+  label->SetEnabledColor(kTextColorPrimary);
+  label->SetFontList(views::Label::GetDefaultFontList().DeriveWithSizeDelta(4));
+  label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+  label->SetMultiLine(true);
+  label_container->AddChildView(label);
+}
+
+}  // namespace ash
diff --git a/ash/assistant/ui/main_stage/assistant_text_element_view.h b/ash/assistant/ui/main_stage/assistant_text_element_view.h
new file mode 100644
index 0000000..c147642
--- /dev/null
+++ b/ash/assistant/ui/main_stage/assistant_text_element_view.h
@@ -0,0 +1,33 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_TEXT_ELEMENT_VIEW_H_
+#define ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_TEXT_ELEMENT_VIEW_H_
+
+#include "base/macros.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+class AssistantTextElement;
+
+// AssistantTextElementView is the visual representation of an
+// AssistantTextElement. It is a child view of UiElementContainerView.
+class AssistantTextElementView : public views::View {
+ public:
+  explicit AssistantTextElementView(const AssistantTextElement* text_element);
+  ~AssistantTextElementView() override;
+
+  // views::View:
+  void ChildPreferredSizeChanged(views::View* child) override;
+
+ private:
+  void InitLayout(const AssistantTextElement* text_element);
+
+  DISALLOW_COPY_AND_ASSIGN(AssistantTextElementView);
+};
+
+}  // namespace ash
+
+#endif  // ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_TEXT_ELEMENT_VIEW_H_
diff --git a/ash/assistant/ui/ui_element_container_view.cc b/ash/assistant/ui/main_stage/ui_element_container_view.cc
similarity index 73%
rename from ash/assistant/ui/ui_element_container_view.cc
rename to ash/assistant/ui/main_stage/ui_element_container_view.cc
index b553fb2..0df384c 100644
--- a/ash/assistant/ui/ui_element_container_view.cc
+++ b/ash/assistant/ui/main_stage/ui_element_container_view.cc
@@ -2,58 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/assistant/ui/ui_element_container_view.h"
+#include "ash/assistant/ui/main_stage/ui_element_container_view.h"
 
 #include "ash/assistant/assistant_controller.h"
 #include "ash/assistant/model/assistant_ui_element.h"
 #include "ash/assistant/ui/assistant_ui_constants.h"
+#include "ash/assistant/ui/main_stage/assistant_text_element_view.h"
 #include "ash/public/cpp/app_list/answer_card_contents_registry.h"
 #include "base/callback.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/unguessable_token.h"
-#include "ui/gfx/canvas.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 
 namespace ash {
 
-namespace {
-
-// Appearance.
-constexpr SkColor kTextBackgroundColor = SkColorSetARGB(0x8A, 0x42, 0x85, 0xF4);
-constexpr int kTextCornerRadiusDip = 16;
-constexpr int kTextPaddingHorizontalDip = 12;
-constexpr int kTextPaddingVerticalDip = 4;
-
-// RoundRectBackground ---------------------------------------------------------
-
-class RoundRectBackground : public views::Background {
- public:
-  RoundRectBackground(SkColor color, int corner_radius)
-      : color_(color), corner_radius_(corner_radius) {}
-
-  ~RoundRectBackground() override = default;
-
-  // views::Background:
-  void Paint(gfx::Canvas* canvas, views::View* view) const override {
-    cc::PaintFlags flags;
-    flags.setAntiAlias(true);
-    flags.setColor(color_);
-    canvas->DrawRoundRect(view->GetContentsBounds(), corner_radius_, flags);
-  }
-
- private:
-  const SkColor color_;
-  const int corner_radius_;
-
-  DISALLOW_COPY_AND_ASSIGN(RoundRectBackground);
-};
-
-}  // namespace
-
-// UiElementContainerView ------------------------------------------------------
-
 UiElementContainerView::UiElementContainerView(
     AssistantController* assistant_controller)
     : assistant_controller_(assistant_controller),
@@ -170,26 +131,7 @@
     const AssistantTextElement* text_element) {
   DCHECK(!is_processing_ui_element_);
 
-  // Container.
-  views::View* text_container = new views::View();
-  text_container->SetBackground(std::make_unique<RoundRectBackground>(
-      kTextBackgroundColor, kTextCornerRadiusDip));
-  text_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal,
-      gfx::Insets(kTextPaddingVerticalDip, kTextPaddingHorizontalDip)));
-
-  // Label.
-  views::Label* text_view =
-      new views::Label(base::UTF8ToUTF16(text_element->text()));
-  text_view->SetAutoColorReadabilityEnabled(false);
-  text_view->SetEnabledColor(kTextColorPrimary);
-  text_view->SetFontList(text_view->font_list().DeriveWithSizeDelta(4));
-  text_view->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
-  text_view->SetMultiLine(true);
-
-  text_container->AddChildView(text_view);
-  AddChildView(text_container);
-
+  AddChildView(new AssistantTextElementView(text_element));
   PreferredSizeChanged();
 }
 
diff --git a/ash/assistant/ui/ui_element_container_view.h b/ash/assistant/ui/main_stage/ui_element_container_view.h
similarity index 92%
rename from ash/assistant/ui/ui_element_container_view.h
rename to ash/assistant/ui/main_stage/ui_element_container_view.h
index edd218e7..f5f0c46 100644
--- a/ash/assistant/ui/ui_element_container_view.h
+++ b/ash/assistant/ui/main_stage/ui_element_container_view.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 ASH_ASSISTANT_UI_UI_ELEMENT_CONTAINER_VIEW_H_
-#define ASH_ASSISTANT_UI_UI_ELEMENT_CONTAINER_VIEW_H_
+#ifndef ASH_ASSISTANT_UI_MAIN_STAGE_UI_ELEMENT_CONTAINER_VIEW_H_
+#define ASH_ASSISTANT_UI_MAIN_STAGE_UI_ELEMENT_CONTAINER_VIEW_H_
 
 #include <deque>
 #include <memory>
@@ -73,4 +73,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_ASSISTANT_UI_UI_ELEMENT_CONTAINER_VIEW_H_
+#endif  // ASH_ASSISTANT_UI_MAIN_STAGE_UI_ELEMENT_CONTAINER_VIEW_H_
diff --git a/ash/shell.cc b/ash/shell.cc
index 79f46c7..9465855b 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -135,7 +135,6 @@
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/native_cursor_manager_ash_classic.h"
-#include "ash/wm/native_cursor_manager_ash_mus.h"
 #include "ash/wm/overlay_event_filter.h"
 #include "ash/wm/overview/window_selector_controller.h"
 #include "ash/wm/resize_shadow_controller.h"
@@ -1031,10 +1030,9 @@
     native_cursor_manager_ = new NativeCursorManagerAshClassic;
     cursor_manager_ = std::make_unique<CursorManager>(
         base::WrapUnique(native_cursor_manager_));
-  } else if (config == Config::MUS) {
-    native_cursor_manager_ = new NativeCursorManagerAshMus;
-    cursor_manager_ = std::make_unique<CursorManager>(
-        base::WrapUnique(native_cursor_manager_));
+  } else {
+    // TODO(jamescook|estade): Cursor manager for Config::MASH. We might be able
+    // to use most of the classic version after we switch to ws2.
   }
 
   shell_delegate_->PreInit();
diff --git a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc
new file mode 100644
index 0000000..ba4f9e5
--- /dev/null
+++ b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h"
+
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
+#include "ash/system/bluetooth/bluetooth_detailed_view.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "ash/system/unified/unified_detailed_view_delegate.h"
+
+namespace ash {
+
+UnifiedBluetoothDetailedViewController::UnifiedBluetoothDetailedViewController(
+    UnifiedSystemTrayController* tray_controller)
+    : detailed_view_delegate_(
+          std::make_unique<UnifiedDetailedViewDelegate>(tray_controller)) {
+  Shell::Get()->system_tray_notifier()->AddBluetoothObserver(this);
+}
+
+UnifiedBluetoothDetailedViewController::
+    ~UnifiedBluetoothDetailedViewController() {
+  Shell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this);
+}
+
+views::View* UnifiedBluetoothDetailedViewController::CreateView() {
+  DCHECK(!view_);
+  view_ = new tray::BluetoothDetailedView(
+      detailed_view_delegate_.get(),
+      Shell::Get()->session_controller()->login_status());
+  view_->Update();
+  return view_;
+}
+
+void UnifiedBluetoothDetailedViewController::OnBluetoothRefresh() {
+  view_->Update();
+}
+
+void UnifiedBluetoothDetailedViewController::OnBluetoothDiscoveringChanged() {
+  view_->Update();
+}
+
+}  // namespace ash
diff --git a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h
new file mode 100644
index 0000000..cf83c66
--- /dev/null
+++ b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h
@@ -0,0 +1,48 @@
+// 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 ASH_SYSTEM_BLUETOOTH_UNIFIED_BLUETOOTH_DETAILED_VIEW_CONTROLLER_H_
+#define ASH_SYSTEM_BLUETOOTH_UNIFIED_BLUETOOTH_DETAILED_VIEW_CONTROLLER_H_
+
+#include <memory>
+
+#include "ash/system/bluetooth/bluetooth_observer.h"
+#include "ash/system/unified/detailed_view_controller.h"
+#include "base/macros.h"
+
+namespace ash {
+
+namespace tray {
+class BluetoothDetailedView;
+}  // namespace tray
+
+class DetailedViewDelegate;
+class UnifiedSystemTrayController;
+
+// Controller of Bluetooth detailed view in UnifiedSystemTray.
+class UnifiedBluetoothDetailedViewController : public DetailedViewController,
+                                               public BluetoothObserver {
+ public:
+  explicit UnifiedBluetoothDetailedViewController(
+      UnifiedSystemTrayController* tray_controller);
+  ~UnifiedBluetoothDetailedViewController() override;
+
+  // DetailedViewControllerBase:
+  views::View* CreateView() override;
+
+  // BluetoothObserver:
+  void OnBluetoothRefresh() override;
+  void OnBluetoothDiscoveringChanged() override;
+
+ private:
+  const std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_;
+
+  tray::BluetoothDetailedView* view_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedBluetoothDetailedViewController);
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_BLUETOOTH_UNIFIED_BLUETOOTH_DETAILED_VIEW_CONTROLLER_H_
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc
index dd312e0..7ef28e7 100644
--- a/ash/system/status_area_widget.cc
+++ b/ash/system/status_area_widget.cc
@@ -50,12 +50,12 @@
   overview_button_tray_ = std::make_unique<OverviewButtonTray>(shelf_);
   status_area_widget_delegate_->AddChildView(overview_button_tray_.get());
 
-  system_tray_ = std::make_unique<SystemTray>(shelf_);
-  status_area_widget_delegate_->AddChildView(system_tray_.get());
-
   if (features::IsSystemTrayUnifiedEnabled()) {
     unified_system_tray_ = std::make_unique<UnifiedSystemTray>(shelf_);
     status_area_widget_delegate_->AddChildView(unified_system_tray_.get());
+  } else {
+    system_tray_ = std::make_unique<SystemTray>(shelf_);
+    status_area_widget_delegate_->AddChildView(system_tray_.get());
   }
 
   // Must happen after the widget is initialized so the native window exists.
@@ -104,8 +104,6 @@
   if (notification_tray_) {
     system_tray_->InitializeTrayItems(notification_tray_.get());
     notification_tray_->Initialize();
-  } else {
-    system_tray_->InitializeTrayItems(nullptr);
   }
   palette_tray_->Initialize();
   virtual_keyboard_tray_->Initialize();
@@ -123,7 +121,8 @@
 }
 
 StatusAreaWidget::~StatusAreaWidget() {
-  system_tray_->Shutdown();
+  if (system_tray_)
+    system_tray_->Shutdown();
 
   notification_tray_.reset();
   // Must be destroyed after |notification_tray_|.
@@ -143,7 +142,10 @@
 }
 
 void StatusAreaWidget::UpdateAfterShelfAlignmentChange() {
-  system_tray_->UpdateAfterShelfAlignmentChange();
+  if (system_tray_)
+    system_tray_->UpdateAfterShelfAlignmentChange();
+  if (unified_system_tray_)
+    unified_system_tray_->UpdateAfterShelfAlignmentChange();
   if (notification_tray_)
     notification_tray_->UpdateAfterShelfAlignmentChange();
   logout_button_tray_->UpdateAfterShelfAlignmentChange();
@@ -164,7 +166,8 @@
     return;
   login_status_ = login_status;
 
-  system_tray_->UpdateAfterLoginStatusChange(login_status);
+  if (system_tray_)
+    system_tray_->UpdateAfterLoginStatusChange(login_status);
   logout_button_tray_->UpdateAfterLoginStatusChange();
   overview_button_tray_->UpdateAfterLoginStatusChange(login_status);
 }
@@ -197,7 +200,7 @@
 bool StatusAreaWidget::ShouldShowShelf() const {
   // The system tray bubble may or may not want to force the shelf to be
   // visible.
-  if (system_tray_->IsSystemBubbleVisible())
+  if (system_tray_ && system_tray_->IsSystemBubbleVisible())
     return system_tray_->ShouldShowShelf();
 
   // All other tray bubbles will force the shelf to be visible.
@@ -214,7 +217,10 @@
   status_area_widget_delegate_->SchedulePaint();
   if (notification_tray_)
     notification_tray_->SchedulePaint();
-  system_tray_->SchedulePaint();
+  if (system_tray_)
+    system_tray_->SchedulePaint();
+  if (unified_system_tray_)
+    unified_system_tray_->SchedulePaint();
   virtual_keyboard_tray_->SchedulePaint();
   logout_button_tray_->SchedulePaint();
   ime_menu_tray_->SchedulePaint();
@@ -242,7 +248,10 @@
 void StatusAreaWidget::UpdateShelfItemBackground(SkColor color) {
   if (notification_tray_)
     notification_tray_->UpdateShelfItemBackground(color);
-  system_tray_->UpdateShelfItemBackground(color);
+  if (system_tray_)
+    system_tray_->UpdateShelfItemBackground(color);
+  if (unified_system_tray_)
+    unified_system_tray_->UpdateShelfItemBackground(color);
   virtual_keyboard_tray_->UpdateShelfItemBackground(color);
   ime_menu_tray_->UpdateShelfItemBackground(color);
   select_to_speak_tray_->UpdateShelfItemBackground(color);
diff --git a/ash/system/unified/accessibility_feature_pod_controller_unittest.cc b/ash/system/unified/accessibility_feature_pod_controller_unittest.cc
index 7bb7355..91c028e7 100644
--- a/ash/system/unified/accessibility_feature_pod_controller_unittest.cc
+++ b/ash/system/unified/accessibility_feature_pod_controller_unittest.cc
@@ -21,8 +21,8 @@
     NoSessionAshTestBase::SetUp();
 
     tray_model_ = std::make_unique<UnifiedSystemTrayModel>();
-    tray_controller_ = std::make_unique<UnifiedSystemTrayController>(
-        tray_model_.get(), GetPrimarySystemTray());
+    tray_controller_ =
+        std::make_unique<UnifiedSystemTrayController>(tray_model_.get());
   }
 
   void TearDown() override {
diff --git a/ash/system/unified/top_shortcuts_view_unittest.cc b/ash/system/unified/top_shortcuts_view_unittest.cc
index 0f67728..523c838 100644
--- a/ash/system/unified/top_shortcuts_view_unittest.cc
+++ b/ash/system/unified/top_shortcuts_view_unittest.cc
@@ -26,8 +26,7 @@
     NoSessionAshTestBase::SetUp();
 
     model_ = std::make_unique<UnifiedSystemTrayModel>();
-    controller_ = std::make_unique<UnifiedSystemTrayController>(
-        model_.get(), GetPrimarySystemTray());
+    controller_ = std::make_unique<UnifiedSystemTrayController>(model_.get());
   }
 
   void TearDown() override {
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc
index 6c0203e..77f31c86 100644
--- a/ash/system/unified/unified_system_tray_bubble.cc
+++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -23,9 +23,7 @@
 
 UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray,
                                                  bool show_by_click)
-    : controller_(std::make_unique<UnifiedSystemTrayController>(
-          tray->model(),
-          tray->shelf()->GetStatusAreaWidget()->system_tray())),
+    : controller_(std::make_unique<UnifiedSystemTrayController>(tray->model())),
       tray_(tray) {
   if (show_by_click)
     time_shown_by_click_ = base::TimeTicks::Now();
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index d98192a..9f4317a 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -11,25 +11,19 @@
 #include "ash/shell.h"
 #include "ash/system/audio/unified_volume_slider_controller.h"
 #include "ash/system/bluetooth/bluetooth_feature_pod_controller.h"
-#include "ash/system/bluetooth/tray_bluetooth.h"
+#include "ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h"
 #include "ash/system/brightness/unified_brightness_slider_controller.h"
 #include "ash/system/cast/cast_feature_pod_controller.h"
-#include "ash/system/cast/tray_cast.h"
 #include "ash/system/cast/unified_cast_detailed_view_controller.h"
 #include "ash/system/ime/ime_feature_pod_controller.h"
-#include "ash/system/ime/tray_ime_chromeos.h"
 #include "ash/system/ime/unified_ime_detailed_view_controller.h"
 #include "ash/system/network/network_feature_pod_controller.h"
-#include "ash/system/network/tray_network.h"
-#include "ash/system/network/tray_vpn.h"
 #include "ash/system/network/unified_network_detailed_view_controller.h"
 #include "ash/system/network/unified_vpn_detailed_view_controller.h"
 #include "ash/system/network/vpn_feature_pod_controller.h"
 #include "ash/system/night_light/night_light_feature_pod_controller.h"
 #include "ash/system/rotation/rotation_lock_feature_pod_controller.h"
-#include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_controller.h"
-#include "ash/system/tray_accessibility.h"
 #include "ash/system/unified/accessibility_feature_pod_controller.h"
 #include "ash/system/unified/detailed_view_controller.h"
 #include "ash/system/unified/feature_pod_controller_base.h"
@@ -44,6 +38,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "ui/gfx/animation/slide_animation.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 
@@ -54,48 +49,11 @@
 // Threshold in pixel that fully collapses / expands the view through gesture.
 const int kDragThreshold = 200;
 
-// As a hack, we embedded detailed views by holding a reference to old
-// SystemTray. UnifiedSystemTray should not have references to SystemTray and
-// SystemTrayItems, so this class will be removed soon. The right approach to
-// embed a detailed view is to write a subclass of DetailedViewController
-// for each detailed view, and instantiate it in Show*DetailedView() method.
-//
-// TODO(tetsui): Remove this class.
-class SystemTrayItemDetailedViewController : public DetailedViewController {
- public:
-  explicit SystemTrayItemDetailedViewController(
-      SystemTrayItem* system_tray_item)
-      : system_tray_item_(system_tray_item) {}
-
-  views::View* CreateView() override {
-    LoginStatus login_status =
-        Shell::Get()->session_controller()->login_status();
-    return system_tray_item_->CreateDetailedView(login_status);
-  }
-
-  ~SystemTrayItemDetailedViewController() override {
-    // We have to call SystemTrayItem::OnDetailedViewDestoryed() on bubble
-    // close, because typically each SystemTrayItem observes a model and it
-    // calls Update() method of each detailed view.
-    system_tray_item_->OnDetailedViewDestroyed();
-  }
-
- private:
-  // Reference to the SystemTrayItem of the currently shown detailed view.
-  // Unowned.
-  SystemTrayItem* const system_tray_item_;
-
-  DISALLOW_COPY_AND_ASSIGN(SystemTrayItemDetailedViewController);
-};
-
 }  // namespace
 
 UnifiedSystemTrayController::UnifiedSystemTrayController(
-    UnifiedSystemTrayModel* model,
-    SystemTray* system_tray)
-    : model_(model),
-      system_tray_(system_tray),
-      animation_(std::make_unique<gfx::SlideAnimation>(this)) {
+    UnifiedSystemTrayModel* model)
+    : model_(model), animation_(std::make_unique<gfx::SlideAnimation>(this)) {
   animation_->Reset(model->expanded_on_open() ? 1.0 : 0.0);
   animation_->SetSlideDuration(kExpandAnimationDurationMs);
   animation_->SetTweenType(gfx::Tween::EASE_IN_OUT);
@@ -223,25 +181,35 @@
 }
 
 void UnifiedSystemTrayController::ShowNetworkDetailedView() {
+  Shell::Get()->metrics()->RecordUserMetricsAction(
+      UMA_STATUS_AREA_DETAILED_NETWORK_VIEW);
   ShowDetailedView(
       std::make_unique<UnifiedNetworkDetailedViewController>(this));
 }
 
 void UnifiedSystemTrayController::ShowBluetoothDetailedView() {
-  // TODO(tetsui): Implement Bluetooth's own DetailedViewController.
-  ShowSystemTrayItemDetailedView(system_tray_->GetTrayBluetooth());
+  Shell::Get()->metrics()->RecordUserMetricsAction(
+      UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW);
+  ShowDetailedView(
+      std::make_unique<UnifiedBluetoothDetailedViewController>(this));
 }
 
 void UnifiedSystemTrayController::ShowCastDetailedView() {
+  Shell::Get()->metrics()->RecordUserMetricsAction(
+      UMA_STATUS_AREA_DETAILED_CAST_VIEW);
   ShowDetailedView(std::make_unique<UnifiedCastDetailedViewController>(this));
 }
 
 void UnifiedSystemTrayController::ShowAccessibilityDetailedView() {
+  Shell::Get()->metrics()->RecordUserMetricsAction(
+      UMA_STATUS_AREA_DETAILED_ACCESSIBILITY);
   ShowDetailedView(
       std::make_unique<UnifiedAccessibilityDetailedViewController>(this));
 }
 
 void UnifiedSystemTrayController::ShowVPNDetailedView() {
+  Shell::Get()->metrics()->RecordUserMetricsAction(
+      UMA_STATUS_AREA_DETAILED_VPN_VIEW);
   ShowDetailedView(std::make_unique<UnifiedVPNDetailedViewController>(this));
 }
 
@@ -302,12 +270,6 @@
   detailed_view_controller_ = std::move(controller);
 }
 
-void UnifiedSystemTrayController::ShowSystemTrayItemDetailedView(
-    SystemTrayItem* system_tray_item) {
-  ShowDetailedView(
-      std::make_unique<SystemTrayItemDetailedViewController>(system_tray_item));
-}
-
 void UnifiedSystemTrayController::UpdateExpandedAmount() {
   double expanded_amount = animation_->GetCurrentValue();
   unified_view_->SetExpandedAmount(expanded_amount);
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h
index c9c70df7..f9f0fff2 100644
--- a/ash/system/unified/unified_system_tray_controller.h
+++ b/ash/system/unified/unified_system_tray_controller.h
@@ -21,8 +21,6 @@
 
 class DetailedViewController;
 class FeaturePodControllerBase;
-class SystemTray;
-class SystemTrayItem;
 class UnifiedBrightnessSliderController;
 class UnifiedVolumeSliderController;
 class UnifiedSystemTrayModel;
@@ -31,10 +29,7 @@
 // Controller class of UnifiedSystemTrayView. Handles events of the view.
 class ASH_EXPORT UnifiedSystemTrayController : public gfx::AnimationDelegate {
  public:
-  // |system_tray| is used to show detailed views which are still not
-  // implemented on UnifiedSystemTray.
-  UnifiedSystemTrayController(UnifiedSystemTrayModel* model,
-                              SystemTray* system_tray);
+  explicit UnifiedSystemTrayController(UnifiedSystemTrayModel* model);
   ~UnifiedSystemTrayController() override;
 
   // Create the view. The created view is unowned.
@@ -112,11 +107,6 @@
   // Show the detailed view.
   void ShowDetailedView(std::unique_ptr<DetailedViewController> controller);
 
-  // Show detailed view of SystemTrayItem.
-  // TODO(tetsui): Remove when Unified's own DetailedViewControllers are
-  // implemented.
-  void ShowSystemTrayItemDetailedView(SystemTrayItem* system_tray_item);
-
   // Update how much the view is expanded based on |animation_|.
   void UpdateExpandedAmount();
 
@@ -130,11 +120,6 @@
   // Model that stores UI specific variables. Unowned.
   UnifiedSystemTrayModel* const model_;
 
-  // Only used to show detailed views which are still not implemented on
-  // UnifiedSystemTray. Unowned.
-  // TODO(tetsui): Remove reference to |system_tray|.
-  SystemTray* const system_tray_;
-
   // Unowned. Owned by Views hierarchy.
   UnifiedSystemTrayView* unified_view_ = nullptr;
 
diff --git a/ash/system/unified/unified_system_tray_controller_unittest.cc b/ash/system/unified/unified_system_tray_controller_unittest.cc
index 530cf1e..c0ff2721 100644
--- a/ash/system/unified/unified_system_tray_controller_unittest.cc
+++ b/ash/system/unified/unified_system_tray_controller_unittest.cc
@@ -40,8 +40,7 @@
     base::RunLoop().RunUntilIdle();
 
     model_ = std::make_unique<UnifiedSystemTrayModel>();
-    controller_ = std::make_unique<UnifiedSystemTrayController>(
-        model(), nullptr /* system_tray */);
+    controller_ = std::make_unique<UnifiedSystemTrayController>(model());
     view_.reset(controller_->CreateView());
 
     view_->AddObserver(this);
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 48d714a..85521bc 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -228,7 +228,6 @@
   ScreenOrientationControllerTestApi(
       Shell::Get()->screen_orientation_controller())
       .UpdateNaturalOrientation();
-  ash_test_helper_->NotifyClientAboutAcceleratedWidgets();
 }
 
 aura::Window* AshTestBase::CurrentContext() {
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 9946d5b..0a57bb72 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -253,17 +253,6 @@
   run_loop.RunUntilIdle();
 }
 
-void AshTestHelper::NotifyClientAboutAcceleratedWidgets() {
-  if (config_ == Config::CLASSIC)
-    return;
-  if (base::FeatureList::IsEnabled(features::kMash))
-    return;
-  // TODO(crbug.com/841941): Remove this. Config::MUS is deprecated.
-  Shell* shell = Shell::Get();
-  window_tree_client_setup_.NotifyClientAboutAcceleratedWidgets(
-      shell->display_manager());
-}
-
 PrefService* AshTestHelper::GetLocalStatePrefService() {
   return Shell::Get()->local_state_.get();
 }
@@ -309,7 +298,6 @@
   window_tree_client_private_ =
       std::make_unique<aura::WindowTreeClientPrivate>(window_tree_client);
   window_tree_client_private_->CallOnConnect();
-  NotifyClientAboutAcceleratedWidgets();
 }
 
 void AshTestHelper::CreateShell() {
diff --git a/ash/test/ash_test_helper.h b/ash/test/ash_test_helper.h
index 85292bf..6a525b2 100644
--- a/ash/test/ash_test_helper.h
+++ b/ash/test/ash_test_helper.h
@@ -84,8 +84,6 @@
 
   void RunAllPendingInMessageLoop();
 
-  void NotifyClientAboutAcceleratedWidgets();
-
   PrefService* GetLocalStatePrefService();
 
   TestShellDelegate* test_shell_delegate() { return test_shell_delegate_; }
diff --git a/ash/wm/native_cursor_manager_ash.h b/ash/wm/native_cursor_manager_ash.h
index 28756c5a..68426a6 100644
--- a/ash/wm/native_cursor_manager_ash.h
+++ b/ash/wm/native_cursor_manager_ash.h
@@ -16,6 +16,9 @@
 // Ash specific extensions to NativeCursorManager. This lets us switch whether
 // we're using the native cursor, along with exposing additional data about how
 // we're going to render cursors.
+// TODO(jamescook): If we don't end up with a mash implementation of this
+// interface then collapse it with NativeCursorManagerAshClassic, which is the
+// only subclass.
 class ASH_EXPORT NativeCursorManagerAsh : public ::wm::NativeCursorManager {
  public:
   ~NativeCursorManagerAsh() override = default;
diff --git a/ash/wm/native_cursor_manager_ash_mus.cc b/ash/wm/native_cursor_manager_ash_mus.cc
deleted file mode 100644
index 1f72c07..0000000
--- a/ash/wm/native_cursor_manager_ash_mus.cc
+++ /dev/null
@@ -1,205 +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 "ash/wm/native_cursor_manager_ash_mus.h"
-
-#include <memory>
-
-#include "ash/display/cursor_window_controller.h"
-#include "ash/display/window_tree_host_manager.h"
-#include "ash/shell.h"
-#include "ui/aura/env.h"
-#include "ui/aura/mus/window_manager_delegate.h"
-#include "ui/aura/mus/window_port_mus.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/base/cursor/image_cursors.h"
-#include "ui/base/cursor/ozone/cursor_data_factory_ozone.h"
-#include "ui/base/layout.h"
-#include "ui/wm/core/cursor_manager.h"
-
-namespace ash {
-namespace {
-
-void NotifyCursorVisibilityChange(bool visible) {
-  // Communicate the cursor visibility state to the mus server.
-  Shell::window_manager_client()->SetCursorVisible(visible);
-
-  // Communicate the cursor visibility change to our local root window objects.
-  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
-  for (aura::Window::Windows::iterator iter = root_windows.begin();
-       iter != root_windows.end(); ++iter)
-    (*iter)->GetHost()->OnCursorVisibilityChanged(visible);
-
-  Shell::Get()
-      ->window_tree_host_manager()
-      ->cursor_window_controller()
-      ->SetVisibility(visible);
-}
-
-void NotifyMouseEventsEnableStateChange(bool enabled) {
-  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
-  for (aura::Window::Windows::iterator iter = root_windows.begin();
-       iter != root_windows.end(); ++iter)
-    (*iter)->GetHost()->dispatcher()->OnMouseEventsEnableStateChanged(enabled);
-  // Mirror window never process events.
-}
-
-}  // namespace
-
-NativeCursorManagerAshMus::NativeCursorManagerAshMus() {
-  // If we're in a mus client, we aren't going to have all of ozone initialized
-  // even though we're in an ozone build. All the hard coded USE_OZONE ifdefs
-  // that handle cursor code in //content/ expect that there will be a
-  // CursorFactoryOzone instance. Partially initialize the ozone cursor
-  // internals here, like we partially initialize other ozone subsystems in
-  // ChromeBrowserMainExtraPartsViews.
-  cursor_factory_ozone_ = std::make_unique<ui::CursorDataFactoryOzone>();
-  image_cursors_ = std::make_unique<ui::ImageCursors>();
-}
-
-NativeCursorManagerAshMus::~NativeCursorManagerAshMus() = default;
-
-void NativeCursorManagerAshMus::SetNativeCursorEnabled(bool enabled) {
-  native_cursor_enabled_ = enabled;
-
-  ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
-  SetCursor(cursor_manager->GetCursor(), cursor_manager);
-}
-
-float NativeCursorManagerAshMus::GetScale() const {
-  return image_cursors_->GetScale();
-}
-
-display::Display::Rotation NativeCursorManagerAshMus::GetRotation() const {
-  return image_cursors_->GetRotation();
-}
-
-void NativeCursorManagerAshMus::SetDisplay(
-    const display::Display& display,
-    ::wm::NativeCursorManagerDelegate* delegate) {
-  DCHECK(display.is_valid());
-  // Use the platform's device scale factor instead of the display's, which
-  // might have been adjusted for the UI scale.
-  const float original_scale = Shell::Get()
-                                   ->display_manager()
-                                   ->GetDisplayInfo(display.id())
-                                   .device_scale_factor();
-  // And use the nearest resource scale factor.
-  const float cursor_scale =
-      ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactor(original_scale));
-
-  if (image_cursors_->SetDisplay(display, cursor_scale))
-    SetCursor(delegate->GetCursor(), delegate);
-
-  Shell::Get()
-      ->window_tree_host_manager()
-      ->cursor_window_controller()
-      ->SetDisplay(display);
-}
-
-void NativeCursorManagerAshMus::SetCursor(
-    gfx::NativeCursor cursor,
-    ::wm::NativeCursorManagerDelegate* delegate) {
-  if (image_cursors_) {
-    if (native_cursor_enabled_) {
-      image_cursors_->SetPlatformCursor(&cursor);
-    } else {
-      gfx::NativeCursor invisible_cursor(ui::CursorType::kNone);
-      image_cursors_->SetPlatformCursor(&invisible_cursor);
-      cursor.SetPlatformCursor(invisible_cursor.platform());
-    }
-  }
-  cursor.set_device_scale_factor(image_cursors_->GetScale());
-
-  delegate->CommitCursor(cursor);
-
-  if (delegate->IsCursorVisible())
-    SetCursorOnAllRootWindows(cursor);
-}
-
-void NativeCursorManagerAshMus::SetVisibility(
-    bool visible,
-    ::wm::NativeCursorManagerDelegate* delegate) {
-  delegate->CommitVisibility(visible);
-
-  if (visible) {
-    SetCursor(delegate->GetCursor(), delegate);
-  } else {
-    gfx::NativeCursor invisible_cursor(ui::CursorType::kNone);
-    image_cursors_->SetPlatformCursor(&invisible_cursor);
-    SetCursorOnAllRootWindows(invisible_cursor);
-  }
-
-  NotifyCursorVisibilityChange(visible);
-}
-
-void NativeCursorManagerAshMus::SetCursorSize(
-    ui::CursorSize cursor_size,
-    ::wm::NativeCursorManagerDelegate* delegate) {
-  delegate->CommitCursorSize(cursor_size);
-
-  Shell::window_manager_client()->SetCursorSize(cursor_size);
-
-  Shell::Get()
-      ->window_tree_host_manager()
-      ->cursor_window_controller()
-      ->SetCursorSize(cursor_size);
-}
-
-void NativeCursorManagerAshMus::SetMouseEventsEnabled(
-    bool enabled,
-    ::wm::NativeCursorManagerDelegate* delegate) {
-  delegate->CommitMouseEventsEnabled(enabled);
-
-  if (enabled) {
-    aura::Env::GetInstance()->SetLastMouseLocation(disabled_cursor_location_);
-  } else {
-    disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
-  }
-
-  SetVisibility(delegate->IsCursorVisible(), delegate);
-
-  NotifyMouseEventsEnableStateChange(enabled);
-}
-
-void NativeCursorManagerAshMus::SetCursorOnAllRootWindows(
-    gfx::NativeCursor cursor) {
-  ui::CursorData mojo_cursor;
-
-  // Only send a real mojo cursor to the window server when native cursors are
-  // enabled. Otherwise send a kNone cursor as the global override cursor. If
-  // you need to debug window manager side cursor window positioning, setting
-  // |native_cursor_enabled| to always be true will display both.
-  if (native_cursor_enabled_) {
-    if (cursor.platform()) {
-      mojo_cursor =
-          ui::CursorDataFactoryOzone::GetCursorData(cursor.platform());
-    } else {
-      mojo_cursor = ui::CursorData(cursor.native_type());
-    }
-  } else {
-    mojo_cursor = ui::CursorData(ui::CursorType::kNone);
-  }
-
-  if (!mojo_cursor.IsSameAs(last_cursor_sent_to_window_server_)) {
-    // As the window manager, tell mus to use |mojo_cursor| everywhere. We do
-    // this instead of trying to set per-window because otherwise we run into
-    // the event targeting issue.
-    last_cursor_sent_to_window_server_ = mojo_cursor;
-    Shell::window_manager_client()->SetGlobalOverrideCursor(mojo_cursor);
-  }
-
-  // Make sure the local state is set properly, so that local queries show that
-  // we set the cursor.
-  for (aura::Window* root : Shell::Get()->GetAllRootWindows())
-    root->GetHost()->SetCursor(cursor);
-
-  Shell::Get()
-      ->window_tree_host_manager()
-      ->cursor_window_controller()
-      ->SetCursor(cursor);
-}
-
-}  // namespace ash
diff --git a/ash/wm/native_cursor_manager_ash_mus.h b/ash/wm/native_cursor_manager_ash_mus.h
deleted file mode 100644
index 8331d20..0000000
--- a/ash/wm/native_cursor_manager_ash_mus.h
+++ /dev/null
@@ -1,72 +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 ASH_WM_NATIVE_CURSOR_MANAGER_ASH_MUS_H_
-#define ASH_WM_NATIVE_CURSOR_MANAGER_ASH_MUS_H_
-
-#include "ash/wm/native_cursor_manager_ash.h"
-#include "ui/base/cursor/cursor_data.h"
-
-namespace ui {
-class CursorDataFactoryOzone;
-class ImageCursors;
-}  // namespace ui
-
-namespace ash {
-
-// An NativeCursorManagerAsh which is used in Mushrome mode.
-//
-// NativeCursorManagerAshClassic implicitly communicates with ozone via
-// ImageCursors and the window tree host, but in mushrome, we want to
-// communicate with the window server purely through the mus interfaces.
-//
-// This doesn't mean that we can just cut out all ozone communication; we'll
-// have to do what the mash does, which is install just the cursor factory part
-// of ozone.
-class ASH_EXPORT NativeCursorManagerAshMus : public NativeCursorManagerAsh {
- public:
-  NativeCursorManagerAshMus();
-  ~NativeCursorManagerAshMus() override;
-
- private:
-  // Overridden from NativeCursorManagerAsh:
-  void SetNativeCursorEnabled(bool enabled) override;
-  float GetScale() const override;
-  display::Display::Rotation GetRotation() const override;
-
-  // Overridden from ::wm::NativeCursorManager:
-  void SetDisplay(const display::Display& display,
-                  ::wm::NativeCursorManagerDelegate* delegate) override;
-  void SetCursor(gfx::NativeCursor cursor,
-                 ::wm::NativeCursorManagerDelegate* delegate) override;
-  void SetVisibility(bool visible,
-                     ::wm::NativeCursorManagerDelegate* delegate) override;
-  void SetCursorSize(ui::CursorSize cursor_size,
-                     ::wm::NativeCursorManagerDelegate* delegate) override;
-  void SetMouseEventsEnabled(
-      bool enabled,
-      ::wm::NativeCursorManagerDelegate* delegate) override;
-
-  void SetCursorOnAllRootWindows(gfx::NativeCursor cursor);
-
-  // The cursor location where the cursor was disabled.
-  gfx::Point disabled_cursor_location_;
-
-  bool native_cursor_enabled_ = true;
-
-  std::unique_ptr<ui::CursorDataFactoryOzone> cursor_factory_ozone_;
-
-  std::unique_ptr<::ui::ImageCursors> image_cursors_;
-
-  // Cached version of the last Cursor sent to the ws. Cached to avoid
-  // unnecessary IPCs as well as avoiding pushing the cursor to hardware, which
-  // can be slow.
-  ui::CursorData last_cursor_sent_to_window_server_;
-
-  DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerAshMus);
-};
-
-}  // namespace ash
-
-#endif  // ASH_WM_NATIVE_CURSOR_MANAGER_ASH_MUS_H_
diff --git a/base/profiler/native_stack_sampler.h b/base/profiler/native_stack_sampler.h
index baf64e5..2fb8620 100644
--- a/base/profiler/native_stack_sampler.h
+++ b/base/profiler/native_stack_sampler.h
@@ -80,7 +80,7 @@
 
   // Notifies the sampler that we've stopped recording the current
   // profile.
-  virtual void ProfileRecordingStopped(StackBuffer* stackbuffer) = 0;
+  virtual void ProfileRecordingStopped() = 0;
 
  protected:
   NativeStackSampler();
diff --git a/base/profiler/native_stack_sampler_mac.cc b/base/profiler/native_stack_sampler_mac.cc
index a161173f..08f5e96 100644
--- a/base/profiler/native_stack_sampler_mac.cc
+++ b/base/profiler/native_stack_sampler_mac.cc
@@ -480,7 +480,7 @@
       std::vector<StackSamplingProfiler::Module>* modules) override;
   void RecordStackSample(StackBuffer* stack_buffer,
                          StackSamplingProfiler::Sample* sample) override;
-  void ProfileRecordingStopped(StackBuffer* stack_buffer) override;
+  void ProfileRecordingStopped() override;
 
  private:
   // Suspends the thread with |thread_port_|, copies its stack and resumes the
@@ -549,7 +549,7 @@
   SuspendThreadAndRecordStack(stack_buffer, sample);
 }
 
-void NativeStackSamplerMac::ProfileRecordingStopped(StackBuffer* stack_buffer) {
+void NativeStackSamplerMac::ProfileRecordingStopped() {
   current_modules_ = nullptr;
 }
 
diff --git a/base/profiler/native_stack_sampler_win.cc b/base/profiler/native_stack_sampler_win.cc
index b53197d..ee1b7232 100644
--- a/base/profiler/native_stack_sampler_win.cc
+++ b/base/profiler/native_stack_sampler_win.cc
@@ -20,6 +20,8 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/profiler/win32_stack_frame_unwinder.h"
+#include "base/stl_util.h"
+#include "base/strings/string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -138,7 +140,7 @@
   };
 
   // Rewrite pointers in the context.
-  for (size_t i = 0; i < arraysize(nonvolatile_registers); ++i) {
+  for (size_t i = 0; i < base::size(nonvolatile_registers); ++i) {
     DWORD64* const reg = &(context->*nonvolatile_registers[i]);
     RewritePointerIfInOriginalStack(top, bottom, stack_copy,
                                     reinterpret_cast<const void**>(reg));
@@ -220,14 +222,14 @@
   DWORD age;
   win::PEImage(module_handle).GetDebugId(&guid, &age, /* pdb_file= */ nullptr);
   const int kGUIDSize = 39;
-  std::wstring build_id;
+  base::string16 build_id;
   int result =
       ::StringFromGUID2(guid, WriteInto(&build_id, kGUIDSize), kGUIDSize);
   if (result != kGUIDSize)
     return std::string();
   RemoveChars(build_id, L"{}-", &build_id);
   build_id += StringPrintf(L"%d", age);
-  return WideToUTF8(build_id);
+  return UTF16ToUTF8(build_id);
 }
 
 // ScopedDisablePriorityBoost -------------------------------------------------
@@ -397,7 +399,7 @@
       std::vector<StackSamplingProfiler::Module>* modules) override;
   void RecordStackSample(StackBuffer* stack_buffer,
                          StackSamplingProfiler::Sample* sample) override;
-  void ProfileRecordingStopped(StackBuffer* stack_buffer) override;
+  void ProfileRecordingStopped() override;
 
  private:
   // Attempts to query the module filename, base address, and id for
@@ -471,7 +473,7 @@
   CopyToSample(stack, sample, current_modules_);
 }
 
-void NativeStackSamplerWin::ProfileRecordingStopped(StackBuffer* stack_buffer) {
+void NativeStackSamplerWin::ProfileRecordingStopped() {
   current_modules_ = nullptr;
 }
 
@@ -481,7 +483,7 @@
     StackSamplingProfiler::Module* module) {
   wchar_t module_name[MAX_PATH];
   DWORD result_length =
-      GetModuleFileName(module_handle, module_name, arraysize(module_name));
+      ::GetModuleFileName(module_handle, module_name, base::size(module_name));
   if (result_length == 0)
     return false;
 
@@ -490,10 +492,7 @@
   module->base_address = reinterpret_cast<uintptr_t>(module_handle);
 
   module->id = GetBuildIDForModule(module_handle);
-  if (module->id.empty())
-    return false;
-
-  return true;
+  return !module->id.empty();
 }
 
 size_t NativeStackSamplerWin::GetModuleIndex(
@@ -522,7 +521,7 @@
   sample->frames.clear();
   sample->frames.reserve(stack.size());
 
-  for (const RecordedFrame& frame : stack) {
+  for (const auto& frame : stack) {
     sample->frames.push_back(StackSamplingProfiler::Frame(
         reinterpret_cast<uintptr_t>(frame.instruction_pointer),
         GetModuleIndex(frame.module.Get(), modules)));
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index a8cddf0..4c76434e 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -549,7 +549,7 @@
   if (collection->sample == collection->params.samples_per_burst - 1) {
     profile.profile_duration = Time::Now() - collection->profile_start_time +
                                collection->params.sampling_interval;
-    collection->native_sampler->ProfileRecordingStopped(stack_buffer_.get());
+    collection->native_sampler->ProfileRecordingStopped();
   }
 }
 
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc
index 8fc25c9..30dcf18 100644
--- a/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -22,6 +22,7 @@
 #include "base/profiler/stack_sampling_profiler.h"
 #include "base/run_loop.h"
 #include "base/scoped_native_library.h"
+#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
@@ -866,7 +867,7 @@
     params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
     params[1].samples_per_burst = 100000;
 
-    SampleRecordedCounter samples_recorded[arraysize(params)];
+    SampleRecordedCounter samples_recorded[base::size(params)];
 
     TestProfilerInfo profiler_info0(target_thread_id, params[0],
                                     &samples_recorded[0]);
diff --git a/build/android/play_services/preprocess.py b/build/android/play_services/preprocess.py
index e822c1a..bb3424a 100755
--- a/build/android/play_services/preprocess.py
+++ b/build/android/play_services/preprocess.py
@@ -154,11 +154,6 @@
 
     res_path = os.path.join(tmp_paths['imported_clients'], client_dir, 'res')
     if not os.path.isdir(res_path):
-      # We declare the libraries in GN as `android_java_prebuilt` and add to
-      # each an `android_resources` target. So we need to the resources
-      # directory to exist.
-      os.makedirs(res_path)
-      open(os.path.join(res_path, '.gitkeep'), 'a').close()
       continue
 
     for res_type in os.listdir(res_path):
diff --git a/build/config/coverage/BUILD.gn b/build/config/coverage/BUILD.gn
index 6a6ec88..e407cb4 100644
--- a/build/config/coverage/BUILD.gn
+++ b/build/config/coverage/BUILD.gn
@@ -9,7 +9,6 @@
     cflags = [
       "-fprofile-instr-generate",
       "-fcoverage-mapping",
-      "-fno-use-cxa-atexit",
 
       # Following experimental flags removes unused header functions from the
       # coverage mapping data embedded in the test binaries, and the reduction
@@ -19,5 +18,9 @@
       "-limited-coverage-experimental=true",
     ]
     ldflags = [ "-fprofile-instr-generate" ]
+
+    if (!is_win) {
+      cflags += [ "-fno-cxa-atexit" ]
+    }
   }
 }
diff --git a/cc/paint/paint_op_buffer_fuzzer.cc b/cc/paint/paint_op_buffer_fuzzer.cc
index dfc4a33b..d94150a 100644
--- a/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/cc/paint/paint_op_buffer_fuzzer.cc
@@ -123,11 +123,13 @@
   }
 
   auto context_provider_no_support = viz::TestContextProvider::Create();
+  context_provider_no_support->BindToCurrentThread();
   CHECK(!context_provider_no_support->GrContext()->supportsDistanceFieldText());
   Raster(context_provider_no_support, font_manager.strike_client(), data, size);
 
   auto context_provider_with_support = viz::TestContextProvider::Create(
       std::string("GL_OES_standard_derivatives"));
+  context_provider_with_support->BindToCurrentThread();
   CHECK(
       context_provider_with_support->GrContext()->supportsDistanceFieldText());
   Raster(context_provider_with_support, font_manager.strike_client(), data,
diff --git a/chrome/VERSION b/chrome/VERSION
index 2320086..c6f4a889 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=69
 MINOR=0
-BUILD=3447
+BUILD=3448
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java
index fc99712c..4db3745 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java
@@ -112,7 +112,7 @@
         sStateChangeTask = new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                if (!sPendingShareActivities.isEmpty()) return null;
+                if (!sPendingShareActivities.isEmpty() || sEnabledComponents == null) return null;
                 for (int i = 0; i < sEnabledComponents.size(); i++) {
                     triggeringActivity.getPackageManager().setComponentEnabledSetting(
                             sEnabledComponents.get(i),
@@ -148,4 +148,4 @@
             StrictMode.setThreadPolicy(oldPolicy);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index e9cfe2af..6d9748cdc 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4619,7 +4619,10 @@
   }
 
   if (is_android) {
-    deps += [ "//chrome/browser/ui/webui/snippets_internals:mojo_bindings_js" ]
+    deps += [
+      "//chrome/browser/ui/webui/eoc_internals:mojo_bindings_js",
+      "//chrome/browser/ui/webui/snippets_internals:mojo_bindings_js",
+    ]
   }
 
   if (optimize_webui) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 4b6a57c..2c5de15 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3453,7 +3453,7 @@
 
     {"stop-loading-in-background",
      flag_descriptions::kStopLoadingInBackgroundName,
-     flag_descriptions::kStopLoadingInBackgroundDescription, kOsAndroid,
+     flag_descriptions::kStopLoadingInBackgroundDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kStopLoadingInBackground)},
 
     {"stop-non-timers-in-background",
diff --git a/chrome/browser/accessibility/browser_accessibility_state_browsertest.cc b/chrome/browser/accessibility/browser_accessibility_state_browsertest.cc
index 862446c..9aeb266 100644
--- a/chrome/browser/accessibility/browser_accessibility_state_browsertest.cc
+++ b/chrome/browser/accessibility/browser_accessibility_state_browsertest.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 "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/browser_accessibility_state.h"
diff --git a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc
index eb8df5a..5a0da5f 100644
--- a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc
+++ b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/bind_test_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/android/customtabs/detached_resource_request.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_context.h"
diff --git a/chrome/browser/android/data_usage/data_use_matcher_unittest.cc b/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
index 9e633f23..7c81406 100644
--- a/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
diff --git a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
index b3ca7e5..50d1578 100644
--- a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
@@ -18,7 +18,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/data_usage/data_use_matcher.h"
diff --git a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
index bca89fe..b2f1c70 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
 #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc b/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc
index 9f6ba873..9880483 100644
--- a/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc
+++ b/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
 #include "chrome/browser/android/data_usage/external_data_use_observer.h"
diff --git a/chrome/browser/android/data_usage/tab_data_use_entry_unittest.cc b/chrome/browser/android/data_usage/tab_data_use_entry_unittest.cc
index d009bd7..56c098d 100644
--- a/chrome/browser/android/data_usage/tab_data_use_entry_unittest.cc
+++ b/chrome/browser/android/data_usage/tab_data_use_entry_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/bind_helpers.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
diff --git a/chrome/browser/android/history_report/data_observer.cc b/chrome/browser/android/history_report/data_observer.cc
index 02d683c..704fd8c7 100644
--- a/chrome/browser/android/history_report/data_observer.cc
+++ b/chrome/browser/android/history_report/data_observer.cc
@@ -25,21 +25,29 @@
     UsageReportsBufferService* usage_reports_buffer_service,
     BookmarkModel* bookmark_model,
     history::HistoryService* history_service)
-    : data_changed_callback_(data_changed_callback),
+    : bookmark_model_(bookmark_model),
+      data_changed_callback_(data_changed_callback),
       data_cleared_callback_(data_cleared_callback),
       stop_reporting_callback_(stop_reporting_callback),
       delta_file_service_(delta_file_service),
       usage_reports_buffer_service_(usage_reports_buffer_service) {
-  bookmark_model->AddObserver(this);
+  bookmark_model_->AddObserver(this);
   history_service->AddObserver(this);
 }
 
-DataObserver::~DataObserver() {}
+DataObserver::~DataObserver() {
+  if (bookmark_model_)
+    bookmark_model_->RemoveObserver(this);
+}
 
 void DataObserver::BookmarkModelLoaded(BookmarkModel* model,
                                        bool ids_reassigned) {}
 
-void DataObserver::BookmarkModelBeingDeleted(BookmarkModel* model) {}
+void DataObserver::BookmarkModelBeingDeleted(BookmarkModel* model) {
+  DCHECK_EQ(model, bookmark_model_);
+  bookmark_model_->RemoveObserver(this);
+  bookmark_model_ = nullptr;
+}
 
 void DataObserver::BookmarkNodeMoved(BookmarkModel* model,
                                      const BookmarkNode* old_parent,
diff --git a/chrome/browser/android/history_report/data_observer.h b/chrome/browser/android/history_report/data_observer.h
index 7414d3ae..c8e8eb9 100644
--- a/chrome/browser/android/history_report/data_observer.h
+++ b/chrome/browser/android/history_report/data_observer.h
@@ -80,6 +80,7 @@
  private:
   void DeleteBookmarks(const std::set<GURL>& removed_urls);
 
+  bookmarks::BookmarkModel* bookmark_model_;
   base::Callback<void(void)> data_changed_callback_;
   base::Callback<void(void)> data_cleared_callback_;
   base::Callback<void(void)> stop_reporting_callback_;
diff --git a/chrome/browser/android/history_report/data_provider.cc b/chrome/browser/android/history_report/data_provider.cc
index d4b3e5c..d8a49e9 100644
--- a/chrome/browser/android/history_report/data_provider.cc
+++ b/chrome/browser/android/history_report/data_provider.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/model_loader.h"
 #include "components/bookmarks/browser/url_and_title.h"
 #include "components/history/core/browser/history_db_task.h"
 #include "components/history/core/browser/history_service.h"
@@ -132,7 +133,7 @@
                      base::Unretained(&context),
                      base::Unretained(entries.get())));
       std::vector<UrlAndTitle> bookmarks;
-      bookmark_model_->BlockTillLoaded();
+      bookmark_model_->model_loader()->BlockTillLoaded();
       bookmark_model_->GetBookmarks(&bookmarks);
       BookmarkMap bookmark_map;
       for (size_t i = 0; i < bookmarks.size(); ++i) {
@@ -195,7 +196,7 @@
   }
 
   std::vector<UrlAndTitle> bookmarks;
-  bookmark_model_->BlockTillLoaded();
+  bookmark_model_->model_loader()->BlockTillLoaded();
   bookmark_model_->GetBookmarks(&bookmarks);
   urls.reserve(urls.size() + bookmarks.size());
   for (size_t i = 0; i < bookmarks.size(); i++) {
diff --git a/chrome/browser/android/ntp/content_suggestions_notifier_service_unittest.cc b/chrome/browser/android/ntp/content_suggestions_notifier_service_unittest.cc
index 5cb97e2..32a55b96 100644
--- a/chrome/browser/android/ntp/content_suggestions_notifier_service_unittest.cc
+++ b/chrome/browser/android/ntp/content_suggestions_notifier_service_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/android/application_status_listener.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/android/ntp/content_suggestions_notifier.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
index 72b1882..03ffce63 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
@@ -70,8 +70,9 @@
       decider_(OomInterventionDecider::GetForBrowserContext(
           web_contents->GetBrowserContext())),
       binding_(this),
+      scoped_observer_(this),
       weak_ptr_factory_(this) {
-  OutOfMemoryReporter::FromWebContents(web_contents)->AddObserver(this);
+  scoped_observer_.Add(breakpad::CrashDumpManager::GetInstance());
   shared_metrics_buffer_ = base::UnsafeSharedMemoryRegion::Create(
       sizeof(blink::OomInterventionMetrics));
   metrics_mapping_ = shared_metrics_buffer_.Map();
@@ -110,7 +111,6 @@
 }
 
 void OomInterventionTabHelper::WebContentsDestroyed() {
-  OutOfMemoryReporter::FromWebContents(web_contents())->RemoveObserver(this);
   StopMonitoring();
 }
 
@@ -196,9 +196,14 @@
   }
 }
 
-void OomInterventionTabHelper::OnForegroundOOMDetected(
-    const GURL& url,
-    ukm::SourceId source_id) {
+void OomInterventionTabHelper::OnCrashDumpProcessed(
+    const breakpad::CrashDumpManager::CrashDumpDetails& details) {
+  if (details.process_host_id !=
+      web_contents()->GetMainFrame()->GetProcess()->GetID())
+    return;
+  if (!breakpad::CrashDumpManager::IsForegroundOom(details))
+    return;
+
   DCHECK(IsLastVisibleWebContents(web_contents()));
   if (near_oom_detected_time_) {
     base::TimeDelta elapsed_time =
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
index 7643aa8..ccc7bd2 100644
--- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
+++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h
@@ -8,10 +8,11 @@
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "base/scoped_observer.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/oom_intervention/near_oom_monitor.h"
-#include "chrome/browser/metrics/oom/out_of_memory_reporter.h"
 #include "chrome/browser/ui/interventions/intervention_delegate.h"
+#include "components/crash/content/browser/crash_dump_manager_android.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -24,13 +25,11 @@
 
 class OomInterventionDecider;
 
-// A tab helper for near-OOM intervention. This class depends on
-// OutOfMemoryReporter. OutOfMemoryReporter must be created on TabHelpers
-// before creating OomInterventionTabHelper.
+// A tab helper for near-OOM intervention.
 class OomInterventionTabHelper
     : public content::WebContentsObserver,
       public content::WebContentsUserData<OomInterventionTabHelper>,
-      public OutOfMemoryReporter::Observer,
+      public breakpad::CrashDumpManager::Observer,
       public blink::mojom::OomInterventionHost,
       public InterventionDelegate {
  public:
@@ -59,9 +58,9 @@
   void DocumentAvailableInMainFrame() override;
   void OnVisibilityChanged(content::Visibility visibility) override;
 
-  // OutOfMemoryReporter::Observer:
-  void OnForegroundOOMDetected(const GURL& url,
-                               ukm::SourceId source_id) override;
+  // CrashDumpManager::Observer:
+  void OnCrashDumpProcessed(
+      const breakpad::CrashDumpManager::CrashDumpDetails& details) override;
 
   // Starts observing near-OOM situation if it's not started.
   void StartMonitoringIfNeeded();
@@ -112,6 +111,10 @@
   base::UnsafeSharedMemoryRegion shared_metrics_buffer_;
   base::WritableSharedMemoryMapping metrics_mapping_;
 
+  ScopedObserver<breakpad::CrashDumpManager,
+                 breakpad::CrashDumpManager::Observer>
+      scoped_observer_;
+
   base::WeakPtrFactory<OomInterventionTabHelper> weak_ptr_factory_;
 };
 
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.cc b/chrome/browser/android/provider/bookmark_model_observer_task.cc
index 2e20366..9ba697b 100644
--- a/chrome/browser/android/provider/bookmark_model_observer_task.cc
+++ b/chrome/browser/android/provider/bookmark_model_observer_task.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/provider/bookmark_model_observer_task.h"
 
 #include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/model_loader.h"
 #include "content/public/browser/browser_thread.h"
 
 using bookmarks::BookmarkModel;
@@ -16,7 +17,7 @@
   // Ensure the initialization of the native bookmark model.
   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(model_);
-  model_->BlockTillLoaded();
+  model_->model_loader()->BlockTillLoaded();
 }
 
 BookmarkModel* BookmarkModelTask::model() const {
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
index 81fb4ff..791fb25 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/strings/nullable_string16.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/android/chrome_feature_list.h"
 #include "chrome/browser/installable/installable_manager.h"
diff --git a/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
index a3eabe1..fac4b39 100644
--- a/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
+++ b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/infobars/core/confirm_infobar_delegate.h"
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index a891fd9..26fa096 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -19,7 +19,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_entropy_provider.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc b/chrome/browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc
index 292c86b..ce958c91e 100644
--- a/chrome/browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc
+++ b/chrome/browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/json/json_reader.h"
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index 93ace63b..451433e9 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -12,7 +12,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/banners/app_banner_manager.h"
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 77f1e2df..b326b50 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -170,6 +170,10 @@
       </if>
       <include name="IDR_FEEDBACK_MANIFEST" file="resources\feedback\manifest.json" type="BINDATA" />
       <if expr="is_android">
+        <include name="IDR_EOC_INTERNALS_HTML" file="resources\eoc_internals\eoc_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" />
+        <include name="IDR_EOC_INTERNALS_CSS" file="resources\eoc_internals\eoc_internals.css" compress="gzip" type="BINDATA" />
+        <include name="IDR_EOC_INTERNALS_JS" file="resources\eoc_internals\eoc_internals.js" compress="gzip" type="BINDATA" />
+        <include name="IDR_EOC_INTERNALS_MOJO_JS" file="${root_gen_dir}\chrome\browser\ui\webui\eoc_internals\eoc_internals.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
         <include name="IDR_OFFLINE_INTERNALS_HTML" file="resources\offline_pages\offline_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
         <include name="IDR_OFFLINE_INTERNALS_CSS" file="resources\offline_pages\offline_internals.css" type="BINDATA" compress="gzip" />
         <include name="IDR_OFFLINE_INTERNALS_JS" file="resources\offline_pages\offline_internals.js" type="BINDATA" compress="gzip" />
diff --git a/chrome/browser/budget_service/budget_database_unittest.cc b/chrome/browser/budget_service/budget_database_unittest.cc
index 40e0af0b..f622f2b 100644
--- a/chrome/browser/budget_service/budget_database_unittest.cc
+++ b/chrome/browser/budget_service/budget_database_unittest.cc
@@ -9,7 +9,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/budget_service/budget.pb.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
diff --git a/chrome/browser/budget_service/budget_manager_unittest.cc b/chrome/browser/budget_service/budget_manager_unittest.cc
index 0e54319..e4133d170 100644
--- a/chrome/browser/budget_service/budget_manager_unittest.cc
+++ b/chrome/browser/budget_service/budget_manager_unittest.cc
@@ -6,7 +6,7 @@
 #include <string>
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/budget_service/budget_manager.h"
 #include "chrome/browser/budget_service/budget_manager_factory.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 0d32442..bad2d266 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -698,7 +698,12 @@
   locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
       locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
 
-  ui::ResourceBundle::GetSharedInstance().AddDataPack(std::move(data_pack));
+  if (data_pack) {
+    ui::ResourceBundle::GetSharedInstance().AddDataPack(std::move(data_pack));
+  } else {
+    LOG(ERROR) << "Failed to load resources.pak\n"
+               << "Some features may not be available.";
+  }
 
   return locale;
 }
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json
index 3805676..bac76f6b 100644
--- a/chrome/browser/chrome_content_browser_manifest_overlay.json
+++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -91,6 +91,7 @@
           "translate.mojom.ContentTranslateDriver",
 
           // TODO(beng): These should be moved to a separate capability.
+          "eoc_internals.mojom.PageHandler",
           "media.mojom.MediaEngagementScoreDetailsProvider",
           "mojom.BluetoothInternalsHandler",
           "mojom.DiscardsDetailsProvider",
diff --git a/chrome/browser/chrome_security_exploit_browsertest.cc b/chrome/browser/chrome_security_exploit_browsertest.cc
index c6c82fa..bb5c8b8 100644
--- a/chrome/browser/chrome_security_exploit_browsertest.cc
+++ b/chrome/browser/chrome_security_exploit_browsertest.cc
@@ -6,7 +6,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc
index a459646..8afafcf 100644
--- a/chrome/browser/chrome_service_worker_browsertest.cc
+++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -12,7 +12,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index 982e104b..3f41992a 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -130,17 +130,21 @@
     if (is_aborted_)
       return;
 
+    // Finish Restart immediately if testing.
+    if (CrostiniManager::GetInstance()->skip_restart_for_testing()) {
+      content::BrowserThread::PostTask(
+          content::BrowserThread::UI, FROM_HERE,
+          base::BindOnce(&CrostiniRestarter::FinishRestart,
+                         base::WrapRefCounted(this),
+                         ConciergeClientResult::SUCCESS));
+      return;
+    }
+
     auto* cros_component_manager =
         g_browser_process->platform_part()->cros_component_manager();
-    if (cros_component_manager) {
-      cros_component_manager->Load(
-          "cros-termina",
-          component_updater::CrOSComponentManager::MountPolicy::kMount,
-          base::BindOnce(&CrostiniRestarter::InstallImageLoaderFinished,
-                         base::WrapRefCounted(this)));
-    } else {
-      // Running in test. We still PostTask to prevent races between observers
-      // aborting.
+    if (!cros_component_manager) {
+      // Running in unittest. We still PostTask to prevent races between
+      // observers aborting.
       content::BrowserThread::PostTask(
           content::BrowserThread::UI, FROM_HERE,
           base::BindOnce(
@@ -148,7 +152,14 @@
               base::WrapRefCounted(this),
               component_updater::CrOSComponentManager::Error::NONE,
               base::FilePath()));
+      return;
     }
+
+    cros_component_manager->Load(
+        "cros-termina",
+        component_updater::CrOSComponentManager::MountPolicy::kMount,
+        base::BindOnce(&CrostiniRestarter::InstallImageLoaderFinished,
+                       base::WrapRefCounted(this)));
   }
 
   void AddObserver(CrostiniManager::RestartObserver* observer) {
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h
index feb4269..a573c6f 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.h
+++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -210,6 +210,10 @@
 
   void AbortRestartCrostini(Profile* profile, RestartId id);
 
+  // Can be called for testing to skip restart.
+  void set_skip_restart_for_testing() { skip_restart_for_testing_ = true; };
+  bool skip_restart_for_testing() { return skip_restart_for_testing_; }
+
   // ConciergeClient::Observer:
   void OnContainerStarted(
       const vm_tools::concierge::ContainerStartedSignal& signal) override;
@@ -305,6 +309,8 @@
                 StartContainerCallback>
       start_container_callbacks_;
 
+  bool skip_restart_for_testing_ = false;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<CrostiniManager> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index 7cfffd50..673386e6 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "components/prefs/pref_service.h"
+#include "google_apis/gaia/gaia_auth_util.h"
 
 namespace {
 
@@ -149,7 +150,13 @@
 std::string ContainerUserNameForProfile(Profile* profile) {
   // Get rid of the @domain.name in the profile user name (an email address).
   std::string container_username = profile->GetProfileUserName();
-  return container_username.substr(0, container_username.find('@'));
+  if (container_username.find('@') != std::string::npos) {
+    // gaia::CanonicalizeEmail CHECKs its argument contains'@'.
+    container_username = gaia::CanonicalizeEmail(container_username);
+    // |container_username| may have changed, so we have to find again.
+    return container_username.substr(0, container_username.find('@'));
+  }
+  return container_username;
 }
 
 std::string AppNameFromCrostiniAppId(const std::string& id) {
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
index 9368299a..6785ee1 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/extensions/file_manager/event_router.h"
 #include "chrome/browser/chromeos/file_manager/file_watcher.h"
@@ -15,6 +16,7 @@
 #include "chrome/browser/chromeos/file_system_provider/icon_set.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
 #include "chrome/test/base/testing_profile.h"
@@ -22,6 +24,7 @@
 #include "chromeos/disks/mock_disk_mount_manager.h"
 #include "components/drive/file_change.h"
 #include "components/prefs/pref_service.h"
+#include "components/signin/core/browser/signin_manager_base.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/install_warning.h"
 #include "google_apis/drive/test_util.h"
@@ -211,6 +214,8 @@
         .WillRepeatedly(ReturnRef(volumes_));
     EXPECT_CALL(*disk_mount_manager_mock_, mount_points())
         .WillRepeatedly(ReturnRef(mount_points_));
+    ON_CALL(*disk_mount_manager_mock_, MountPath(_, _, _, _, _, _))
+        .WillByDefault(Invoke(this, &FileManagerPrivateApiTest::SshfsMount));
   }
 
   // ExtensionApiTest override
@@ -309,6 +314,21 @@
     return (volume_it == volumes_.end()) ? nullptr : volume_it->second.get();
   }
 
+  void SshfsMount(const std::string& source_path,
+                  const std::string& source_format,
+                  const std::string& mount_label,
+                  const std::vector<std::string>& mount_options,
+                  chromeos::MountType type,
+                  chromeos::MountAccessMode access_mode) {
+    disk_mount_manager_mock_->NotifyMountEvent(
+        chromeos::disks::DiskMountManager::MountEvent::MOUNTING,
+        chromeos::MountError::MOUNT_ERROR_NONE,
+        chromeos::disks::DiskMountManager::MountPointInfo(
+            source_path, "/media/fuse/" + mount_label,
+            chromeos::MountType::MOUNT_TYPE_NETWORK_STORAGE,
+            chromeos::disks::MountCondition::MOUNT_CONDITION_NONE));
+  }
+
  protected:
   chromeos::disks::MockDiskMountManager* disk_mount_manager_mock_;
   DiskMountManager::DiskMap volumes_;
@@ -485,6 +505,11 @@
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       {features::kCrostini, features::kExperimentalCrostiniUI}, {});
+  crostini::CrostiniManager::GetInstance()->set_skip_restart_for_testing();
+
+  // Profile must be signed in with email for crostini.
+  SigninManagerFactory::GetForProfileIfExists(browser()->profile())
+      ->SetAuthenticatedAccountInfo("12345", "testuser@gmail.com");
 
   ASSERT_TRUE(RunComponentExtensionTest("file_browser/crostini_test"));
 }
diff --git a/chrome/browser/chromeos/external_metrics_unittest.cc b/chrome/browser/chromeos/external_metrics_unittest.cc
index fed0cc6..965252b 100644
--- a/chrome/browser/chromeos/external_metrics_unittest.cc
+++ b/chrome/browser/chromeos/external_metrics_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/metrics/statistics_recorder.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "components/metrics/serialization/metric_sample.h"
 #include "components/metrics/serialization/serialization_utils.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
index fb66d1d..af3b96e 100644
--- a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
@@ -5,7 +5,7 @@
 #include <utility>
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
diff --git a/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc b/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc
index 82bd9f5e..234be67 100644
--- a/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/recent_download_source_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/files/file.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
 #include "chrome/browser/chromeos/fileapi/recent_download_source.h"
diff --git a/chrome/browser/chromeos/fileapi/recent_model_unittest.cc b/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
index 8f4208a5..ea146a3 100644
--- a/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/files/file_path.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/fileapi/recent_file.h"
 #include "chrome/browser/chromeos/fileapi/recent_model.h"
 #include "chrome/browser/chromeos/fileapi/recent_model_factory.h"
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index f3352ee6..2ddeb3e 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/statistics_recorder.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
 #include "chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h"
 #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc b/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
index 32c783f..ec820d9 100644
--- a/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
+++ b/chrome/browser/chromeos/lock_screen_apps/lock_screen_profile_creator_impl_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler_unittest.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler_unittest.cc
index 7e578b3..30013ef 100644
--- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler_unittest.cc
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_screenlock_state_handler_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h"
 #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc b/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc
index 6b43b11f..f77e8b8 100644
--- a/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc
+++ b/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 
 #include "base/metrics/statistics_recorder.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/login/screens/network_error.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 577fe864..df1e9ec 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_test_utils.h"
 #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/chromeos/note_taking_helper_unittest.cc b/chrome/browser/chromeos/note_taking_helper_unittest.cc
index 6ae957e..6d0cdddc 100644
--- a/chrome/browser/chromeos/note_taking_helper_unittest.cc
+++ b/chrome/browser/chromeos/note_taking_helper_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
 #include "chrome/browser/chromeos/note_taking_controller_client.h"
diff --git a/chrome/browser/chromeos/power/power_metrics_reporter_unittest.cc b/chrome/browser/chromeos/power/power_metrics_reporter_unittest.cc
index b721695..cf452bf 100644
--- a/chrome/browser/chromeos/power/power_metrics_reporter_unittest.cc
+++ b/chrome/browser/chromeos/power/power_metrics_reporter_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/fake_power_manager_client.h"
diff --git a/chrome/browser/chromeos/settings/install_attributes_unittest.cc b/chrome/browser/chromeos/settings/install_attributes_unittest.cc
index 7f762f1..8793756 100644
--- a/chrome/browser/chromeos/settings/install_attributes_unittest.cc
+++ b/chrome/browser/chromeos/settings/install_attributes_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
 #include "chromeos/chromeos_paths.h"
 #include "chromeos/cryptohome/tpm_util.h"
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc
index 5f8fa34..b4bf0054 100644
--- a/chrome/browser/chromeos/tether/tether_service_unittest.cc
+++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/timer/mock_timer.h"
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc
index 2c67ed6..4f960e34 100644
--- a/chrome/browser/client_hints/client_hints_browsertest.cc
+++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -8,7 +8,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/stl_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc b/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc
index c49f1dab..b7abf85 100644
--- a/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc
+++ b/chrome/browser/component_updater/sw_reporter_installer_win_unittest.cc
@@ -18,7 +18,7 @@
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "base/version.h"
diff --git a/chrome/browser/conflicts/module_blacklist_cache_util_win.cc b/chrome/browser/conflicts/module_blacklist_cache_util_win.cc
index 4cbc7bd..81c4479 100644
--- a/chrome/browser/conflicts/module_blacklist_cache_util_win.cc
+++ b/chrome/browser/conflicts/module_blacklist_cache_util_win.cc
@@ -75,7 +75,7 @@
   return delta < base::TimeDelta() ? 0 : static_cast<uint32_t>(delta.InHours());
 }
 
-bool ReadModuleBlacklistCache(
+ReadResult ReadModuleBlacklistCache(
     const base::FilePath& module_blacklist_cache_path,
     third_party_dlls::PackedListMetadata* metadata,
     std::vector<third_party_dlls::PackedListModule>* blacklisted_modules,
@@ -88,48 +88,48 @@
                   base::File::FLAG_OPEN | base::File::FLAG_READ |
                       base::File::FLAG_SHARE_DELETE);
   if (!file.IsValid())
-    return false;
+    return ReadResult::kFailOpenFile;
 
   third_party_dlls::PackedListMetadata read_metadata;
   if (!SafeRead(&file, reinterpret_cast<char*>(&read_metadata),
                 sizeof(read_metadata))) {
-    return false;
+    return ReadResult::kFailReadMetadata;
   }
 
   // Make sure the version is supported.
   if (read_metadata.version > third_party_dlls::PackedListVersion::kCurrent)
-    return false;
+    return ReadResult::kFailInvalidVersion;
 
   std::vector<third_party_dlls::PackedListModule> read_blacklisted_modules(
       read_metadata.module_count);
   if (!SafeRead(&file, reinterpret_cast<char*>(read_blacklisted_modules.data()),
                 sizeof(third_party_dlls::PackedListModule) *
                     read_metadata.module_count)) {
-    return false;
+    return ReadResult::kFailReadModules;
   }
 
   // The list should be sorted.
   if (!std::is_sorted(read_blacklisted_modules.begin(),
                       read_blacklisted_modules.end(), internal::ModuleLess())) {
-    return false;
+    return ReadResult::kFailModulesNotSorted;
   }
 
   base::MD5Digest read_md5_digest;
   if (!SafeRead(&file, reinterpret_cast<char*>(&read_md5_digest.a),
                 base::size(read_md5_digest.a))) {
-    return false;
+    return ReadResult::kFailReadMD5;
   }
 
   if (!IsMD5DigestEqual(read_md5_digest,
                         CalculateModuleBlacklistCacheMD5(
                             read_metadata, read_blacklisted_modules))) {
-    return false;
+    return ReadResult::kFailInvalidMD5;
   }
 
   *metadata = read_metadata;
   *blacklisted_modules = std::move(read_blacklisted_modules);
   *md5_digest = read_md5_digest;
-  return true;
+  return ReadResult::kSuccess;
 }
 
 bool WriteModuleBlacklistCache(
diff --git a/chrome/browser/conflicts/module_blacklist_cache_util_win.h b/chrome/browser/conflicts/module_blacklist_cache_util_win.h
index 9523fcd..06e6107 100644
--- a/chrome/browser/conflicts/module_blacklist_cache_util_win.h
+++ b/chrome/browser/conflicts/module_blacklist_cache_util_win.h
@@ -28,11 +28,33 @@
 // (1601-01-01 00:00:00 UTC).
 uint32_t CalculateTimeDateStamp(base::Time time);
 
+// The possible result value when trying to read an existing module blacklist
+// cache. These values are persisted to logs. Entries should not be renumbered
+// and numeric values should never be reused.
+enum class ReadResult {
+  // A valid cache was successfully read.
+  kSuccess = 0,
+  // Failed to open the cache file for reading.
+  kFailOpenFile = 1,
+  // Failed to parse the metadata structure.
+  kFailReadMetadata = 2,
+  // The version of the cache is not supported by the current version of Chrome.
+  kFailInvalidVersion = 3,
+  // Failed to read the entire array of PackedListModule.
+  kFailReadModules = 4,
+  // The cache was rejected because the array was not correctly sorted.
+  kFailModulesNotSorted = 5,
+  // Failed to read the MD5 digest.
+  kFailReadMD5 = 6,
+  // The cache was rejected because the MD5 digest did not match the content.
+  kFailInvalidMD5 = 7,
+  kMaxValue = kFailInvalidMD5
+};
+
 // Reads an existing module blacklist cache at |module_blacklist_cache_path|
-// into |metadata| and |blacklisted_modules|. Returns false on failure or if
-// the md5 digest doesn't match. Failures also does not modify the out
-// arguments.
-bool ReadModuleBlacklistCache(
+// into |metadata| and |blacklisted_modules| and return a ReadResult. Failures
+// do not modify the out arguments.
+ReadResult ReadModuleBlacklistCache(
     const base::FilePath& module_blacklist_cache_path,
     third_party_dlls::PackedListMetadata* metadata,
     std::vector<third_party_dlls::PackedListModule>* blacklisted_modules,
diff --git a/chrome/browser/conflicts/module_blacklist_cache_util_win_unittest.cc b/chrome/browser/conflicts/module_blacklist_cache_util_win_unittest.cc
index 82a589f..0418609 100644
--- a/chrome/browser/conflicts/module_blacklist_cache_util_win_unittest.cc
+++ b/chrome/browser/conflicts/module_blacklist_cache_util_win_unittest.cc
@@ -162,7 +162,8 @@
   third_party_dlls::PackedListMetadata read_metadata;
   std::vector<third_party_dlls::PackedListModule> read_blacklisted_modules;
   base::MD5Digest read_md5_digest;
-  EXPECT_TRUE(
+  EXPECT_EQ(
+      ReadResult::kSuccess,
       ReadModuleBlacklistCache(module_blacklist_cache_path(), &read_metadata,
                                &read_blacklisted_modules, &read_md5_digest));
 
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 005f898..6b4fdc1 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -31,7 +31,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/sys_info.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
diff --git a/chrome/browser/download/download_history.cc b/chrome/browser/download/download_history.cc
index 3c14fa8..5732f63c 100644
--- a/chrome/browser/download/download_history.cc
+++ b/chrome/browser/download/download_history.cc
@@ -299,16 +299,6 @@
   // ManagerGoingDown() may have happened before the history loaded.
   if (!notifier_.GetManager())
     return;
-
-  notifier_.GetManager()->OnHistoryQueryComplete(
-      base::BindOnce(&DownloadHistory::LoadHistoryDownloads,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(infos)));
-}
-
-void DownloadHistory::LoadHistoryDownloads(std::unique_ptr<InfoVector> infos) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(notifier_.GetManager());
-
   for (InfoVector::const_iterator it = infos->begin();
        it != infos->end(); ++it) {
     loading_id_ = history::ToContentDownloadId(it->id);
diff --git a/chrome/browser/download/download_history.h b/chrome/browser/download/download_history.h
index d3cb176..a8452164 100644
--- a/chrome/browser/download/download_history.h
+++ b/chrome/browser/download/download_history.h
@@ -108,10 +108,6 @@
   // table.
   void QueryCallback(std::unique_ptr<std::vector<history::DownloadRow>> infos);
 
-  // Called to create all history downloads.
-  void LoadHistoryDownloads(
-      std::unique_ptr<std::vector<history::DownloadRow>> infos);
-
   // May add |item| to |history_|.
   void MaybeAddToHistory(download::DownloadItem* item);
 
diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc
index 94497fb..79e4a32 100644
--- a/chrome/browser/download/download_target_determiner_unittest.cc
+++ b/chrome/browser/download/download_target_determiner_unittest.cc
@@ -17,7 +17,7 @@
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_path_override.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/value_conversions.h"
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index 2d7ea60..117e5c27 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -20,7 +20,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
diff --git a/chrome/browser/engagement/important_sites_usage_counter_unittest.cc b/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
index d6925f9..0eae133 100644
--- a/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
+++ b/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/engagement/important_sites_util_unittest.cc b/chrome/browser/engagement/important_sites_util_unittest.cc
index 20eea71e..fc961117 100644
--- a/chrome/browser/engagement/important_sites_util_unittest.cc
+++ b/chrome/browser/engagement/important_sites_util_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/sample_vector.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/engagement/site_engagement_score.h"
diff --git a/chrome/browser/engagement/site_engagement_helper_unittest.cc b/chrome/browser/engagement/site_engagement_helper_unittest.cc
index cd2f972..52b96f4 100644
--- a/chrome/browser/engagement/site_engagement_helper_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_helper_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/engagement/site_engagement_helper.h"
 
 #include "base/memory/ptr_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/timer/mock_timer.h"
 #include "base/values.h"
 #include "chrome/browser/engagement/site_engagement_metrics.h"
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc
index bb2f6440..2c45138 100644
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/values.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index 00f02e1..46d2ac4 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -18,7 +18,7 @@
 #include "base/path_service.h"
 #include "base/rand_util.h"
 #include "base/synchronization/lock.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
diff --git a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc
index 34bcef2..b7c13df 100644
--- a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h"
 #include "chrome/browser/extensions/chrome_test_extension_loader.h"
 #include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc
index 042747d..c45a45c 100644
--- a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc
+++ b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc
@@ -51,7 +51,7 @@
   omnibox_view->OnAfterPossibleChange(true);
   WaitForAutocompleteDone(autocomplete_controller);
   EXPECT_TRUE(autocomplete_controller->done());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
 
   // Quickly type another query and accept it before getting suggestions back
   // for the query. The popup will close after accepting input - ensure that it
@@ -71,7 +71,7 @@
   // This checks that the keyword provider (via javascript)
   // gets told to navigate to the string "command".
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
-  EXPECT_FALSE(popup_model->IsDisplayingResults());
+  EXPECT_FALSE(popup_model->IsOpen());
 }
 
 // Tests deleting a deletable omnibox extension suggestion result.
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
index 22bbf3ac..019f769 100644
--- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -182,24 +182,25 @@
 
 std::unique_ptr<KeyedService> ExtensionSessionsTest::BuildProfileSyncService(
     content::BrowserContext* context) {
-  std::unique_ptr<syncer::SyncApiComponentFactoryMock> factory(
-      new syncer::SyncApiComponentFactoryMock());
+  auto factory = std::make_unique<
+      testing::NiceMock<syncer::SyncApiComponentFactoryMock>>();
 
-  factory->SetLocalDeviceInfoProvider(
-      std::unique_ptr<syncer::LocalDeviceInfoProvider>(
-          new syncer::LocalDeviceInfoProviderMock(
-              kSessionTags[0], "machine name", "Chromium 10k", "Chrome 10k",
-              sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id")));
+  ON_CALL(*factory, CreateLocalDeviceInfoProvider())
+      .WillByDefault(testing::Invoke([]() {
+        return std::make_unique<syncer::LocalDeviceInfoProviderMock>(
+            kSessionTags[0], "machine name", "Chromium 10k", "Chrome 10k",
+            sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id");
+      }));
 
   Profile* profile = static_cast<Profile*>(context);
-  browser_sync::ProfileSyncServiceMock* sync_service =
-      new browser_sync::ProfileSyncServiceMock(
-          CreateProfileSyncServiceParamsForTest(
-              std::make_unique<browser_sync::ChromeSyncClient>(profile),
-              profile));
-  static_cast<browser_sync::ChromeSyncClient*>(sync_service->GetSyncClient())
-      ->SetSyncApiComponentFactoryForTesting(std::move(factory));
-  return base::WrapUnique(sync_service);
+  auto sync_client = std::make_unique<browser_sync::ChromeSyncClient>(profile);
+  sync_client->SetSyncApiComponentFactoryForTesting(std::move(factory));
+
+  auto sync_service =
+      std::make_unique<testing::NiceMock<browser_sync::ProfileSyncServiceMock>>(
+          CreateProfileSyncServiceParamsForTest(std::move(sync_client),
+                                                profile));
+  return sync_service;
 }
 
 void ExtensionSessionsTest::CreateTestProfileSyncService() {
diff --git a/chrome/browser/extensions/bookmark_app_navigation_browsertest.h b/chrome/browser/extensions/bookmark_app_navigation_browsertest.h
index c97ab09c..27d6354 100644
--- a/chrome/browser/extensions/bookmark_app_navigation_browsertest.h
+++ b/chrome/browser/extensions/bookmark_app_navigation_browsertest.h
@@ -10,7 +10,7 @@
 
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/ssl/cert_verifier_browser_test.h"
 #include "extensions/common/extension.h"
diff --git a/chrome/browser/extensions/bookmark_app_navigation_throttle_browsertest.cc b/chrome/browser/extensions/bookmark_app_navigation_throttle_browsertest.cc
index a8f77fda..66fc560 100644
--- a/chrome/browser/extensions/bookmark_app_navigation_throttle_browsertest.cc
+++ b/chrome/browser/extensions/bookmark_app_navigation_throttle_browsertest.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 "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part_unittest.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part_unittest.cc
index 1c11afe5..fb0f1a6 100644
--- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part_unittest.cc
+++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part_unittest.cc
@@ -7,7 +7,7 @@
 #include <string>
 #include <vector>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/common/chrome_content_client.h"
 #include "extensions/common/url_pattern_set.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/extension_functional_browsertest.cc b/chrome/browser/extensions/extension_functional_browsertest.cc
index 0f33f9c1..3e4c631 100644
--- a/chrome/browser/extensions/extension_functional_browsertest.cc
+++ b/chrome/browser/extensions/extension_functional_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include <stddef.h>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
diff --git a/chrome/browser/extensions/favicon_downloader_unittest.cc b/chrome/browser/extensions/favicon_downloader_unittest.cc
index 9152d5a..57440d6e 100644
--- a/chrome/browser/extensions/favicon_downloader_unittest.cc
+++ b/chrome/browser/extensions/favicon_downloader_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/bind.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/common/favicon_url.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc b/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc
index b361949a..04bc7f9 100644
--- a/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc
+++ b/chrome/browser/extensions/forced_extensions/installation_tracker_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/extensions/forced_extensions/installation_tracker.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/timer/mock_timer.h"
 #include "base/values.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 4a770b0..44bd85a 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -12,7 +12,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc
index ab8b96f..4d0533a 100644
--- a/chrome/browser/extensions/window_open_apitest.cc
+++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -6,7 +6,7 @@
 
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index 79d6f211..8bf2f13 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -162,7 +162,7 @@
 
   void OnExtensionSystemReady(content::BrowserContext* context) {
     // Process the notification and delete this.
-    ExtensionService* service =
+    extensions::ExtensionService* service =
         extensions::ExtensionSystem::Get(context)->extension_service();
     if (service) {
       // Trigger an extension update check. If the extension specified in the
diff --git a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc
index 855bfa7..7b90e3f 100644
--- a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc
@@ -21,7 +21,7 @@
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/clock.h"
diff --git a/chrome/browser/history/chrome_history_backend_client.cc b/chrome/browser/history/chrome_history_backend_client.cc
index c2d53c8d7..02bff04 100644
--- a/chrome/browser/history/chrome_history_backend_client.cc
+++ b/chrome/browser/history/chrome_history_backend_client.cc
@@ -6,7 +6,8 @@
 
 #include "build/build_config.h"
 #include "chrome/common/channel_info.h"
-#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/history_bookmark_model.h"
+#include "components/bookmarks/browser/model_loader.h"
 #include "components/bookmarks/browser/url_and_title.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -27,35 +28,34 @@
 #endif
 
 ChromeHistoryBackendClient::ChromeHistoryBackendClient(
-    bookmarks::BookmarkModel* bookmark_model)
-    : bookmark_model_(bookmark_model) {
-}
+    bookmarks::ModelLoader* model_loader)
+    : model_loader_(model_loader) {}
 
 ChromeHistoryBackendClient::~ChromeHistoryBackendClient() {
 }
 
 bool ChromeHistoryBackendClient::IsBookmarked(const GURL& url) {
-  if (!bookmark_model_)
+  if (!model_loader_)
     return false;
 
   // HistoryBackendClient is used to determine if an URL is bookmarked. The data
   // is loaded on a separate thread and may not be done when this method is
   // called, therefore blocks until the bookmarks have finished loading.
-  bookmark_model_->BlockTillLoaded();
-  return bookmark_model_->IsBookmarked(url);
+  model_loader_->BlockTillLoaded();
+  return model_loader_->history_bookmark_model()->IsBookmarked(url);
 }
 
 void ChromeHistoryBackendClient::GetBookmarks(
     std::vector<history::URLAndTitle>* bookmarks) {
-  if (!bookmark_model_)
+  if (!model_loader_)
     return;
 
   // HistoryBackendClient is used to determine the set of bookmarked URLs. The
   // data is loaded on a separate thread and may not be done when this method is
   // called, therefore blocks until the bookmarks have finished loading.
   std::vector<bookmarks::UrlAndTitle> url_and_titles;
-  bookmark_model_->BlockTillLoaded();
-  bookmark_model_->GetBookmarks(&url_and_titles);
+  model_loader_->BlockTillLoaded();
+  model_loader_->history_bookmark_model()->GetBookmarks(&url_and_titles);
 
   bookmarks->reserve(bookmarks->size() + url_and_titles.size());
   for (const auto& url_and_title : url_and_titles) {
diff --git a/chrome/browser/history/chrome_history_backend_client.h b/chrome/browser/history/chrome_history_backend_client.h
index 7d689f5..aa9109c 100644
--- a/chrome/browser/history/chrome_history_backend_client.h
+++ b/chrome/browser/history/chrome_history_backend_client.h
@@ -6,18 +6,19 @@
 #define CHROME_BROWSER_HISTORY_CHROME_HISTORY_BACKEND_CLIENT_H_
 
 #include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "components/history/core/browser/history_backend_client.h"
 
 namespace bookmarks {
-class BookmarkModel;
+class ModelLoader;
 }
 
 // ChromeHistoryBackendClient implements history::HistoryBackendClient interface
 // to provides access to embedder-specific features.
 class ChromeHistoryBackendClient : public history::HistoryBackendClient {
  public:
-  explicit ChromeHistoryBackendClient(bookmarks::BookmarkModel* bookmark_model);
+  explicit ChromeHistoryBackendClient(bookmarks::ModelLoader* model_loader);
   ~ChromeHistoryBackendClient() override;
 
   // history::HistoryBackendClient implementation.
@@ -36,9 +37,8 @@
 #endif  // defined(OS_ANDROID)
 
  private:
-  // BookmarkModel instance providing access to bookmarks. May be null during
-  // testing but must outlive ChromeHistoryBackendClient if non-null.
-  bookmarks::BookmarkModel* bookmark_model_;
+  // ModelLoader is used to access bookmarks. May be null during testing.
+  scoped_refptr<bookmarks::ModelLoader> model_loader_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeHistoryBackendClient);
 };
diff --git a/chrome/browser/history/chrome_history_client.cc b/chrome/browser/history/chrome_history_client.cc
index 1e4bda2..808f5cf 100644
--- a/chrome/browser/history/chrome_history_client.cc
+++ b/chrome/browser/history/chrome_history_client.cc
@@ -16,15 +16,17 @@
 
 ChromeHistoryClient::ChromeHistoryClient(
     bookmarks::BookmarkModel* bookmark_model)
-    : bookmark_model_(bookmark_model), is_bookmark_model_observer_(false) {
+    : bookmark_model_(bookmark_model) {
+  if (bookmark_model_)
+    bookmark_model_->AddObserver(this);
 }
 
 ChromeHistoryClient::~ChromeHistoryClient() {
+  StopObservingBookmarkModel();
 }
 
 void ChromeHistoryClient::OnHistoryServiceCreated(
     history::HistoryService* history_service) {
-  DCHECK(!is_bookmark_model_observer_);
   if (bookmark_model_) {
     on_bookmarks_removed_ =
         base::Bind(&history::HistoryService::URLsNoLongerBookmarked,
@@ -33,28 +35,12 @@
         history_service->AddFaviconsChangedCallback(
             base::Bind(&bookmarks::BookmarkModel::OnFaviconsChanged,
                        base::Unretained(bookmark_model_)));
-    bookmark_model_->AddObserver(this);
-    is_bookmark_model_observer_ = true;
   }
 }
 
 void ChromeHistoryClient::Shutdown() {
-  // It's possible that bookmarks haven't loaded and history is waiting for
-  // bookmarks to complete loading. In such a situation history can't shutdown
-  // (meaning if we invoked HistoryService::Cleanup now, we would deadlock). To
-  // break the deadlock we tell BookmarkModel it's about to be deleted so that
-  // it can release the signal history is waiting on, allowing history to
-  // shutdown (HistoryService::Cleanup to complete). In such a scenario history
-  // sees an incorrect view of bookmarks, but it's better than a deadlock.
-  if (bookmark_model_) {
-    if (is_bookmark_model_observer_) {
-      is_bookmark_model_observer_ = false;
-      bookmark_model_->RemoveObserver(this);
-      favicons_changed_subscription_.reset();
-      on_bookmarks_removed_.Reset();
-    }
-    bookmark_model_->Shutdown();
-  }
+  favicons_changed_subscription_.reset();
+  StopObservingBookmarkModel();
 }
 
 bool ChromeHistoryClient::CanAddURL(const GURL& url) {
@@ -69,12 +55,26 @@
 
 std::unique_ptr<history::HistoryBackendClient>
 ChromeHistoryClient::CreateBackendClient() {
-  return std::make_unique<ChromeHistoryBackendClient>(bookmark_model_);
+  return std::make_unique<ChromeHistoryBackendClient>(
+      bookmark_model_ ? bookmark_model_->model_loader() : nullptr);
+}
+
+void ChromeHistoryClient::StopObservingBookmarkModel() {
+  if (!bookmark_model_)
+    return;
+  bookmark_model_->RemoveObserver(this);
+  bookmark_model_ = nullptr;
 }
 
 void ChromeHistoryClient::BookmarkModelChanged() {
 }
 
+void ChromeHistoryClient::BookmarkModelBeingDeleted(
+    bookmarks::BookmarkModel* model) {
+  DCHECK_EQ(model, bookmark_model_);
+  StopObservingBookmarkModel();
+}
+
 void ChromeHistoryClient::BookmarkNodeRemoved(
     bookmarks::BookmarkModel* bookmark_model,
     const bookmarks::BookmarkNode* parent,
@@ -83,8 +83,8 @@
     const std::set<GURL>& removed_urls) {
   BaseBookmarkModelObserver::BookmarkNodeRemoved(bookmark_model, parent,
                                                  old_index, node, removed_urls);
-  DCHECK(!on_bookmarks_removed_.is_null());
-  on_bookmarks_removed_.Run(removed_urls);
+  if (on_bookmarks_removed_)
+    on_bookmarks_removed_.Run(removed_urls);
 }
 
 void ChromeHistoryClient::BookmarkAllUserNodesRemoved(
@@ -92,6 +92,6 @@
     const std::set<GURL>& removed_urls) {
   BaseBookmarkModelObserver::BookmarkAllUserNodesRemoved(bookmark_model,
                                                          removed_urls);
-  DCHECK(!on_bookmarks_removed_.is_null());
-  on_bookmarks_removed_.Run(removed_urls);
+  if (on_bookmarks_removed_)
+    on_bookmarks_removed_.Run(removed_urls);
 }
diff --git a/chrome/browser/history/chrome_history_client.h b/chrome/browser/history/chrome_history_client.h
index e274eca..775c21b 100644
--- a/chrome/browser/history/chrome_history_client.h
+++ b/chrome/browser/history/chrome_history_client.h
@@ -39,10 +39,11 @@
   std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override;
 
  private:
+  void StopObservingBookmarkModel();
+
   // bookmarks::BaseBookmarkModelObserver implementation.
   void BookmarkModelChanged() override;
-
-  // bookmarks::BookmarkModelObserver implementation.
+  void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override;
   void BookmarkNodeRemoved(bookmarks::BookmarkModel* bookmark_model,
                            const bookmarks::BookmarkNode* parent,
                            int old_index,
@@ -52,9 +53,8 @@
                                    const std::set<GURL>& removed_urls) override;
 
   // BookmarkModel instance providing access to bookmarks. May be null during
-  // testing but must outlive ChromeHistoryClient if non-null.
+  // testing, and is null while shutting down.
   bookmarks::BookmarkModel* bookmark_model_;
-  bool is_bookmark_model_observer_;
 
   // Callback invoked when URLs are removed from BookmarkModel.
   base::Callback<void(const std::set<GURL>&)> on_bookmarks_removed_;
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc
index 6a59814..20c4e176 100644
--- a/chrome/browser/installable/installable_manager_browsertest.cc
+++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/banners/app_banner_manager_desktop.h"
 #include "chrome/browser/installable/installable_manager.h"
 #include "chrome/browser/installable/installable_metrics.h"
diff --git a/chrome/browser/lifetime/browser_shutdown_browsertest.cc b/chrome/browser/lifetime/browser_shutdown_browsertest.cc
index 1f6ecdc..f320f82 100644
--- a/chrome/browser/lifetime/browser_shutdown_browsertest.cc
+++ b/chrome/browser/lifetime/browser_shutdown_browsertest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/chrome_notification_types.h"
diff --git a/chrome/browser/mac/exception_processor_unittest.mm b/chrome/browser/mac/exception_processor_unittest.mm
index 8ef87aca..7c52d422 100644
--- a/chrome/browser/mac/exception_processor_unittest.mm
+++ b/chrome/browser/mac/exception_processor_unittest.mm
@@ -9,7 +9,7 @@
 #include <sys/wait.h>
 
 #include "base/mac/os_crash_dumps.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/media/media_engagement_contents_observer_unittest.cc b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
index 3747473..25168e0 100644
--- a/chrome/browser/media/media_engagement_contents_observer_unittest.cc
+++ b/chrome/browser/media/media_engagement_contents_observer_unittest.cc
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/optional.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/test_mock_time_task_runner.h"
diff --git a/chrome/browser/media/media_engagement_preloaded_list_unittest.cc b/chrome/browser/media/media_engagement_preloaded_list_unittest.cc
index 75ace4e..251184f 100644
--- a/chrome/browser/media/media_engagement_preloaded_list_unittest.cc
+++ b/chrome/browser/media/media_engagement_preloaded_list_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/path_service.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/media/media_engagement_service_unittest.cc b/chrome/browser/media/media_engagement_service_unittest.cc
index 0bb43766..c17f714 100644
--- a/chrome/browser/media/media_engagement_service_unittest.cc
+++ b/chrome/browser/media/media_engagement_service_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/values.h"
diff --git a/chrome/browser/media/media_engagement_session_unittest.cc b/chrome/browser/media/media_engagement_session_unittest.cc
index 9520b50c..4d1c044 100644
--- a/chrome/browser/media/media_engagement_session_unittest.cc
+++ b/chrome/browser/media/media_engagement_session_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/media/media_engagement_session.h"
 
 #include "base/memory/scoped_refptr.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/media/media_engagement_service.h"
 #include "chrome/test/base/testing_profile.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 de15c858..b6f287d 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
@@ -3,9 +3,10 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h"
+
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
diff --git a/chrome/browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc b/chrome/browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc
index 7eb2067e..281b39c 100644
--- a/chrome/browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc
+++ b/chrome/browser/media/router/discovery/media_sink_discovery_metrics_unittest.cc
@@ -3,9 +3,10 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/media/router/discovery/media_sink_discovery_metrics.h"
+
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/media/router/event_page_request_manager_unittest.cc b/chrome/browser/media/router/event_page_request_manager_unittest.cc
index eb2fb2e..e98562d 100644
--- a/chrome/browser/media/router/event_page_request_manager_unittest.cc
+++ b/chrome/browser/media/router/event_page_request_manager_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/media/router/media_router_metrics_unittest.cc b/chrome/browser/media/router/media_router_metrics_unittest.cc
index 6002a86..a5dc0907 100644
--- a/chrome/browser/media/router/media_router_metrics_unittest.cc
+++ b/chrome/browser/media/router/media_router_metrics_unittest.cc
@@ -3,9 +3,10 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/media/router/media_router_metrics.h"
+
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/ui/media_router/media_cast_mode.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 c4528cf7..5ea9e4d 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
@@ -14,7 +14,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/media/router/media_router_factory.h"
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_metrics_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_metrics_unittest.cc
index 07e982c..4d0d864 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_metrics_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_metrics_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/version.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc
index cb7f58c..5dce17b 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc
@@ -3,7 +3,8 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h"
-#include "base/test/histogram_tester.h"
+
+#include "base/test/metrics/histogram_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc b/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
index f24e690c..5c80bf6 100644
--- a/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
+++ b/chrome/browser/metrics/antivirus_metrics_provider_win_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/sys_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_checker.h"
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
index 6c7a7c5..497c0614 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_service_manager_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc
index 83dd398..f103184e 100644
--- a/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc
+++ b/chrome/browser/metrics/chrome_stability_metrics_provider_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc
index c3435587..028fb65a 100644
--- a/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc
+++ b/chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/platform_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/metrics/metrics_service_browsertest.cc b/chrome/browser/metrics/metrics_service_browsertest.cc
index fbd9d10..1fff89e 100644
--- a/chrome/browser/metrics/metrics_service_browsertest.cc
+++ b/chrome/browser/metrics/metrics_service_browsertest.cc
@@ -14,7 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/process/memory.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_restrictions.h"
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
index 897acc2..9a3c183 100644
--- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
+++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/trace_event_analyzer.h"
 #include "base/trace_event/memory_dump_manager.h"
diff --git a/chrome/browser/metrics/tab_stats_tracker_browsertest.cc b/chrome/browser/metrics/tab_stats_tracker_browsertest.cc
index 4b4abc2..73811bf 100644
--- a/chrome/browser/metrics/tab_stats_tracker_browsertest.cc
+++ b/chrome/browser/metrics/tab_stats_tracker_browsertest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/metrics/tab_stats_tracker.h"
 
 #include "base/containers/flat_map.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/metrics/tab_stats_tracker_unittest.cc b/chrome/browser/metrics/tab_stats_tracker_unittest.cc
index ac41f6f..0ae52a8 100644
--- a/chrome/browser/metrics/tab_stats_tracker_unittest.cc
+++ b/chrome/browser/metrics/tab_stats_tracker_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <algorithm>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/power_monitor_test_base.h"
 #include "base/test/scoped_task_environment.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/metrics/upgrade_metrics_provider_unittest.cc b/chrome/browser/metrics/upgrade_metrics_provider_unittest.cc
index d5667f1b..c5a0135 100644
--- a/chrome/browser/metrics/upgrade_metrics_provider_unittest.cc
+++ b/chrome/browser/metrics/upgrade_metrics_provider_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/metrics/upgrade_metrics_provider.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc
index 6b04e48e..bdcca894 100644
--- a/chrome/browser/net/chrome_network_delegate_unittest.cc
+++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
diff --git a/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc b/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc
index 247af1a..7f01ea53 100644
--- a/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc
+++ b/chrome/browser/net/nqe/ui_network_quality_estimator_service_browsertest.cc
@@ -9,7 +9,7 @@
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h"
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc
index ac06227..b6dc02b 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_unittest.cc
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/message_loop/message_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.cc b/chrome/browser/net/trial_comparison_cert_verifier.cc
index e1855039..ecf442b2 100644
--- a/chrome/browser/net/trial_comparison_cert_verifier.cc
+++ b/chrome/browser/net/trial_comparison_cert_verifier.cc
@@ -22,10 +22,14 @@
 #include "chrome/common/chrome_features.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "content/public/browser/browser_thread.h"
+#include "crypto/sha2.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_verify_proc.h"
 #include "net/cert/cert_verify_result.h"
 #include "net/cert/crl_set.h"
+#include "net/cert/ev_root_ca_metadata.h"
+#include "net/cert/internal/cert_errors.h"
+#include "net/cert/internal/parsed_certificate.h"
 #include "net/cert/multi_threaded_cert_verifier.h"
 #include "net/cert/x509_util.h"
 #include "net/log/net_log.h"
@@ -116,6 +120,81 @@
           a.verified_cert->EqualsIncludingChain(b.verified_cert.get()));
 }
 
+scoped_refptr<net::ParsedCertificate> ParsedCertificateFromBuffer(
+    CRYPTO_BUFFER* cert_handle,
+    net::CertErrors* errors) {
+  return net::ParsedCertificate::Create(
+      net::x509_util::DupCryptoBuffer(cert_handle),
+      net::x509_util::DefaultParseCertificateOptions(), errors);
+}
+
+net::ParsedCertificateList ParsedCertificateListFromX509Certificate(
+    const net::X509Certificate* cert) {
+  net::CertErrors parsing_errors;
+
+  net::ParsedCertificateList certs;
+  scoped_refptr<net::ParsedCertificate> target =
+      ParsedCertificateFromBuffer(cert->cert_buffer(), &parsing_errors);
+  if (!target)
+    return {};
+  certs.push_back(target);
+
+  for (const auto& buf : cert->intermediate_buffers()) {
+    scoped_refptr<net::ParsedCertificate> intermediate =
+        ParsedCertificateFromBuffer(buf.get(), &parsing_errors);
+    if (!intermediate)
+      return {};
+    certs.push_back(intermediate);
+  }
+
+  return certs;
+}
+
+// Tests whether cert has multiple EV policies, and at least one matches the
+// root. This is not a complete test of EV, but just enough to give a possible
+// explanation as to why the platform verifier did not validate as EV while
+// builtin did. (Since only the builtin verifier correctly handles multiple
+// candidate EV policies.)
+bool CertHasMultipleEVPoliciesAndOneMatchesRoot(
+    const net::X509Certificate* cert) {
+  if (cert->intermediate_buffers().empty())
+    return false;
+
+  net::ParsedCertificateList certs =
+      ParsedCertificateListFromX509Certificate(cert);
+  if (certs.empty())
+    return false;
+
+  net::ParsedCertificate* leaf = certs.front().get();
+  net::ParsedCertificate* root = certs.back().get();
+
+  if (!leaf->has_policy_oids())
+    return false;
+
+  const net::EVRootCAMetadata* ev_metadata =
+      net::EVRootCAMetadata::GetInstance();
+  std::set<net::der::Input> candidate_oids;
+  for (const net::der::Input& oid : leaf->policy_oids()) {
+    if (ev_metadata->IsEVPolicyOIDGivenBytes(oid))
+      candidate_oids.insert(oid);
+  }
+
+  if (candidate_oids.size() <= 1)
+    return false;
+
+  net::SHA256HashValue root_fingerprint;
+  crypto::SHA256HashString(root->der_cert().AsStringPiece(),
+                           root_fingerprint.data,
+                           sizeof(root_fingerprint.data));
+
+  for (const net::der::Input& oid : candidate_oids) {
+    if (ev_metadata->HasEVPolicyOIDGivenBytes(root_fingerprint, oid))
+      return true;
+  }
+
+  return false;
+}
+
 }  // namespace
 
 class TrialComparisonCertVerifier::TrialVerificationJob {
@@ -250,6 +329,24 @@
     }
 #endif
 
+    bool chains_equal = primary_result_.verified_cert &&
+                        trial_result_.verified_cert &&
+                        primary_result_.verified_cert->EqualsIncludingChain(
+                            trial_result_.verified_cert.get());
+
+    if (chains_equal && (trial_result_.cert_status & net::CERT_STATUS_IS_EV) &&
+        !(primary_result_.cert_status & net::CERT_STATUS_IS_EV) &&
+        (primary_error_ == trial_error_)) {
+      // The platform CertVerifyProc impls only check a single potential EV
+      // policy from the leaf.  If the leaf had multiple policies, builtin
+      // verifier may verify it as EV when the platform verifier did not.
+      if (CertHasMultipleEVPoliciesAndOneMatchesRoot(
+              trial_result_.verified_cert.get())) {
+        FinishSuccess(kIgnoredMultipleEVPoliciesAndOneMatchesRoot);
+        return;
+      }
+    }
+
     FinishWithError();
   }
 
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.h b/chrome/browser/net/trial_comparison_cert_verifier.h
index 89e7107..af5630b 100644
--- a/chrome/browser/net/trial_comparison_cert_verifier.h
+++ b/chrome/browser/net/trial_comparison_cert_verifier.h
@@ -29,7 +29,8 @@
     kBothValidDifferentDetails = 4,
     kBothErrorDifferentDetails = 5,
     kIgnoredMacUndesiredRevocationChecking = 6,
-    kMaxValue = kIgnoredMacUndesiredRevocationChecking
+    kIgnoredMultipleEVPoliciesAndOneMatchesRoot = 7,
+    kMaxValue = kIgnoredMultipleEVPoliciesAndOneMatchesRoot
   };
 
   TrialComparisonCertVerifier(
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
index 0222cca15..90970ed 100644
--- a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
+++ b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/net/trial_comparison_cert_verifier.h"
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h"
@@ -13,6 +13,7 @@
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/ssl/cert_logger.pb.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -20,10 +21,12 @@
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "crypto/sha2.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
 #include "net/cert/cert_verify_proc.h"
 #include "net/cert/cert_verify_result.h"
+#include "net/cert/ev_root_ca_metadata.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util.h"
 #include "net/log/net_log_with_source.h"
@@ -1203,3 +1206,211 @@
 
   ASSERT_EQ(1U, full_reports.size());
 }
+
+TEST_F(TrialComparisonCertVerifierTest, MultipleEVPolicies) {
+  base::FilePath certs_dir;
+  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &certs_dir));
+  certs_dir = certs_dir.AppendASCII("net")
+                  .AppendASCII("trial_comparison_cert_verifier_unittest")
+                  .AppendASCII("target-multiple-policies");
+  scoped_refptr<net::X509Certificate> cert_chain =
+      CreateCertificateChainFromFile(certs_dir, "chain.pem",
+                                     net::X509Certificate::FORMAT_AUTO);
+  ASSERT_TRUE(cert_chain);
+  ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
+
+  net::SHA256HashValue root_fingerprint;
+  crypto::SHA256HashString(net::x509_util::CryptoBufferAsStringPiece(
+                               cert_chain->intermediate_buffers().back().get()),
+                           root_fingerprint.data,
+                           sizeof(root_fingerprint.data));
+
+  // Both policies in the target are EV policies, but only 1.2.6.7 is valid for
+  // the root in this chain.
+  net::ScopedTestEVPolicy scoped_ev_policy_1(
+      net::EVRootCAMetadata::GetInstance(), root_fingerprint, "1.2.6.7");
+  net::ScopedTestEVPolicy scoped_ev_policy_2(
+      net::EVRootCAMetadata::GetInstance(), net::SHA256HashValue(), "1.2.3.4");
+
+  // Both verifiers return OK, but secondary returns EV status.
+  net::CertVerifyResult primary_result;
+  primary_result.verified_cert = cert_chain;
+  scoped_refptr<FakeCertVerifyProc> verify_proc1 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, primary_result);
+
+  net::CertVerifyResult secondary_result;
+  secondary_result.verified_cert = cert_chain;
+  secondary_result.cert_status =
+      net::CERT_STATUS_IS_EV | net::CERT_STATUS_REV_CHECKING_ENABLED;
+  scoped_refptr<FakeCertVerifyProc> verify_proc2 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, secondary_result);
+
+  TrialComparisonCertVerifier verifier(profile(), verify_proc1, verify_proc2);
+
+  net::CertVerifier::RequestParams params(
+      leaf_cert_1_, "127.0.0.1", 0 /* flags */,
+      std::string() /* ocsp_response */, {} /* additional_trust_anchors */);
+  net::CertVerifyResult result;
+  net::TestCompletionCallback callback;
+  std::unique_ptr<net::CertVerifier::Request> request;
+  int error =
+      verifier.Verify(params, nullptr /* crl_set */, &result,
+                      callback.callback(), &request, net::NetLogWithSource());
+  ASSERT_THAT(error, IsError(net::ERR_IO_PENDING));
+  EXPECT_TRUE(request);
+
+  error = callback.WaitForResult();
+  EXPECT_THAT(error, IsError(net::OK));
+
+  verify_proc2->WaitForVerifyCall();
+
+  // Expect no report.
+  reporting_service_test_helper()->ExpectNoRequests(service());
+
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
+                               1);
+  histograms_.ExpectUniqueSample(
+      "Net.CertVerifier_TrialComparisonResult",
+      TrialComparisonCertVerifier::kIgnoredMultipleEVPoliciesAndOneMatchesRoot,
+      1);
+}
+
+TEST_F(TrialComparisonCertVerifierTest, MultipleEVPoliciesNoneValidForRoot) {
+  base::FilePath certs_dir;
+  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &certs_dir));
+  certs_dir = certs_dir.AppendASCII("net")
+                  .AppendASCII("trial_comparison_cert_verifier_unittest")
+                  .AppendASCII("target-multiple-policies");
+  scoped_refptr<net::X509Certificate> cert_chain =
+      CreateCertificateChainFromFile(certs_dir, "chain.pem",
+                                     net::X509Certificate::FORMAT_AUTO);
+  ASSERT_TRUE(cert_chain);
+
+  // Both policies in the target are EV policies, but neither is valid for the
+  // root in this chain.
+  net::ScopedTestEVPolicy scoped_ev_policy_1(
+      net::EVRootCAMetadata::GetInstance(), {1}, "1.2.6.7");
+  net::ScopedTestEVPolicy scoped_ev_policy_2(
+      net::EVRootCAMetadata::GetInstance(), {2}, "1.2.3.4");
+
+  // Both verifiers return OK, but secondary returns EV status.
+  net::CertVerifyResult primary_result;
+  primary_result.verified_cert = cert_chain;
+  scoped_refptr<FakeCertVerifyProc> verify_proc1 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, primary_result);
+
+  net::CertVerifyResult secondary_result;
+  secondary_result.verified_cert = cert_chain;
+  secondary_result.cert_status =
+      net::CERT_STATUS_IS_EV | net::CERT_STATUS_REV_CHECKING_ENABLED;
+  scoped_refptr<FakeCertVerifyProc> verify_proc2 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, secondary_result);
+
+  TrialComparisonCertVerifier verifier(profile(), verify_proc1, verify_proc2);
+
+  net::CertVerifier::RequestParams params(
+      leaf_cert_1_, "127.0.0.1", 0 /* flags */,
+      std::string() /* ocsp_response */, {} /* additional_trust_anchors */);
+  net::CertVerifyResult result;
+  net::TestCompletionCallback callback;
+  std::unique_ptr<net::CertVerifier::Request> request;
+  int error =
+      verifier.Verify(params, nullptr /* crl_set */, &result,
+                      callback.callback(), &request, net::NetLogWithSource());
+  ASSERT_THAT(error, IsError(net::ERR_IO_PENDING));
+  EXPECT_TRUE(request);
+
+  error = callback.WaitForResult();
+  EXPECT_THAT(error, IsError(net::OK));
+
+  verify_proc2->WaitForVerifyCall();
+
+  // Expect a report.
+  std::vector<std::string> full_reports;
+  reporting_service_test_helper()->WaitForRequestsDestroyed(
+      ReportExpectation::Successful({{"127.0.0.1", RetryStatus::NOT_RETRIED}}),
+      &full_reports);
+
+  ASSERT_EQ(1U, full_reports.size());
+
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
+                               1);
+  histograms_.ExpectUniqueSample(
+      "Net.CertVerifier_TrialComparisonResult",
+      TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
+}
+
+TEST_F(TrialComparisonCertVerifierTest, MultiplePoliciesOnlyOneIsEV) {
+  base::FilePath certs_dir;
+  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &certs_dir));
+  certs_dir = certs_dir.AppendASCII("net")
+                  .AppendASCII("trial_comparison_cert_verifier_unittest")
+                  .AppendASCII("target-multiple-policies");
+  scoped_refptr<net::X509Certificate> cert_chain =
+      CreateCertificateChainFromFile(certs_dir, "chain.pem",
+                                     net::X509Certificate::FORMAT_AUTO);
+  ASSERT_TRUE(cert_chain);
+  ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
+
+  net::SHA256HashValue root_fingerprint;
+  crypto::SHA256HashString(net::x509_util::CryptoBufferAsStringPiece(
+                               cert_chain->intermediate_buffers().back().get()),
+                           root_fingerprint.data,
+                           sizeof(root_fingerprint.data));
+
+  // One policy in the target is an EV policy and is valid for the root.
+  net::ScopedTestEVPolicy scoped_ev_policy_1(
+      net::EVRootCAMetadata::GetInstance(), root_fingerprint, "1.2.6.7");
+
+  // Both verifiers return OK, but secondary returns EV status.
+  net::CertVerifyResult primary_result;
+  primary_result.verified_cert = cert_chain;
+  scoped_refptr<FakeCertVerifyProc> verify_proc1 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, primary_result);
+
+  net::CertVerifyResult secondary_result;
+  secondary_result.verified_cert = cert_chain;
+  secondary_result.cert_status =
+      net::CERT_STATUS_IS_EV | net::CERT_STATUS_REV_CHECKING_ENABLED;
+  scoped_refptr<FakeCertVerifyProc> verify_proc2 =
+      base::MakeRefCounted<FakeCertVerifyProc>(net::OK, secondary_result);
+
+  TrialComparisonCertVerifier verifier(profile(), verify_proc1, verify_proc2);
+
+  net::CertVerifier::RequestParams params(
+      leaf_cert_1_, "127.0.0.1", 0 /* flags */,
+      std::string() /* ocsp_response */, {} /* additional_trust_anchors */);
+  net::CertVerifyResult result;
+  net::TestCompletionCallback callback;
+  std::unique_ptr<net::CertVerifier::Request> request;
+  int error =
+      verifier.Verify(params, nullptr /* crl_set */, &result,
+                      callback.callback(), &request, net::NetLogWithSource());
+  ASSERT_THAT(error, IsError(net::ERR_IO_PENDING));
+  EXPECT_TRUE(request);
+
+  error = callback.WaitForResult();
+  EXPECT_THAT(error, IsError(net::OK));
+
+  verify_proc2->WaitForVerifyCall();
+
+  // Expect a report.
+  std::vector<std::string> full_reports;
+  reporting_service_test_helper()->WaitForRequestsDestroyed(
+      ReportExpectation::Successful({{"127.0.0.1", RetryStatus::NOT_RETRIED}}),
+      &full_reports);
+
+  ASSERT_EQ(1U, full_reports.size());
+
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
+  histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
+                               1);
+  histograms_.ExpectUniqueSample(
+      "Net.CertVerifier_TrialComparisonResult",
+      TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
+}
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
index 05b3847..d8adffb 100644
--- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
+++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -13,7 +13,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/user_action_tester.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
index d759fd5..0d16d0d 100644
--- a/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
+++ b/chrome/browser/offline_pages/background_loader_offliner_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/bind.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #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"
@@ -67,9 +67,9 @@
   void SavePage(const SavePageParams& save_page_params,
                 std::unique_ptr<OfflinePageArchiver> archiver,
                 content::WebContents* web_contents,
-                const SavePageCallback& callback) override {
+                SavePageCallback callback) override {
     mock_saving_ = true;
-    save_page_callback_ = callback;
+    save_page_callback_ = std::move(callback);
     save_page_params_ = save_page_params;
   }
 
@@ -77,7 +77,7 @@
     DCHECK(mock_saving_);
     mock_saving_ = false;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(save_page_callback_,
+        FROM_HERE, base::BindOnce(std::move(save_page_callback_),
                                   SavePageResult::ARCHIVE_CREATION_FAILED, 0));
   }
 
@@ -85,15 +85,15 @@
     DCHECK(mock_saving_);
     mock_saving_ = false;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(save_page_callback_, SavePageResult::SUCCESS, 123456));
+        FROM_HERE, base::BindOnce(std::move(save_page_callback_),
+                                  SavePageResult::SUCCESS, 123456));
   }
 
   void CompleteSavingAsAlreadyExists() {
     DCHECK(mock_saving_);
     mock_saving_ = false;
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(save_page_callback_,
+        FROM_HERE, base::BindOnce(std::move(save_page_callback_),
                                   SavePageResult::ALREADY_EXISTS, 123456));
   }
 
diff --git a/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc b/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc
index 41aa0d0..5493834 100644
--- a/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc
+++ b/chrome/browser/offline_pages/offline_page_mhtml_archiver.cc
@@ -58,10 +58,10 @@
     const base::FilePath& archives_dir,
     const CreateArchiveParams& create_archive_params,
     content::WebContents* web_contents,
-    const CreateArchiveCallback& callback) {
+    CreateArchiveCallback callback) {
   DCHECK(callback_.is_null());
   DCHECK(!callback.is_null());
-  callback_ = callback;
+  callback_ = std::move(callback);
 
   // TODO(chili): crbug/710248 These checks should probably be done inside
   // the offliner.
@@ -154,9 +154,9 @@
     return;
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(callback_, this, ArchiverResult::SUCCESSFULLY_CREATED, url,
-                 file_path, title, file_size, digest));
+      FROM_HERE, base::BindOnce(std::move(callback_), this,
+                                ArchiverResult::SUCCESSFULLY_CREATED, url,
+                                file_path, title, file_size, digest));
 }
 
 bool OfflinePageMHTMLArchiver::HasConnectionSecurityError(
@@ -187,8 +187,9 @@
 void OfflinePageMHTMLArchiver::ReportFailure(ArchiverResult result) {
   DCHECK(result != ArchiverResult::SUCCESSFULLY_CREATED);
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(callback_, this, result, GURL(), base::FilePath(),
-                            base::string16(), 0, std::string()));
+      FROM_HERE,
+      base::BindOnce(std::move(callback_), this, result, GURL(),
+                     base::FilePath(), base::string16(), 0, std::string()));
 }
 
 }  // namespace offline_pages
diff --git a/chrome/browser/offline_pages/offline_page_mhtml_archiver.h b/chrome/browser/offline_pages/offline_page_mhtml_archiver.h
index 632fc9df..b3c0ca6 100644
--- a/chrome/browser/offline_pages/offline_page_mhtml_archiver.h
+++ b/chrome/browser/offline_pages/offline_page_mhtml_archiver.h
@@ -50,7 +50,7 @@
   void CreateArchive(const base::FilePath& archives_dir,
                      const CreateArchiveParams& create_archive_params,
                      content::WebContents* web_contents,
-                     const CreateArchiveCallback& callback) override;
+                     CreateArchiveCallback callback) override;
 
  protected:
   // Try to generate MHTML.
diff --git a/chrome/browser/offline_pages/offline_page_mhtml_archiver_unittest.cc b/chrome/browser/offline_pages/offline_page_mhtml_archiver_unittest.cc
index 8d04667..f62cffec 100644
--- a/chrome/browser/offline_pages/offline_page_mhtml_archiver_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_mhtml_archiver_unittest.cc
@@ -139,9 +139,9 @@
   int64_t last_file_size() const { return last_file_size_; }
   const std::string& last_digest() const { return last_digest_; }
 
-  const OfflinePageArchiver::CreateArchiveCallback callback() {
-    return base::Bind(&OfflinePageMHTMLArchiverTest::OnCreateArchiveDone,
-                      base::Unretained(this));
+  OfflinePageArchiver::CreateArchiveCallback callback() {
+    return base::BindOnce(&OfflinePageMHTMLArchiverTest::OnCreateArchiveDone,
+                          base::Unretained(this));
   }
 
  private:
diff --git a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
index 9d4a409..61a34f2 100644
--- a/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
+++ b/chrome/browser/offline_pages/offline_page_request_handler_unittest.cc
@@ -17,7 +17,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/default_clock.h"
 #include "chrome/browser/offline_pages/offline_page_model_factory.h"
@@ -271,12 +271,12 @@
   void CreateArchive(const base::FilePath& archives_dir,
                      const CreateArchiveParams& create_archive_params,
                      content::WebContents* web_contents,
-                     const CreateArchiveCallback& callback) override {
+                     CreateArchiveCallback callback) override {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, this, ArchiverResult::SUCCESSFULLY_CREATED, url_,
-                   archive_file_path_, base::string16(), archive_file_size_,
-                   digest_));
+        FROM_HERE, base::BindOnce(std::move(callback), this,
+                                  ArchiverResult::SUCCESSFULLY_CREATED, url_,
+                                  archive_file_path_, base::string16(),
+                                  archive_file_size_, digest_));
   }
 
   void PublishArchive(
@@ -971,7 +971,8 @@
 
 class OfflinePageRequestJobBuilder {
  public:
-  OfflinePageRequestJobBuilder(OfflinePageRequestHandlerTestBase* test_base)
+  explicit OfflinePageRequestJobBuilder(
+      OfflinePageRequestHandlerTestBase* test_base)
       : test_base_(test_base) {}
 
   void InterceptRequest(const GURL& url,
diff --git a/chrome/browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc b/chrome/browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc
index 90bbe6da..85e55e0 100644
--- a/chrome/browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc
+++ b/chrome/browser/offline_pages/prefetch/offline_metrics_collector_impl_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <string>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
diff --git a/chrome/browser/offline_pages/prefetch/thumbnail_fetcher_impl_unittest.cc b/chrome/browser/offline_pages/prefetch/thumbnail_fetcher_impl_unittest.cc
index 3345c60..ce0718f 100644
--- a/chrome/browser/offline_pages/prefetch/thumbnail_fetcher_impl_unittest.cc
+++ b/chrome/browser/offline_pages/prefetch/thumbnail_fetcher_impl_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/offline_pages/prefetch/thumbnail_fetcher_impl.h"
 
 #include "base/test/bind_test_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "components/ntp_snippets/category_rankers/fake_category_ranker.h"
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc
index 55e6bad..e1e8eb98 100644
--- a/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/process/kill.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "base/timer/mock_timer.h"
 #include "chrome/browser/page_load_metrics/metrics_navigation_throttle.h"
diff --git a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_browsertest.cc
index d6c7a71..2083fb1 100644
--- a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_browsertest.cc
@@ -5,7 +5,7 @@
 #include <string>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer.h"
 #include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
diff --git a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc
index 1ce71fb..375fa6e2 100644
--- a/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/ads_page_load_metrics_observer_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
diff --git a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc
index 423a396..616591745 100644
--- a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer_browsertest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer.h"
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer_unittest.cc
index 9e58cc0..9cd9f24 100644
--- a/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <vector>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.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"
 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
diff --git a/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
index cd654bf..d7fba22 100644
--- a/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/media_page_load_metrics_observer_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.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"
diff --git a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc
index 7108c7244..82ffc01 100644
--- a/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/page_load_metrics/observers/histogram_suffixes.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
index 24fe3bc..12bb635 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.h"
 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
index b83338a6..2550264 100644
--- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
index 735be4c..47af5063 100644
--- a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/macros.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/stl_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
diff --git a/chrome/browser/page_load_metrics/observers/tab_restore_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/tab_restore_page_load_metrics_observer_unittest.cc
index a8ed47e..9aa1c07e 100644
--- a/chrome/browser/page_load_metrics/observers/tab_restore_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/tab_restore_page_load_metrics_observer_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.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"
diff --git a/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_unittest.cc
index aa9bae6..cac2da1 100644
--- a/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_unittest.cc
@@ -8,7 +8,7 @@
 #include <vector>
 #include "base/macros.h"
 #include "base/metrics/histogram_base.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index e5ff71e..f2a58fdc 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -17,7 +17,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/password_manager/account_chooser_dialog_android_unittest.cc b/chrome/browser/password_manager/account_chooser_dialog_android_unittest.cc
index c23d937..6457172 100644
--- a/chrome/browser/password_manager/account_chooser_dialog_android_unittest.cc
+++ b/chrome/browser/password_manager/account_chooser_dialog_android_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/password_manager/account_chooser_dialog_android.h"
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc b/chrome/browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc
index 561e2ef..cd377b9 100644
--- a/chrome/browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc
+++ b/chrome/browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/macros.h"
-#include "base/test/histogram_tester.h"
 #include "chrome/browser/password_manager/auto_signin_first_run_dialog_android.h"
+
+#include "base/macros.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index d9e876f..8962552 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -15,7 +15,7 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index ffe4a29..6ffedd9 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/scoped_observer.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "components/os_crypt/os_crypt_mocker.h"
diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc
index 8fa7b67..606077a 100644
--- a/chrome/browser/password_manager/password_store_win_unittest.cc
+++ b/chrome/browser/password_manager/password_store_win_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/task_scheduler/post_task.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/permissions/permission_context_base_unittest.cc b/chrome/browser/permissions/permission_context_base_unittest.cc
index ccf5e7c..c96902e0 100644
--- a/chrome/browser/permissions/permission_context_base_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_entropy_provider.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc b/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc
index 3d68815..9abeccff 100644
--- a/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc
+++ b/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc
@@ -9,7 +9,7 @@
 
 #include "base/bind.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/permissions/permission_request_manager_unittest.cc b/chrome/browser/permissions/permission_request_manager_unittest.cc
index 061cb51..8ca1aa2 100644
--- a/chrome/browser/permissions/permission_request_manager_unittest.cc
+++ b/chrome/browser/permissions/permission_request_manager_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/command_line.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/engagement/site_engagement_service.h"
 #include "chrome/browser/permissions/mock_permission_request.h"
diff --git a/chrome/browser/permissions/permission_util_unittest.cc b/chrome/browser/permissions/permission_util_unittest.cc
index c551e31..d6fad3d 100644
--- a/chrome/browser/permissions/permission_util_unittest.cc
+++ b/chrome/browser/permissions/permission_util_unittest.cc
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/test/histogram_tester.h"
+#include "chrome/browser/permissions/permission_util.h"
+
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/permissions/permission_uma_util.h"
-#include "chrome/browser/permissions/permission_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index bc4523d..655501f 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -319,4 +319,62 @@
                 .WaitAndGetTitle());
 }
 
+// Tests that calling PictureInPictureWindowController::Close() twice has no
+// side effect.
+IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
+                       CloseTwiceSideEffects) {
+  GURL test_page_url = ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(
+          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+  ui_test_utils::NavigateToURL(browser(), test_page_url);
+
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(active_web_contents);
+
+  SetUpWindowController(active_web_contents);
+  ASSERT_TRUE(window_controller());
+
+  EXPECT_TRUE(
+      content::ExecuteScript(active_web_contents, "enterPictureInPicture();"));
+
+  // Wait for resize event from the page.
+  base::string16 expected_title = base::ASCIIToUTF16("1");
+  EXPECT_EQ(expected_title,
+            content::TitleWatcher(active_web_contents, expected_title)
+                .WaitAndGetTitle());
+
+  window_controller()->Close();
+
+  // Wait for the window to close.
+  expected_title = base::ASCIIToUTF16("left");
+  EXPECT_EQ(expected_title,
+            content::TitleWatcher(active_web_contents, expected_title)
+                .WaitAndGetTitle());
+
+  bool video_paused = false;
+
+  // Video is paused after Picture-in-Picture window was closed.
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      active_web_contents, "window.domAutomationController.send(video.paused);",
+      &video_paused));
+  EXPECT_TRUE(video_paused);
+
+  // Resume playback.
+  ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      active_web_contents, "window.domAutomationController.send(video.paused);",
+      &video_paused));
+  EXPECT_FALSE(video_paused);
+
+  // This should be a no-op because the window is not visible.
+  window_controller()->Close();
+
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      active_web_contents, "window.domAutomationController.send(video.paused);",
+      &video_paused));
+  EXPECT_FALSE(video_paused);
+}
+
 #endif  // !defined(OS_LINUX) && !defined(OS_WIN)
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
index 2f21627..4f785d7 100644
--- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -14,7 +14,7 @@
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_scheduler/post_task.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/predictors/loading_data_collector_unittest.cc b/chrome/browser/predictors/loading_data_collector_unittest.cc
index e8bc28b..15ee833 100644
--- a/chrome/browser/predictors/loading_data_collector_unittest.cc
+++ b/chrome/browser/predictors/loading_data_collector_unittest.cc
@@ -9,7 +9,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/predictors/loading_predictor_config.h"
 #include "chrome/browser/predictors/loading_test_util.h"
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc
index c6965fd8..6d42f3d 100644
--- a/chrome/browser/predictors/loading_predictor_unittest.cc
+++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -10,7 +10,7 @@
 #include <utility>
 #include <vector>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/predictors/loading_test_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/predictors/loading_stats_collector_unittest.cc b/chrome/browser/predictors/loading_stats_collector_unittest.cc
index 4508b12..b6b7ece 100644
--- a/chrome/browser/predictors/loading_stats_collector_unittest.cc
+++ b/chrome/browser/predictors/loading_stats_collector_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <vector>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/predictors/loading_test_util.h"
 #include "chrome/browser/predictors/preconnect_manager.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
index e82278f..80625b0 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -11,7 +11,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/browser/history/history_service_factory.h"
diff --git a/chrome/browser/prerender/prerender_test_utils.h b/chrome/browser/prerender/prerender_test_utils.h
index 88c7be0..a2d4893 100644
--- a/chrome/browser/prerender/prerender_test_utils.h
+++ b/chrome/browser/prerender/prerender_test_utils.h
@@ -18,7 +18,7 @@
 #include "base/run_loop.h"
 #include "base/scoped_observer.h"
 #include "base/synchronization/lock.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #include "chrome/browser/prerender/prerender_contents.h"
 #include "chrome/browser/prerender/prerender_manager.h"
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 8867647..dcd93df 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/metrics/field_trial_param_associator.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/simple_test_tick_clock.h"
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc
index 6b44c5da..105414b 100644
--- a/chrome/browser/previews/previews_browsertest.cc
+++ b/chrome/browser/previews/previews_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include "base/command_line.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/previews/previews_infobar_delegate_unittest.cc b/chrome/browser/previews/previews_infobar_delegate_unittest.cc
index c062982b..9481a93 100644
--- a/chrome/browser/previews/previews_infobar_delegate_unittest.cc
+++ b/chrome/browser/previews/previews_infobar_delegate_unittest.cc
@@ -19,7 +19,7 @@
 #include "base/optional.h"
 #include "base/run_loop.h"
 #include "base/strings/string16.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/process_singleton_posix_unittest.cc b/chrome/browser/process_singleton_posix_unittest.cc
index 005cd38d..e4f4f89 100644
--- a/chrome/browser/process_singleton_posix_unittest.cc
+++ b/chrome/browser/process_singleton_posix_unittest.cc
@@ -27,7 +27,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/waitable_event.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_timeouts.h"
 #include "base/test/thread_test_helper.h"
 #include "base/threading/thread.h"
diff --git a/chrome/browser/process_singleton_win_unittest.cc b/chrome/browser/process_singleton_win_unittest.cc
index 5106f885..0b811ac 100644
--- a/chrome/browser/process_singleton_win_unittest.cc
+++ b/chrome/browser/process_singleton_win_unittest.cc
@@ -20,7 +20,7 @@
 #include "base/process/process_handle.h"
 #include "base/strings/string16.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/multiprocess_test.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/wrapped_window_proc.h"
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 7bf2b29..e036078 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -199,18 +199,9 @@
           BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
 
 #if defined(OS_CHROMEOS)
-  // Set a task runner for the get network id call in DataReductionProxyConfig
-  // to work around the bug that recv() in AddressTrackerLinux blocks IO thread
-  // and freezes the screen. Using SingleThreadTaskRunner so that task scheduler
-  // does not create too many worker threads when https://crbug.com/821607
-  // happens.
-  // TODO(https://crbug.com/821607): Remove after the bug is resolved.
   io_data_->data_reduction_proxy_io_data()
       ->config()
-      ->set_get_network_id_task_runner(
-          base::CreateSingleThreadTaskRunnerWithTraits(
-              {base::MayBlock(), base::TaskPriority::BACKGROUND,
-               base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));
+      ->EnableGetNetworkIdAsynchronously();
 #endif
 }
 
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index 5696dbaa..d3aae92 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -15,7 +15,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
diff --git a/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc b/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc
index 55c4638..e40376afc 100644
--- a/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc
+++ b/chrome/browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/resource_coordinator/test_lifecycle_unit.h"
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
index 0740be64..67ea9deb 100644
--- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/feature_list.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc
index 4a70b9d..626a0c72c 100644
--- a/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc
@@ -10,7 +10,7 @@
 
 #include "base/macros.h"
 #include "base/metrics/metrics_hashes.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/resource_coordinator/tab_helper.h"
diff --git a/chrome/browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc
index d9c7d9ce..4410f350 100644
--- a/chrome/browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_web_contents_data_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/resource_coordinator/tab_manager_web_contents_data.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "chrome/browser/resource_coordinator/time.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/resources/eoc_internals/OWNERS b/chrome/browser/resources/eoc_internals/OWNERS
new file mode 100644
index 0000000..7e6bf66
--- /dev/null
+++ b/chrome/browser/resources/eoc_internals/OWNERS
@@ -0,0 +1 @@
+file://components/ntp_snippets/OWNERS
\ No newline at end of file
diff --git a/chrome/browser/resources/eoc_internals/eoc_internals.css b/chrome/browser/resources/eoc_internals/eoc_internals.css
new file mode 100644
index 0000000..fb5abb1
--- /dev/null
+++ b/chrome/browser/resources/eoc_internals/eoc_internals.css
@@ -0,0 +1,3 @@
+/* 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. */
diff --git a/chrome/browser/resources/eoc_internals/eoc_internals.html b/chrome/browser/resources/eoc_internals/eoc_internals.html
new file mode 100644
index 0000000..8a428ff
--- /dev/null
+++ b/chrome/browser/resources/eoc_internals/eoc_internals.html
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>EOC Internals</title>
+  <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+  <link rel="stylesheet" href="eoc_internals.css">
+
+  <script src="chrome://resources/js/mojo_bindings.js"></script>
+  <script src="eoc_internals.mojom.js"></script>
+
+  <script src="eoc_internals.js"></script>
+</head>
+
+<body>
+  TODO: Implement this.
+</body>
+</html>
\ No newline at end of file
diff --git a/chrome/browser/resources/eoc_internals/eoc_internals.js b/chrome/browser/resources/eoc_internals/eoc_internals.js
new file mode 100644
index 0000000..678b4d9
--- /dev/null
+++ b/chrome/browser/resources/eoc_internals/eoc_internals.js
@@ -0,0 +1,18 @@
+// 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.
+
+(function() {
+'use strict';
+
+// Reference to the backend.
+let pageHandler = null;
+
+document.addEventListener('DOMContentLoaded', function() {
+  // Setup backend mojo.
+  pageHandler = new eocInternals.mojom.PageHandlerPtr;
+  Mojo.bindInterface(
+      eocInternals.mojom.PageHandler.name,
+      mojo.makeRequest(pageHandler).handle);
+});
+})();
\ No newline at end of file
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css
index a5a7afe..0578a76 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -103,8 +103,7 @@
   top: calc(50% - 155px);
 }
 
-body.hide-fakebox-logo #logo,
-body.hide-fakebox-logo #fakebox {
+body.hide-fakebox #fakebox {
   opacity: 0;
 }
 
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
index 2d78025d..6e6b596 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -86,7 +86,7 @@
   RIPPLE_EFFECT: 'ripple-effect',
   // Applies drag focus style to the fakebox
   FAKEBOX_DRAG_FOCUS: 'fakebox-drag-focused',
-  HIDE_FAKEBOX_AND_LOGO: 'hide-fakebox-logo',
+  HIDE_FAKEBOX: 'hide-fakebox',
   HIDE_NOTIFICATION: 'mv-notice-hide',
   INITED: 'inited',  // Reveals the <body> once init() is done.
   LEFT_ALIGN_ATTRIBUTION: 'left-align-attribution',
@@ -574,7 +574,7 @@
   if (isFakeboxFocused()) {
     setFakeboxFocus(false);
     setFakeboxDragFocus(false);
-    setFakeboxAndLogoVisibility(false);
+    setFakeboxVisibility(false);
   }
 }
 
@@ -584,7 +584,7 @@
  * (re-enables the fakebox and unhides the logo.)
  */
 function onInputCancel() {
-  setFakeboxAndLogoVisibility(true);
+  setFakeboxVisibility(true);
 }
 
 
@@ -624,8 +624,8 @@
 /**
  * @param {boolean} show True to show the fakebox and logo.
  */
-function setFakeboxAndLogoVisibility(show) {
-  document.body.classList.toggle(CLASSES.HIDE_FAKEBOX_AND_LOGO, !show);
+function setFakeboxVisibility(show) {
+  document.body.classList.toggle(CLASSES.HIDE_FAKEBOX, !show);
 }
 
 
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn b/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
index a25ebda..4f4ba6a6 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
@@ -82,6 +82,8 @@
     ":password_list_item",
     ":password_manager_proxy",
     "..:global_scroll_target_behavior",
+    "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
+    "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
     "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
     "//ui/webui/resources/cr_elements/cr_toast:cr_toast",
     "//ui/webui/resources/js:assert",
@@ -95,7 +97,7 @@
 js_library("password_edit_dialog") {
   deps = [
     ":show_password_behavior",
-    "//third_party/polymer/v1_0/components-chromium/paper-input:paper-input-extracted",
+    "//ui/webui/resources/cr_elements/cr_input:cr_input",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
index 7466d9c..ef7c9c6 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
@@ -1,10 +1,10 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
 <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="../icons.html">
 <link rel="import" href="../settings_shared_css.html">
 <link rel="import" href="../settings_vars_css.html">
@@ -13,52 +13,43 @@
 <dom-module id="password-edit-dialog">
   <template>
     <style include="settings-shared">
-      paper-input[readonly] {
-        /* Lighter than label to appear uneditable. */
-        color: var(--paper-grey-500);
-
-        /* For readonly inputs we don't want to show focus styles. */
-        --paper-input-container-underline-focus: {
-          display: none;
-        };
-
-        --paper-input-container-label-focus: {
-          color: var(--secondary-text-color);
-        };
-      }
-
       #passwordGroup {
         align-items: center;
         display: flex;
+        /* Offset contained cr-input margin to have consistent spacing with
+           other inputs. */
+        margin-top: -8px;
       }
 
-      paper-input {
+      cr-input {
         width: var(--settings-input-max-width);
+        --cr-input-error-display: none;
       }
 
       paper-icon-button-light {
         -webkit-margin-start: 2px;
         background-size: 24px;  /* Other buttons are sized by --cr-icon-size. */
+        margin-top: 16px;  /* Line up with cr-input. */
       }
     </style>
     <cr-dialog id="dialog" close-text="$i18n{close}">
       <div slot="title">$i18n{passwordDetailsTitle}</div>
       <div slot="body">
-        <paper-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}"
+        <cr-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}"
             value="[[item.entry.loginPair.urls.link]]" readonly
-            always-float-label on-focus="onInputFocus_">
-        </paper-input>
-        <paper-input id="usernameInput" label="$i18n{editPasswordUsernameLabel}"
+            on-focus="onInputFocus_">
+        </cr-input>
+        <cr-input id="usernameInput" label="$i18n{editPasswordUsernameLabel}"
             value="[[item.entry.loginPair.username]]" readonly
-            always-float-label on-focus="onInputFocus_">
-        </paper-input>
+            on-focus="onInputFocus_">
+        </cr-input>
         <div id="passwordGroup">
-          <paper-input id="passwordInput" always-float-label
+          <cr-input id="passwordInput" readonly
               label="$i18n{editPasswordPasswordLabel}"
               type="[[getPasswordInputType_(item.password)]]"
-              value="[[getPassword_(item.password)]]" readonly
+              value="[[getPassword_(item.password)]]"
               on-focus="onInputFocus_">
-          </paper-input>
+          </cr-input>
           <paper-icon-button-light id="showPasswordButtonContainer"
               class$="[[getIconClass_(item.password)]]"
               hidden$="[[item.entry.federationText]]">
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
index 8ea5c3f..de24af2 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
@@ -39,7 +39,7 @@
    */
   onInputFocus_: function(event) {
     const inputElement =
-        /** @type {!PaperInputElement} */ (Polymer.dom(event).localTarget)
+        /** @type {!CrInputElement} */ (Polymer.dom(event).localTarget)
             .inputElement;
     inputElement.setSelectionRange(0, 0);
     inputElement.focus();
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html
index 1c5cf73..2d63321 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.html
+++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -4,13 +4,13 @@
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
 <link rel="import" href="sync_browser_proxy.html">
 <link rel="import" href="../privacy_page/personalization_options.html">
@@ -31,16 +31,8 @@
         -webkit-margin-start: var(--settings-indent-width);
       }
 
-      paper-input {
+      cr-input {
         width: var(--settings-input-max-width);
-        --paper-input-container-focus-color: var(--google-blue-500);
-        --paper-input-container-input: {
-          font-size: inherit;
-        };
-      }
-
-      #saveNewPassphrase {
-        margin-top: 20px;
       }
 
       #existingPassphrase {
@@ -49,20 +41,24 @@
         border-bottom: var(--settings-separator-line);
       }
 
-      #existingPassphraseContainer,
-      #passphraseRecoverHint {
-        align-items: center;
+      #existingPassphraseContainer {
+        /* The contained cr-input has different spacing on top and bottom due
+           to space allocated for error message, so it's easier to line up with
+           "start" alignment. */
+        align-items: start;
       }
 
       #existingPassphraseInput {
         /* The submit button for the existing passphrase is on the same line. */
         -webkit-margin-end: 16px;
-        display: inline-block;
-        --paper-input-container: {
-          padding: 0;
-          /* TODO(scottchen): remove margin once large font properly padded. */
-          margin-bottom: 1rem;
-        };
+      }
+
+      #submitExistingPassphrase {
+        margin-top: 8px;  /* Aligns with cr-input on the same line. */
+      }
+
+      #passphraseRecoverHint {
+        align-items: center;
       }
 
       #sync-data-types .list-item:not([hidden]) ~ .list-item:not([hidden]) {
@@ -151,12 +147,12 @@
               </span>
             </div>
             <div id="existingPassphraseContainer" class="list-item">
-              <paper-input id="existingPassphraseInput" type="password"
+              <cr-input id="existingPassphraseInput" type="password"
                   value="{{existingPassphrase_}}"
                   placeholder="$i18n{passphrasePlaceholder}"
                   error-message="$i18n{incorrectPassphraseError}"
                   on-keypress="onSubmitExistingPassphraseTap_">
-              </paper-input>
+              </cr-input>
               <paper-button id="submitExistingPassphrase"
                   on-click="onSubmitExistingPassphraseTap_"
                   class="action-button" disabled="[[!existingPassphrase_]]">
@@ -396,16 +392,16 @@
                 <div class="list-item">
                   <span>$i18nRaw{passphraseExplanationText}</span>
                 </div>
-                <paper-input id="passphraseInput" type="password"
+                <cr-input id="passphraseInput" type="password"
                     value="{{passphrase_}}"
                     placeholder="$i18n{passphrasePlaceholder}"
                     error-message="$i18n{emptyPassphraseError}">
-                </paper-input>
-                <paper-input id="passphraseConfirmationInput" type="password"
+                </cr-input>
+                <cr-input id="passphraseConfirmationInput" type="password"
                     value="{{confirmation_}}"
                     placeholder="$i18n{passphraseConfirmationPlaceholder}"
                     error-message="$i18n{mismatchedPassphraseError}">
-                </paper-input>
+                </cr-input>
                 <paper-button id="saveNewPassphrase"
                     on-click="onSaveNewPassphraseTap_" class="action-button"
                     disabled="[[!isSaveNewPassphraseEnabled_(passphrase_,
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js
index 5076295e..5ad605f 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -367,7 +367,7 @@
     assert(this.creatingNewPassphrase_);
 
     // Ignore events on irrelevant elements or with irrelevant keys.
-    if (e.target.tagName != 'PAPER-BUTTON' && e.target.tagName != 'PAPER-INPUT')
+    if (e.target.tagName != 'PAPER-BUTTON' && e.target.tagName != 'CR-INPUT')
       return;
     if (e.type == 'keypress' && e.key != 'Enter')
       return;
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
index 86198277..2412c10 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/thread_test_helper.h"
 #include "base/time/clock.h"
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
index 554cfae..73eca38 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/sequence_checker.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/safe_browsing/certificate_reporting_service.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
index 9dd4bb3..0ad5c52 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/thread_test_helper.h"
 #include "base/time/clock.h"
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index ccd049d..5515306 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -5,7 +5,7 @@
 
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index d6bf784e..407676935 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -17,7 +17,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "build/build_config.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
index 9241ef41..bb1cabd 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc
index 3124450f..9f6fa03 100644
--- a/chrome/browser/safe_browsing/threat_details_unittest.cc
+++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/pickle.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 06848a8..015cf0d 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -19,7 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/cancelable_task_tracker.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index d9ed4712..0a3637e 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -968,11 +968,11 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
-  const GURL webui_url("chrome://omnibox");
+  const GURL webui_url(chrome::kChromeUIOmniboxURL);
   ui_test_utils::NavigateToURL(browser(), webui_url);
   content::WebContents* old_tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
+  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
             old_tab->GetMainFrame()->GetEnabledBindings());
 
   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
@@ -980,7 +980,7 @@
   content::WebContents* new_tab =
       new_browser->tab_strip_model()->GetActiveWebContents();
   EXPECT_EQ(webui_url, new_tab->GetURL());
-  EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
+  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
             new_tab->GetMainFrame()->GetEnabledBindings());
 }
 
diff --git a/chrome/browser/signin/dice_tab_helper_unittest.cc b/chrome/browser/signin/dice_tab_helper_unittest.cc
index d4b235a..19d3424 100644
--- a/chrome/browser/signin/dice_tab_helper_unittest.cc
+++ b/chrome/browser/signin/dice_tab_helper_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/signin/dice_tab_helper.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/user_action_tester.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/core/browser/signin_metrics.h"
diff --git a/chrome/browser/signin/force_signin_verifier_unittest.cc b/chrome/browser/signin/force_signin_verifier_unittest.cc
index 86ac2d25..2cc4ed4 100644
--- a/chrome/browser/signin/force_signin_verifier_unittest.cc
+++ b/chrome/browser/signin/force_signin_verifier_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/signin/force_signin_verifier.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.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/signin/signin_global_error_unittest.cc b/chrome/browser/signin/signin_global_error_unittest.cc
index da26a8a..1a3a295 100644
--- a/chrome/browser/signin/signin_global_error_unittest.cc
+++ b/chrome/browser/signin/signin_global_error_unittest.cc
@@ -11,7 +11,7 @@
 
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/signin/signin_ui_util_unittest.cc b/chrome/browser/signin/signin_ui_util_unittest.cc
index ff8a11e..1a565a8 100644
--- a/chrome/browser/signin/signin_ui_util_unittest.cc
+++ b/chrome/browser/signin/signin_ui_util_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/signin/signin_ui_util.h"
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/user_action_tester.h"
 #include "build/buildflag.h"
 #include "chrome/browser/signin/account_tracker_service_factory.h"
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc
index 4ec99e0..3cfcf40 100644
--- a/chrome/browser/site_details_browsertest.cc
+++ b/chrome/browser/site_details_browsertest.cc
@@ -17,7 +17,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/metrics/metrics_memory_details.h"
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index 2ac4bc0..2048216 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_service.h"
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
index 627c321..61264ba 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/command_line.h"
 #include "base/json/json_reader.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ssl/connection_help_tab_helper_browsertest.cc b/chrome/browser/ssl/connection_help_tab_helper_browsertest.cc
index d14d98fb..446917ac 100644
--- a/chrome/browser/ssl/connection_help_tab_helper_browsertest.cc
+++ b/chrome/browser/ssl/connection_help_tab_helper_browsertest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ssl/connection_help_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
index 4b12382..5140f83 100644
--- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -11,7 +11,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_command_line.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/ssl/security_state_tab_helper_unittest.cc b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
index 1343ee08..839e759 100644
--- a/chrome/browser/ssl/security_state_tab_helper_unittest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/security_state/content/ssl_status_input_event_data.h"
 #include "content/public/browser/navigation_entry.h"
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index baf724e..e3fb61b6 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -25,7 +25,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind_test_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_command_line.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
diff --git a/chrome/browser/ssl/ssl_error_handler_unittest.cc b/chrome/browser/ssl/ssl_error_handler_unittest.cc
index 6f2c9f1..e2671f5 100644
--- a/chrome/browser/ssl/ssl_error_handler_unittest.cc
+++ b/chrome/browser/ssl/ssl_error_handler_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/test/simple_test_tick_clock.h"
diff --git a/chrome/browser/ssl/typed_navigation_timing_throttle_browsertest.cc b/chrome/browser/ssl/typed_navigation_timing_throttle_browsertest.cc
index e5e86ff..a80426cb 100644
--- a/chrome/browser/ssl/typed_navigation_timing_throttle_browsertest.cc
+++ b/chrome/browser/ssl/typed_navigation_timing_throttle_browsertest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/logging.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ssl/typed_navigation_timing_throttle_unittest.cc b/chrome/browser/ssl/typed_navigation_timing_throttle_unittest.cc
index 11cc7ce..b869658 100644
--- a/chrome/browser/ssl/typed_navigation_timing_throttle_unittest.cc
+++ b/chrome/browser/ssl/typed_navigation_timing_throttle_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ssl/typed_navigation_timing_throttle.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/navigation_throttle.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
index 25b7281..f7b014451 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -20,7 +20,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/metrics/subprocess_metrics_provider.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
index a6710016..9f44bdc 100644
--- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/task/cancelable_task_tracker.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
index a333474..3838a5eb 100644
--- a/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_popup_browsertest.cc
@@ -8,7 +8,7 @@
 
 #include "base/lazy_instance.h"
 #include "base/logging.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
index 94e9a90..ec8a857 100644
--- a/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_settings_browsertest.cc
@@ -6,7 +6,7 @@
 #include <string>
 #include <utility>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_unittest.cc
index cbbbc6a..57b4bf32 100644
--- a/chrome/browser/subresource_filter/subresource_filter_unittest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_unittest.cc
@@ -4,7 +4,7 @@
 
 #include <utility>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h"
 #include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h"
 #include "chrome/browser/subresource_filter/subresource_filter_test_harness.h"
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 9838d0c..0ff7ef18 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/sync/chrome_sync_client.h"
 
+#include <string>
 #include <utility>
 
 #include "base/bind.h"
@@ -127,10 +128,20 @@
 namespace browser_sync {
 
 namespace {
+
 #if defined(OS_WIN)
 const base::FilePath::CharType kLoopbackServerBackendFilename[] =
     FILE_PATH_LITERAL("profile.pb");
 #endif  // defined(OS_WIN)
+
+syncer::ModelTypeSet GetDisabledTypesFromCommandLine() {
+  std::string disabled_types_str =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kDisableSyncTypes);
+
+  return syncer::ModelTypeSetFromString(disabled_types_str);
+}
+
 }  // namespace
 
 // Chrome implementation of SyncSessionsClient. Needs to be in a separate class
@@ -197,8 +208,8 @@
 
 ChromeSyncClient::ChromeSyncClient(Profile* profile)
     : profile_(profile),
-      sync_sessions_client_(new SyncSessionsClientImpl(profile)),
-      weak_ptr_factory_(this) {}
+      sync_sessions_client_(std::make_unique<SyncSessionsClientImpl>(profile)) {
+}
 
 ChromeSyncClient::~ChromeSyncClient() {
 }
@@ -218,7 +229,6 @@
     component_factory_ = std::make_unique<ProfileSyncComponentsFactoryImpl>(
         this, chrome::GetChannel(), chrome::GetVersionString(),
         ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET,
-        *base::CommandLine::ForCurrentProcess(),
         prefs::kSavingBrowserHistoryDisabled,
         content::BrowserThread::GetTaskRunnerForThread(
             content::BrowserThread::UI),
@@ -297,15 +307,23 @@
       base::Unretained(profile_));
 }
 
-syncer::SyncApiComponentFactory::RegisterDataTypesMethod
-ChromeSyncClient::GetRegisterPlatformTypesCallback() {
-  return base::Bind(
+syncer::DataTypeController::TypeVector
+ChromeSyncClient::CreateDataTypeControllers(
+    syncer::LocalDeviceInfoProvider* local_device_info_provider) {
+  syncer::ModelTypeSet disabled_types = GetDisabledTypesFromCommandLine();
+
+  syncer::DataTypeController::TypeVector controllers =
+      component_factory_->CreateCommonDataTypeControllers(
+          disabled_types, local_device_info_provider);
+
+// TODO(mastiz): Merge the two functions below into one or inline bodies here,
+// since there is common code.
 #if defined(OS_ANDROID)
-      &ChromeSyncClient::RegisterAndroidDataTypes,
+  RegisterAndroidDataTypes(&controllers);
 #else
-      &ChromeSyncClient::RegisterDesktopDataTypes,
+  RegisterDesktopDataTypes(disabled_types, &controllers);
 #endif  // defined(OS_ANDROID)
-      weak_ptr_factory_.GetWeakPtr());
+  return controllers;
 }
 
 BookmarkUndoService* ChromeSyncClient::GetBookmarkUndoServiceIfExists() {
@@ -567,9 +585,8 @@
 }
 
 void ChromeSyncClient::RegisterDesktopDataTypes(
-    syncer::SyncService* sync_service,
     syncer::ModelTypeSet disabled_types,
-    syncer::ModelTypeSet enabled_types) {
+    syncer::DataTypeController::TypeVector* controllers) {
   base::Closure error_callback =
       base::Bind(&syncer::ReportUnrecoverableError, chrome::GetChannel());
 
@@ -577,112 +594,96 @@
   // App sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::APPS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ExtensionDataTypeController>(
-            syncer::APPS, error_callback, this, profile_));
+    controllers->push_back(std::make_unique<ExtensionDataTypeController>(
+        syncer::APPS, error_callback, this, profile_));
   }
 
   // Extension sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::EXTENSIONS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ExtensionDataTypeController>(
-            syncer::EXTENSIONS, error_callback, this, profile_));
+    controllers->push_back(std::make_unique<ExtensionDataTypeController>(
+        syncer::EXTENSIONS, error_callback, this, profile_));
   }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
 #if !defined(OS_ANDROID)
   // Theme sync is enabled by default.  Register unless explicitly disabled.
   if (!disabled_types.Has(syncer::THEMES)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ThemeDataTypeController>(error_callback, this,
-                                                  profile_));
+    controllers->push_back(std::make_unique<ThemeDataTypeController>(
+        error_callback, this, profile_));
   }
 #endif  // !defined(OS_ANDROID)
 
   // Search Engine sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<SearchEngineDataTypeController>(
-            error_callback, this,
-            TemplateURLServiceFactory::GetForProfile(profile_)));
+    controllers->push_back(std::make_unique<SearchEngineDataTypeController>(
+        error_callback, this,
+        TemplateURLServiceFactory::GetForProfile(profile_)));
   }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // Extension setting sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ExtensionSettingDataTypeController>(
-            syncer::EXTENSION_SETTINGS, error_callback, this, profile_));
+    controllers->push_back(std::make_unique<ExtensionSettingDataTypeController>(
+        syncer::EXTENSION_SETTINGS, error_callback, this, profile_));
   }
 
   // App setting sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::APP_SETTINGS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ExtensionSettingDataTypeController>(
-            syncer::APP_SETTINGS, error_callback, this, profile_));
+    controllers->push_back(std::make_unique<ExtensionSettingDataTypeController>(
+        syncer::APP_SETTINGS, error_callback, this, profile_));
   }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
 #if BUILDFLAG(ENABLE_APP_LIST)
-  sync_service->RegisterDataTypeController(
-      std::make_unique<AsyncDirectoryTypeController>(
-          syncer::APP_LIST, error_callback, this, syncer::GROUP_UI,
-          BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
+  controllers->push_back(std::make_unique<AsyncDirectoryTypeController>(
+      syncer::APP_LIST, error_callback, this, syncer::GROUP_UI,
+      BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
 #endif  // BUILDFLAG(ENABLE_APP_LIST)
 
 #if defined(OS_LINUX) || defined(OS_WIN)
   // Dictionary sync is enabled by default.
   if (!disabled_types.Has(syncer::DICTIONARY)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<AsyncDirectoryTypeController>(
-            syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI,
-            BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
+    controllers->push_back(std::make_unique<AsyncDirectoryTypeController>(
+        syncer::DICTIONARY, error_callback, this, syncer::GROUP_UI,
+        BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
   }
 #endif  // defined(OS_LINUX) || defined(OS_WIN)
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-  sync_service->RegisterDataTypeController(
-      std::make_unique<SupervisedUserSyncDataTypeController>(
-          syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_));
-  sync_service->RegisterDataTypeController(
-      std::make_unique<SupervisedUserSyncDataTypeController>(
-          syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_));
+  controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>(
+      syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_));
+  controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>(
+      syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_));
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
 
 #if defined(OS_CHROMEOS)
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableWifiCredentialSync) &&
       !disabled_types.Has(syncer::WIFI_CREDENTIALS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<AsyncDirectoryTypeController>(
-            syncer::WIFI_CREDENTIALS, error_callback, this, syncer::GROUP_UI,
-            BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
+    controllers->push_back(std::make_unique<AsyncDirectoryTypeController>(
+        syncer::WIFI_CREDENTIALS, error_callback, this, syncer::GROUP_UI,
+        BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)));
   }
   if (arc::IsArcAllowedForProfile(profile_)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ArcPackageSyncDataTypeController>(
-            syncer::ARC_PACKAGE, error_callback, this, profile_));
+    controllers->push_back(std::make_unique<ArcPackageSyncDataTypeController>(
+        syncer::ARC_PACKAGE, error_callback, this, profile_));
   }
 #endif  // defined(OS_CHROMEOS)
 }
 
 void ChromeSyncClient::RegisterAndroidDataTypes(
-    syncer::SyncService* sync_service,
-    syncer::ModelTypeSet disabled_types,
-    syncer::ModelTypeSet enabled_types) {
+    syncer::DataTypeController::TypeVector* controllers) {
   base::Closure error_callback =
       base::Bind(&syncer::ReportUnrecoverableError, chrome::GetChannel());
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-  sync_service->RegisterDataTypeController(
-      std::make_unique<SupervisedUserSyncDataTypeController>(
-          syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_));
-  sync_service->RegisterDataTypeController(
-      std::make_unique<SupervisedUserSyncDataTypeController>(
-          syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_));
+  controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>(
+      syncer::SUPERVISED_USER_SETTINGS, error_callback, this, profile_));
+  controllers->push_back(std::make_unique<SupervisedUserSyncDataTypeController>(
+      syncer::SUPERVISED_USER_WHITELISTS, error_callback, this, profile_));
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
 }
 
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h
index 231eac8..6aedd85 100644
--- a/chrome/browser/sync/chrome_sync_client.h
+++ b/chrome/browser/sync/chrome_sync_client.h
@@ -46,8 +46,8 @@
   history::HistoryService* GetHistoryService() override;
   bool HasPasswordStore() override;
   base::Closure GetPasswordStateChangedCallback() override;
-  syncer::SyncApiComponentFactory::RegisterDataTypesMethod
-  GetRegisterPlatformTypesCallback() override;
+  syncer::DataTypeController::TypeVector CreateDataTypeControllers(
+      syncer::LocalDeviceInfoProvider* local_device_info_provider) override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   invalidation::InvalidationService* GetInvalidationService() override;
   BookmarkUndoService* GetBookmarkUndoServiceIfExists() override;
@@ -73,18 +73,13 @@
 
  private:
   // Register data types which are enabled on desktop platforms only.
-  // |disabled_types| and |enabled_types| correspond only to those types
-  // being explicitly disabled/enabled by the command line.
-  void RegisterDesktopDataTypes(syncer::SyncService* sync_service,
-                                syncer::ModelTypeSet disabled_types,
-                                syncer::ModelTypeSet enabled_types);
+  void RegisterDesktopDataTypes(
+      syncer::ModelTypeSet disabled_types,
+      syncer::DataTypeController::TypeVector* controllers);
 
   // Register data types which are enabled on Android platforms only.
-  // |disabled_types| and |enabled_types| correspond only to those types
-  // being explicitly disabled/enabled by the command line.
-  void RegisterAndroidDataTypes(syncer::SyncService* sync_service,
-                                syncer::ModelTypeSet disabled_types,
-                                syncer::ModelTypeSet enabled_types);
+  void RegisterAndroidDataTypes(
+      syncer::DataTypeController::TypeVector* controllers);
 
   Profile* const profile_;
 
@@ -104,8 +99,6 @@
   // Generates and monitors the ExtensionsActivity object used by sync.
   ExtensionsActivityMonitor extensions_activity_monitor_;
 
-  base::WeakPtrFactory<ChromeSyncClient> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(ChromeSyncClient);
 };
 
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc
index fe02d73..ffe4235 100644
--- a/chrome/browser/sync/profile_sync_test_util.cc
+++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -26,13 +26,14 @@
 #include "components/sync/model/model_type_store_test_util.h"
 
 using browser_sync::ProfileSyncService;
+using testing::NiceMock;
 
 ProfileSyncService::InitParams CreateProfileSyncServiceParamsForTest(
     Profile* profile) {
   auto sync_client = std::make_unique<browser_sync::ChromeSyncClient>(profile);
 
   sync_client->SetSyncApiComponentFactoryForTesting(
-      std::make_unique<syncer::SyncApiComponentFactoryMock>());
+      std::make_unique<NiceMock<syncer::SyncApiComponentFactoryMock>>());
 
   ProfileSyncService::InitParams init_params =
       CreateProfileSyncServiceParamsForTest(std::move(sync_client), profile);
@@ -74,7 +75,7 @@
 
 std::unique_ptr<KeyedService> BuildMockProfileSyncService(
     content::BrowserContext* context) {
-  return std::make_unique<browser_sync::ProfileSyncServiceMock>(
+  return std::make_unique<NiceMock<browser_sync::ProfileSyncServiceMock>>(
       CreateProfileSyncServiceParamsForTest(
           Profile::FromBrowserContext(context)));
 }
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
index 47d8ad4..cd1657a0 100644
--- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -4,7 +4,7 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
diff --git a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
index 37f4ddeb..397aad0 100644
--- a/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.cc
+++ b/chrome/browser/tab_contents/navigation_metrics_recorder_browsertest.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 "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/tab_contents/navigation_metrics_recorder.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index c45ee858..e0d98fd 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -47,7 +47,7 @@
 // theme packs that aren't int-equal to this. Increment this number if you
 // change default theme assets or if you need themes to recreate their generated
 // images (which are cached).
-const int kThemePackVersion = 48;
+const int kThemePackVersion = 49;
 
 // IDs that are in the DataPack won't clash with the positive integer
 // uint16_t. kHeaderID should always have the maximum value because we want the
@@ -1215,18 +1215,21 @@
 
   for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
     int prs_id = kFrameTintMap[i].key;
+    // If the theme doesn't provide an image, attempt to fall back to one it
+    // does.
     if (!images->count(prs_id)) {
-      if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
-        // Fall back from inactive incognito to active incognito.
-        prs_id = PRS_THEME_FRAME_INCOGNITO;
-        if (!images->count(prs_id)) {
-          // From there, fall back to the normal frame.
-          prs_id = PRS_THEME_FRAME;
-        }
-      } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
-        // Fall back from inactive overlay to overlay, but stop there.
+      // Fall back from inactive overlay to active overlay.
+      if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE)
         prs_id = PRS_THEME_FRAME_OVERLAY;
-      }
+
+      // Fall back from inactive incognito to active incognito.
+      if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE)
+        prs_id = PRS_THEME_FRAME_INCOGNITO;
+
+      // For all non-overlay images, fall back to PRS_THEME_FRAME as a last
+      // resort.
+      if (!images->count(prs_id) && prs_id != PRS_THEME_FRAME_OVERLAY)
+        prs_id = PRS_THEME_FRAME;
     }
 
     // Note that if the original ID and all the fallbacks are absent, the caller
diff --git a/chrome/browser/themes/browser_theme_pack_unittest.cc b/chrome/browser/themes/browser_theme_pack_unittest.cc
index 535ef2ad..828336e 100644
--- a/chrome/browser/themes/browser_theme_pack_unittest.cc
+++ b/chrome/browser/themes/browser_theme_pack_unittest.cc
@@ -230,11 +230,29 @@
     // Here are a few images that we shouldn't expect because even though
     // they're included in the theme pack, they were autogenerated and
     // therefore shouldn't show up when calling HasCustomImage().
+    // Verify they do appear when calling GetImageNamed(), though.
     EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INACTIVE));
+    EXPECT_FALSE(pack->GetImageNamed(IDR_THEME_FRAME_INACTIVE).IsEmpty());
     EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO));
+    EXPECT_FALSE(pack->GetImageNamed(IDR_THEME_FRAME_INCOGNITO).IsEmpty());
     EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO_INACTIVE));
+    EXPECT_FALSE(
+        pack->GetImageNamed(IDR_THEME_FRAME_INCOGNITO_INACTIVE).IsEmpty());
+
+    // The overlay images are missing and they do not fall back to the active
+    // frame image.
+    EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY));
+    EXPECT_TRUE(pack->GetImageNamed(IDR_THEME_FRAME_OVERLAY).IsEmpty());
+    EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY_INACTIVE));
+    EXPECT_TRUE(
+        pack->GetImageNamed(IDR_THEME_FRAME_OVERLAY_INACTIVE).IsEmpty());
+
 #if !defined(OS_MACOSX)
+    // The tab background image is missing, but will still be generated in
+    // CreateTabBackgroundImages based on IDR_THEME_FRAME.
     EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO));
+    EXPECT_FALSE(
+        pack->GetImageNamed(IDR_THEME_TAB_BACKGROUND_INCOGNITO).IsEmpty());
 #endif
 
     // Make sure we don't have phantom data.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 1a3dbe9..dbf7c9f 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1081,7 +1081,10 @@
   }
 
   if (is_android) {
-    deps += [ "//chrome/browser/ui/webui/snippets_internals:mojo_bindings" ]
+    deps += [
+      "//chrome/browser/ui/webui/eoc_internals:mojo_bindings",
+      "//chrome/browser/ui/webui/snippets_internals:mojo_bindings",
+    ]
   }
 
   if (!is_fuchsia) {
@@ -1219,6 +1222,10 @@
       "android/view_android_helper.h",
       "browser_otr_state_android.cc",
       "screen_capture_notification_ui_stub.cc",
+      "webui/eoc_internals/eoc_internals_page_handler.cc",
+      "webui/eoc_internals/eoc_internals_page_handler.h",
+      "webui/eoc_internals/eoc_internals_ui.cc",
+      "webui/eoc_internals/eoc_internals_ui.h",
       "webui/offline/offline_internals_ui.cc",
       "webui/offline/offline_internals_ui.h",
       "webui/offline/offline_internals_ui_message_handler.cc",
diff --git a/chrome/browser/ui/ash/network/tether_notification_presenter_unittest.cc b/chrome/browser/ui/ash/network/tether_notification_presenter_unittest.cc
index 8559f4e..0cb8989 100644
--- a/chrome/browser/ui/ash/network/tether_notification_presenter_unittest.cc
+++ b/chrome/browser/ui/ash/network/tether_notification_presenter_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/observer_list.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
index ae3569e..7dcdc8de 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -170,6 +170,7 @@
     case POPUP_ITEM_ID_PASSWORD_ENTRY:
     case POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY:
     case POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY:
+    case POPUP_ITEM_ID_GOOGLE_PAY_BRANDING:
       return normal_font_list_;
     case POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY:
     case POPUP_ITEM_ID_DATALIST_ENTRY:
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
index ad19396..ef601893 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/json/json_reader.h"
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/values.h"
 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index 4bce110..50f755fd 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -9,7 +9,7 @@
 #include "base/macros.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc
index 66470f4..966ffdb 100644
--- a/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc
+++ b/chrome/browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
diff --git a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
index 2727944..0c6ce4c 100644
--- a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/supports_user_data.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
index a98ca203..9c80c71 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
@@ -13,7 +13,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/path_service.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
index c15ca23..24e9e9d 100644
--- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
+++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -11,7 +11,7 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h"
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index e291f041..0e3e45d 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -1800,7 +1800,8 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   content::RenderViewHost* webui_rvh = popup->GetRenderViewHost();
   content::RenderFrameHost* webui_rfh = popup->GetMainFrame();
-  EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI, webui_rfh->GetEnabledBindings());
+  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
+            webui_rfh->GetEnabledBindings());
 
   // Navigate to another page in the popup.
   GURL nonwebui_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
@@ -1814,7 +1815,7 @@
   back_load_observer.Wait();
   EXPECT_EQ(webui_rvh, popup->GetRenderViewHost());
   EXPECT_TRUE(webui_rvh->IsRenderViewLive());
-  EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
+  EXPECT_EQ(content::BINDINGS_POLICY_MOJO_WEB_UI,
             webui_rvh->GetMainFrame()->GetEnabledBindings());
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/credit_card_autofill_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/autofill/credit_card_autofill_touch_bar_controller_unittest.mm
index 16046dd..b473946 100644
--- a/chrome/browser/ui/cocoa/autofill/credit_card_autofill_touch_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/credit_card_autofill_touch_bar_controller_unittest.mm
@@ -7,7 +7,7 @@
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/autofill/autofill_popup_controller.h"
 #include "chrome/browser/ui/autofill/autofill_popup_layout_model.h"
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
index 81071199..de0b7cb6 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
@@ -13,7 +13,7 @@
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/devtools/devtools_window_testing.h"
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
index 253b467..d05d841 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -760,7 +760,7 @@
     return true;
   }
 
-  if (model()->popup_model()->IsDisplayingResults()) {
+  if (model()->popup_model()->IsOpen()) {
     if (cmd == @selector(insertBacktab:)) {
       if (model()->popup_model()->selected_line_state() ==
             OmniboxPopupModel::KEYWORD) {
@@ -855,7 +855,7 @@
   if (cmd == @selector(deleteForward:)) {
     const NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
     if ((modifiers & NSShiftKeyMask) != 0) {
-      if (model()->popup_model()->IsDisplayingResults()) {
+      if (model()->popup_model()->IsOpen()) {
         model()->popup_model()->TryDeletingCurrentItem();
         return true;
       }
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
index d56be1d6b..552401f 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
@@ -52,11 +52,11 @@
 
 class MockOmniboxPopupView : public OmniboxPopupView {
  public:
-  MockOmniboxPopupView() {}
+  MockOmniboxPopupView() : is_open_(false) {}
   ~MockOmniboxPopupView() override {}
 
   // Overridden from OmniboxPopupView:
-  bool IsOpen() const override { return false; }
+  bool IsOpen() const override { return is_open_; }
   void InvalidateLine(size_t line) override {}
   void OnLineSelected(size_t line) override {}
   void UpdatePopupAppearance() override {}
@@ -64,28 +64,14 @@
   void PaintUpdatesNow() override {}
   void OnDragCanceled() override {}
 
+  void set_is_open(bool is_open) { is_open_ = is_open; }
+
  private:
+  bool is_open_;
+
   DISALLOW_COPY_AND_ASSIGN(MockOmniboxPopupView);
 };
 
-class MockOmniboxPopupModel : public OmniboxPopupModel {
- public:
-  MockOmniboxPopupModel(OmniboxPopupView* popup_view,
-                        OmniboxEditModel* edit_model)
-      : OmniboxPopupModel(popup_view, edit_model) {}
-  ~MockOmniboxPopupModel() override {}
-
-  bool IsDisplayingResults() const override { return is_displaying_results_; }
-  void set_is_displaying_results(bool is_displaying_results) {
-    is_displaying_results_ = is_displaying_results;
-  }
-
- private:
-  bool is_displaying_results_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(MockOmniboxPopupModel);
-};
-
 class TestingToolbarModelDelegate : public ChromeToolbarModelDelegate {
  public:
   TestingToolbarModelDelegate() {}
@@ -145,17 +131,17 @@
   SetModel(&view, model);
 
   MockOmniboxPopupView popup_view;
-  MockOmniboxPopupModel popup_model(&popup_view, model);
+  OmniboxPopupModel popup_model(&popup_view, model);
 
   // With popup closed verify that tab doesn't autocomplete.
-  popup_model.set_is_displaying_results(false);
+  popup_view.set_is_open(false);
   view.OnDoCommandBySelector(@selector(insertTab:));
   EXPECT_EQ(0, model->up_or_down_count());
   view.OnDoCommandBySelector(@selector(insertBacktab:));
   EXPECT_EQ(0, model->up_or_down_count());
 
   // With popup open verify that tab does autocomplete.
-  popup_model.set_is_displaying_results(true);
+  popup_view.set_is_open(true);
   view.OnDoCommandBySelector(@selector(insertTab:));
   EXPECT_EQ(1, model->up_or_down_count());
   view.OnDoCommandBySelector(@selector(insertBacktab:));
@@ -171,10 +157,10 @@
   SetModel(&view, model);
 
   MockOmniboxPopupView popup_view;
-  MockOmniboxPopupModel popup_model(&popup_view, model);
+  OmniboxPopupModel popup_model(&popup_view, model);
 
   // With popup closed verify that pressing up and down arrow works.
-  popup_model.set_is_displaying_results(false);
+  popup_view.set_is_open(false);
   model->set_up_or_down_count(0);
   view.OnDoCommandBySelector(@selector(moveDown:));
   EXPECT_EQ(1, model->up_or_down_count());
@@ -183,7 +169,7 @@
   EXPECT_EQ(-1, model->up_or_down_count());
 
   // With popup open verify that pressing up and down arrow works.
-  popup_model.set_is_displaying_results(true);
+  popup_view.set_is_open(true);
   model->set_up_or_down_count(0);
   view.OnDoCommandBySelector(@selector(moveDown:));
   EXPECT_EQ(1, model->up_or_down_count());
@@ -202,7 +188,7 @@
   MockOmniboxEditModel* model =
       new MockOmniboxEditModel(&view, &edit_controller, profile());
   MockOmniboxPopupView popup_view;
-  MockOmniboxPopupModel popup_model(&popup_view, model);
+  OmniboxPopupModel popup_model(&popup_view, model);
 
   model->OnSetFocus(true);
   SetModel(&view, model);
@@ -234,7 +220,7 @@
   MockOmniboxEditModel* model =
       new MockOmniboxEditModel(&view, &edit_controller, profile());
   MockOmniboxPopupView popup_view;
-  MockOmniboxPopupModel popup_model(&popup_view, model);
+  OmniboxPopupModel popup_model(&popup_view, model);
 
   model->OnSetFocus(true);
   SetModel(&view, model);
diff --git a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_views.mm b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_views.mm
index 773ebae..78439b7f 100644
--- a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_views.mm
+++ b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_views.mm
@@ -7,6 +7,7 @@
 #include "components/renderer_context_menu/views/toolkit_delegate_views.h"
 #import "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/gfx/mac/coordinate_conversion.h"
+#include "ui/views/widget/widget.h"
 
 class ToolkitDelegateViewsMac : public ToolkitDelegateViews {
  public:
@@ -46,6 +47,8 @@
   gfx::Point menu_point = gfx::ScreenPointFromNSPoint(
       ui::ConvertPointFromWindowToScreen([parent_view_ window], position));
 
+  views::Widget* owner =
+      views::Widget::GetTopLevelWidgetForNativeView(parent_view_);
   static_cast<ToolkitDelegateViews*>(toolkit_delegate())
-      ->RunMenuAt(nullptr, menu_point, params().source_type);
+      ->RunMenuAt(owner, menu_point, params().source_type);
 }
diff --git a/chrome/browser/ui/cocoa/share_menu_controller_browsertest.mm b/chrome/browser/ui/cocoa/share_menu_controller_browsertest.mm
index 43f37743..6f7202b 100644
--- a/chrome/browser/ui/cocoa/share_menu_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/share_menu_controller_browsertest.mm
@@ -7,7 +7,7 @@
 #import "base/mac/scoped_nsobject.h"
 #import "base/path_service.h"
 #include "base/strings/sys_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm
index 1b5f371..e8b97e0b 100644
--- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #import "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
index 4f143f0..19fece8f 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/content_settings/chrome_content_settings_utils.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
index 7ebd3a3..92326c4 100644
--- a/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/desktop_ios_promotion/desktop_ios_promotion_bubble_controller.h"
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_timeouts.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/sync/profile_sync_test_util.h"
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
index 9aa3046..6cc94b35 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 196ba8e..c601be22d8 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 6c39e998..483ed86 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -607,7 +607,7 @@
   };
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   // ctrl-Enter triggers desired_tld feature, thus www.bar.com shall be
   // opened.
   ASSERT_TRUE(SendKeyAndWait(browser(), ui::VKEY_RETURN, ui::EF_CONTROL_DOWN,
@@ -652,7 +652,7 @@
   };
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextPrefixKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   // Arrow down to the "abc" entry in the popup.
   size_t size = popup_model->result().size();
@@ -737,7 +737,7 @@
   // Test Enter to search.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   // Check if the default match result is Search Primary Provider.
   ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
@@ -760,7 +760,7 @@
   EXPECT_TRUE(omnibox_view->IsSelectAll());
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchSingleCharKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   EXPECT_EQ("z", UTF16ToUTF8(omnibox_view->GetText()));
 
   // Check if the default match result is Search Primary Provider.
@@ -786,7 +786,7 @@
   // Input something to trigger inline autocomplete.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   base::string16 old_text = omnibox_view->GetText();
 
@@ -931,7 +931,7 @@
   // Input something that can match history items.
   omnibox_view->SetUserText(ASCIIToUTF16("site.com/p"));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
   EXPECT_EQ(ASCIIToUTF16("site.com/path/1"), omnibox_view->GetText());
   base::string16::size_type start, end;
   omnibox_view->GetSelectionBounds(&start, &end);
@@ -959,7 +959,7 @@
   // suggested text, and should select all.
   omnibox_view->SetUserText(ASCIIToUTF16("site.com/p"));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
   omnibox_view->model()->OnUpOrDownKeyPressed(1);
   EXPECT_EQ(ASCIIToUTF16("www.site.com/path/2"), omnibox_view->GetText());
   omnibox_view->GetSelectionBounds(&start, &end);
@@ -1134,7 +1134,7 @@
   // Type "fo" to trigger inline autocomplete.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordPrefixKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  ASSERT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
   ASSERT_NE(search_keyword, omnibox_view->GetText());
 
   // Keyword hint shouldn't be visible.
@@ -1145,7 +1145,7 @@
   // should also get a keyword hint because we've typed a keyword exactly.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordCompletionKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  ASSERT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
   ASSERT_NE(search_keyword, omnibox_view->GetText());
   ASSERT_TRUE(omnibox_view->model()->is_keyword_hint());
   ASSERT_FALSE(omnibox_view->model()->keyword().empty());
@@ -1162,7 +1162,7 @@
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchKeywordKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
   OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   ASSERT_EQ(ASCIIToUTF16("foobar.com"), omnibox_view->GetText());
   omnibox_view->model()->OnUpOrDownKeyPressed(1);
   omnibox_view->model()->OnUpOrDownKeyPressed(-1);
@@ -1196,7 +1196,7 @@
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_T, 0));
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_E, 0));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   base::string16 search_keyword2(ASCIIToUTF16(kSearchKeyword2));
   while ((omnibox_view->GetText() != search_keyword2) &&
          (popup_model->selected_line() < popup_model->result().size() - 1))
@@ -1231,7 +1231,7 @@
   // Non-default substituting keyword shouldn't be matched by default.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   // Check if the default match result is Search Primary Provider.
   ASSERT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
@@ -1241,7 +1241,7 @@
 
   omnibox_view->SetUserText(base::string16());
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_FALSE(popup_model->IsDisplayingResults());
+  ASSERT_FALSE(popup_model->IsOpen());
 
   // Try a non-substituting keyword.
   template_url_service->Remove(template_url);
@@ -1252,7 +1252,7 @@
   // We always allow exact matches for non-substituting keywords.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kSearchTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   ASSERT_EQ(AutocompleteMatchType::HISTORY_KEYWORD,
             popup_model->result().default_match()->type);
   ASSERT_EQ("http://abc.com/",
@@ -1286,12 +1286,12 @@
   // Input something that can match history items.
   omnibox_view->SetUserText(ASCIIToUTF16("site.com/p"));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   // Delete the inline autocomplete part.
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_DELETE, 0));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   ASSERT_GE(popup_model->result().size(), 3U);
 
   base::string16 user_text = omnibox_view->GetText();
@@ -1434,7 +1434,7 @@
   };
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   size_t old_selected_line = popup_model->selected_line();
   EXPECT_EQ(0U, old_selected_line);
@@ -1576,7 +1576,7 @@
   // Input something to trigger inline autocomplete.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   base::string16 old_text = omnibox_view->GetText();
 
@@ -1687,7 +1687,7 @@
   // Input something to trigger inline autocomplete.
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kInlineAutocompleteTextKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
   size_t start, end;
   omnibox_view->GetSelectionBounds(&start, &end);
   EXPECT_TRUE(start != end);
@@ -1697,7 +1697,7 @@
   // Unfocus the omnibox. This should close the popup but should not run
   // autocomplete.
   ui_test_utils::ClickOnView(browser(), VIEW_ID_TAB_CONTAINER);
-  ASSERT_FALSE(popup_model->IsDisplayingResults());
+  ASSERT_FALSE(popup_model->IsOpen());
   EXPECT_EQ(old_autocomplete_text,
       omnibox_view->model()->autocomplete_controller()->input_.text());
 }
@@ -1707,34 +1707,34 @@
   ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
   OmniboxPopupModel* popup_model = omnibox_view->model()->popup_model();
   ASSERT_TRUE(popup_model);
-  EXPECT_FALSE(popup_model->IsDisplayingResults());
+  EXPECT_FALSE(popup_model->IsOpen());
 
   // Paste should yield the expected text and open the popup.
   SetClipboardText(ASCIIToUTF16(kSearchText));
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
   EXPECT_EQ(ASCIIToUTF16(kSearchText), omnibox_view->GetText());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
 
   // Close the popup and select all.
   omnibox_view->CloseOmniboxPopup();
   omnibox_view->SelectAll(false);
-  EXPECT_FALSE(popup_model->IsDisplayingResults());
+  EXPECT_FALSE(popup_model->IsOpen());
 
   // Pasting the same text again over itself should re-open the popup.
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
   EXPECT_EQ(ASCIIToUTF16(kSearchText), omnibox_view->GetText());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
   omnibox_view->CloseOmniboxPopup();
-  EXPECT_FALSE(popup_model->IsDisplayingResults());
+  EXPECT_FALSE(popup_model->IsOpen());
 
   // Pasting amid text should yield the expected text and re-open the popup.
   omnibox_view->SetWindowTextAndCaretPos(ASCIIToUTF16("abcd"), 2, false, false);
   SetClipboardText(ASCIIToUTF16("123"));
   ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_V, kCtrlOrCmdMask));
   EXPECT_EQ(ASCIIToUTF16("ab123cd"), omnibox_view->GetText());
-  EXPECT_TRUE(popup_model->IsDisplayingResults());
+  EXPECT_TRUE(popup_model->IsOpen());
 
   // Ctrl/Cmd+Alt+V should not paste.
   ASSERT_NO_FATAL_FAILURE(
@@ -1894,7 +1894,7 @@
       std::string(chrome::kChromeUISettingsURL) + chrome::kSearchEnginesSubPage;
   EXPECT_EQ(ASCIIToUTF16(target_url), omnibox_view->GetText());
 #endif
-  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
 }
 
 IN_PROC_BROWSER_TEST_F(OmniboxViewTest, CtrlArrowAfterArrowSuggestions) {
@@ -1909,7 +1909,7 @@
   };
   ASSERT_NO_FATAL_FAILURE(SendKeySequence(kKeys));
   ASSERT_NO_FATAL_FAILURE(WaitForAutocompleteControllerDone());
-  ASSERT_TRUE(popup_model->IsDisplayingResults());
+  ASSERT_TRUE(popup_model->IsOpen());
 
   ASSERT_EQ(ASCIIToUTF16("bar.com/1"), omnibox_view->GetText());
 
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 7990ea84..7c0743b 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -13,7 +13,7 @@
 #include "base/bind.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 6ab7bf8..1fc70fc2 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/metrics/histogram_samples.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
diff --git a/chrome/browser/ui/passwords/manage_passwords_test.h b/chrome/browser/ui/passwords/manage_passwords_test.h
index e4f41aab..bbf24c19 100644
--- a/chrome/browser/ui/passwords/manage_passwords_test.h
+++ b/chrome/browser/ui/passwords/manage_passwords_test.h
@@ -10,7 +10,7 @@
 
 #include "base/macros.h"
 #include "base/metrics/histogram_samples.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/fake_form_fetcher.h"
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 52dd3f1..260d3c9 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -13,7 +13,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
 #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h"
diff --git a/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc b/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc
index a143691c..defb512c 100644
--- a/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc
+++ b/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/passwords/password_dialog_prompts.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ui/profile_error_browsertest.cc b/chrome/browser/ui/profile_error_browsertest.cc
index 74baf84..daeb800 100644
--- a/chrome/browser/ui/profile_error_browsertest.cc
+++ b/chrome/browser/ui/profile_error_browsertest.cc
@@ -8,7 +8,7 @@
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/simple_message_box_internal.h"
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc
index 9f9112c0..3110937 100644
--- a/chrome/browser/ui/search/local_ntp_browsertest.cc
+++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -13,7 +13,7 @@
 #include "base/metrics/statistics_recorder.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/chrome/browser/ui/search/local_ntp_doodle_browsertest.cc b/chrome/browser/ui/search/local_ntp_doodle_browsertest.cc
index 18c706e..3bf3aa2 100644
--- a/chrome/browser/ui/search/local_ntp_doodle_browsertest.cc
+++ b/chrome/browser/ui/search/local_ntp_doodle_browsertest.cc
@@ -12,7 +12,7 @@
 #include "base/optional.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/search_provider_logos/logo_service_factory.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
index b80809a2..0600100ec 100644
--- a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
+++ b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/metrics/histogram.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/common/search/ntp_logging_events.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index 9bff337..7dae88c7 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -276,7 +276,7 @@
       // Remove focus only if the popup is closed. This will prevent someone
       // from changing the omnibox value and closing the popup without user
       // interaction.
-      if (!omnibox_view->model()->popup_model()->IsDisplayingResults())
+      if (!omnibox_view->model()->popup_model()->IsOpen())
         web_contents()->Focus();
       break;
   }
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index feadd629..378480b 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -15,7 +15,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/ui/tabs/tab_strip_model_stats_recorder_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_stats_recorder_unittest.cc
index 18fad1b..38b829f 100644
--- a/chrome/browser/ui/tabs/tab_strip_model_stats_recorder_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model_stats_recorder_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model_stats_recorder.h"
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
index af57972..b2d875d 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
@@ -5,7 +5,7 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 1484351..b3175ae 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -859,7 +859,7 @@
           ->GetOmniboxView()
           ->model()
           ->popup_model()
-          ->IsDisplayingResults()) {
+          ->IsOpen()) {
     return false;
   }
   return true;
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
index 5f1aa0d..dacb84e 100644
--- a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
+++ b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/metrics/histogram_base.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
diff --git a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
index 41503bf7..7de8132f 100644
--- a/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/external_protocol_dialog_browsertest.cc
@@ -6,7 +6,7 @@
 #include <string>
 
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/external_protocol_dialog_delegate.h"
diff --git a/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm b/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm
index 1a34fad..5e73ca1 100644
--- a/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_native_widget_window_mac.mm
@@ -6,6 +6,10 @@
 
 #import <AppKit/AppKit.h>
 
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+
 namespace {
 constexpr NSInteger kWindowButtonsOffsetFromBottom = 9;
 constexpr NSInteger kWindowButtonsOffsetFromLeft = 11;
@@ -105,4 +109,13 @@
   return NO;
 }
 
+// Handle "Move focus to the window toolbar" configured in System Preferences ->
+// Keyboard -> Shortcuts -> Keyboard. Usually Ctrl+F5. The argument (|unknown|)
+// tends to just be nil.
+- (void)_handleFocusToolbarHotKey:(id)unknown {
+  Browser* browser = chrome::FindBrowserWithWindow(self);
+  if (browser)
+    chrome::ExecuteCommand(browser, IDC_FOCUS_TOOLBAR);
+}
+
 @end
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
index edf6b8e..029d4bc 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -23,7 +23,7 @@
 #include "base/run_loop.h"
 #include "base/scoped_observer.h"
 #include "base/strings/string_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
index 474d71b..e0d0efc 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index ee69177..57909102 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -796,9 +796,6 @@
   // correctly enable subpixel AA.
   omnibox_view_->SetBackgroundColor(background_color);
   omnibox_view_->EmphasizeURLComponents();
-
-  // Keep the popup in sync when we refresh the background.
-  GetOmniboxPopupView()->UpdatePopupAppearance();
 }
 
 void LocationBarView::RefreshLocationIcon() {
@@ -1121,6 +1118,9 @@
 }
 
 void LocationBarView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+  OmniboxPopupView* popup = GetOmniboxPopupView();
+  if (popup->IsOpen())
+    popup->UpdatePopupAppearance();
   RefreshBackground();
   RefreshFocusRing();
 }
@@ -1198,15 +1198,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // LocationBarView, private OmniboxEditController implementation:
 
-void LocationBarView::OnInputInProgress(bool in_progress) {
-  ChromeOmniboxEditController::OnInputInProgress(in_progress);
-
-  if (ui::MaterialDesignController::IsRefreshUi()) {
-    GetOmniboxPopupView()->UpdatePopupAppearance();
-    RefreshFocusRing();
-  }
-}
-
 void LocationBarView::OnChanged() {
   RefreshLocationIcon();
   location_icon_view_->set_show_tooltip(!GetOmniboxView()->IsEditingOrEmpty());
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 641aff3..a6f03ba 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -384,7 +384,6 @@
   void AnimationEnded(const gfx::Animation* animation) override;
 
   // ChromeOmniboxEditController:
-  void OnInputInProgress(bool in_progress) override;
   void OnChanged() override;
   void OnPopupVisibilityChanged() override;
   const ToolbarModel* GetToolbarModel() const override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index 618d6131..1e4e6fc 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -313,7 +313,7 @@
 }
 
 void OmniboxPopupContentsView::UpdatePopupAppearance() {
-  if (!PopupShouldBeOpen()) {
+  if (model_->result().empty() || omnibox_view_->IsImeShowingPopup()) {
     // No matches or the IME is showing a popup window which may overlap
     // the omnibox popup window.  Close any existing popup.
     if (popup_) {
@@ -551,22 +551,6 @@
   return OmniboxPopupModel::kNoMatch;
 }
 
-bool OmniboxPopupContentsView::PopupShouldBeOpen() const {
-  if (omnibox_view_->IsImeShowingPopup())
-    return false;
-
-  if (!model_->result().empty())
-    return true;
-
-  if (LocationBarView::IsRounded() &&
-      model_->edit_model()->user_input_in_progress() &&
-      model_->edit_model()->has_focus()) {
-    return true;
-  }
-
-  return false;
-}
-
 OmniboxResultView* OmniboxPopupContentsView::result_view_at(size_t i) {
   return static_cast<OmniboxResultView*>(child_at(static_cast<int>(i)));
 }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
index f98aecf..85511e7 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
@@ -100,9 +100,6 @@
   // the specified point.
   size_t GetIndexForPoint(const gfx::Point& point);
 
-  // Returns true if the popup should be open.
-  bool PopupShouldBeOpen() const;
-
   OmniboxResultView* result_view_at(size_t i);
 
   LocationBarView* location_bar_view() { return location_bar_view_; }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 8d3711c..80c39d8 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -425,7 +425,7 @@
   if (model()->is_keyword_hint() && !event.IsShiftDown())
     return model()->AcceptKeyword(KeywordModeEntryMethod::TAB);
 
-  if (!model()->popup_model()->IsDisplayingResults())
+  if (!model()->popup_model()->IsOpen())
     return false;
 
   if (event.IsShiftDown() && (model()->popup_model()->selected_line_state() ==
@@ -836,7 +836,7 @@
     const ui::KeyEvent& event) {
   if (views::FocusManager::IsTabTraversalKeyEvent(event) &&
       ((model()->is_keyword_hint() && !event.IsShiftDown()) ||
-       model()->popup_model()->IsDisplayingResults())) {
+       model()->popup_model()->IsOpen())) {
     return true;
   }
   if (event.key_code() == ui::VKEY_ESCAPE)
@@ -1008,7 +1008,7 @@
   // TODO(tommycli): This seems like it should apply to the Cocoa version of
   // the Omnibox as well. Investigate moving this into the OmniboxEditModel.
   if (!model()->user_input_in_progress() && model()->popup_model() &&
-      model()->popup_model()->IsDisplayingResults() &&
+      model()->popup_model()->IsOpen() &&
       text() != model()->GetCurrentPermanentUrlText()) {
     RevertAll();
   } else {
@@ -1184,7 +1184,7 @@
       break;
 
     case ui::VKEY_DELETE:
-      if (shift && model()->popup_model()->IsDisplayingResults())
+      if (shift && model()->popup_model()->IsOpen())
         model()->popup_model()->TryDeletingCurrentItem();
       break;
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
index 48bf0e16..37679be 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -134,7 +134,7 @@
   omnibox_view_views->ExecuteCommand(IDS_PASTE_AND_GO, ui::EF_NONE);
 
   // The popup should not be open.
-  EXPECT_FALSE(view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_FALSE(view->model()->popup_model()->IsOpen());
 }
 
 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, DoNotNavigateOnDrop) {
@@ -367,7 +367,7 @@
 
   // The omnibox popup should open with suggestions displayed.
   omnibox_view->model()->popup_model()->OnResultChanged();
-  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
 
   // The omnibox text should be selected.
   EXPECT_TRUE(omnibox_view->IsSelectAll());
@@ -378,14 +378,14 @@
                          ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
                          ui::EF_LEFT_MOUSE_BUTTON);
   omnibox_view_views->OnMousePressed(pressed);
-  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
 
   // Simulate a mouse drag of the omnibox text, and the omnibox should close.
   ui::MouseEvent dragged(ui::ET_MOUSE_DRAGGED, point, point,
                          ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
   omnibox_view_views->OnMouseDragged(dragged);
 
-  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
 }
 
 IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle) {
@@ -415,7 +415,7 @@
 
   // The omnibox popup should open with suggestions displayed.
   omnibox_view->model()->popup_model()->OnResultChanged();
-  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
 
   // TODO(krb): For some reason, we need to hit End twice to be registered.
   ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_END, false,
@@ -429,7 +429,7 @@
   omnibox_view->GetSelectionBounds(&prev_start, &end);
 
   chrome::FocusAppMenu(browser());
-  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
 
   // Re-focus.
   chrome::FocusLocationBar(browser());
@@ -549,7 +549,7 @@
   // The omnibox popup should open with suggestions displayed.
   chrome::FocusLocationBar(browser());
   omnibox_view->model()->popup_model()->OnResultChanged();
-  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
   OmniboxViewViews* omnibox_view_views =
       static_cast<OmniboxViewViews*>(omnibox_view);
 
@@ -641,7 +641,7 @@
   // The omnibox popup should open with suggestions displayed.
   chrome::FocusLocationBar(browser());
   omnibox_view->model()->popup_model()->OnResultChanged();
-  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsDisplayingResults());
+  EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen());
   ui::AXNodeData popup_node_data_2;
   popup_view->GetAccessibleNodeData(&popup_node_data_2);
   EXPECT_TRUE(popup_node_data_2.HasState(ax::mojom::State::kExpanded));
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
index 686d12f..f9c78ee 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/browser_commands.h"
diff --git a/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc
index 036879c..79f0a2e0 100644
--- a/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_can_make_payment_metrics_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
diff --git a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
index bce8b4d..d9dc0a4 100644
--- a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "components/autofill/core/browser/autofill_profile.h"
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
index 61b7f51..5964dc5 100644
--- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
index 7091c8db..70c95f8 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
@@ -12,7 +12,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 8269747..f3c65f36 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -113,6 +113,7 @@
 #endif
 
 #if defined(OS_ANDROID)
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h"
 #include "chrome/browser/ui/webui/offline/offline_internals_ui.h"
 #include "chrome/browser/ui/webui/snippets_internals/snippets_internals_ui.h"
 #include "chrome/browser/ui/webui/webapks_ui.h"
@@ -495,6 +496,9 @@
 #endif  // !defined(OFFICIAL_BUILD)
 #endif  // defined(OS_CHROMEOS)
 #if defined(OS_ANDROID)
+  if (url.host_piece() == chrome::kChromeUIEocInternalsHost &&
+      !profile->IsOffTheRecord())
+    return &NewWebUI<EocInternalsUI>;
   if (url.host_piece() == chrome::kChromeUIOfflineInternalsHost)
     return &NewWebUI<OfflineInternalsUI>;
   if (url.host_piece() == chrome::kChromeUISnippetsInternalsHost &&
diff --git a/chrome/browser/ui/webui/eoc_internals/BUILD.gn b/chrome/browser/ui/webui/eoc_internals/BUILD.gn
new file mode 100644
index 0000000..b00810f
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("mojo_bindings") {
+  sources = [
+    "eoc_internals.mojom",
+  ]
+}
diff --git a/chrome/browser/ui/webui/eoc_internals/OWNERS b/chrome/browser/ui/webui/eoc_internals/OWNERS
new file mode 100644
index 0000000..2d4c4676
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/OWNERS
@@ -0,0 +1,4 @@
+file://components/ntp_snippets/OWNERS
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom b/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom
new file mode 100644
index 0000000..71a64854
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom
@@ -0,0 +1,8 @@
+// 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.
+
+module eoc_internals.mojom;
+
+interface PageHandler {
+};
\ No newline at end of file
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc
new file mode 100644
index 0000000..54db92a42
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.cc
@@ -0,0 +1,11 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h"
+
+EocInternalsPageHandler::EocInternalsPageHandler(
+    eoc_internals::mojom::PageHandlerRequest request)
+    : binding_(this, std::move(request)) {}
+
+EocInternalsPageHandler::~EocInternalsPageHandler() {}
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h
new file mode 100644
index 0000000..f8d20c8
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+// Concrete implementation of eoc_internals::mojom::PageHandler.
+class EocInternalsPageHandler : public eoc_internals::mojom::PageHandler {
+ public:
+  explicit EocInternalsPageHandler(
+      eoc_internals::mojom::PageHandlerRequest request);
+  ~EocInternalsPageHandler() override;
+
+ private:
+  mojo::Binding<eoc_internals::mojom::PageHandler> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(EocInternalsPageHandler);
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_PAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.cc b/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.cc
new file mode 100644
index 0000000..eb3023d
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.cc
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h"
+
+#include "build/build_config.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/browser_resources.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/chrome_feature_list.h"
+#endif
+
+EocInternalsUI::EocInternalsUI(content::WebUI* web_ui)
+    : ui::MojoWebUIController(web_ui) {
+  content::WebUIDataSource* source =
+      content::WebUIDataSource::Create(chrome::kChromeUIEocInternalsHost);
+
+  source->AddResourcePath("eoc_internals.css", IDR_EOC_INTERNALS_CSS);
+  source->AddResourcePath("eoc_internals.js", IDR_EOC_INTERNALS_JS);
+  source->AddResourcePath("eoc_internals.mojom.js", IDR_EOC_INTERNALS_MOJO_JS);
+  source->SetDefaultResource(IDR_EOC_INTERNALS_HTML);
+  source->UseGzip();
+
+  Profile* profile = Profile::FromWebUI(web_ui);
+  content::WebUIDataSource::Add(profile, source);
+  // This class is the caller of the callback when an observer interface is
+  // triggered. So this base::Unretained is safe.
+  AddHandlerToRegistry(base::BindRepeating(
+      &EocInternalsUI::BindEocInternalsPageHandler, base::Unretained(this)));
+}
+
+EocInternalsUI::~EocInternalsUI() {}
+
+void EocInternalsUI::BindEocInternalsPageHandler(
+    eoc_internals::mojom::PageHandlerRequest request) {
+  page_handler_.reset(new EocInternalsPageHandler(std::move(request)));
+}
diff --git a/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h b/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h
new file mode 100644
index 0000000..7209b4c
--- /dev/null
+++ b/chrome/browser/ui/webui/eoc_internals/eoc_internals_ui.h
@@ -0,0 +1,32 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals.mojom.h"
+#include "chrome/browser/ui/webui/eoc_internals/eoc_internals_page_handler.h"
+#include "ui/webui/mojo_web_ui_controller.h"
+
+// UI controller for chrome://eoc-internals, hooks up a concrete implementation
+// of eoc_internals::mojom::PageHandler to requests for that page handler
+// that will come from the frontend.
+class EocInternalsUI : public ui::MojoWebUIController {
+ public:
+  explicit EocInternalsUI(content::WebUI* web_ui);
+  ~EocInternalsUI() override;
+
+ private:
+  void BindEocInternalsPageHandler(
+      eoc_internals::mojom::PageHandlerRequest request);
+
+  std::unique_ptr<EocInternalsPageHandler> page_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(EocInternalsUI);
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_EOC_INTERNALS_EOC_INTERNALS_UI_H_
diff --git a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
index 386eaa6..47835d2b 100644
--- a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
+++ b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
@@ -10,7 +10,7 @@
 
 #include "base/hash.h"
 #include "base/macros.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index 1358770..4f83824 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <string>
 
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc b/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
index 8de7fc5..a65c05c 100644
--- a/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_ui_browsertest.cc
@@ -7,7 +7,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "chrome/browser/profiles/profiles_state.h"
diff --git a/chrome/browser/usb/web_usb_detector_unittest.cc b/chrome/browser/usb/web_usb_detector_unittest.cc
index 077193a..b4258f1 100644
--- a/chrome/browser/usb/web_usb_detector_unittest.cc
+++ b/chrome/browser/usb/web_usb_detector_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
diff --git a/chrome/browser/vr/service/browser_xr_device.cc b/chrome/browser/vr/service/browser_xr_device.cc
index 6d5fc443..0b51951 100644
--- a/chrome/browser/vr/service/browser_xr_device.cc
+++ b/chrome/browser/vr/service/browser_xr_device.cc
@@ -12,6 +12,7 @@
 BrowserXrDevice::BrowserXrDevice(device::VRDevice* device, bool is_fallback)
     : device_(device), is_fallback_(is_fallback), weak_ptr_factory_(this) {
   device_->SetVRDeviceEventListener(this);
+  display_info_ = device->GetVRDisplayInfo();
 }
 
 BrowserXrDevice::~BrowserXrDevice() {
@@ -20,6 +21,7 @@
 
 void BrowserXrDevice::OnChanged(
     device::mojom::VRDisplayInfoPtr vr_device_info) {
+  display_info_ = vr_device_info.Clone();
   for (VRDisplayHost* display : displays_) {
     display->OnChanged(vr_device_info.Clone());
   }
diff --git a/chrome/browser/vr/service/browser_xr_device.h b/chrome/browser/vr/service/browser_xr_device.h
index b5d04ba..0843a77 100644
--- a/chrome/browser/vr/service/browser_xr_device.h
+++ b/chrome/browser/vr/service/browser_xr_device.h
@@ -41,6 +41,9 @@
       device::mojom::VRDisplayHost::RequestPresentCallback callback);
   VRDisplayHost* GetPresentingDisplayHost() { return presenting_display_host_; }
   void UpdateListeningForActivate(VRDisplayHost* display);
+  device::mojom::VRDisplayInfoPtr GetVRDisplayInfo() {
+    return display_info_.Clone();
+  }
 
   // Methods called by VRDeviceManager to inspect the device.
   bool IsFallbackDevice() { return is_fallback_; }
@@ -57,6 +60,8 @@
   device::VRDevice* device_;
 
   std::set<VRDisplayHost*> displays_;
+  device::mojom::VRDisplayInfoPtr display_info_;
+
   VRDisplayHost* listening_for_activation_display_host_ = nullptr;
   VRDisplayHost* presenting_display_host_ = nullptr;
   bool is_fallback_;
diff --git a/chrome/browser/vr/service/vr_display_host.cc b/chrome/browser/vr/service/vr_display_host.cc
index ba3815f..eff4c12 100644
--- a/chrome/browser/vr/service/vr_display_host.cc
+++ b/chrome/browser/vr/service/vr_display_host.cc
@@ -62,8 +62,10 @@
   display_->StopSession();
 }
 
-void VRDisplayHost::RequestSession(RequestSessionCallback callback) {
-  if (!IsSecureContextRequirementSatisfied()) {
+void VRDisplayHost::RequestSession(device::mojom::XRSessionOptionsPtr options,
+                                   RequestSessionCallback callback) {
+  if (!InternalSupportsSession(std::move(options)) ||
+      !IsSecureContextRequirementSatisfied()) {
     std::move(callback).Run(false);
     return;
   }
@@ -81,6 +83,20 @@
           browser_device_->GetPresentingDisplayHost() != nullptr);
 }
 
+void VRDisplayHost::SupportsSession(device::mojom::XRSessionOptionsPtr options,
+                                    SupportsSessionCallback callback) {
+  std::move(callback).Run(InternalSupportsSession(std::move(options)));
+}
+
+bool VRDisplayHost::InternalSupportsSession(
+    device::mojom::XRSessionOptionsPtr options) {
+  if (options->exclusive) {
+    return browser_device_->GetVRDisplayInfo()->capabilities->canPresent;
+  }
+
+  return true;
+}
+
 void VRDisplayHost::RequestPresent(
     device::mojom::VRSubmitFrameClientPtr client,
     device::mojom::VRPresentationProviderRequest request,
diff --git a/chrome/browser/vr/service/vr_display_host.h b/chrome/browser/vr/service/vr_display_host.h
index 788d5da..c8464eb 100644
--- a/chrome/browser/vr/service/vr_display_host.h
+++ b/chrome/browser/vr/service/vr_display_host.h
@@ -36,7 +36,11 @@
   ~VRDisplayHost() override;
 
   // device::mojom::VRDisplayHost
-  void RequestSession(RequestSessionCallback callback) override;
+  void RequestSession(device::mojom::XRSessionOptionsPtr options,
+                      RequestSessionCallback callback) override;
+  void SupportsSession(device::mojom::XRSessionOptionsPtr options,
+                       SupportsSessionCallback callback) override;
+
   void RequestPresent(device::mojom::VRSubmitFrameClientPtr client,
                       device::mojom::VRPresentationProviderRequest request,
                       device::mojom::VRRequestPresentOptionsPtr options,
@@ -61,6 +65,8 @@
   void ReportRequestPresent();
   bool IsAnotherHostPresenting();
 
+  bool InternalSupportsSession(device::mojom::XRSessionOptionsPtr options);
+
   // TODO(https://crbug.com/837538): Instead, check before returning this
   // object.
   bool IsSecureContextRequirementSatisfied();
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index b0912602..b15735d 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -168,6 +168,7 @@
 const char kDeprecatedChromeUIHistoryFrameURL[] = "chrome://history-frame/";
 
 #if defined(OS_ANDROID)
+const char kChromeUIEocInternalsHost[] = "eoc-internals";
 const char kChromeUIJavaCrashURL[] = "chrome://java-crash/";
 const char kChromeUINativeBookmarksURL[] = "chrome-native://bookmarks/";
 const char kChromeUINativeHistoryURL[] = "chrome-native://history/";
@@ -376,6 +377,7 @@
     kChromeUIUberHost,
 #endif
 #if defined(OS_ANDROID)
+    kChromeUIEocInternalsHost,
     kChromeUIOfflineInternalsHost,
     kChromeUISnippetsInternalsHost,
     kChromeUIWebApksHost,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index 94e6d66..3070dd3 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -168,6 +168,7 @@
 extern const char kDeprecatedChromeUIHistoryFrameURL[];
 
 #if defined(OS_ANDROID)
+extern const char kChromeUIEocInternalsHost[];
 extern const char kChromeUIJavaCrashURL[];
 extern const char kChromeUINativeBookmarksURL[];
 extern const char kChromeUINativeHistoryURL[];
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc
index 4d77d21..1406fef2 100644
--- a/chrome/installer/setup/setup_util_unittest.cc
+++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -20,7 +20,7 @@
 #include "base/process/process_handle.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_reg_util_win.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
@@ -35,8 +35,8 @@
 #include "chrome/installer/setup/setup_util.h"
 #include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/google_update_constants.h"
-#include "chrome/installer/util/installation_state.h"
 #include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/installation_state.h"
 #include "chrome/installer/util/updating_app_registration_data.h"
 #include "chrome/installer/util/util_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
index 2d8edd1..6d55709 100644
--- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -10,7 +10,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/renderer/autofill/fake_content_password_manager_driver.h"
 #include "chrome/renderer/autofill/fake_password_manager_client.h"
diff --git a/chrome/renderer/chrome_content_renderer_client_unittest.cc b/chrome/renderer/chrome_content_renderer_client_unittest.cc
index be0a2285..1bcfd127 100644
--- a/chrome/renderer/chrome_content_renderer_client_unittest.cc
+++ b/chrome/renderer/chrome_content_renderer_client_unittest.cc
@@ -13,7 +13,7 @@
 
 #include "base/metrics/histogram_samples.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/renderer/searchbox/search_bouncer.h"
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index 42c2199..6b1bace 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -393,8 +393,8 @@
       base::NumberToString(content::RenderView::GetRenderViewCount()));
 
 #if !defined(OS_ANDROID)
-  if ((render_frame()->GetEnabledBindings() &
-       content::BINDINGS_POLICY_WEB_UI)) {
+  if (render_frame()->GetEnabledBindings() &
+      content::kWebUIBindingsPolicyMask) {
     for (const auto& script : webui_javascript_)
       render_frame()->ExecuteJavaScript(script);
     webui_javascript_.clear();
diff --git a/chrome/renderer/chrome_render_frame_observer_browsertest.cc b/chrome/renderer/chrome_render_frame_observer_browsertest.cc
index b352a206..ffb1b3d 100644
--- a/chrome/renderer/chrome_render_frame_observer_browsertest.cc
+++ b/chrome/renderer/chrome_render_frame_observer_browsertest.cc
@@ -7,7 +7,7 @@
 #include <tuple>
 
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_test.h"
 #include "components/translate/content/common/translate.mojom.h"
 #include "components/translate/content/renderer/translate_helper.h"
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc
index 0b4a0ec..669fc19 100644
--- a/chrome/renderer/net/net_error_helper_core_unittest.cc
+++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -18,7 +18,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/timer/mock_timer.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
diff --git a/chrome/renderer/safe_browsing/threat_dom_details_browsertest.cc b/chrome/renderer/safe_browsing/threat_dom_details_browsertest.cc
index 9335847..5f3875af 100644
--- a/chrome/renderer/safe_browsing/threat_dom_details_browsertest.cc
+++ b/chrome/renderer/safe_browsing/threat_dom_details_browsertest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/test/base/chrome_render_view_test.h"
 #include "components/safe_browsing/common/safe_browsing.mojom.h"
diff --git a/chrome/services/file_util/public/cpp/sandboxed_zip_analyzer_unittest.cc b/chrome/services/file_util/public/cpp/sandboxed_zip_analyzer_unittest.cc
index 144129d..d45eaaf 100644
--- a/chrome/services/file_util/public/cpp/sandboxed_zip_analyzer_unittest.cc
+++ b/chrome/services/file_util/public/cpp/sandboxed_zip_analyzer_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/macros.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/safe_browsing/archive_analyzer_results.h"
diff --git a/chrome/test/data/extensions/api_test/file_browser/crostini_test/manifest.json b/chrome/test/data/extensions/api_test/file_browser/crostini_test/manifest.json
index 48bba8c9..3427b7f8 100644
--- a/chrome/test/data/extensions/api_test/file_browser/crostini_test/manifest.json
+++ b/chrome/test/data/extensions/api_test/file_browser/crostini_test/manifest.json
@@ -4,7 +4,7 @@
   "name": "chrome.fileManagerPrivate tests",
   "version": "0.1",
   "manifest_version": 2,
-  "description": "Tests of chrome.fileManagerPrivate.isCrostiniEnabled",
+  "description": "Tests of chrome.fileManagerPrivate.[isCrostiniEnabled|mountCrostiniContainer]",
   "app": {
     "background": {
       "scripts": ["test.js"]
diff --git a/chrome/test/data/extensions/api_test/file_browser/crostini_test/test.js b/chrome/test/data/extensions/api_test/file_browser/crostini_test/test.js
index 90d7203..bdbc3694 100644
--- a/chrome/test/data/extensions/api_test/file_browser/crostini_test/test.js
+++ b/chrome/test/data/extensions/api_test/file_browser/crostini_test/test.js
@@ -10,4 +10,8 @@
           chrome.test.assertTrue(enabled);
         }));
   },
+  function testMountCrostiniContainer() {
+    chrome.fileManagerPrivate.mountCrostiniContainer(
+        chrome.test.callbackPass(() => {}));
+  }
 ]);
diff --git a/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/chain.pem b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/chain.pem
new file mode 100644
index 0000000..8c68f56e
--- /dev/null
+++ b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/chain.pem
@@ -0,0 +1,285 @@
+[Created by: ./generate-chains.py]
+
+Chain where the leaf has two policies and the intermediate has anyPolicy.
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            6b:e1:0f:c9:fa:59:38:73:f8:5d:58:01:76:a1:f9:07:db:92:01:5c
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=Intermediate
+        Validity
+            Not Before: Mar 10 12:00:00 2018 GMT
+            Not After : Jan  1 12:00:00 2021 GMT
+        Subject: CN=Target
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a7:fb:0c:b8:75:eb:c8:c2:7a:0c:72:ee:89:76:
+                    8c:a8:0c:54:51:5a:2d:69:42:9f:78:ea:57:3f:c0:
+                    c2:4f:6d:b9:92:cf:41:f5:83:70:56:02:06:80:f6:
+                    0b:61:3d:ff:d6:2c:0e:9d:59:fc:91:a6:47:fe:f0:
+                    36:07:48:1e:18:5b:d1:59:50:e9:07:a7:a6:3b:0c:
+                    53:e3:31:53:e0:3b:c3:1d:02:c4:6d:ed:a7:9d:bc:
+                    a4:f6:1a:1a:c8:c4:51:28:60:11:2d:3f:2c:93:60:
+                    d5:4e:44:83:e3:2b:ea:47:98:7a:c4:6e:6d:67:32:
+                    2c:29:28:3f:b0:73:c1:b2:ce:fc:f6:15:e3:16:d5:
+                    00:11:b4:98:91:43:42:d6:0f:ed:82:95:2f:23:69:
+                    60:0e:9a:09:1b:9a:67:c1:a0:83:d4:74:80:6f:de:
+                    67:34:73:d9:79:bb:83:6b:90:0c:a7:59:05:5c:96:
+                    9b:e2:7e:f2:d7:6b:57:09:81:8b:6a:54:d2:58:50:
+                    22:49:3c:ca:44:a1:a9:c9:41:50:39:d4:ad:78:3c:
+                    e0:4b:74:ff:d6:04:61:6a:e5:4d:eb:2d:45:11:78:
+                    a7:30:bc:12:31:c5:1e:e6:f8:dc:81:60:6f:0b:01:
+                    bc:50:a2:c1:e4:6c:eb:87:b4:b5:89:86:b3:cc:0a:
+                    68:d1
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                9D:8B:D4:7E:BA:F1:1F:2F:2B:E6:6A:5E:E5:36:FD:A6:3E:F5:5F:B0
+            X509v3 Authority Key Identifier: 
+                keyid:DE:60:17:6D:1C:07:19:9D:2A:ED:85:01:D1:5F:20:9F:30:B6:35:87
+
+            Authority Information Access: 
+                CA Issuers - URI:http://url-for-aia/Intermediate.cer
+
+            X509v3 CRL Distribution Points: 
+
+                Full Name:
+                  URI:http://url-for-crl/Intermediate.crl
+
+            X509v3 Key Usage: critical
+                Digital Signature, Key Encipherment
+            X509v3 Extended Key Usage: 
+                TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Certificate Policies: 
+                Policy: 1.2.3.4
+                Policy: 1.2.6.7
+
+            X509v3 Subject Alternative Name: 
+                DNS:test.example
+    Signature Algorithm: sha256WithRSAEncryption
+         4a:36:57:8d:fe:fa:8e:fa:66:44:6c:5f:0e:52:d7:d7:49:e1:
+         d7:8b:58:49:bf:7d:21:11:01:53:34:23:86:c3:3b:72:b6:e5:
+         31:e7:f0:23:28:b3:20:3a:ad:b2:53:40:df:19:38:49:95:2d:
+         bb:7e:67:76:e8:1d:93:62:01:c0:b5:54:67:ff:0e:4d:c6:04:
+         8a:f8:e8:0e:25:26:7e:d8:ee:09:06:9e:59:6d:0c:a7:21:72:
+         fa:7d:c9:1e:87:a0:89:4b:06:bf:fb:3c:66:ff:62:f6:e6:c7:
+         0b:fb:89:37:36:fc:4b:ef:40:a2:54:19:ff:4f:d3:1f:6e:75:
+         91:df:e8:0a:b6:62:48:2c:2d:ca:10:d0:c3:8a:38:b9:d2:45:
+         a3:75:14:53:da:e9:b4:d7:3f:7d:f0:df:79:3d:a5:29:97:9a:
+         0d:21:59:16:b9:9a:ee:cb:10:1f:7d:51:db:4c:ad:4d:af:89:
+         44:52:5f:25:bd:b9:d7:41:a1:a7:5b:4e:39:bc:f9:22:b2:ec:
+         06:c9:ca:8b:5f:f0:fe:3e:3e:12:2f:ff:c4:cf:da:66:d9:c7:
+         65:cc:2f:fa:f1:b1:b4:2f:17:94:03:14:23:89:f5:58:46:eb:
+         e5:a1:16:db:d9:cf:c3:bd:29:65:80:4b:f7:4f:75:23:88:42:
+         b5:06:cf:0a
+-----BEGIN CERTIFICATE-----
+MIID1DCCArygAwIBAgIUa+EPyfpZOHP4XVgBdqH5B9uSAVwwDQYJKoZIhvcNAQEL
+BQAwFzEVMBMGA1UEAwwMSW50ZXJtZWRpYXRlMB4XDTE4MDMxMDEyMDAwMFoXDTIx
+MDEwMTEyMDAwMFowETEPMA0GA1UEAwwGVGFyZ2V0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAp/sMuHXryMJ6DHLuiXaMqAxUUVotaUKfeOpXP8DCT225
+ks9B9YNwVgIGgPYLYT3/1iwOnVn8kaZH/vA2B0geGFvRWVDpB6emOwxT4zFT4DvD
+HQLEbe2nnbyk9hoayMRRKGARLT8sk2DVTkSD4yvqR5h6xG5tZzIsKSg/sHPBss78
+9hXjFtUAEbSYkUNC1g/tgpUvI2lgDpoJG5pnwaCD1HSAb95nNHPZebuDa5AMp1kF
+XJab4n7y12tXCYGLalTSWFAiSTzKRKGpyUFQOdSteDzgS3T/1gRhauVN6y1FEXin
+MLwSMcUe5vjcgWBvCwG8UKLB5Gzrh7S1iYazzApo0QIDAQABo4IBHDCCARgwHQYD
+VR0OBBYEFJ2L1H668R8vK+ZqXuU2/aY+9V+wMB8GA1UdIwQYMBaAFN5gF20cBxmd
+Ku2FAdFfIJ8wtjWHMD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDov
+L3VybC1mb3ItYWlhL0ludGVybWVkaWF0ZS5jZXIwNAYDVR0fBC0wKzApoCegJYYj
+aHR0cDovL3VybC1mb3ItY3JsL0ludGVybWVkaWF0ZS5jcmwwDgYDVR0PAQH/BAQD
+AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAXBgNVHSAEEDAOMAUG
+AyoDBDAFBgMqBgcwFwYDVR0RBBAwDoIMdGVzdC5leGFtcGxlMA0GCSqGSIb3DQEB
+CwUAA4IBAQBKNleN/vqO+mZEbF8OUtfXSeHXi1hJv30hEQFTNCOGwztytuUx5/Aj
+KLMgOq2yU0DfGThJlS27fmd26B2TYgHAtVRn/w5NxgSK+OgOJSZ+2O4JBp5ZbQyn
+IXL6fckeh6CJSwa/+zxm/2L25scL+4k3NvxL70CiVBn/T9MfbnWR3+gKtmJILC3K
+ENDDiji50kWjdRRT2um01z998N95PaUpl5oNIVkWuZruyxAffVHbTK1Nr4lEUl8l
+vbnXQaGnW045vPkisuwGycqLX/D+Pj4SL//Ez9pm2cdlzC/68bG0LxeUAxQjifVY
+RuvloRbb2c/DvSllgEv3T3UjiEK1Bs8K
+-----END CERTIFICATE-----
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            76:42:db:45:76:7f:b8:53:d5:02:1e:c2:90:7e:60:72:5a:78:fc:c8
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=Root
+        Validity
+            Not Before: Mar 10 12:00:00 2018 GMT
+            Not After : Jan  1 12:00:00 2021 GMT
+        Subject: CN=Intermediate
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b2:2f:54:6d:cb:bc:2b:71:f5:87:7a:7d:5d:ab:
+                    c3:0e:bd:15:b0:a5:47:e4:2b:2a:a0:a0:0d:0f:65:
+                    fc:84:85:2c:b4:24:a7:cf:87:9e:89:d9:f3:cf:de:
+                    89:61:c7:64:42:65:5f:39:13:89:92:48:54:9c:33:
+                    6b:8e:dc:dc:c6:4d:79:f8:63:37:f4:41:0d:57:ee:
+                    5b:0d:6d:2f:6a:d6:78:d3:d3:f7:29:d0:fa:89:ec:
+                    72:ec:11:49:fe:78:8f:38:ac:69:27:e3:f9:19:3d:
+                    58:18:2e:2d:f6:7c:a5:30:1f:1d:79:65:b5:b1:4d:
+                    05:6a:4b:dd:01:2e:a7:64:d1:16:23:07:05:1a:09:
+                    6a:67:73:d0:f3:d9:c3:81:9e:99:ac:ee:58:06:b5:
+                    d6:ce:df:0d:c4:14:42:cb:44:e1:7b:2a:1f:e6:38:
+                    e6:00:4b:39:d1:89:0c:27:d6:e3:61:16:7e:44:8f:
+                    25:65:8d:a6:a4:95:85:3e:13:c5:d6:14:83:c1:e3:
+                    69:cf:88:ed:f7:74:9e:2b:8e:a7:5f:ad:d2:84:98:
+                    06:14:85:88:54:0a:b6:9c:8a:8f:0b:d1:c4:2c:5e:
+                    06:96:55:4a:92:7b:14:bb:aa:bf:cd:d4:a5:a8:ae:
+                    ef:eb:d8:97:75:7b:a0:7a:b6:69:1c:27:37:f2:f9:
+                    e5:09
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                DE:60:17:6D:1C:07:19:9D:2A:ED:85:01:D1:5F:20:9F:30:B6:35:87
+            X509v3 Authority Key Identifier: 
+                keyid:E3:1C:57:80:6D:50:B5:5E:E3:27:A5:3F:E5:CC:E0:A9:45:56:C1:9E
+
+            Authority Information Access: 
+                CA Issuers - URI:http://url-for-aia/Root.cer
+
+            X509v3 CRL Distribution Points: 
+
+                Full Name:
+                  URI:http://url-for-crl/Root.crl
+
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Certificate Policies: 
+                Policy: X509v3 Any Policy
+
+    Signature Algorithm: sha256WithRSAEncryption
+         46:e3:84:f5:f8:ca:cd:67:47:bc:e7:5c:c8:15:9b:43:38:4e:
+         e8:01:ae:c3:0b:fe:d7:b2:27:5b:d5:eb:1f:c9:b0:13:8e:2d:
+         ad:34:bb:f3:ce:5f:1e:4a:1c:ee:62:de:bb:8d:95:47:c7:61:
+         8d:01:c4:a4:0e:27:24:25:55:23:97:54:08:f6:39:0d:b2:26:
+         41:d5:0a:68:66:19:06:79:4b:78:c6:6e:20:d5:12:12:d0:21:
+         92:e9:8f:f2:b2:c3:01:5f:9a:12:f3:5d:d4:b9:64:4b:60:f0:
+         5c:ee:38:82:95:80:e3:cf:56:80:60:e5:65:51:30:5d:97:80:
+         67:a5:91:79:25:35:8a:18:88:77:0c:6d:9f:1f:32:46:75:4c:
+         52:98:8c:bf:88:05:99:9f:48:83:3b:4b:57:81:39:59:93:d8:
+         45:0b:8a:21:3e:92:fa:21:88:c2:60:f8:7e:a4:5a:2f:5f:17:
+         d1:ac:9b:e8:d8:9c:28:fb:32:d8:99:bd:59:63:e0:93:7b:8f:
+         2c:47:2f:f8:ac:67:e8:5e:c9:e8:56:26:75:49:3e:c4:ba:58:
+         3a:e3:ec:15:08:5d:d5:0c:e5:62:92:c0:33:ce:4e:21:6c:9b:
+         2d:81:66:48:76:e2:45:9f:27:84:68:66:5f:7a:a8:4a:15:92:
+         e0:3c:bb:5e
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIUdkLbRXZ/uFPVAh7CkH5gclp4/MgwDQYJKoZIhvcNAQEL
+BQAwDzENMAsGA1UEAwwEUm9vdDAeFw0xODAzMTAxMjAwMDBaFw0yMTAxMDExMjAw
+MDBaMBcxFTATBgNVBAMMDEludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALIvVG3LvCtx9Yd6fV2rww69FbClR+QrKqCgDQ9l/ISFLLQk
+p8+HnonZ88/eiWHHZEJlXzkTiZJIVJwza47c3MZNefhjN/RBDVfuWw1tL2rWeNPT
+9ynQ+onscuwRSf54jzisaSfj+Rk9WBguLfZ8pTAfHXlltbFNBWpL3QEup2TRFiMH
+BRoJamdz0PPZw4GemazuWAa11s7fDcQUQstE4XsqH+Y45gBLOdGJDCfW42EWfkSP
+JWWNpqSVhT4TxdYUg8Hjac+I7fd0niuOp1+t0oSYBhSFiFQKtpyKjwvRxCxeBpZV
+SpJ7FLuqv83Upaiu7+vYl3V7oHq2aRwnN/L55QkCAwEAAaOB3jCB2zAdBgNVHQ4E
+FgQU3mAXbRwHGZ0q7YUB0V8gnzC2NYcwHwYDVR0jBBgwFoAU4xxXgG1QtV7jJ6U/
+5czgqUVWwZ4wNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzAChhtodHRwOi8vdXJs
+LWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL3VybC1m
+b3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
+MBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEARuOE9fjKzWdH
+vOdcyBWbQzhO6AGuwwv+17InW9XrH8mwE44trTS7885fHkoc7mLeu42VR8dhjQHE
+pA4nJCVVI5dUCPY5DbImQdUKaGYZBnlLeMZuINUSEtAhkumP8rLDAV+aEvNd1Llk
+S2DwXO44gpWA489WgGDlZVEwXZeAZ6WReSU1ihiIdwxtnx8yRnVMUpiMv4gFmZ9I
+gztLV4E5WZPYRQuKIT6S+iGIwmD4fqRaL18X0ayb6NicKPsy2Jm9WWPgk3uPLEcv
++Kxn6F7J6FYmdUk+xLpYOuPsFQhd1QzlYpLAM85OIWybLYFmSHbiRZ8nhGhmX3qo
+ShWS4Dy7Xg==
+-----END CERTIFICATE-----
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            76:42:db:45:76:7f:b8:53:d5:02:1e:c2:90:7e:60:72:5a:78:fc:c7
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=Root
+        Validity
+            Not Before: Mar 10 12:00:00 2018 GMT
+            Not After : Jan  1 12:00:00 2021 GMT
+        Subject: CN=Root
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:9a:8f:40:d0:8f:a9:e6:69:43:b2:9a:c5:a9:f9:
+                    0f:20:56:10:59:91:36:08:26:d2:eb:0c:e6:82:de:
+                    a5:90:ca:67:dc:f8:17:bc:71:91:9c:f3:46:eb:71:
+                    65:f5:a5:e0:9c:5e:e5:09:2f:a2:9c:5d:49:29:20:
+                    d0:bb:58:c3:ac:9d:4c:a4:df:8a:06:40:13:93:63:
+                    1d:24:d8:5c:01:57:0c:34:ea:47:ae:31:1a:21:d7:
+                    cf:29:73:44:96:97:01:c8:36:57:77:4c:1d:e0:bc:
+                    5a:93:06:3b:d5:45:3f:98:09:8c:db:cc:f2:eb:90:
+                    28:53:94:9f:8d:fd:97:75:ca:c7:fe:92:cf:58:1b:
+                    93:66:37:12:c2:6b:bb:38:a2:43:24:dc:41:c3:b3:
+                    3c:69:f9:a1:7b:ad:7d:92:b3:22:a5:31:df:34:86:
+                    62:43:d8:11:3d:dd:7c:1b:24:9f:0d:2a:0f:c5:1c:
+                    7d:c4:fe:55:4d:33:7a:0a:ef:98:55:64:3f:a7:c6:
+                    40:d3:f7:e0:2d:68:f8:83:0f:c3:8d:c4:65:89:1c:
+                    ab:c8:0d:30:6c:da:dd:8d:a2:8f:ac:96:d8:de:41:
+                    e7:b8:3d:d4:5b:8f:c3:3d:87:6b:d6:7f:bb:4d:23:
+                    d5:08:60:bc:d2:54:85:fe:4f:b4:49:cf:18:32:74:
+                    a1:3f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                E3:1C:57:80:6D:50:B5:5E:E3:27:A5:3F:E5:CC:E0:A9:45:56:C1:9E
+            X509v3 Authority Key Identifier: 
+                keyid:E3:1C:57:80:6D:50:B5:5E:E3:27:A5:3F:E5:CC:E0:A9:45:56:C1:9E
+
+            Authority Information Access: 
+                CA Issuers - URI:http://url-for-aia/Root.cer
+
+            X509v3 CRL Distribution Points: 
+
+                Full Name:
+                  URI:http://url-for-crl/Root.crl
+
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+    Signature Algorithm: sha256WithRSAEncryption
+         93:ab:ec:9b:45:d5:12:c4:80:33:e0:f3:1f:ec:3d:5b:47:80:
+         2a:f4:7b:87:1f:aa:19:ec:7e:b6:1f:39:15:b2:7e:05:28:01:
+         74:60:3c:ef:06:77:e0:2c:59:19:01:12:52:3a:c5:e9:81:24:
+         57:4f:95:b4:5c:22:d9:89:8d:e8:7a:77:1d:57:bd:b6:97:11:
+         a3:7b:5f:df:27:68:77:2c:50:8b:8e:57:64:62:9b:f3:d4:d7:
+         09:7c:9f:65:76:22:87:a5:23:e5:cd:cf:56:50:7d:c8:c2:4f:
+         30:91:3b:d7:1b:f9:04:63:ef:19:5a:a0:46:fc:11:8b:c3:9d:
+         b0:8b:d7:ae:5c:21:74:36:96:57:db:c4:f1:a8:1c:73:be:e9:
+         0b:4d:76:60:37:d0:8f:29:a2:da:55:1b:64:46:10:16:ec:ca:
+         4d:52:fc:e4:30:9f:8e:b9:57:40:87:67:f6:9b:e6:2e:6c:fb:
+         ea:5c:ee:29:51:4c:03:70:66:d8:ce:bd:78:aa:e8:d5:25:49:
+         f6:f2:9d:e4:45:90:55:45:0c:10:37:c1:b9:4d:75:b1:77:3a:
+         89:38:58:fe:ad:46:13:79:ff:7d:c0:04:a6:5e:ae:86:f2:65:
+         16:1f:0e:b2:71:e3:5e:35:18:4b:d1:70:c6:9e:fb:eb:f5:ca:
+         3f:03:7f:56
+-----BEGIN CERTIFICATE-----
+MIIDeDCCAmCgAwIBAgIUdkLbRXZ/uFPVAh7CkH5gclp4/McwDQYJKoZIhvcNAQEL
+BQAwDzENMAsGA1UEAwwEUm9vdDAeFw0xODAzMTAxMjAwMDBaFw0yMTAxMDExMjAw
+MDBaMA8xDTALBgNVBAMMBFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCaj0DQj6nmaUOymsWp+Q8gVhBZkTYIJtLrDOaC3qWQymfc+Be8cZGc80br
+cWX1peCcXuUJL6KcXUkpINC7WMOsnUyk34oGQBOTYx0k2FwBVww06keuMRoh188p
+c0SWlwHINld3TB3gvFqTBjvVRT+YCYzbzPLrkChTlJ+N/Zd1ysf+ks9YG5NmNxLC
+a7s4okMk3EHDszxp+aF7rX2SsyKlMd80hmJD2BE93XwbJJ8NKg/FHH3E/lVNM3oK
+75hVZD+nxkDT9+AtaPiDD8ONxGWJHKvIDTBs2t2Noo+sltjeQee4PdRbj8M9h2vW
+f7tNI9UIYLzSVIX+T7RJzxgydKE/AgMBAAGjgcswgcgwHQYDVR0OBBYEFOMcV4Bt
+ULVe4yelP+XM4KlFVsGeMB8GA1UdIwQYMBaAFOMcV4BtULVe4yelP+XM4KlFVsGe
+MDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlh
+L1Jvb3QuY2VyMCwGA1UdHwQlMCMwIaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9S
+b290LmNybDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAk6vsm0XVEsSAM+DzH+w9W0eAKvR7hx+qGex+th85FbJ+BSgB
+dGA87wZ34CxZGQESUjrF6YEkV0+VtFwi2YmN6Hp3HVe9tpcRo3tf3ydodyxQi45X
+ZGKb89TXCXyfZXYih6Uj5c3PVlB9yMJPMJE71xv5BGPvGVqgRvwRi8OdsIvXrlwh
+dDaWV9vE8agcc77pC012YDfQjymi2lUbZEYQFuzKTVL85DCfjrlXQIdn9pvmLmz7
+6lzuKVFMA3Bm2M69eKro1SVJ9vKd5EWQVUUMEDfBuU11sXc6iThY/q1GE3n/fcAE
+pl6uhvJlFh8OsnHjXjUYS9Fwxp776/XKPwN/Vg==
+-----END CERTIFICATE-----
diff --git a/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/generate-chains.py b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/generate-chains.py
new file mode 100755
index 0000000..3393929
--- /dev/null
+++ b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/generate-chains.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (c) 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Chain where the leaf has two policies and the intermediate has anyPolicy."""
+
+import sys
+sys.path += ['../../../../../../net/data']
+
+import gencerts
+
+# Self-signed root certificate.
+root = gencerts.create_self_signed_root_certificate('Root')
+
+# Intermediate certificate.
+intermediate = gencerts.create_intermediate_certificate('Intermediate', root)
+intermediate.get_extensions().set_property('certificatePolicies', 'anyPolicy')
+
+# Target certificate.
+target = gencerts.create_end_entity_certificate('Target', intermediate)
+target.get_extensions().set_property('certificatePolicies', '1.2.3.4,1.2.6.7')
+target.get_extensions().set_property('subjectAltName', 'DNS:test.example')
+
+chain = [target, intermediate, root]
+gencerts.write_chain(__doc__, chain, 'chain.pem')
diff --git a/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Intermediate.key b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Intermediate.key
new file mode 100644
index 0000000..76737634
--- /dev/null
+++ b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Intermediate.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAsi9Ubcu8K3H1h3p9XavDDr0VsKVH5CsqoKAND2X8hIUstCSn
+z4eeidnzz96JYcdkQmVfOROJkkhUnDNrjtzcxk15+GM39EENV+5bDW0vatZ409P3
+KdD6iexy7BFJ/niPOKxpJ+P5GT1YGC4t9nylMB8deWW1sU0FakvdAS6nZNEWIwcF
+GglqZ3PQ89nDgZ6ZrO5YBrXWzt8NxBRCy0Theyof5jjmAEs50YkMJ9bjYRZ+RI8l
+ZY2mpJWFPhPF1hSDweNpz4jt93SeK46nX63ShJgGFIWIVAq2nIqPC9HELF4GllVK
+knsUu6q/zdSlqK7v69iXdXugerZpHCc38vnlCQIDAQABAoIBAAs5L/g6fP+/jdea
+v4rG5uJmxpb50i1tCqJTcn8lzWILgWVXabqIsFO+hrzxJ3YhOQ91kynlMSUlqS6t
+jnjRMJbNCoG6viuEbXK8cL/HwNTZ7YJqN4dKwn0th4+XBzIgJeVL9tOsaGROmN3t
+Crgb4cvGKfUbkvY4A79OR/1rEuAmsFN6wC863DIJgOJWOYc+OhrgR+mk8yhVhgfF
+whUXOYIFrPLubGg7KpvkwZL36BiNMiihyk+o7L6Ocs8tvH36W1gmYvD+mxUC4LAR
+wuhZ/oqhKCeHT1j+m8KaW4eyOKBNjAzkLInljI6nWvY3MxcgHUispISD86/flY4G
+wDvn4oECgYEA7DEsIAullSsm3/JmvlNgIxt906ZLcbuaqJmEnsnqDOo2mk8Mhyyk
+tYYXUi1dANwrvGwapeh9aDldHRc6ZSrRAk4TYPR0XLrOVzadfWya3oUlCnKQnCF5
+yyMcmm2mmRwIb5VBonI3B6vEHYlHBhz3zhysSiUi4G8ijRUbGSWAbd8CgYEAwSDL
+yKeA5E/KxpjSiFB94iicAMjL1V4jwJ7qUPnU9rixGuLfBB6XdPkghOkFGwyG3kJh
+dnfmytqmdjC83vNF53+cvfq8gCT2S7w7Zdl3vCUsXFWWO474z53DZ5dcwriiOBfi
+c6gTB9cZomsd6hF4WNSCzT32Akni5xcnBNbkuhcCgYA7KZYD8ObpFoYGUpGp2viZ
+0qkR+vWq53M2CD5QCAO4eHJ09JgOw//9+DifPP2u2XebGvkR1cqT8MqCHu9hp/fy
+u9vezVzYXXKSJfwNDsc8Nd2xYEEY2snHOGRRymWQtJToXlqydimSolPdkiVYQqlP
+157Qc7zouu3MqRzAj8Q7wQKBgQCaukXKGrkfMfZJqkJyR9qzCMoDrtvvtB58wlUE
+T0SZ7lqmKcF3MXMymi29jlsy0pRzGUewfFuBhi/7XQzUqp8E266eXnYLTJGvF72W
+2eYd7MJfr4pPaTpaTBEzu4br0rTUr/4Tn0Kv81tsTtmGoDyFHq009kFUkBGkB16R
+eAGEPQKBgHsUTLjkM6XtCtZ6QTposfthFXNtWRuS16wJFeHxDLuSMxO7SfMxJ3j3
+vvKUlEybLbBPdwFUwV2DANB2ljJdPwJd8iXc1bYmG557u59BoOyHigwL65hPZXGy
+VNQRB42LtAtF9pPv31xXFq5jnOVfulnFx9m7PUgF8vcAoUYCJjzO
+-----END RSA PRIVATE KEY-----
diff --git a/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Root.key b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Root.key
new file mode 100644
index 0000000..9f59998
--- /dev/null
+++ b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Root.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAmo9A0I+p5mlDsprFqfkPIFYQWZE2CCbS6wzmgt6lkMpn3PgX
+vHGRnPNG63Fl9aXgnF7lCS+inF1JKSDQu1jDrJ1MpN+KBkATk2MdJNhcAVcMNOpH
+rjEaIdfPKXNElpcByDZXd0wd4LxakwY71UU/mAmM28zy65AoU5Sfjf2XdcrH/pLP
+WBuTZjcSwmu7OKJDJNxBw7M8afmhe619krMipTHfNIZiQ9gRPd18GySfDSoPxRx9
+xP5VTTN6Cu+YVWQ/p8ZA0/fgLWj4gw/DjcRliRyryA0wbNrdjaKPrJbY3kHnuD3U
+W4/DPYdr1n+7TSPVCGC80lSF/k+0Sc8YMnShPwIDAQABAoIBAC92QCQLidPcjVJi
+XsKkXbXDV//5LItySKCvdHXJozQEQ8LCWJ+gjGOS/Ts9tl6p0oCST2jzvM6hgt7j
+WdW+G1B9eVTD5GGo+Znv/LocypwKvA/fxaVDJNAxskb7Q5uuwXhW36Mdt6sUjAfM
+CUGjozSv8hZpKEuYGBoacKisr/8WjQHbK+SpuCNn749HHMPo7hl3OzJ8MZWZzMfE
+cfD/Ka27SJaZOBF4O1YozKDPizVqLd3Ypfzl5C90UDCKwdXXigrIWUfANkH8HrvV
+aB3RmUhiKuMtOsge4xpnt25lMJzZQwcTMRjbzw6UvFUK8ieicT7D1ZZYkjuESXSp
+I8qY6wECgYEAy8LQcR6LlAKSaKIXwdjHonNJGEyL44Y4vDxQRUzitw5RZ6fYYSm3
+lTU5B/Fj2m7iBdVH5GpelgdtKRPj1GVVJW5vglqfqvGjsO/ajJlpMxIalslYV8ds
+kvgbH/Xq5f3dR8RDHR+D7TPZ3mFz33DQ3ItWsl5uHfuf5yfmvlr/3IECgYEAwi9D
+9Hf/5wCgPP6SbmPW40SH0c/mTnLhMCA4s/YRadXUv1HwW9DdoMc+nb0XotVK6PpK
++mRHyKsp1U+YEVJVMaAnVX2Pvtqh0YRFsDdVUaff4shjb4UCr5GC/H1oqD6xE5qA
+Js4uNTuozxXHa4gBSzuNl3uLA89dmg9xTolUnb8CgYEAtETF3t5URH1GBJYriI9+
+h2WRbJMETCZKeZauubD8/1EGijs/vy6GQdaVf0Z7vhvNkbWQ5i+JQRiO5gG31ghU
+nUooE16T1kv0Myzw4OU04j8JERBPPVGs6BXjAZKy4AmKRN0JN3HTaP8vqIP1XOBV
+mFkaObI7oAEnBf4SMaUWqoECgYEAq6d2jcvqNfzSqThsnxK4qYwx9+Gs99oLgCxr
+k4HI4OK6PymirLdUw0R98JhwJWwg3RQsZW1yG0xbHYpPpbg/QTAOtT7aa97+vqQL
+qnsve5BHlESJydItjp+1x5bghiFtDSQ9dpA6PqpvTig1cbP3WNbbEnaOa57KYl6W
+TdOOLicCgYBrL6F/t5OaGTQCetNBO8vhn7dlvZ3Wa2DHmxpWuP4SY4SEUT/3m7mH
+TXTIQe6uIe6QHXrL+K5xLAxICBdI0FuxzyOEP01psyeYlESuqsP1tWja0tVzDVei
+/Z2jKbpU9696ggoBxBNZtukoQPBFvZvnWn9YSrHJhwZZZhImRAX58Q==
+-----END RSA PRIVATE KEY-----
diff --git a/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Target.key b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Target.key
new file mode 100644
index 0000000..8a2cdf03
--- /dev/null
+++ b/chrome/test/data/net/trial_comparison_cert_verifier_unittest/target-multiple-policies/keys/Target.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAp/sMuHXryMJ6DHLuiXaMqAxUUVotaUKfeOpXP8DCT225ks9B
+9YNwVgIGgPYLYT3/1iwOnVn8kaZH/vA2B0geGFvRWVDpB6emOwxT4zFT4DvDHQLE
+be2nnbyk9hoayMRRKGARLT8sk2DVTkSD4yvqR5h6xG5tZzIsKSg/sHPBss789hXj
+FtUAEbSYkUNC1g/tgpUvI2lgDpoJG5pnwaCD1HSAb95nNHPZebuDa5AMp1kFXJab
+4n7y12tXCYGLalTSWFAiSTzKRKGpyUFQOdSteDzgS3T/1gRhauVN6y1FEXinMLwS
+McUe5vjcgWBvCwG8UKLB5Gzrh7S1iYazzApo0QIDAQABAoIBAF/+A8/pexsXn307
+tHqTZ1+k5A41NRwguVb0u3UwJxoSvuhZTf0J5okP0T2i3O/t6SQvuw5KXR2yYxQZ
+mxZgLOqIlcKvjOsV79VwfwOmraLHJAGREkUreQyXv8DvO/0cyrAC7e3oWwXBYUO/
+vYp1DwVo6kcUP6qoLjo6yOKB09/koZB9lhUxO3ns5Cc2zwaWs5qZfsrcdF0cOG2p
+XvJw8qY4svnGx6hYpGzoN0i9JpD9eigU9tI6XcWu7jPBYmCO6wRGhs+m6FqUBVSG
+J/jyFQHWANoPO7jeC4/SXvN6QQx6m4kh6RTuByg+4IdgVbRNArA2s0ZIV5p5znk0
+XT4FYdECgYEA3G+nWxJYIqYMUzZQXAyl5KgQrFB/fGyPPMPtdEo+uKLKk1ULNfld
+xwzg15WFdttWbnsNgMgYhTmhWgGy9WMYgZ//kDwmU50X5voY9Fc3eL1DqMtiblJ0
+ThDmv71DNYnBN079KCO3ongbNmMjFenZmf1kjw9jncBD7z/q+q6LT0UCgYEAwxTn
+tXnMUv3jhXczXAx66Q1k8QnkAlBqD/DGG9TyyjHhUE57ttTrWB4CDMBj2WEn3qal
+ZGniF0vMTLOYYPwCcPLRIIR3cKnDk7xNP0xMhNZZmdK23s9nxRy4c3eExGUjOjzh
+ufzxQuOeG1HO7qPleTC/dNY6dZrA39wDpgOQlh0CgYAKzAU8dreOauero7tn5s6x
+VnIKnp6/72lMpqQY0BImZQLbGI1GBYLMXxscNBynZ7LiEnDk3+gjjmES0YZ8cnAe
+2UFhRTDzY3xqOdHDFgqHhW2s9NlLYgqEUFudBJ4oHykxllLcBnPWJ1/d2Bk914hq
+/HhScYSFk4dATrcptCbqqQKBgGFicjk50DIt5AKgetccs87bjOR3F4fANPI4M+14
+5KrjM6MvSrr+l22prURIVpAR3CFd93qlEOSoRhiUHyFrLJzN2m/tMOLhHG0Ht1g9
+8oTtrFUJx5h62UahC8M4iuKvymIsOlLqXlYR4r+omzCuSMOy/iCJQS2sT1RxNLEP
+XoJRAoGBAJ/VH2DAdFz0pcqsHNwSAugMguZbweOsFT8L4R+4krY5ITkW/9tUqJfT
+MWLR3SqsG0mEmqCMFT8Vn0Guqyhldg//QZdFVTbUv0/DnEE/42XSoBFFS626zeVr
+lM5zzHUZDKDHKSlEykdIIdK8LUFQK93mCYSz1FPzW4frejzDtamp
+-----END RSA PRIVATE KEY-----
diff --git a/chrome/test/data/webui/cr_elements/cr_dialog_test.js b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
index 76dc02e..877e454 100644
--- a/chrome/test/data/webui/cr_elements/cr_dialog_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
@@ -11,6 +11,34 @@
     PolymerTest.clearBody();
   });
 
+  test('close event bubbles', function() {
+    document.body.innerHTML = `
+      <cr-dialog>
+        <div slot="title">title</div>
+        <div slot="body">body</div>
+      </cr-dialog>`;
+
+    const dialog = document.body.querySelector('cr-dialog');
+    dialog.showModal();
+    const whenFired = test_util.eventToPromise('close', dialog);
+    dialog.close();
+    return whenFired;
+  });
+
+  test('cancel event bubbles', function() {
+    document.body.innerHTML = `
+      <cr-dialog>
+        <div slot="title">title</div>
+        <div slot="body">body</div>
+      </cr-dialog>`;
+
+    const dialog = document.body.querySelector('cr-dialog');
+    dialog.showModal();
+    const whenFired = test_util.eventToPromise('cancel', dialog);
+    dialog.cancel();
+    return whenFired;
+  });
+
   test('focuses title on show', function() {
     document.body.innerHTML = `
       <cr-dialog>
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index 18e4217..0171a21 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -272,6 +272,7 @@
 
   /** @override */
   extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    '../settings/test_util.js',
     'cr_dialog_test.js',
   ]),
 };
diff --git a/chrome/test/data/webui/cr_elements/cr_input_test.js b/chrome/test/data/webui/cr_elements/cr_input_test.js
index 7cce810..c0634e3b 100644
--- a/chrome/test/data/webui/cr_elements/cr_input_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_input_test.js
@@ -15,24 +15,31 @@
   });
 
   test('AttributesCorrectlySupported', function() {
-    assertFalse(input.hasAttribute('autofocus'));
-    assertFalse(input.hasAttribute('disabled'));
-    assertFalse(input.hasAttribute('tabindex'));
-
+    assertFalse(input.autofocus);
     crInput.setAttribute('autofocus', 'autofocus');
-    assertTrue(input.hasAttribute('autofocus'));
+    assertTrue(input.autofocus);
 
+    assertFalse(input.disabled);
     crInput.setAttribute('disabled', 'disabled');
-    assertTrue(input.hasAttribute('disabled'));
+    assertTrue(input.disabled);
 
+    assertFalse(input.hasAttribute('tabindex'));
     crInput.tabIndex = '-1';
-    assertEquals('-1', input.getAttribute('tabindex'));
+    assertEquals(-1, input.tabIndex);
     crInput.tabIndex = '0';
-    assertEquals('0', input.getAttribute('tabindex'));
+    assertEquals(0, input.tabIndex);
 
     assertEquals('none', getComputedStyle(crInput.$.label).display);
     crInput.label = 'label';
     assertEquals('block', getComputedStyle(crInput.$.label).display);
+
+    assertFalse(input.readOnly);
+    crInput.setAttribute('readonly', 'readonly');
+    assertTrue(input.readOnly);
+
+    assertEquals('text', input.type);
+    crInput.setAttribute('type', 'password');
+    assertEquals('password', input.type);
   });
 
   test('placeholderCorrectlyBound', function() {
diff --git a/chrome/test/data/webui/print_preview/advanced_item_test.js b/chrome/test/data/webui/print_preview/advanced_item_test.js
new file mode 100644
index 0000000..e7d6d26
--- /dev/null
+++ b/chrome/test/data/webui/print_preview/advanced_item_test.js
@@ -0,0 +1,118 @@
+// 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.
+
+cr.define('advanced_item_test', function() {
+  /** @enum {string} */
+  const TestNames = {
+    DisplaySelect: 'display select',
+    DisplayInput: 'display input',
+    QueryName: 'query name',
+    QueryOption: 'query option',
+  };
+
+  const suiteName = 'AdvancedItemTest';
+  suite(suiteName, function() {
+    /** @type {?PrintPreviewAdvancedSettingsItemElement} */
+    let item = null;
+
+    /** @override */
+    setup(function() {
+      PolymerTest.clearBody();
+      item = document.createElement('print-preview-advanced-settings-item');
+
+      // Create capability.
+      item.capability = print_preview_test_utils
+                            .getCddTemplateWithAdvancedSettings(2, 'FooDevice')
+                            .capabilities.printer.vendor_capability[1];
+
+      document.body.appendChild(item);
+      Polymer.dom.flush();
+    });
+
+    // Test that a select capability is displayed correctly.
+    test(assert(TestNames.DisplaySelect), function() {
+      const label = item.$$('.label');
+      assertEquals('Paper Type', label.textContent);
+
+      // Check that the default option is selected.
+      const select = item.$$('select');
+      assertEquals(0, select.selectedIndex);
+      assertEquals('Standard', select.options[0].textContent.trim());
+      assertEquals('Recycled', select.options[1].textContent.trim());
+      assertEquals('Special', select.options[2].textContent.trim());
+
+      // The input should not be shown for a select capability.
+      const input = item.$$('input');
+      assertTrue(input.parentElement.hidden);
+    });
+
+    test(assert(TestNames.DisplayInput), function() {
+      // Create capability
+      item.capability = print_preview_test_utils
+                            .getCddTemplateWithAdvancedSettings(3, 'FooDevice')
+                            .capabilities.printer.vendor_capability[2];
+      Polymer.dom.flush();
+
+      const label = item.$$('.label');
+      assertEquals('Watermark', label.textContent);
+
+      // The input should be shown.
+      const input = item.$$('input');
+      assertFalse(input.parentElement.hidden);
+      assertEquals('', input.value);
+
+      // No select.
+      assertEquals(null, item.$$('select'));
+    });
+
+    // Test that the setting is displayed correctly when the search query
+    // matches its display name.
+    test(assert(TestNames.QueryName), function() {
+      const query = /(Type)/i;
+      assertTrue(item.hasMatch(query));
+      item.updateHighlighting(query);
+
+      const label = item.$$('.label');
+      assertEquals(
+          item.capability.display_name + item.capability.display_name,
+          label.textContent);
+
+      // Label should be highlighted.
+      const searchHits = label.querySelectorAll('.search-highlight-hit');
+      assertEquals(1, searchHits.length);
+      assertEquals('Type', searchHits[0].textContent);
+
+      // No highlighting on the control.
+      const control = item.$$('.value');
+      assertEquals(0, control.querySelectorAll('.search-highlight-hit').length);
+      assertEquals(0, control.querySelectorAll('.search-bubble').length);
+    });
+
+    // Test that the setting is displayed correctly when the search query
+    // matches one of the select options.
+    test(assert(TestNames.QueryOption), function() {
+      const query = /(cycle)/i;
+      assertTrue(item.hasMatch(query));
+      item.updateHighlighting(query);
+
+      const label = item.$$('.label');
+      assertEquals('Paper Type', label.textContent);
+
+      // Label should not be highlighted.
+      assertEquals(0, label.querySelectorAll('.search-highlight-hit').length);
+
+      // Control should have highlight bubble but no highlighting.
+      const control = item.$$('.value');
+      assertEquals(0, control.querySelectorAll('.search-highlight-hit').length);
+      const searchBubbleHits = control.querySelectorAll('.search-bubble');
+      assertEquals(1, searchBubbleHits.length);
+      assertEquals('cycle', searchBubbleHits[0].textContent);
+    });
+  });
+
+  return {
+    suiteName: suiteName,
+    TestNames: TestNames,
+  };
+});
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
index d8d46753..97a1c14 100644
--- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
+++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -752,3 +752,39 @@
 TEST_F('PrintPreviewDestinationItemTest', 'QueryDescription', function() {
   this.runMochaTest(destination_item_test.TestNames.QueryDescription);
 });
+
+PrintPreviewAdvancedItemTest = class extends NewPrintPreviewTest {
+  /** @override */
+  get browsePreload() {
+    return 'chrome://print/new/advanced_settings_item.html';
+  }
+
+  /** @override */
+  get extraLibraries() {
+    return super.extraLibraries.concat([
+      'print_preview_test_utils.js',
+      'advanced_item_test.js',
+    ]);
+  }
+
+  /** @override */
+  get suiteName() {
+    return advanced_item_test.suiteName;
+  }
+};
+
+TEST_F('PrintPreviewAdvancedItemTest', 'DisplaySelect', function() {
+  this.runMochaTest(advanced_item_test.TestNames.DisplaySelect);
+});
+
+TEST_F('PrintPreviewAdvancedItemTest', 'DisplayInput', function() {
+  this.runMochaTest(advanced_item_test.TestNames.DisplayInput);
+});
+
+TEST_F('PrintPreviewAdvancedItemTest', 'QueryName', function() {
+  this.runMochaTest(advanced_item_test.TestNames.QueryName);
+});
+
+TEST_F('PrintPreviewAdvancedItemTest', 'QueryOption', function() {
+  this.runMochaTest(advanced_item_test.TestNames.QueryOption);
+});
diff --git a/chrome/test/data/webui/print_preview/print_preview_test_utils.js b/chrome/test/data/webui/print_preview/print_preview_test_utils.js
index 018b429..8695eb0 100644
--- a/chrome/test/data/webui/print_preview/print_preview_test_utils.js
+++ b/chrome/test/data/webui/print_preview/print_preview_test_utils.js
@@ -85,6 +85,10 @@
   }
 
   /**
+   * Gets a CDD template and adds some dummy vendor capabilities. For select
+   * capabilities, the values of these options are arbitrary. These values are
+   * provided and read by the destination, so there are no fixed options like
+   * there are for margins or color.
    * @param {number} numSettings
    * @param {string} printerId
    * @param {string=} opt_printerName Defaults to an empty string.
@@ -99,7 +103,7 @@
 
     template.capabilities.printer.vendor_capability = [{
       display_name: 'Print Area',
-      id: 'Print Area',
+      id: 'printArea',
       type: 'SELECT',
       select_cap: {
         option: [
@@ -116,7 +120,7 @@
     // Add new capability.
     template.capabilities.printer.vendor_capability.push({
       display_name: 'Paper Type',
-      id: 'Paper Type',
+      id: 'paperType',
       type: 'SELECT',
       select_cap: {
         option: [
@@ -126,6 +130,19 @@
         ]
       }
     });
+
+    if (numSettings < 3)
+      return template;
+
+    template.capabilities.printer.vendor_capability.push({
+      display_name: 'Watermark',
+      id: 'watermark',
+      type: 'TYPED_VALUE',
+      typed_value_cap: {
+        default: '',
+      }
+    });
+
     return template;
   }
 
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js b/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
index 7f7c4f5..5e4205a 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
@@ -16,16 +16,11 @@
     cr.webUIListenerCallback('sync-prefs-changed', {passphraseRequired: true});
     Polymer.dom.flush();
 
-    const input = testElement.$$('#existingPassphraseInput');
-
-    let focused = false;
-    input.addEventListener('focus', function() {
-      focused = true;
-    });
-
     // Simulate event normally fired by main_page_behavior after subpage
     // animation ends.
     testElement.fire('show-container');
-    assertTrue(focused);
+    assertEquals(
+        testElement.$$('#existingPassphraseInput').inputElement,
+        testElement.$$('#existingPassphraseInput').shadowRoot.activeElement);
   });
 });
diff --git a/chrome/test/nacl/nacl_browsertest_uma.cc b/chrome/test/nacl/nacl_browsertest_uma.cc
index fa719ded..6b1a4e7 100644
--- a/chrome/test/nacl/nacl_browsertest_uma.cc
+++ b/chrome/test/nacl/nacl_browsertest_uma.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 "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "chrome/browser/metrics/subprocess_metrics_provider.h"
 #include "chrome/test/nacl/nacl_browsertest_util.h"
diff --git a/chrome/test/vr/auto_bisect.py b/chrome/test/vr/auto_bisect.py
index 991ec5a9..7e92a46 100755
--- a/chrome/test/vr/auto_bisect.py
+++ b/chrome/test/vr/auto_bisect.py
@@ -347,7 +347,7 @@
 
   # Temporary workaround for https://crbug.com/812428. We could get the same
   # effect by isolating/uploading/running using "mb.py run -s", but that has
-  # the issue of apparently not having a way to spcify a task output directory.
+  # the issue of apparently not having a way to specify a task output directory.
   # So instead, manually append the additional arguments that running that way
   # would do for us to work around the vpython issues until they're fixed.
   # TODO(https://crbug.com/819719): Remove this when possible.
@@ -359,10 +359,10 @@
     '${platform}:git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c',
 
     '.swarming_module:infra/tools/luci/vpython-native/'
-    '${platform}:git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c',
+    '${platform}:git_revision:ad60019cb66a75b59991d43b95a43f68e3fff81b',
 
     '.swarming_module:infra/tools/luci/vpython/'
-    '${platform}:git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c',
+    '${platform}:git_revision:ad60019cb66a75b59991d43b95a43f68e3fff81b',
   ]
   for package in cipd_packages:
     swarming_args.extend(['--cipd-package', package])
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 9d2b0d90..3c91ab2d 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -84,8 +84,6 @@
     "tts/tts_controller.h",
     "tts/tts_controller_impl.cc",
     "tts/tts_controller_impl.h",
-    "tts/tts_message_filter.cc",
-    "tts/tts_message_filter.h",
     "tts/tts_platform.cc",
     "tts/tts_platform.h",
     "url_request_context_factory.cc",
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 37d06928..df993e9 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -37,7 +37,6 @@
 #include "chromecast/browser/renderer_config.h"
 #include "chromecast/browser/service/cast_service_simple.h"
 #include "chromecast/browser/tts/tts_controller.h"
-#include "chromecast/browser/tts/tts_message_filter.h"
 #include "chromecast/browser/url_request_context_factory.h"
 #include "chromecast/common/global_descriptors.h"
 #include "chromecast/media/audio/cast_audio_manager.h"
@@ -325,7 +324,6 @@
       render_process_id, browser_context));
   host->AddFilter(new extensions::ExtensionsGuestViewMessageFilter(
       render_process_id, browser_context));
-  host->AddFilter(new TtsMessageFilter(host->GetBrowserContext()));
   host->AddFilter(
       new CastExtensionMessageFilter(render_process_id, browser_context));
 #endif
diff --git a/chromecast/browser/tts/tts_message_filter.cc b/chromecast/browser/tts/tts_message_filter.cc
deleted file mode 100644
index fd48c194..0000000
--- a/chromecast/browser/tts/tts_message_filter.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 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.
-
-// PLEASE NOTE: this is a copy with modifications from chrome/browser/speech.
-// It is temporary until a refactoring to move the chrome TTS implementation up
-// into components and extensions/components can be completed.
-
-#include "chromecast/browser/tts/tts_message_filter.h"
-
-#include <stddef.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "chromecast/common/tts_messages.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/render_process_host.h"
-
-using content::BrowserThread;
-
-TtsMessageFilter::TtsMessageFilter(content::BrowserContext* browser_context)
-    : BrowserMessageFilter(TtsMsgStart),
-      browser_context_(browser_context),
-      valid_(true) {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->AddVoicesChangedDelegate(this);
-
-  // TODO(rdaum): This appears to be unnecessary. Commented out for now, as
-  // cannot be ported cleanly to cast.
-  // TODO(dmazzoni): make it so that we can listen for a BrowserContext
-  // being destroyed rather than a Profile.  http://crbug.com/444668
-  //  Profile* profile = Profile::FromBrowserContext(browser_context);
-  //  notification_registrar_.Add(this,
-  //                              chrome::NOTIFICATION_PROFILE_DESTROYED,
-  //                              content::Source<Profile>(profile));
-
-  // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero
-  // until all pointers to this class are invalidated.
-  AddRef();
-}
-
-void TtsMessageFilter::OverrideThreadForMessage(const IPC::Message& message,
-                                                BrowserThread::ID* thread) {
-  switch (message.type()) {
-    case TtsHostMsg_InitializeVoiceList::ID:
-    case TtsHostMsg_Speak::ID:
-    case TtsHostMsg_Pause::ID:
-    case TtsHostMsg_Resume::ID:
-    case TtsHostMsg_Cancel::ID:
-      *thread = BrowserThread::UI;
-      break;
-  }
-}
-
-bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(TtsMessageFilter, message)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void TtsMessageFilter::OnChannelClosing() {
-  base::AutoLock lock(mutex_);
-  valid_ = false;
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
-}
-
-bool TtsMessageFilter::Valid() {
-  base::AutoLock lock(mutex_);
-  return valid_;
-}
-
-void TtsMessageFilter::OnDestruct() const {
-  {
-    base::AutoLock lock(mutex_);
-    valid_ = false;
-  }
-  BrowserThread::DeleteOnUIThread::Destruct(this);
-}
-
-TtsMessageFilter::~TtsMessageFilter() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  Cleanup();
-}
-
-void TtsMessageFilter::OnInitializeVoiceList() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (!browser_context_)
-    return;
-
-  TtsController* tts_controller = TtsController::GetInstance();
-  std::vector<VoiceData> voices;
-  tts_controller->GetVoices(browser_context_, &voices);
-
-  std::vector<TtsVoice> out_voices;
-  out_voices.resize(voices.size());
-  for (size_t i = 0; i < voices.size(); ++i) {
-    TtsVoice& out_voice = out_voices[i];
-    out_voice.voice_uri = voices[i].name;
-    out_voice.name = voices[i].name;
-    out_voice.lang = voices[i].lang;
-    out_voice.local_service = !voices[i].remote;
-    out_voice.is_default = (i == 0);
-  }
-  Send(new TtsMsg_SetVoiceList(out_voices));
-}
-
-void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (!browser_context_)
-    return;
-
-  std::unique_ptr<Utterance> utterance(new Utterance(browser_context_));
-  utterance->set_src_id(request.id);
-  utterance->set_text(request.text);
-  utterance->set_lang(request.lang);
-  utterance->set_voice_name(request.voice);
-  utterance->set_can_enqueue(true);
-  utterance->set_continuous_parameters(request.rate, request.pitch,
-                                       request.volume);
-
-  utterance->set_event_delegate(this);
-
-  TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
-}
-
-void TtsMessageFilter::OnPause() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Pause();
-}
-
-void TtsMessageFilter::OnResume() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Resume();
-}
-
-void TtsMessageFilter::OnCancel() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Stop();
-}
-
-void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
-                                  TtsEventType event_type,
-                                  int char_index,
-                                  const std::string& error_message) {
-  if (!Valid())
-    return;
-
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  switch (event_type) {
-    case TTS_EVENT_START:
-      Send(new TtsMsg_DidStartSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_END:
-      Send(new TtsMsg_DidFinishSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_WORD:
-      Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_SENTENCE:
-      Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_MARKER:
-      Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_INTERRUPTED:
-      Send(new TtsMsg_WasInterrupted(utterance->src_id()));
-      break;
-    case TTS_EVENT_CANCELLED:
-      Send(new TtsMsg_WasCancelled(utterance->src_id()));
-      break;
-    case TTS_EVENT_ERROR:
-      Send(
-          new TtsMsg_SpeakingErrorOccurred(utterance->src_id(), error_message));
-      break;
-    case TTS_EVENT_PAUSE:
-      Send(new TtsMsg_DidPauseSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_RESUME:
-      Send(new TtsMsg_DidResumeSpeaking(utterance->src_id()));
-      break;
-  }
-}
-
-void TtsMessageFilter::OnVoicesChanged() {
-  if (!Valid())
-    return;
-
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  OnInitializeVoiceList();
-}
-
-void TtsMessageFilter::OnChannelClosingInUIThread() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  Cleanup();
-  Release();  // Balanced in TtsMessageFilter().
-}
-
-void TtsMessageFilter::Cleanup() {
-  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
-  TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
-}
-
-void TtsMessageFilter::Observe(int type,
-                               const content::NotificationSource& source,
-                               const content::NotificationDetails& details) {
-  browser_context_ = nullptr;
-  notification_registrar_.RemoveAll();
-}
diff --git a/chromecast/browser/tts/tts_message_filter.h b/chromecast/browser/tts/tts_message_filter.h
deleted file mode 100644
index 4f3af30..0000000
--- a/chromecast/browser/tts/tts_message_filter.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 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.
-
-// PLEASE NOTE: this is a copy with modifications from chrome/browser/speech.
-// It is temporary until a refactoring to move the chrome TTS implementation up
-// into components and extensions/components can be completed.
-
-#ifndef CHROMECAST_BROWSER_TTS_TTS_MESSAGE_FILTER_H_
-#define CHROMECAST_BROWSER_TTS_TTS_MESSAGE_FILTER_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
-#include "chromecast/browser/tts/tts_controller.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-
-namespace content {
-class BrowserContext;
-}
-
-struct TtsUtteranceRequest;
-
-class TtsMessageFilter : public content::BrowserMessageFilter,
-                         public content::NotificationObserver,
-                         public UtteranceEventDelegate,
-                         public VoicesChangedDelegate {
- public:
-  explicit TtsMessageFilter(content::BrowserContext* browser_context);
-
-  // content::BrowserMessageFilter implementation.
-  void OverrideThreadForMessage(const IPC::Message& message,
-                                content::BrowserThread::ID* thread) override;
-  bool OnMessageReceived(const IPC::Message& message) override;
-  void OnChannelClosing() override;
-  void OnDestruct() const override;
-
-  // UtteranceEventDelegate implementation.
-  void OnTtsEvent(Utterance* utterance,
-                  TtsEventType event_type,
-                  int char_index,
-                  const std::string& error_message) override;
-
-  // VoicesChangedDelegate implementation.
-  void OnVoicesChanged() override;
-
- private:
-  friend class content::BrowserThread;
-  friend class base::DeleteHelper<TtsMessageFilter>;
-
-  ~TtsMessageFilter() override;
-
-  void OnInitializeVoiceList();
-  void OnSpeak(const TtsUtteranceRequest& utterance);
-  void OnPause();
-  void OnResume();
-  void OnCancel();
-
-  void OnChannelClosingInUIThread();
-
-  void Cleanup();
-
-  // Thread-safe check to make sure this class is still valid and not
-  // about to be deleted.
-  bool Valid();
-
-  // content::NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
-  content::BrowserContext* browser_context_;
-  mutable base::Lock mutex_;
-  mutable bool valid_;
-  content::NotificationRegistrar notification_registrar_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsMessageFilter);
-};
-
-#endif  // CHROMECAST_BROWSER_TTS_TTS_MESSAGE_FILTER_H_
diff --git a/chromecast/common/BUILD.gn b/chromecast/common/BUILD.gn
index 41b71dc..4283bf2 100644
--- a/chromecast/common/BUILD.gn
+++ b/chromecast/common/BUILD.gn
@@ -11,12 +11,7 @@
     "cast_content_client.h",
     "cast_resource_delegate.cc",
     "cast_resource_delegate.h",
-    "common_message_generator.cc",
-    "common_message_generator.h",
     "global_descriptors.h",
-    "tts_messages.h",
-    "tts_utterance_request.cc",
-    "tts_utterance_request.h",
   ]
 
   deps = [
diff --git a/chromecast/common/OWNERS b/chromecast/common/OWNERS
index a3a5b25..08850f4 100644
--- a/chromecast/common/OWNERS
+++ b/chromecast/common/OWNERS
@@ -1,4 +1,2 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_messages*.h=set noparent
-per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/chromecast/common/common_message_generator.cc b/chromecast/common/common_message_generator.cc
deleted file mode 100644
index 016a179..0000000
--- a/chromecast/common/common_message_generator.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 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.
-
-// Get basic type definitions.
-#define IPC_MESSAGE_IMPL
-#include "chromecast/common/common_message_generator.h"
-
-// Generate constructors.
-#include "ipc/struct_constructor_macros.h"
-#include "chromecast/common/common_message_generator.h"
-
-// Generate destructors.
-#include "ipc/struct_destructor_macros.h"
-#include "chromecast/common/common_message_generator.h"
-
-// Generate param traits write methods.
-#include "ipc/param_traits_write_macros.h"
-namespace IPC {
-#include "chromecast/common/common_message_generator.h"
-}  // namespace IPC
-
-// Generate param traits read methods.
-#include "ipc/param_traits_read_macros.h"
-namespace IPC {
-#include "chromecast/common/common_message_generator.h"
-}  // namespace IPC
-
-// Generate param traits log methods.
-#include "ipc/param_traits_log_macros.h"
-namespace IPC {
-#include "chromecast/common/common_message_generator.h"
-}  // namespace IPC
diff --git a/chromecast/common/common_message_generator.h b/chromecast/common/common_message_generator.h
deleted file mode 100644
index 8260292..0000000
--- a/chromecast/common/common_message_generator.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 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.
-
-// Multiply-included file, hence no include guard.
-
-#undef CHROMECAST_COMMON_TTS_MESSAGES_H_
-#include "chromecast/common/tts_messages.h"
-#ifndef CHROMECAST_COMMON_TTS_MESSAGES_H_
-#error "Failed to include header chromecast/common/tts_messages.h"
-#endif
diff --git a/chromecast/common/tts_messages.h b/chromecast/common/tts_messages.h
deleted file mode 100644
index d761c3d..0000000
--- a/chromecast/common/tts_messages.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 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 CHROMECAST_COMMON_TTS_MESSAGES_H_
-#define CHROMECAST_COMMON_TTS_MESSAGES_H_
-
-// PLEASE NOTE: this is a copy with modifications from chrome/common
-// It is temporary until a refactoring to move the chrome TTS implementation up
-// into components and extensions/components can be completed.
-
-#include <vector>
-
-#include "chromecast/common/tts_utterance_request.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_param_traits.h"
-
-#define IPC_MESSAGE_START TtsMsgStart
-
-IPC_STRUCT_TRAITS_BEGIN(TtsUtteranceRequest)
-  IPC_STRUCT_TRAITS_MEMBER(id)
-  IPC_STRUCT_TRAITS_MEMBER(text)
-  IPC_STRUCT_TRAITS_MEMBER(lang)
-  IPC_STRUCT_TRAITS_MEMBER(voice)
-  IPC_STRUCT_TRAITS_MEMBER(volume)
-  IPC_STRUCT_TRAITS_MEMBER(rate)
-  IPC_STRUCT_TRAITS_MEMBER(pitch)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(TtsVoice)
-  IPC_STRUCT_TRAITS_MEMBER(voice_uri)
-  IPC_STRUCT_TRAITS_MEMBER(name)
-  IPC_STRUCT_TRAITS_MEMBER(lang)
-  IPC_STRUCT_TRAITS_MEMBER(local_service)
-  IPC_STRUCT_TRAITS_MEMBER(is_default)
-IPC_STRUCT_TRAITS_END()
-
-// Renderer -> Browser messages.
-
-IPC_MESSAGE_CONTROL0(TtsHostMsg_InitializeVoiceList)
-IPC_MESSAGE_CONTROL1(TtsHostMsg_Speak, TtsUtteranceRequest)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Pause)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Resume)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Cancel)
-
-// Browser -> Renderer messages.
-
-IPC_MESSAGE_CONTROL1(TtsMsg_SetVoiceList, std::vector<TtsVoice>)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidStartSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidFinishSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidPauseSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidResumeSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL2(TtsMsg_WordBoundary,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL2(TtsMsg_SentenceBoundary,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL2(TtsMsg_MarkerEvent,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL1(TtsMsg_WasInterrupted, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_WasCancelled, int /* utterance id */)
-IPC_MESSAGE_CONTROL2(TtsMsg_SpeakingErrorOccurred,
-                     int /* utterance id */,
-                     std::string /* error message */)
-
-#endif  // CHROMECAST_COMMON_TTS_MESSAGES_H_
diff --git a/chromecast/common/tts_utterance_request.cc b/chromecast/common/tts_utterance_request.cc
deleted file mode 100644
index e453616..0000000
--- a/chromecast/common/tts_utterance_request.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 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.
-
-// PLEASE NOTE: this is a copy with modifications from chrome/common
-// It is temporary until a refactoring to move the chrome TTS implementation up
-// into components and extensions/components can be completed.
-
-#include "chromecast/common/tts_utterance_request.h"
-
-TtsUtteranceRequest::TtsUtteranceRequest()
-    : id(0), volume(1.0), rate(1.0), pitch(1.0) {}
-
-TtsUtteranceRequest::~TtsUtteranceRequest() {}
-
-TtsVoice::TtsVoice() : local_service(true), is_default(false) {}
-
-TtsVoice::TtsVoice(const TtsVoice& other) = default;
-
-TtsVoice::~TtsVoice() {}
diff --git a/chromecast/common/tts_utterance_request.h b/chromecast/common/tts_utterance_request.h
deleted file mode 100644
index 44b6f37..0000000
--- a/chromecast/common/tts_utterance_request.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 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 CHROMECAST_COMMON_TTS_UTTERANCE_REQUEST_H_
-#define CHROMECAST_COMMON_TTS_UTTERANCE_REQUEST_H_
-
-// PLEASE NOTE: this is a copy with modifications from chrome/common
-// It is temporary until a refactoring to move the chrome TTS implementation up
-// into components and extensions/components can be completed.
-
-#include <vector>
-
-#include "base/strings/string16.h"
-
-struct TtsUtteranceRequest {
-  TtsUtteranceRequest();
-  ~TtsUtteranceRequest();
-
-  int id;
-  std::string text;
-  std::string lang;
-  std::string voice;
-  float volume;
-  float rate;
-  float pitch;
-};
-
-struct TtsVoice {
-  TtsVoice();
-  TtsVoice(const TtsVoice& other);
-  ~TtsVoice();
-
-  std::string voice_uri;
-  std::string name;
-  std::string lang;
-  bool local_service;
-  bool is_default;
-};
-
-#endif  // CHROMECAST_COMMON_TTS_UTTERANCE_REQUEST_H_
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn
index 1575559d..a698c3d 100644
--- a/chromecast/renderer/BUILD.gn
+++ b/chromecast/renderer/BUILD.gn
@@ -30,8 +30,6 @@
     "cast_content_renderer_client.h",
     "cast_media_load_deferrer.cc",
     "cast_media_load_deferrer.h",
-    "tts_dispatcher.cc",
-    "tts_dispatcher.h",
   ]
 
   public_deps = [
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 146a9ad..29accd6 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -16,7 +16,6 @@
 #include "chromecast/renderer/cast_media_load_deferrer.h"
 #include "chromecast/renderer/media/key_systems_cast.h"
 #include "chromecast/renderer/media/media_caps_observer_impl.h"
-#include "chromecast/renderer/tts_dispatcher.h"
 #include "components/network_hints/renderer/prescient_networking_dispatcher.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_names.mojom.h"
@@ -300,11 +299,5 @@
   supported_bitstream_audio_codecs_ = codecs;
 }
 
-std::unique_ptr<blink::WebSpeechSynthesizer>
-CastContentRendererClient::OverrideSpeechSynthesizer(
-    blink::WebSpeechSynthesizerClient* client) {
-  return std::make_unique<TtsDispatcher>(client);
-}
-
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index 508af7c..1a69bb3 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -72,8 +72,6 @@
                       base::OnceClosure closure) override;
   bool AllowIdleMediaSuspend() override;
   void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override;
-  std::unique_ptr<blink::WebSpeechSynthesizer> OverrideSpeechSynthesizer(
-      blink::WebSpeechSynthesizerClient* client) override;
 
  protected:
   CastContentRendererClient();
diff --git a/chromecast/renderer/tts_dispatcher.cc b/chromecast/renderer/tts_dispatcher.cc
deleted file mode 100644
index b7f2ae9..0000000
--- a/chromecast/renderer/tts_dispatcher.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (c) 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.
-
-// Note: this is a copy from chrome/renderer with modifications
-// necessary to compile in chromecast.
-// TODO(rdaum): internal b/74442017 move to components/ & extensions/components
-
-#include "chromecast/renderer/tts_dispatcher.h"
-
-#include <stddef.h>
-
-#include "base/strings/utf_string_conversions.h"
-#include "chromecast/common/tts_messages.h"
-#include "chromecast/common/tts_utterance_request.h"
-#include "content/public/renderer/render_thread.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_utterance.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_voice.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-using content::RenderThread;
-using blink::WebSpeechSynthesizerClient;
-using blink::WebSpeechSynthesisUtterance;
-using blink::WebSpeechSynthesisVoice;
-using blink::WebString;
-using blink::WebVector;
-
-int TtsDispatcher::next_utterance_id_ = 1;
-
-TtsDispatcher::TtsDispatcher(WebSpeechSynthesizerClient* client)
-    : synthesizer_client_(client) {
-  RenderThread::Get()->AddObserver(this);
-}
-
-TtsDispatcher::~TtsDispatcher() {
-  RenderThread::Get()->RemoveObserver(this);
-}
-
-bool TtsDispatcher::OnControlMessageReceived(const IPC::Message& message) {
-  IPC_BEGIN_MESSAGE_MAP(TtsDispatcher, message)
-    IPC_MESSAGE_HANDLER(TtsMsg_SetVoiceList, OnSetVoiceList)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidStartSpeaking, OnDidStartSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidFinishSpeaking, OnDidFinishSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidPauseSpeaking, OnDidPauseSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidResumeSpeaking, OnDidResumeSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_WordBoundary, OnWordBoundary)
-    IPC_MESSAGE_HANDLER(TtsMsg_SentenceBoundary, OnSentenceBoundary)
-    IPC_MESSAGE_HANDLER(TtsMsg_MarkerEvent, OnMarkerEvent)
-    IPC_MESSAGE_HANDLER(TtsMsg_WasInterrupted, OnWasInterrupted)
-    IPC_MESSAGE_HANDLER(TtsMsg_WasCancelled, OnWasCancelled)
-    IPC_MESSAGE_HANDLER(TtsMsg_SpeakingErrorOccurred, OnSpeakingErrorOccurred)
-  IPC_END_MESSAGE_MAP()
-
-  // Always return false because there may be multiple TtsDispatchers
-  // and we want them all to have a chance to handle this message.
-  return false;
-}
-
-void TtsDispatcher::UpdateVoiceList() {
-  RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList());
-}
-
-void TtsDispatcher::Speak(const WebSpeechSynthesisUtterance& web_utterance) {
-  int id = next_utterance_id_++;
-
-  utterance_id_map_[id] = web_utterance;
-
-  TtsUtteranceRequest utterance;
-  utterance.id = id;
-  utterance.text = web_utterance.GetText().Utf8();
-  utterance.lang = web_utterance.Lang().Utf8();
-  utterance.voice = web_utterance.Voice().Utf8();
-  utterance.volume = web_utterance.Volume();
-  utterance.rate = web_utterance.Rate();
-  utterance.pitch = web_utterance.Pitch();
-  RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance));
-}
-
-void TtsDispatcher::Pause() {
-  RenderThread::Get()->Send(new TtsHostMsg_Pause());
-}
-
-void TtsDispatcher::Resume() {
-  RenderThread::Get()->Send(new TtsHostMsg_Resume());
-}
-
-void TtsDispatcher::Cancel() {
-  RenderThread::Get()->Send(new TtsHostMsg_Cancel());
-}
-
-WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) {
-  const auto iter = utterance_id_map_.find(utterance_id);
-  if (iter == utterance_id_map_.end())
-    return WebSpeechSynthesisUtterance();
-  return iter->second;
-}
-
-void TtsDispatcher::OnSetVoiceList(const std::vector<TtsVoice>& voices) {
-  WebVector<WebSpeechSynthesisVoice> out_voices(voices.size());
-  for (size_t i = 0; i < voices.size(); ++i) {
-    out_voices[i] = WebSpeechSynthesisVoice();
-    out_voices[i].SetVoiceURI(WebString::FromUTF8(voices[i].voice_uri));
-    out_voices[i].SetName(WebString::FromUTF8(voices[i].name));
-    out_voices[i].SetLanguage(WebString::FromUTF8(voices[i].lang));
-    out_voices[i].SetIsLocalService(voices[i].local_service);
-    out_voices[i].SetIsDefault(voices[i].is_default);
-  }
-  synthesizer_client_->SetVoiceList(out_voices);
-}
-
-void TtsDispatcher::OnDidStartSpeaking(int utterance_id) {
-  if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end())
-    return;
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidStartSpeaking(utterance);
-}
-
-void TtsDispatcher::OnDidFinishSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnDidPauseSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidPauseSpeaking(utterance);
-}
-
-void TtsDispatcher::OnDidResumeSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidResumeSpeaking(utterance);
-}
-
-void TtsDispatcher::OnWordBoundary(int utterance_id, int char_index) {
-  CHECK(char_index >= 0);
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->WordBoundaryEventOccurred(
-      utterance, static_cast<unsigned>(char_index));
-}
-
-void TtsDispatcher::OnSentenceBoundary(int utterance_id, int char_index) {
-  CHECK(char_index >= 0);
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->SentenceBoundaryEventOccurred(
-      utterance, static_cast<unsigned>(char_index));
-}
-
-void TtsDispatcher::OnMarkerEvent(int utterance_id, int char_index) {
-  // Not supported yet.
-}
-
-void TtsDispatcher::OnWasInterrupted(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support "interrupted".
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnWasCancelled(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support "cancelled".
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id,
-                                            const std::string& error_message) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support an error message.
-  synthesizer_client_->SpeakingErrorOccurred(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
diff --git a/chromecast/renderer/tts_dispatcher.h b/chromecast/renderer/tts_dispatcher.h
deleted file mode 100644
index 856c3a7..0000000
--- a/chromecast/renderer/tts_dispatcher.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 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 CHROMECAST_RENDERER_TTS_DISPATCHER_H_
-#define CHROMECAST_RENDERER_TTS_DISPATCHER_H_
-
-// Note: this is a copy from chrome/renderer with modifications
-// necessary to compile in chromecast.
-// TODO(rdaum): internal b/74442017 move to components/ & extensions/components
-
-#include <map>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "content/public/renderer/render_thread_observer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer_client.h"
-
-namespace IPC {
-class Message;
-}
-
-struct TtsVoice;
-
-// TtsDispatcher is a delegate for methods used by Blink for speech synthesis
-// APIs. It's the complement of TtsDispatcherHost (owned by RenderViewHost).
-// Each TtsDispatcher is owned by the WebSpeechSynthesizerClient in Blink;
-// it registers itself to listen to IPC upon construction and unregisters
-// itself when deleted. There can be multiple TtsDispatchers alive at once,
-// so each one routes IPC messages to its WebSpeechSynthesizerClient only if
-// the utterance id (which is globally unique) matches.
-class TtsDispatcher : public blink::WebSpeechSynthesizer,
-                      public content::RenderThreadObserver {
- public:
-  explicit TtsDispatcher(blink::WebSpeechSynthesizerClient* client);
-  ~TtsDispatcher() override;
-
- private:
-  // RenderThreadObserver override.
-  bool OnControlMessageReceived(const IPC::Message& message) override;
-
-  // blink::WebSpeechSynthesizer implementation.
-  void UpdateVoiceList() override;
-  void Speak(const blink::WebSpeechSynthesisUtterance& utterance) override;
-  void Pause() override;
-  void Resume() override;
-  void Cancel() override;
-
-  blink::WebSpeechSynthesisUtterance FindUtterance(int utterance_id);
-
-  void OnSetVoiceList(const std::vector<TtsVoice>& voices);
-  void OnDidStartSpeaking(int utterance_id);
-  void OnDidFinishSpeaking(int utterance_id);
-  void OnDidPauseSpeaking(int utterance_id);
-  void OnDidResumeSpeaking(int utterance_id);
-  void OnWordBoundary(int utterance_id, int char_index);
-  void OnSentenceBoundary(int utterance_id, int char_index);
-  void OnMarkerEvent(int utterance_id, int char_index);
-  void OnWasInterrupted(int utterance_id);
-  void OnWasCancelled(int utterance_id);
-  void OnSpeakingErrorOccurred(int utterance_id,
-                               const std::string& error_message);
-
-  // The WebKit client class that we use to send events back to the JS world.
-  // Weak reference, this will be valid as long as this object exists.
-  blink::WebSpeechSynthesizerClient* synthesizer_client_;
-
-  // Next utterance id, used to map response IPCs to utterance objects.
-  static int next_utterance_id_;
-
-  // Map from id to utterance objects.
-  std::map<int, blink::WebSpeechSynthesisUtterance> utterance_id_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsDispatcher);
-};
-
-#endif  // CHROMECAST_RENDERER_TTS_DISPATCHER_H_
diff --git a/chromeos/components/drivefs/BUILD.gn b/chromeos/components/drivefs/BUILD.gn
index 0821bcb5..c0267e5 100644
--- a/chromeos/components/drivefs/BUILD.gn
+++ b/chromeos/components/drivefs/BUILD.gn
@@ -10,6 +10,7 @@
     "drive_file_stream_service_provider_delegate.h",
     "drivefs_host.cc",
     "drivefs_host.h",
+    "drivefs_host_observer.h",
     "pending_connection_manager.cc",
     "pending_connection_manager.h",
   ]
diff --git a/chromeos/components/drivefs/drivefs_host.cc b/chromeos/components/drivefs/drivefs_host.cc
index 2f6a14e..c1d972f0 100644
--- a/chromeos/components/drivefs/drivefs_host.cc
+++ b/chromeos/components/drivefs/drivefs_host.cc
@@ -8,6 +8,7 @@
 
 #include "base/strings/strcat.h"
 #include "base/unguessable_token.h"
+#include "chromeos/components/drivefs/drivefs_host_observer.h"
 #include "chromeos/components/drivefs/pending_connection_manager.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
@@ -113,6 +114,11 @@
       chromeos::disks::DiskMountManager::GetInstance()->UnmountPath(
           mount_path_.value(), chromeos::UNMOUNT_OPTIONS_NONE, {});
     }
+    if (mounted()) {
+      for (auto& observer : host_->observers_) {
+        observer.OnUnmounted();
+      }
+    }
   }
 
   bool mounted() const { return drivefs_has_mounted_ && !mount_path_.empty(); }
@@ -183,6 +189,12 @@
     }
   }
 
+  void OnSyncingStatusUpdate(mojom::SyncingStatusPtr status) override {
+    for (auto& observer : host_->observers_) {
+      observer.OnSyncingStatusUpdate(*status);
+    }
+  }
+
   void NotifyDelegateOnMounted() { host_->delegate_->OnMounted(mount_path()); }
 
   void GotChromeAccessToken(const base::Optional<std::string>& access_token,
@@ -259,6 +271,14 @@
   chromeos::disks::DiskMountManager::GetInstance()->RemoveObserver(this);
 }
 
+void DriveFsHost::AddObserver(DriveFsHostObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void DriveFsHost::RemoveObserver(DriveFsHostObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 bool DriveFsHost::Mount() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const AccountId& account_id = delegate_->GetAccountId();
diff --git a/chromeos/components/drivefs/drivefs_host.h b/chromeos/components/drivefs/drivefs_host.h
index f9003e2..9dd33252 100644
--- a/chromeos/components/drivefs/drivefs_host.h
+++ b/chromeos/components/drivefs/drivefs_host.h
@@ -29,6 +29,8 @@
 
 namespace drivefs {
 
+class DriveFsHostObserver;
+
 // A host for a DriveFS process. In addition to managing its lifetime via
 // mounting and unmounting, it also bridges between the DriveFS process and the
 // file manager.
@@ -75,6 +77,9 @@
               Delegate* delegate);
   ~DriveFsHost() override;
 
+  void AddObserver(DriveFsHostObserver* observer);
+  void RemoveObserver(DriveFsHostObserver* observer);
+
   // Mount DriveFS.
   bool Mount();
 
@@ -115,6 +120,8 @@
   // The connection to the identity service. Access via |GetIdentityManager()|.
   identity::mojom::IdentityManagerPtr identity_manager_;
 
+  base::ObserverList<DriveFsHostObserver> observers_;
+
   DISALLOW_COPY_AND_ASSIGN(DriveFsHost);
 };
 
diff --git a/chromeos/components/drivefs/drivefs_host_observer.h b/chromeos/components/drivefs/drivefs_host_observer.h
new file mode 100644
index 0000000..ca5f80b
--- /dev/null
+++ b/chromeos/components/drivefs/drivefs_host_observer.h
@@ -0,0 +1,24 @@
+// 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 CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_OBSERVER_H_
+#define CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_OBSERVER_H_
+
+namespace drivefs {
+namespace mojom {
+class SyncingStatus;
+}  // namespace mojom
+
+class DriveFsHostObserver {
+ public:
+  virtual void OnUnmounted() {}
+  virtual void OnSyncingStatusUpdate(const mojom::SyncingStatus& status) {}
+
+ protected:
+  ~DriveFsHostObserver() = default;
+};
+
+}  // namespace drivefs
+
+#endif  // CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_OBSERVER_H_
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc
index 9d675e1c..43b5792 100644
--- a/chromeos/components/drivefs/drivefs_host_unittest.cc
+++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -8,10 +8,12 @@
 
 #include "base/logging.h"
 #include "base/run_loop.h"
+#include "base/scoped_observer.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_split.h"
 #include "base/test/bind_test_util.h"
 #include "base/test/scoped_task_environment.h"
+#include "chromeos/components/drivefs/drivefs_host_observer.h"
 #include "chromeos/components/drivefs/pending_connection_manager.h"
 #include "chromeos/disks/mock_disk_mount_manager.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -207,6 +209,12 @@
   DISALLOW_COPY_AND_ASSIGN(FakeIdentityService);
 };
 
+class MockDriveFsHostObserver : public DriveFsHostObserver {
+ public:
+  MOCK_METHOD0(OnUnmounted, void());
+  MOCK_METHOD1(OnSyncingStatusUpdate, void(const mojom::SyncingStatus& status));
+};
+
 ACTION_P(RunQuitClosure, quit) {
   std::move(*quit).Run();
 }
@@ -353,10 +361,15 @@
 }
 
 TEST_F(DriveFsHostTest, UnmountAfterMountComplete) {
+  MockDriveFsHostObserver observer;
+  ScopedObserver<DriveFsHost, DriveFsHostObserver> observer_scoper(&observer);
+  observer_scoper.Add(host_.get());
+
   ASSERT_NO_FATAL_FAILURE(DoMount());
 
   EXPECT_CALL(*disk_manager_, UnmountPath("/media/drivefsroot/g-ID",
                                           chromeos::UNMOUNT_OPTIONS_NONE, _));
+  EXPECT_CALL(observer, OnUnmounted());
   base::RunLoop run_loop;
   delegate_ptr_.set_connection_error_handler(run_loop.QuitClosure());
   host_->Unmount();
@@ -364,6 +377,11 @@
 }
 
 TEST_F(DriveFsHostTest, UnmountBeforeMountEvent) {
+  MockDriveFsHostObserver observer;
+  ScopedObserver<DriveFsHost, DriveFsHostObserver> observer_scoper(&observer);
+  observer_scoper.Add(host_.get());
+  EXPECT_CALL(observer, OnUnmounted()).Times(0);
+
   auto token = StartMount();
   EXPECT_FALSE(host_->IsMounted());
   host_->Unmount();
@@ -371,6 +389,11 @@
 }
 
 TEST_F(DriveFsHostTest, UnmountBeforeMojoConnection) {
+  MockDriveFsHostObserver observer;
+  ScopedObserver<DriveFsHost, DriveFsHostObserver> observer_scoper(&observer);
+  observer_scoper.Add(host_.get());
+  EXPECT_CALL(observer, OnUnmounted()).Times(0);
+
   auto token = StartMount();
   DispatchMountSuccessEvent(token);
 
@@ -634,5 +657,29 @@
   run_loop.Run();
 }
 
+ACTION_P(CloneStruct, output) {
+  *output = arg0.Clone();
+}
+
+TEST_F(DriveFsHostTest,
+       GetAccessToken_OnSyncingStatusUpdate_ForwardToObservers) {
+  ASSERT_NO_FATAL_FAILURE(DoMount());
+  MockDriveFsHostObserver observer;
+  ScopedObserver<DriveFsHost, DriveFsHostObserver> observer_scoper(&observer);
+  observer_scoper.Add(host_.get());
+  auto status = mojom::SyncingStatus::New();
+  status->item_events.emplace_back(base::in_place, 12, 34, "filename.txt",
+                                   mojom::ItemEvent::State::kInProgress, 123,
+                                   456);
+  mojom::SyncingStatusPtr observed_status;
+  EXPECT_CALL(observer, OnSyncingStatusUpdate(_))
+      .WillOnce(CloneStruct(&observed_status));
+  delegate_ptr_->OnSyncingStatusUpdate(status.Clone());
+  delegate_ptr_.FlushForTesting();
+  testing::Mock::VerifyAndClear(&observer);
+
+  EXPECT_EQ(status, observed_status);
+}
+
 }  // namespace
 }  // namespace drivefs
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom
index 2eb759f..886d6af 100644
--- a/chromeos/components/drivefs/mojom/drivefs.mojom
+++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -40,6 +40,8 @@
 
   // Invoked when the mount is ready for use.
   OnMounted();
+
+  OnSyncingStatusUpdate(SyncingStatus status);
 };
 
 struct DriveFsConfiguration {
@@ -121,3 +123,31 @@
   // Rotation in clockwise degrees.
   int32 rotation = 0;
 };
+
+struct ItemEvent {
+  enum State {
+    kQueued,
+    kInProgress,
+    kCompleted,
+    kFailed,
+  };
+
+  // The stable ID used by DriveFS.
+  int64 stable_id;
+
+  // A unique ID corresponding to a particular sync action.
+  int64 group_id;
+
+  string file_title;
+
+  State state;
+
+  // The following are valid only if |state| is kInProgress or kQueued. -1 acts
+  // as the sentinel value for unset.
+  int64 bytes_transferred = -1;
+  int64 bytes_to_transfer = -1;
+};
+
+struct SyncingStatus {
+  array<ItemEvent> item_events;
+};
diff --git a/chromeos/disks/mock_disk_mount_manager.cc b/chromeos/disks/mock_disk_mount_manager.cc
index 2a35ec05..9b076551 100644
--- a/chromeos/disks/mock_disk_mount_manager.cc
+++ b/chromeos/disks/mock_disk_mount_manager.cc
@@ -144,6 +144,13 @@
   NotifyDiskChanged(DISK_REMOVED, disk);
 }
 
+void MockDiskMountManager::NotifyMountEvent(MountEvent event,
+                                            MountError error_code,
+                                            const MountPointInfo& mount_info) {
+  for (auto& observer : observers_)
+    observer.OnMountEvent(event, error_code, mount_info);
+}
+
 void MockDiskMountManager::SetupDefaultReplies() {
   EXPECT_CALL(*this, AddObserver(_))
       .Times(AnyNumber());
diff --git a/chromeos/disks/mock_disk_mount_manager.h b/chromeos/disks/mock_disk_mount_manager.h
index 48e6b72..33868f5c 100644
--- a/chromeos/disks/mock_disk_mount_manager.h
+++ b/chromeos/disks/mock_disk_mount_manager.h
@@ -62,6 +62,11 @@
   // Invokes fake device remove events.
   void NotifyDeviceRemoveEvents();
 
+  // Invokes specified mount event.
+  void NotifyMountEvent(MountEvent event,
+                        MountError error_code,
+                        const MountPointInfo& mount_info);
+
   // Sets up default results for mock methods.
   void SetupDefaultReplies();
 
diff --git a/chromeos/services/device_sync/device_sync_base.cc b/chromeos/services/device_sync/device_sync_base.cc
index 4866204..57c95fd2 100644
--- a/chromeos/services/device_sync/device_sync_base.cc
+++ b/chromeos/services/device_sync/device_sync_base.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <utility>
+
 #include "chromeos/services/device_sync/device_sync_base.h"
 
 namespace chromeos {
@@ -33,4 +35,4 @@
 
 }  // namespace device_sync
 
-}  // namespace chromeos
\ No newline at end of file
+}  // namespace chromeos
diff --git a/chromeos/services/device_sync/fake_device_sync.cc b/chromeos/services/device_sync/fake_device_sync.cc
index cb66e22..944e918 100644
--- a/chromeos/services/device_sync/fake_device_sync.cc
+++ b/chromeos/services/device_sync/fake_device_sync.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <utility>
+
 #include "chromeos/services/device_sync/fake_device_sync.h"
 
 #include "base/memory/ptr_util.h"
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client.h b/chromeos/services/device_sync/public/cpp/device_sync_client.h
index 64797a1..37b3d4d 100644
--- a/chromeos/services/device_sync/public/cpp/device_sync_client.h
+++ b/chromeos/services/device_sync/public/cpp/device_sync_client.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_DEVICE_SYNC_CLIENT_H_
 
 #include <memory>
+#include <string>
 
 #include "base/callback.h"
 #include "base/macros.h"
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.cc b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.cc
index ddd0e30..a945a05 100644
--- a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.cc
+++ b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.cc
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "chromeos/services/device_sync/public/cpp/device_sync_client_impl.h"
 
 #include "chromeos/components/proximity_auth/logging/logging.h"
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h
index 83fcc010..ced7e4a 100644
--- a/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h
+++ b/chromeos/services/device_sync/public/cpp/device_sync_client_impl.h
@@ -6,6 +6,8 @@
 #define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_DEVICE_SYNC_CLIENT_IMPL_H_
 
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/macros.h"
diff --git a/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc b/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc
index e5bb4bc..73e3ae1 100644
--- a/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc
+++ b/chromeos/services/device_sync/public/cpp/device_sync_client_impl_unittest.cc
@@ -5,6 +5,8 @@
 #include "chromeos/services/device_sync/public/cpp/device_sync_client_impl.h"
 
 #include <algorithm>
+#include <tuple>
+#include <utility>
 
 #include "base/memory/scoped_refptr.h"
 #include "base/no_destructor.h"
@@ -49,7 +51,8 @@
 
 class FakeDeviceSyncImplFactory : public DeviceSyncImpl::Factory {
  public:
-  FakeDeviceSyncImplFactory(std::unique_ptr<FakeDeviceSync> fake_device_sync)
+  explicit FakeDeviceSyncImplFactory(
+      std::unique_ptr<FakeDeviceSync> fake_device_sync)
       : fake_device_sync_(std::move(fake_device_sync)) {}
 
   ~FakeDeviceSyncImplFactory() override = default;
diff --git a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
index 08ee6d5..3aee9ffc 100644
--- a/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
+++ b/chromeos/services/device_sync/public/cpp/fake_device_sync_client.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <queue>
+#include <string>
 
 #include "base/callback.h"
 #include "base/macros.h"
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn
index 0085e1d..44effdd 100644
--- a/chromeos/services/secure_channel/BUILD.gn
+++ b/chromeos/services/secure_channel/BUILD.gn
@@ -34,6 +34,8 @@
     "connection_medium.h",
     "connection_role.cc",
     "connection_role.h",
+    "local_device_metadata_manager.cc",
+    "local_device_metadata_manager.h",
     "multiplexed_channel.cc",
     "multiplexed_channel.h",
     "multiplexed_channel_impl.cc",
@@ -118,6 +120,7 @@
     "connect_to_device_operation_base_unittest.cc",
     "connect_to_device_operation_factory_base_unittest.cc",
     "connection_attempt_base_unittest.cc",
+    "local_device_metadata_manager_unittest.cc",
     "multiplexed_channel_impl_unittest.cc",
     "pending_ble_initiator_connection_request_unittest.cc",
     "pending_ble_listener_connection_request_unittest.cc",
diff --git a/chromeos/services/secure_channel/local_device_metadata_manager.cc b/chromeos/services/secure_channel/local_device_metadata_manager.cc
new file mode 100644
index 0000000..217140f
--- /dev/null
+++ b/chromeos/services/secure_channel/local_device_metadata_manager.cc
@@ -0,0 +1,62 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/services/secure_channel/local_device_metadata_manager.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "chromeos/components/proximity_auth/logging/logging.h"
+
+namespace chromeos {
+
+namespace secure_channel {
+
+LocalDeviceMetadataManager::LocalDeviceMetadataManager() = default;
+
+LocalDeviceMetadataManager::~LocalDeviceMetadataManager() = default;
+
+void LocalDeviceMetadataManager::SetDefaultLocalDeviceDataMetadata(
+    cryptauth::RemoteDeviceRef default_local_device_metadata) {
+  if (default_local_device_metadata_) {
+    PA_LOG(WARNING) << "LocalDeviceMetadataManager::"
+                    << "SetDefaultLocalDeviceDataMetadata(): Setting the "
+                    << "default local device metadata, but one was already "
+                    << "set. Overwriting the old one.";
+  }
+
+  default_local_device_metadata_ = default_local_device_metadata;
+}
+
+const base::Optional<cryptauth::RemoteDeviceRef>&
+LocalDeviceMetadataManager::GetDefaultLocalDeviceMetadata() const {
+  return default_local_device_metadata_;
+}
+
+void LocalDeviceMetadataManager::SetLocalDeviceMetadataForRequest(
+    const base::UnguessableToken& request_id,
+    cryptauth::RemoteDeviceRef local_device_metadata) {
+  if (base::ContainsKey(request_id_to_metadata_map_, request_id)) {
+    PA_LOG(ERROR) << "LocalDeviceMetadataManager::"
+                  << "SetLocalDeviceMetadataForRequest(): Setting local device "
+                  << "metadata for request ID " << request_id << ", but that "
+                  << "request already had metadata set.";
+    NOTREACHED();
+  }
+
+  request_id_to_metadata_map_.insert(
+      std::make_pair(request_id, local_device_metadata));
+}
+
+base::Optional<cryptauth::RemoteDeviceRef>
+LocalDeviceMetadataManager::GetLocalDeviceMetadataForRequest(
+    const base::UnguessableToken& request_id) const {
+  if (base::ContainsKey(request_id_to_metadata_map_, request_id))
+    return request_id_to_metadata_map_.at(request_id);
+
+  return base::nullopt;
+}
+
+}  // namespace secure_channel
+
+}  // namespace chromeos
diff --git a/chromeos/services/secure_channel/local_device_metadata_manager.h b/chromeos/services/secure_channel/local_device_metadata_manager.h
new file mode 100644
index 0000000..4df1ad2
--- /dev/null
+++ b/chromeos/services/secure_channel/local_device_metadata_manager.h
@@ -0,0 +1,62 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_MANAGER_H_
+#define CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_MANAGER_H_
+
+#include <unordered_map>
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/unguessable_token.h"
+#include "components/cryptauth/remote_device_ref.h"
+
+namespace chromeos {
+
+namespace secure_channel {
+
+// Provides the ability set/fetch data associated with the local device.
+class LocalDeviceMetadataManager {
+ public:
+  LocalDeviceMetadataManager();
+  virtual ~LocalDeviceMetadataManager();
+
+  // Sets the default local device metadata; this function is intended to be
+  // called when the user logs in.
+  void SetDefaultLocalDeviceDataMetadata(
+      cryptauth::RemoteDeviceRef default_local_device_metadata);
+
+  // Return value is base::nullopt if SetDefaultLocalDeviceDataMetadata() has
+  // not yet been called.
+  const base::Optional<cryptauth::RemoteDeviceRef>&
+  GetDefaultLocalDeviceMetadata() const;
+
+  // Sets the local device metadata for the request with id |request_id|. This
+  // function is intended to be used before the user logs in; before log-in,
+  // the local device can be represented by several RemoteDeviceRef objects,
+  // each specific to a different user's account.
+  void SetLocalDeviceMetadataForRequest(
+      const base::UnguessableToken& request_id,
+      cryptauth::RemoteDeviceRef default_local_device_metadata);
+
+  // Return value is base::nullopt if SetLocalDeviceMetadataForRequest() has
+  // not yet been called for the |request_id|.
+  base::Optional<cryptauth::RemoteDeviceRef> GetLocalDeviceMetadataForRequest(
+      const base::UnguessableToken& request_id) const;
+
+ private:
+  base::Optional<cryptauth::RemoteDeviceRef> default_local_device_metadata_;
+  std::unordered_map<base::UnguessableToken,
+                     cryptauth::RemoteDeviceRef,
+                     base::UnguessableTokenHash>
+      request_id_to_metadata_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(LocalDeviceMetadataManager);
+};
+
+}  // namespace secure_channel
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_SECURE_CHANNEL_LOCAL_DEVICE_METADATA_MANAGER_H_
diff --git a/chromeos/services/secure_channel/local_device_metadata_manager_unittest.cc b/chromeos/services/secure_channel/local_device_metadata_manager_unittest.cc
new file mode 100644
index 0000000..9ba0e14
--- /dev/null
+++ b/chromeos/services/secure_channel/local_device_metadata_manager_unittest.cc
@@ -0,0 +1,95 @@
+// 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 "chromeos/services/secure_channel/local_device_metadata_manager.h"
+
+#include <memory>
+
+#include "base/run_loop.h"
+#include "base/test/gtest_util.h"
+#include "base/unguessable_token.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace secure_channel {
+
+namespace {
+const size_t kNumTestDevices = 2;
+}  // namespace
+
+class SecureChannelLocalDeviceMetadataManagerTest : public testing::Test {
+ protected:
+  SecureChannelLocalDeviceMetadataManagerTest()
+      : test_device_refs_(
+            cryptauth::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
+  ~SecureChannelLocalDeviceMetadataManagerTest() override = default;
+
+  // testing::Test:
+  void SetUp() override {
+    manager_ = std::make_unique<LocalDeviceMetadataManager>();
+  }
+
+  cryptauth::RemoteDeviceRef GetDevice(size_t index) {
+    EXPECT_TRUE(index < kNumTestDevices);
+    return test_device_refs_[index];
+  }
+
+  LocalDeviceMetadataManager* manager() { return manager_.get(); }
+
+  const cryptauth::RemoteDeviceRefList& test_device_refs() {
+    return test_device_refs_;
+  }
+
+ private:
+  const cryptauth::RemoteDeviceRefList test_device_refs_;
+
+  std::unique_ptr<LocalDeviceMetadataManager> manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(SecureChannelLocalDeviceMetadataManagerTest);
+};
+
+TEST_F(SecureChannelLocalDeviceMetadataManagerTest, DefaultLocalDevice) {
+  // No device should be present before one is added.
+  EXPECT_FALSE(manager()->GetDefaultLocalDeviceMetadata());
+
+  // Set the default local device.
+  manager()->SetDefaultLocalDeviceDataMetadata(test_device_refs()[0]);
+  EXPECT_EQ(test_device_refs()[0], *manager()->GetDefaultLocalDeviceMetadata());
+
+  // Set a new device as the default local device.
+  manager()->SetDefaultLocalDeviceDataMetadata(test_device_refs()[1]);
+  EXPECT_EQ(test_device_refs()[1], *manager()->GetDefaultLocalDeviceMetadata());
+}
+
+TEST_F(SecureChannelLocalDeviceMetadataManagerTest, LocalDevicePerRequest) {
+  auto request_id_1 = base::UnguessableToken::Create();
+  auto request_id_2 = base::UnguessableToken::Create();
+
+  // First request.
+  EXPECT_FALSE(manager()->GetLocalDeviceMetadataForRequest(request_id_1));
+  manager()->SetLocalDeviceMetadataForRequest(request_id_1,
+                                              test_device_refs()[0]);
+  EXPECT_EQ(test_device_refs()[0],
+            *manager()->GetLocalDeviceMetadataForRequest(request_id_1));
+
+  // Second request.
+  EXPECT_FALSE(manager()->GetLocalDeviceMetadataForRequest(request_id_2));
+  manager()->SetLocalDeviceMetadataForRequest(request_id_2,
+                                              test_device_refs()[1]);
+  EXPECT_EQ(test_device_refs()[1],
+            *manager()->GetLocalDeviceMetadataForRequest(request_id_2));
+
+  // Setting new metadata for a request which has already been set should cause
+  // a crash.
+  EXPECT_DCHECK_DEATH(manager()->SetLocalDeviceMetadataForRequest(
+      request_id_1, test_device_refs()[1]));
+  EXPECT_DCHECK_DEATH(manager()->SetLocalDeviceMetadataForRequest(
+      request_id_2, test_device_refs()[0]));
+}
+
+}  // namespace secure_channel
+
+}  // namespace chromeos
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc
index 06232ab..7f2b78b8 100644
--- a/components/autofill/core/browser/autofill_data_util.cc
+++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -44,6 +44,11 @@
      IDS_AUTOFILL_CC_UNION_PAY},
     {autofill::kVisaCard, "visa", IDR_AUTOFILL_CC_VISA, IDS_AUTOFILL_CC_VISA},
 };
+
+const PaymentRequestData kGooglePayBrandingRequestData = {
+    "googlePay", "googlePay", IDR_AUTOFILL_GOOGLE_PAY,
+    IDS_AUTOFILL_CC_GOOGLE_PAY};
+
 const PaymentRequestData kGenericPaymentRequestData = {
     autofill::kGenericCard, "generic", IDR_AUTOFILL_CC_GENERIC,
     IDS_AUTOFILL_CC_GENERIC};
@@ -420,6 +425,9 @@
     if (issuer_network == data.issuer_network)
       return data;
   }
+  if (issuer_network == kGooglePayBrandingRequestData.issuer_network) {
+    return kGooglePayBrandingRequestData;
+  }
   return kGenericPaymentRequestData;
 }
 
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index f49a2678..58240cb 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -22,6 +22,7 @@
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
+#include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/signin/core/browser/signin_metrics.h"
 #include "components/strings/grit/components_strings.h"
@@ -355,9 +356,23 @@
   // include a hint for keyboard accessory.
   suggestions->push_back(Suggestion(GetSettingsSuggestionValue()));
   suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS;
+  // On Android and Desktop, Google Pay branding is shown along with Settings.
+  // So Google Pay Icon is just attached to an existing menu item.
   if (is_all_server_suggestions)
     suggestions->back().icon = base::ASCIIToUTF16("googlePay");
 
+// On iOS, GooglePayIcon comes at the begining and hence prepended to the list.
+#if defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(
+          features::kAutofillDownstreamUseGooglePayBrandingOniOS) &&
+      is_all_server_suggestions) {
+    Suggestion googlepay_icon;
+    googlepay_icon.icon = base::ASCIIToUTF16("googlePay");
+    googlepay_icon.frontend_id = POPUP_ITEM_ID_GOOGLE_PAY_BRANDING;
+    suggestions->insert(suggestions->begin(), googlepay_icon);
+  }
+#endif
+
 #if defined(OS_ANDROID)
   if (IsKeyboardAccessoryEnabled()) {
     suggestions->back().icon = base::ASCIIToUTF16("settings");
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 226b259..d028058 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -24,6 +24,7 @@
 #include "components/autofill/core/browser/suggestion_test_helpers.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
 #include "components/autofill/core/browser/test_autofill_driver.h"
+#include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
@@ -34,6 +35,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/geometry/rect.h"
 
+using autofill::features::kAutofillDownstreamUseGooglePayBrandingOniOS;
 using base::ASCIIToUTF16;
 using testing::_;
 
@@ -746,6 +748,53 @@
   external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item, true);
 }
 
+#if defined(OS_IOS)
+TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIconOniOS) {
+  // Turn on feature flag.
+  base::test::ScopedFeatureList scoped_feature_list_;
+  scoped_feature_list_.InitAndEnableFeature(
+      kAutofillDownstreamUseGooglePayBrandingOniOS);
+  IssueOnQuery(kQueryId);
+
+  auto element_icons =
+      testing::ElementsAre(base::ASCIIToUTF16("googlePay"), base::string16(),
+                           base::string16(), base::ASCIIToUTF16("googlePay"));
+  EXPECT_CALL(
+      autofill_client_,
+      ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons), _));
+
+  std::vector<Suggestion> autofill_item;
+  autofill_item.push_back(Suggestion());
+  autofill_item[0].frontend_id = kAutofillProfileId;
+
+  // This should call ShowAutofillPopup.
+  external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item, true);
+}
+
+TEST_F(AutofillExternalDelegateUnitTest,
+       ShouldNotShowGooglePayIconOniOSIfExperimentOff) {
+  // Turn on feature flag.
+  base::test::ScopedFeatureList scoped_feature_list_;
+  scoped_feature_list_.InitAndDisableFeature(
+      kAutofillDownstreamUseGooglePayBrandingOniOS);
+  IssueOnQuery(kQueryId);
+
+  auto element_icons = testing::ElementsAre(
+      base::string16(), base::string16(),
+      base::string16() /* Autofill setting item does not have icon. */);
+  EXPECT_CALL(
+      autofill_client_,
+      ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons), _));
+
+  std::vector<Suggestion> autofill_item;
+  autofill_item.push_back(Suggestion());
+  autofill_item[0].frontend_id = kAutofillProfileId;
+
+  // This should call ShowAutofillPopup.
+  external_delegate_->OnSuggestionsReturned(kQueryId, autofill_item, false);
+}
+#endif  // defined(OS_IOS)
+
 TEST_F(AutofillExternalDelegateUnitTest,
        ShouldNotShowGooglePayIconIfSuggestionsContainLocalCards) {
   IssueOnQuery(kQueryId);
diff --git a/components/autofill/core/browser/popup_item_ids.h b/components/autofill/core/browser/popup_item_ids.h
index dca2dd0..a1762b6 100644
--- a/components/autofill/core/browser/popup_item_ids.h
+++ b/components/autofill/core/browser/popup_item_ids.h
@@ -24,6 +24,7 @@
   POPUP_ITEM_ID_CREATE_HINT = -12,
   POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY = -13,
   POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY = -14,
+  POPUP_ITEM_ID_GOOGLE_PAY_BRANDING = -15,
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index f09844e..b45d05b 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -17,6 +17,12 @@
 const base::Feature kAutofillCacheQueryResponses{
     "AutofillCacheQueryResponses", base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Controls whether the credit card downstream keyboard accessory shows
+// the Google Pay logo animation on iOS.
+const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS{
+    "AutofillDownstreamUseGooglePayBrandingOniOS",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Controls whether Autofill attemps to fill dynamically changing forms.
 const base::Feature kAutofillDynamicForms{"AutofillDynamicForms",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 821ee4a..50e99544 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -13,6 +13,7 @@
 // All features in alphabetical order.
 extern const base::Feature kAutofillAddressNormalizer;
 extern const base::Feature kAutofillCacheQueryResponses;
+extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS;
 extern const base::Feature kAutofillDynamicForms;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index 8077193..5413604 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -60,6 +60,9 @@
   <message name="IDS_AUTOFILL_CC_ELO" desc="Elo credit card name.">
     Elo
   </message>
+  <message name="IDS_AUTOFILL_CC_GOOGLE_PAY" desc="Google pay brand name">
+    Google Pay
+  </message>
   <message name="IDS_AUTOFILL_CC_JCB" desc="JCB credit card name." formatter_data="android_java">
     JCB
   </message>
diff --git a/components/bookmarks/browser/BUILD.gn b/components/bookmarks/browser/BUILD.gn
index fd9c3db..ca6cf0c 100644
--- a/components/bookmarks/browser/BUILD.gn
+++ b/components/bookmarks/browser/BUILD.gn
@@ -19,6 +19,8 @@
     "bookmark_undo_delegate.h",
     "bookmark_undo_provider.h",
     "bookmark_utils.h",
+    "history_bookmark_model.h",
+    "model_loader.h",
     "scoped_group_bookmark_actions.h",
     "startup_task_runner_service.h",
     "titled_url_index.h",
@@ -41,6 +43,7 @@
     "bookmark_pasteboard_helper_mac.mm",
     "bookmark_storage.cc",
     "bookmark_utils.cc",
+    "model_loader.cc",
     "scoped_group_bookmark_actions.cc",
     "startup_task_runner_service.cc",
     "titled_url_index.cc",
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc
index 9d31611..7c905b2 100644
--- a/components/bookmarks/browser/bookmark_model.cc
+++ b/components/bookmarks/browser/bookmark_model.cc
@@ -23,6 +23,7 @@
 #include "components/bookmarks/browser/bookmark_storage.h"
 #include "components/bookmarks/browser/bookmark_undo_delegate.h"
 #include "components/bookmarks/browser/bookmark_utils.h"
+#include "components/bookmarks/browser/model_loader.h"
 #include "components/bookmarks/browser/titled_url_index.h"
 #include "components/bookmarks/browser/titled_url_match.h"
 #include "components/bookmarks/browser/typed_count_sorter.h"
@@ -113,23 +114,6 @@
   DISALLOW_COPY_AND_ASSIGN(EmptyUndoDelegate);
 };
 
-void FinishedLoadOnMainThread(
-    base::OnceCallback<void(std::unique_ptr<BookmarkLoadDetails>)> callback,
-    std::unique_ptr<BookmarkLoadDetails> details) {
-  std::move(callback).Run(std::move(details));
-}
-
-void DoLoadOnBackgroundThread(
-    const base::FilePath& profile_path,
-    scoped_refptr<base::SequencedTaskRunner> result_task_runner,
-    base::OnceCallback<void(std::unique_ptr<BookmarkLoadDetails>)> callback,
-    std::unique_ptr<BookmarkLoadDetails> details) {
-  LoadBookmarks(profile_path, details.get());
-  result_task_runner->PostTask(
-      FROM_HERE, base::BindOnce(&FinishedLoadOnMainThread, std::move(callback),
-                                std::move(details)));
-}
-
 }  // namespace
 
 // BookmarkModel --------------------------------------------------------------
@@ -155,15 +139,6 @@
   }
 }
 
-void BookmarkModel::Shutdown() {
-  if (loaded_)
-    return;
-
-  // See comment in HistoryService::ShutdownOnUIThread where this is invoked for
-  // details. It is also called when the BookmarkModel is deleted.
-  loaded_signal_.Signal();
-}
-
 void BookmarkModel::Load(
     PrefService* pref_service,
     const base::FilePath& profile_path,
@@ -178,14 +153,11 @@
 
   store_ = std::make_unique<BookmarkStorage>(this, profile_path,
                                              io_task_runner.get());
-  auto done_loading_callback =
-      base::BindOnce(&BookmarkModel::DoneLoading, weak_factory_.GetWeakPtr());
-  io_task_runner->PostTask(
-      FROM_HERE,
-      base::BindOnce(&DoLoadOnBackgroundThread,
-                     profile_path.Append(kBookmarksFileName), ui_task_runner,
-                     std::move(done_loading_callback),
-                     std::make_unique<BookmarkLoadDetails>(client_.get())));
+  // Creating ModelLoader schedules the load on |io_task_runner|.
+  model_loader_ = base::MakeRefCounted<ModelLoader>(
+      profile_path.Append(kBookmarksFileName), io_task_runner.get(),
+      std::make_unique<BookmarkLoadDetails>(client_.get()),
+      base::BindOnce(&BookmarkModel::DoneLoading, weak_factory_.GetWeakPtr()));
 }
 
 void BookmarkModel::AddObserver(BookmarkModelObserver* observer) {
@@ -591,10 +563,6 @@
     url_index_->GetBookmarks(bookmarks);
 }
 
-void BookmarkModel::BlockTillLoaded() {
-  loaded_signal_.Wait();
-}
-
 const BookmarkNode* BookmarkModel::AddFolder(const BookmarkNode* parent,
                                              int index,
                                              const base::string16& title) {
@@ -827,7 +795,7 @@
   }
 
   index_ = details->owned_index();
-  url_index_ = details->owned_url_index();
+  url_index_ = details->url_index();
   root_ = details->root_node();
   // See declaration for details on why |owned_root_| is reset.
   owned_root_.reset();
@@ -847,8 +815,6 @@
 
   loaded_ = true;
 
-  loaded_signal_.Signal();
-
   // Notify our direct observers.
   for (BookmarkModelObserver& observer : observers_)
     observer.BookmarkModelLoaded(this, details->ids_reassigned());
diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmarks/browser/bookmark_model.h
index 868d8ba..cbfe583 100644
--- a/components/bookmarks/browser/bookmark_model.h
+++ b/components/bookmarks/browser/bookmark_model.h
@@ -15,11 +15,10 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
-#include "base/synchronization/waitable_event.h"
 #include "components/bookmarks/browser/bookmark_client.h"
 #include "components/bookmarks/browser/bookmark_node.h"
 #include "components/bookmarks/browser/bookmark_undo_provider.h"
@@ -50,6 +49,7 @@
 class BookmarkModelObserver;
 class BookmarkStorage;
 class BookmarkUndoDelegate;
+class ModelLoader;
 class ScopedGroupBookmarkActions;
 class TestBookmarkClient;
 class TitledUrlIndex;
@@ -74,9 +74,6 @@
   explicit BookmarkModel(std::unique_ptr<BookmarkClient> client);
   ~BookmarkModel() override;
 
-  // KeyedService:
-  void Shutdown() override;
-
   // Loads the bookmarks. This is called upon creation of the BookmarkModel. You
   // need not invoke this directly. All load operations will be executed on
   // |io_task_runner|. |ui_task_runner| is the task runner the model runs on.
@@ -88,6 +85,9 @@
   // Returns true if the model finished loading.
   bool loaded() const { return loaded_; }
 
+  // Returns the object responsible for tracking loading.
+  ModelLoader* model_loader() { return model_loader_.get(); }
+
   // Returns the root node. The 'bookmark bar' node and 'other' node are
   // children of the root node.
   const BookmarkNode* root_node() const { return root_; }
@@ -192,10 +192,6 @@
   // If not on the main thread you *must* invoke BlockTillLoaded first.
   void GetBookmarks(std::vector<UrlAndTitle>* urls);
 
-  // Blocks until loaded. This is intended for usage on a thread other than
-  // the main thread.
-  void BlockTillLoaded();
-
   // Adds a new folder node at the specified position.
   const BookmarkNode* AddFolder(const BookmarkNode* parent,
                                 int index,
@@ -413,9 +409,13 @@
   std::unique_ptr<BookmarkStorage> store_;
 
   std::unique_ptr<TitledUrlIndex> index_;
-  std::unique_ptr<UrlIndex> url_index_;
 
-  base::WaitableEvent loaded_signal_;
+  // Owned by |model_loader_|.
+  // WARNING: in some tests this does *not* refer to
+  // |ModelLoader::history_bookmark_model_|. This is because some tests
+  // directly call DoneLoading().
+  // TODO: this is confusing, fix tests not to circumvent ModelLoader.
+  scoped_refptr<UrlIndex> url_index_;
 
   // See description of IsDoingExtensiveChanges above.
   int extensive_changes_ = 0;
@@ -427,6 +427,8 @@
   BookmarkUndoDelegate* undo_delegate_ = nullptr;
   std::unique_ptr<BookmarkUndoDelegate> empty_undo_delegate_;
 
+  scoped_refptr<ModelLoader> model_loader_;
+
   base::WeakPtrFactory<BookmarkModel> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkModel);
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc
index 3ae0c62..578817e 100644
--- a/components/bookmarks/browser/bookmark_storage.cc
+++ b/components/bookmarks/browser/bookmark_storage.cc
@@ -155,11 +155,7 @@
 }
 
 void BookmarkLoadDetails::CreateUrlIndex() {
-  url_index_ = std::make_unique<UrlIndex>(std::move(root_node_));
-}
-
-std::unique_ptr<UrlIndex> BookmarkLoadDetails::owned_url_index() {
-  return std::move(url_index_);
+  url_index_ = base::MakeRefCounted<UrlIndex>(std::move(root_node_));
 }
 
 BookmarkPermanentNode* BookmarkLoadDetails::CreatePermanentNode(
diff --git a/components/bookmarks/browser/bookmark_storage.h b/components/bookmarks/browser/bookmark_storage.h
index 0a1b1a1..86d37f2c 100644
--- a/components/bookmarks/browser/bookmark_storage.h
+++ b/components/bookmarks/browser/bookmark_storage.h
@@ -16,6 +16,7 @@
 #include "base/files/important_file_writer.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "components/bookmarks/browser/bookmark_node.h"
 #include "components/bookmarks/browser/titled_url_index.h"
@@ -104,7 +105,7 @@
   bool ids_reassigned() const { return ids_reassigned_; }
 
   void CreateUrlIndex();
-  std::unique_ptr<UrlIndex> owned_url_index();
+  UrlIndex* url_index() { return url_index_.get(); }
 
  private:
   // Creates one of the possible permanent nodes (bookmark bar node, other node
@@ -125,7 +126,7 @@
   std::string computed_checksum_;
   std::string stored_checksum_;
   bool ids_reassigned_ = false;
-  std::unique_ptr<UrlIndex> url_index_;
+  scoped_refptr<UrlIndex> url_index_;
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkLoadDetails);
 };
diff --git a/components/bookmarks/browser/history_bookmark_model.h b/components/bookmarks/browser/history_bookmark_model.h
new file mode 100644
index 0000000..e8beb2d6
--- /dev/null
+++ b/components/bookmarks/browser/history_bookmark_model.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_BOOKMARKS_BROWSER_HISTORY_BOOKMARK_MODEL_H_
+#define COMPONENTS_BOOKMARKS_BROWSER_HISTORY_BOOKMARK_MODEL_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+
+class GURL;
+
+namespace bookmarks {
+
+struct UrlAndTitle;
+
+// Defines the interface use by history. History accesses these functions on a
+// background thread.
+class HistoryBookmarkModel
+    : public base::RefCountedThreadSafe<HistoryBookmarkModel> {
+ public:
+  HistoryBookmarkModel() {}
+
+  virtual bool IsBookmarked(const GURL& url) = 0;
+
+  // Returns, by reference in |bookmarks|, the set of bookmarked urls and their
+  // titles. This returns the unique set of URLs. For example, if two bookmarks
+  // reference the same URL only one entry is added not matter the titles are
+  // same or not.
+  virtual void GetBookmarks(std::vector<UrlAndTitle>* urls) = 0;
+
+ protected:
+  friend class base::RefCountedThreadSafe<HistoryBookmarkModel>;
+
+  virtual ~HistoryBookmarkModel() {}
+};
+
+}  // namespace bookmarks
+
+#endif  // COMPONENTS_BOOKMARKS_BROWSER_HISTORY_BOOKMARK_MODEL_H_
diff --git a/components/bookmarks/browser/model_loader.cc b/components/bookmarks/browser/model_loader.cc
new file mode 100644
index 0000000..a20019b
--- /dev/null
+++ b/components/bookmarks/browser/model_loader.cc
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/bookmarks/browser/model_loader.h"
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/bookmarks/browser/bookmark_storage.h"
+#include "components/bookmarks/browser/url_index.h"
+
+namespace bookmarks {
+
+ModelLoader::ModelLoader(const base::FilePath& profile_path,
+                         base::SequencedTaskRunner* load_sequenced_task_runner,
+                         std::unique_ptr<BookmarkLoadDetails> details,
+                         LoadCallback callback)
+    : loaded_signal_(base::WaitableEvent::ResetPolicy::MANUAL,
+                     base::WaitableEvent::InitialState::NOT_SIGNALED) {
+  load_sequenced_task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&ModelLoader::DoLoadOnBackgroundThread, this, profile_path,
+                     base::ThreadTaskRunnerHandle::Get(), std::move(details),
+                     std::move(callback)));
+}
+
+void ModelLoader::BlockTillLoaded() {
+  loaded_signal_.Wait();
+}
+
+ModelLoader::~ModelLoader() = default;
+
+void ModelLoader::DoLoadOnBackgroundThread(
+    const base::FilePath& profile_path,
+    scoped_refptr<base::SequencedTaskRunner> main_sequenced_task_runner,
+    std::unique_ptr<BookmarkLoadDetails> details,
+    LoadCallback callback) {
+  LoadBookmarks(profile_path, details.get());
+  history_bookmark_model_ = details->url_index();
+  loaded_signal_.Signal();
+  main_sequenced_task_runner->PostTask(
+      FROM_HERE, base::BindOnce(&ModelLoader::OnFinishedLoad, this,
+                                std::move(details), std::move(callback)));
+}
+
+void ModelLoader::OnFinishedLoad(std::unique_ptr<BookmarkLoadDetails> details,
+                                 LoadCallback callback) {
+  std::move(callback).Run(std::move(details));
+}
+
+}  // namespace bookmarks
diff --git a/components/bookmarks/browser/model_loader.h b/components/bookmarks/browser/model_loader.h
new file mode 100644
index 0000000..924c17e
--- /dev/null
+++ b/components/bookmarks/browser/model_loader.h
@@ -0,0 +1,75 @@
+// 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 COMPONENTS_BOOKMARKS_BROWSER_MODEL_LOADER_H_
+#define COMPONENTS_BOOKMARKS_BROWSER_MODEL_LOADER_H_
+
+#include <memory>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/synchronization/waitable_event.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}  // namespace base
+
+namespace bookmarks {
+
+class BookmarkLoadDetails;
+class HistoryBookmarkModel;
+
+// ModelLoader is created by BookmarkModel to track loading of BookmarkModel.
+// ModelLoader may be used on multiple threads. ModelLoader may outlive
+// BookmarkModel.
+class ModelLoader : public base::RefCountedThreadSafe<ModelLoader> {
+ public:
+  using LoadCallback =
+      base::OnceCallback<void(std::unique_ptr<BookmarkLoadDetails>)>;
+  // Creates the ModelLoader, and schedules loading on
+  // |load_sequenced_task_runner|. |callback| is run once loading
+  // completes (on the main thread).
+  ModelLoader(const base::FilePath& profile_path,
+              base::SequencedTaskRunner* load_sequenced_task_runner,
+              std::unique_ptr<BookmarkLoadDetails> details,
+              LoadCallback callback);
+
+  // Blocks until loaded. This is intended for usage on a thread other than
+  // the main thread.
+  void BlockTillLoaded();
+
+  // Returns null until the model has loaded. Use BlockTillLoaded() to ensure
+  // this returns non-null.
+  HistoryBookmarkModel* history_bookmark_model() {
+    return history_bookmark_model_.get();
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<ModelLoader>;
+  ~ModelLoader();
+
+  // Performs the load on a background thread.
+  void DoLoadOnBackgroundThread(
+      const base::FilePath& profile_path,
+      scoped_refptr<base::SequencedTaskRunner> main_sequenced_task_runner,
+      std::unique_ptr<BookmarkLoadDetails> details,
+      LoadCallback callback);
+
+  void OnFinishedLoad(std::unique_ptr<BookmarkLoadDetails> details,
+                      LoadCallback callback);
+
+  scoped_refptr<HistoryBookmarkModel> history_bookmark_model_;
+
+  // Signaled once loading completes.
+  base::WaitableEvent loaded_signal_;
+
+  DISALLOW_COPY_AND_ASSIGN(ModelLoader);
+};
+
+}  // namespace bookmarks
+
+#endif  // COMPONENTS_BOOKMARKS_BROWSER_MODEL_LOADER_H_
diff --git a/components/bookmarks/browser/url_index.cc b/components/bookmarks/browser/url_index.cc
index b8cbf91..44aecac 100644
--- a/components/bookmarks/browser/url_index.cc
+++ b/components/bookmarks/browser/url_index.cc
@@ -14,8 +14,6 @@
   AddImpl(root_.get());
 }
 
-UrlIndex::~UrlIndex() = default;
-
 void UrlIndex::Add(BookmarkNode* parent,
                    int index,
                    std::unique_ptr<BookmarkNode> node) {
@@ -100,6 +98,8 @@
   }
 }
 
+UrlIndex::~UrlIndex() = default;
+
 bool UrlIndex::IsBookmarkedNoLock(const GURL& url) {
   url_lock_.AssertAcquired();
   BookmarkNode tmp_node(url);
diff --git a/components/bookmarks/browser/url_index.h b/components/bookmarks/browser/url_index.h
index 0386be37..1200247 100644
--- a/components/bookmarks/browser/url_index.h
+++ b/components/bookmarks/browser/url_index.h
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/synchronization/lock.h"
 #include "components/bookmarks/browser/bookmark_node.h"
+#include "components/bookmarks/browser/history_bookmark_model.h"
 #include "url/gurl.h"
 
 namespace bookmarks {
@@ -22,18 +23,19 @@
 
 // UrlIndex maintains the bookmark nodes of type url. The nodes are ordered by
 // url for lookup using the url. The mapping is done based on the nodes in the
-// model.
+// model. This class may outlive the BookmarkModel, necessitating this class
+// owning all the nodes.
 //
 // This class is accessed on multiple threads, so all mutation to the underlying
 // set must be done while holding a lock. While this class is accessed on
 // multiple threads, all mutation happens on main thread.
 //
 // This class is an implementation detail of BookmarkModel and is not intended
-// to be public.
-class UrlIndex {
+// to be public. The public functions implemented by way of
+// HistoryBookmarkModel define the public API of this class.
+class UrlIndex : public HistoryBookmarkModel {
  public:
   explicit UrlIndex(std::unique_ptr<BookmarkNode> root);
-  ~UrlIndex();
 
   BookmarkNode* root() { return root_.get(); }
 
@@ -56,11 +58,15 @@
   // Returns true if there is at least one bookmark.
   bool HasBookmarks();
 
-  bool IsBookmarked(const GURL& url);
-
-  void GetBookmarks(std::vector<UrlAndTitle>* bookmarks);
+  // HistoryBookmarkModel:
+  bool IsBookmarked(const GURL& url) override;
+  void GetBookmarks(std::vector<UrlAndTitle>* bookmarks) override;
 
  private:
+  friend class base::RefCountedThreadSafe<UrlIndex>;
+
+  ~UrlIndex() override;
+
   // Used to order BookmarkNodes by URL.
   class NodeUrlComparator {
    public:
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc
index 156c582..04bd90d 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -58,16 +58,6 @@
 
 namespace {
 
-syncer::ModelTypeSet GetDisabledTypesFromCommandLine(
-    const base::CommandLine& command_line) {
-  syncer::ModelTypeSet disabled_types;
-  std::string disabled_types_str =
-      command_line.GetSwitchValueASCII(switches::kDisableSyncTypes);
-
-  disabled_types = syncer::ModelTypeSetFromString(disabled_types_str);
-  return disabled_types;
-}
-
 // This helper function only wraps
 // autofill::AutocompleteSyncBridge::FromWebDataService(). This way, it
 // simplifies life for the compiler which cannot directly cast
@@ -87,7 +77,6 @@
     version_info::Channel channel,
     const std::string& version,
     bool is_tablet,
-    const base::CommandLine& command_line,
     const char* history_disabled_pref,
     const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
     const scoped_refptr<base::SingleThreadTaskRunner>& db_thread,
@@ -97,7 +86,6 @@
       channel_(channel),
       version_(version),
       is_tablet_(is_tablet),
-      command_line_(command_line),
       history_disabled_pref_(history_disabled_pref),
       ui_thread_(ui_thread),
       db_thread_(db_thread),
@@ -106,68 +94,53 @@
 
 ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {}
 
-void ProfileSyncComponentsFactoryImpl::RegisterDataTypes(
-    syncer::SyncService* sync_service,
-    const RegisterDataTypesMethod& register_platform_types_method) {
-  syncer::ModelTypeSet disabled_types =
-      GetDisabledTypesFromCommandLine(command_line_);
-  RegisterCommonDataTypes(sync_service, disabled_types);
-  if (!register_platform_types_method.is_null()) {
-    syncer::ModelTypeSet enabled_types;
-    register_platform_types_method.Run(sync_service, disabled_types,
-                                       enabled_types);
-  }
-}
-
-void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
-    syncer::SyncService* sync_service,
-    syncer::ModelTypeSet disabled_types) {
+syncer::DataTypeController::TypeVector
+ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
+    syncer::ModelTypeSet disabled_types,
+    syncer::LocalDeviceInfoProvider* local_device_info_provider) {
+  syncer::DataTypeController::TypeVector controllers;
   base::Closure error_callback =
-      base::Bind(&syncer::ReportUnrecoverableError, channel_);
+      base::BindRepeating(&syncer::ReportUnrecoverableError, channel_);
 
   // TODO(stanisc): can DEVICE_INFO be one of disabled datatypes?
   // Use an error callback that always uploads a stacktrace if it can to help
   // get USS as stable as possible.
-  sync_service->RegisterDataTypeController(
-      std::make_unique<ModelTypeController>(syncer::DEVICE_INFO, sync_client_,
-                                            ui_thread_));
+  controllers.push_back(std::make_unique<ModelTypeController>(
+      syncer::DEVICE_INFO, sync_client_, ui_thread_));
   // These features are enabled only if there's a DB thread to post tasks to.
   if (db_thread_) {
     // Autocomplete sync is enabled by default.  Register unless explicitly
     // disabled.
     if (!disabled_types.Has(syncer::AUTOFILL)) {
-      sync_service->RegisterDataTypeController(
+      controllers.push_back(
           std::make_unique<autofill::WebDataModelTypeController>(
               syncer::AUTOFILL, sync_client_, db_thread_, web_data_service_,
-              base::Bind(&DelegateFromDataService)));
+              base::BindRepeating(&DelegateFromDataService)));
     }
 
     // Autofill sync is enabled by default.  Register unless explicitly
     // disabled.
     if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AutofillProfileDataTypeController>(
-              db_thread_, error_callback, sync_client_, web_data_service_));
+      controllers.push_back(std::make_unique<AutofillProfileDataTypeController>(
+          db_thread_, error_callback, sync_client_, web_data_service_));
     }
 
     // Wallet data sync is enabled by default, but behind a syncer experiment
     // enforced by the datatype controller. Register unless explicitly disabled.
     bool wallet_disabled = disabled_types.Has(syncer::AUTOFILL_WALLET_DATA);
     if (!wallet_disabled) {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AutofillWalletDataTypeController>(
-              syncer::AUTOFILL_WALLET_DATA, db_thread_, error_callback,
-              sync_client_, web_data_service_));
+      controllers.push_back(std::make_unique<AutofillWalletDataTypeController>(
+          syncer::AUTOFILL_WALLET_DATA, db_thread_, error_callback,
+          sync_client_, web_data_service_));
     }
 
     // Wallet metadata sync depends on Wallet data sync. Register if Wallet data
     // is syncing and metadata sync is not explicitly disabled.
     if (!wallet_disabled &&
         !disabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AutofillWalletDataTypeController>(
-              syncer::AUTOFILL_WALLET_METADATA, db_thread_, error_callback,
-              sync_client_, web_data_service_));
+      controllers.push_back(std::make_unique<AutofillWalletDataTypeController>(
+          syncer::AUTOFILL_WALLET_METADATA, db_thread_, error_callback,
+          sync_client_, web_data_service_));
     }
   }
 
@@ -175,13 +148,12 @@
   // disabled.
   if (!disabled_types.Has(syncer::BOOKMARKS)) {
     if (FeatureList::IsEnabled(switches::kSyncUSSBookmarks)) {
-      sync_service->RegisterDataTypeController(
+      controllers.push_back(
           std::make_unique<sync_bookmarks::BookmarkModelTypeController>(
               sync_client_));
     } else {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<BookmarkDataTypeController>(error_callback,
-                                                       sync_client_));
+      controllers.push_back(std::make_unique<BookmarkDataTypeController>(
+          error_callback, sync_client_));
     }
   }
 
@@ -190,14 +162,14 @@
     // TypedUrl sync is enabled by default.  Register unless explicitly
     // disabled.
     if (!disabled_types.Has(syncer::TYPED_URLS)) {
-      sync_service->RegisterDataTypeController(
+      controllers.push_back(
           std::make_unique<history::TypedURLModelTypeController>(
               sync_client_, history_disabled_pref_));
     }
 
     // Delete directive sync is enabled by default.
     if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
-      sync_service->RegisterDataTypeController(
+      controllers.push_back(
           std::make_unique<HistoryDeleteDirectivesDataTypeController>(
               error_callback, sync_client_));
     }
@@ -206,18 +178,15 @@
     // disabled because the tab sync data is added to the web history on the
     // server.
     if (!disabled_types.Has(syncer::PROXY_TABS)) {
-      sync_service->RegisterDataTypeController(
+      controllers.push_back(
           std::make_unique<ProxyDataTypeController>(syncer::PROXY_TABS));
       if (FeatureList::IsEnabled(switches::kSyncUSSSessions)) {
-        sync_service->RegisterDataTypeController(
-            std::make_unique<ModelTypeController>(syncer::SESSIONS,
-                                                  sync_client_, ui_thread_));
+        controllers.push_back(std::make_unique<ModelTypeController>(
+            syncer::SESSIONS, sync_client_, ui_thread_));
       } else {
-        sync_service->RegisterDataTypeController(
-            std::make_unique<SessionDataTypeController>(
-                error_callback, sync_client_,
-                sync_service->GetLocalDeviceInfoProvider(),
-                history_disabled_pref_));
+        controllers.push_back(std::make_unique<SessionDataTypeController>(
+            error_callback, sync_client_, local_device_info_provider,
+            history_disabled_pref_));
       }
     }
 
@@ -225,59 +194,51 @@
     if (!disabled_types.Has(syncer::FAVICON_IMAGES) &&
         !disabled_types.Has(syncer::FAVICON_TRACKING)) {
       // crbug/384552. We disable error uploading for this data types for now.
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AsyncDirectoryTypeController>(
-              syncer::FAVICON_IMAGES, base::Closure(), sync_client_,
-              syncer::GROUP_UI, ui_thread_));
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AsyncDirectoryTypeController>(
-              syncer::FAVICON_TRACKING, base::Closure(), sync_client_,
-              syncer::GROUP_UI, ui_thread_));
+      controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
+          syncer::FAVICON_IMAGES, base::RepeatingClosure(), sync_client_,
+          syncer::GROUP_UI, ui_thread_));
+      controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
+          syncer::FAVICON_TRACKING, base::RepeatingClosure(), sync_client_,
+          syncer::GROUP_UI, ui_thread_));
     }
   }
 
   // Password sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::PASSWORDS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<PasswordDataTypeController>(
-            error_callback, sync_client_,
-            sync_client_->GetPasswordStateChangedCallback(), password_store_));
+    controllers.push_back(std::make_unique<PasswordDataTypeController>(
+        error_callback, sync_client_,
+        sync_client_->GetPasswordStateChangedCallback(), password_store_));
   }
 
   if (!disabled_types.Has(syncer::PREFERENCES)) {
     if (!override_prefs_controller_to_uss_for_test_) {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<AsyncDirectoryTypeController>(
-              syncer::PREFERENCES, error_callback, sync_client_,
-              syncer::GROUP_UI, ui_thread_));
+      controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
+          syncer::PREFERENCES, error_callback, sync_client_, syncer::GROUP_UI,
+          ui_thread_));
     } else {
-      sync_service->RegisterDataTypeController(
-          std::make_unique<ModelTypeController>(syncer::PREFERENCES,
-                                                sync_client_, ui_thread_));
+      controllers.push_back(std::make_unique<ModelTypeController>(
+          syncer::PREFERENCES, sync_client_, ui_thread_));
     }
   }
 
   if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<AsyncDirectoryTypeController>(
-            syncer::PRIORITY_PREFERENCES, error_callback, sync_client_,
-            syncer::GROUP_UI, ui_thread_));
+    controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
+        syncer::PRIORITY_PREFERENCES, error_callback, sync_client_,
+        syncer::GROUP_UI, ui_thread_));
   }
 
   // Article sync is disabled by default.  Register only if explicitly enabled.
   if (dom_distiller::IsEnableSyncArticlesSet()) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<AsyncDirectoryTypeController>(
-            syncer::ARTICLES, error_callback, sync_client_, syncer::GROUP_UI,
-            ui_thread_));
+    controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
+        syncer::ARTICLES, error_callback, sync_client_, syncer::GROUP_UI,
+        ui_thread_));
   }
 
 #if defined(OS_CHROMEOS)
   if (!disabled_types.Has(syncer::PRINTERS)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ModelTypeController>(syncer::PRINTERS, sync_client_,
-                                              ui_thread_));
+    controllers.push_back(std::make_unique<ModelTypeController>(
+        syncer::PRINTERS, sync_client_, ui_thread_));
   }
 #endif
 
@@ -285,17 +246,17 @@
   // Reading List or Reading List Sync is explicitly disabled.
   if (!disabled_types.Has(syncer::READING_LIST) &&
       reading_list::switches::IsReadingListEnabled()) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ModelTypeController>(syncer::READING_LIST,
-                                              sync_client_, ui_thread_));
+    controllers.push_back(std::make_unique<ModelTypeController>(
+        syncer::READING_LIST, sync_client_, ui_thread_));
   }
 
   if (!disabled_types.Has(syncer::USER_EVENTS) &&
       FeatureList::IsEnabled(switches::kSyncUserEvents)) {
-    sync_service->RegisterDataTypeController(
-        std::make_unique<ModelTypeController>(syncer::USER_EVENTS, sync_client_,
-                                              ui_thread_));
+    controllers.push_back(std::make_unique<ModelTypeController>(
+        syncer::USER_EVENTS, sync_client_, ui_thread_));
   }
+
+  return controllers;
 }
 
 std::unique_ptr<DataTypeManager>
@@ -330,24 +291,26 @@
 
 syncer::SyncApiComponentFactory::SyncComponents
 ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
-    syncer::SyncService* sync_service,
     std::unique_ptr<syncer::DataTypeErrorHandler> error_handler) {
-  BookmarkModel* bookmark_model =
-      sync_service->GetSyncClient()->GetBookmarkModel();
-  syncer::UserShare* user_share = sync_service->GetUserShare();
+  BookmarkModel* bookmark_model = sync_client_->GetBookmarkModel();
+  syncer::UserShare* user_share =
+      sync_client_->GetSyncService()->GetUserShare();
 // TODO(akalin): We may want to propagate this switch up eventually.
 #if defined(OS_ANDROID) || defined(OS_IOS)
   const bool kExpectMobileBookmarksFolder = true;
 #else
   const bool kExpectMobileBookmarksFolder = false;
 #endif
-  BookmarkModelAssociator* model_associator = new BookmarkModelAssociator(
-      bookmark_model, sync_service->GetSyncClient(), user_share,
-      error_handler->Copy(), kExpectMobileBookmarksFolder);
-  BookmarkChangeProcessor* change_processor =
-      new BookmarkChangeProcessor(sync_service->GetSyncClient(),
-                                  model_associator, std::move(error_handler));
-  return SyncComponents(model_associator, change_processor);
+
+  auto model_associator = std::make_unique<BookmarkModelAssociator>(
+      bookmark_model, sync_client_, user_share, error_handler->Copy(),
+      kExpectMobileBookmarksFolder);
+
+  SyncComponents components;
+  components.change_processor = std::make_unique<BookmarkChangeProcessor>(
+      sync_client_, model_associator.get(), std::move(error_handler));
+  components.model_associator = std::move(model_associator);
+  return components;
 }
 
 // static
diff --git a/components/browser_sync/profile_sync_components_factory_impl.h b/components/browser_sync/profile_sync_components_factory_impl.h
index 3d27b5ec..acac43bb6 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.h
+++ b/components/browser_sync/profile_sync_components_factory_impl.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <string>
 
-#include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -16,6 +15,10 @@
 #include "components/sync/driver/sync_api_component_factory.h"
 #include "components/version_info/version_info.h"
 
+namespace syncer {
+class SyncClient;
+}
+
 namespace autofill {
 class AutofillWebDataService;
 }
@@ -34,7 +37,6 @@
       version_info::Channel channel,
       const std::string& version,
       bool is_tablet,
-      const base::CommandLine& command_line,
       const char* history_disabled_pref,
       const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
       const scoped_refptr<base::SingleThreadTaskRunner>& db_thread,
@@ -43,9 +45,9 @@
   ~ProfileSyncComponentsFactoryImpl() override;
 
   // SyncApiComponentFactory implementation:
-  void RegisterDataTypes(
-      syncer::SyncService* sync_service,
-      const RegisterDataTypesMethod& register_platform_types_method) override;
+  syncer::DataTypeController::TypeVector CreateCommonDataTypeControllers(
+      syncer::ModelTypeSet disabled_types,
+      syncer::LocalDeviceInfoProvider* local_device_info_provider) override;
   std::unique_ptr<syncer::DataTypeManager> CreateDataTypeManager(
       syncer::ModelTypeSet initial_types,
       const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
@@ -62,7 +64,6 @@
   std::unique_ptr<syncer::LocalDeviceInfoProvider>
   CreateLocalDeviceInfoProvider() override;
   syncer::SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents(
-      syncer::SyncService* sync_service,
       std::unique_ptr<syncer::DataTypeErrorHandler> error_handler) override;
 
   // Sets a bit that determines whether PREFERENCES should be registered with a
@@ -70,18 +71,11 @@
   static void OverridePrefsForUssTest(bool use_uss);
 
  private:
-  // Register data types which are enabled on both desktop and mobile.
-  // |disabled_types| corresponds only to those types being explicitly disabled
-  // by the command line.
-  void RegisterCommonDataTypes(syncer::SyncService* sync_service,
-                               syncer::ModelTypeSet disabled_types);
-
   // Client/platform specific members.
   syncer::SyncClient* const sync_client_;
   const version_info::Channel channel_;
   const std::string version_;
   const bool is_tablet_;
-  const base::CommandLine command_line_;
   const char* history_disabled_pref_;
   const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
   const scoped_refptr<base::SingleThreadTaskRunner> db_thread_;
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 4d50335..93cbffb 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -135,6 +135,18 @@
   return factory_switches;
 }
 
+DataTypeController::TypeMap BuildDataTypeControllerMap(
+    DataTypeController::TypeVector controllers) {
+  DataTypeController::TypeMap type_map;
+  for (std::unique_ptr<DataTypeController>& controller : controllers) {
+    DCHECK(controller);
+    ModelType type = controller->type();
+    DCHECK_EQ(0U, type_map.count(type));
+    type_map[type] = std::move(controller);
+  }
+  return type_map;
+}
+
 }  // namespace
 
 ProfileSyncService::InitParams::InitParams() = default;
@@ -226,6 +238,7 @@
                           weak_factory_.GetWeakPtr()));
   local_device_ = sync_client_->GetSyncApiComponentFactory()
                       ->CreateLocalDeviceInfoProvider();
+  DCHECK(local_device_);
   sync_stopped_reporter_ = std::make_unique<syncer::SyncStoppedReporter>(
       sync_service_url_, local_device_->GetSyncUserAgent(),
       url_request_context_, syncer::SyncStoppedReporter::ResultCallback());
@@ -256,11 +269,8 @@
           /*dump_stack=*/base::BindRepeating(&syncer::ReportUnrecoverableError,
                                              channel_)));
 
-  syncer::SyncApiComponentFactory::RegisterDataTypesMethod
-      register_platform_types_callback =
-          sync_client_->GetRegisterPlatformTypesCallback();
-  sync_client_->GetSyncApiComponentFactory()->RegisterDataTypes(
-      this, register_platform_types_callback);
+  data_type_controllers_ = BuildDataTypeControllerMap(
+      sync_client_->CreateDataTypeControllers(local_device_.get()));
 
   if (gaia_cookie_manager_service_)
     gaia_cookie_manager_service_->AddObserver(this);
@@ -356,14 +366,6 @@
     engine_->StartSyncingWithServer();
 }
 
-void ProfileSyncService::RegisterDataTypeController(
-    std::unique_ptr<DataTypeController> data_type_controller) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U);
-  data_type_controllers_[data_type_controller->type()] =
-      std::move(data_type_controller);
-}
-
 bool ProfileSyncService::IsDataTypeControllerRunning(
     syncer::ModelType type) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h
index 34a1eeaa..5e232b4 100644
--- a/components/browser_sync/profile_sync_service.h
+++ b/components/browser_sync/profile_sync_service.h
@@ -94,9 +94,6 @@
 //      never be shown for an unregistered type, and nor should it ever be
 //      synced.
 //
-//      A datatype is considered registered once RegisterDataTypeController
-//      has been called with that datatype's DataTypeController.
-//
 //   'Preferred' (user preferences and opt-out for a datatype)
 //
 //      This means the user's opt-in or opt-out preference on a per-datatype
@@ -274,8 +271,6 @@
       const syncer::BaseTransaction* trans) const override;
   syncer::UserShare* GetUserShare() const override;
   syncer::LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const override;
-  void RegisterDataTypeController(std::unique_ptr<syncer::DataTypeController>
-                                      data_type_controller) override;
   void ReenableDatatype(syncer::ModelType type) override;
   syncer::SyncTokenStatus GetSyncTokenStatus() const override;
   std::string QuerySyncStatusSummaryString() override;
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc
index c33feb4..dabd543 100644
--- a/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -415,6 +415,16 @@
     CreateSyncService(std::move(sync_client_owned_), std::move(callback));
 
     EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
+                CreateCommonDataTypeControllers(_, _))
+        .WillOnce(testing::InvokeWithoutArgs([=]() {
+          syncer::DataTypeController::TypeVector controllers;
+          controllers.push_back(
+              std::make_unique<AutofillProfileDataTypeController>(
+                  data_type_thread()->task_runner(), base::DoNothing(),
+                  sync_client_, web_data_service_));
+          return controllers;
+        }));
+    EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
                 CreateDataTypeManager(_, _, _, _, _, _))
         .WillOnce(ReturnNewDataTypeManagerWithDebugListener(
             sync_client_,
@@ -423,10 +433,6 @@
     EXPECT_CALL(personal_data_manager(), IsDataLoaded())
         .WillRepeatedly(Return(true));
 
-    sync_service()->RegisterDataTypeController(
-        std::make_unique<AutofillProfileDataTypeController>(
-            data_type_thread()->task_runner(), base::DoNothing(), sync_client_,
-            web_data_service_));
     sync_service()->Initialize();
     base::RunLoop().Run();
 
diff --git a/components/browser_sync/profile_sync_service_startup_unittest.cc b/components/browser_sync/profile_sync_service_startup_unittest.cc
index 83c1c9b9..1b151d0 100644
--- a/components/browser_sync/profile_sync_service_startup_unittest.cc
+++ b/components/browser_sync/profile_sync_service_startup_unittest.cc
@@ -92,10 +92,17 @@
         profile_sync_service_bundle_.CreateBasicInitParams(start_behavior,
                                                            builder.Build());
 
+    ON_CALL(*component_factory_, CreateCommonDataTypeControllers(_, _))
+        .WillByDefault(testing::InvokeWithoutArgs([=]() {
+          syncer::DataTypeController::TypeVector controllers;
+          controllers.push_back(
+              std::make_unique<syncer::FakeDataTypeController>(
+                  syncer::BOOKMARKS));
+          return controllers;
+        }));
+
     sync_service_ =
         std::make_unique<ProfileSyncService>(std::move(init_params));
-    sync_service_->RegisterDataTypeController(
-        std::make_unique<syncer::FakeDataTypeController>(syncer::BOOKMARKS));
     sync_service_->AddObserver(&observer_);
   }
 
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc
index 989b8b7c..d8f5ec0 100644
--- a/components/browser_sync/profile_sync_service_unittest.cc
+++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -18,7 +18,6 @@
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/fake_signin_manager.h"
 #include "components/sync/base/pref_names.h"
-#include "components/sync/device_info/local_device_info_provider.h"
 #include "components/sync/driver/fake_data_type_controller.h"
 #include "components/sync/driver/signin_manager_wrapper.h"
 #include "components/sync/driver/sync_api_component_factory_mock.h"
@@ -198,9 +197,15 @@
         syncer::ModelTypeStoreTestUtil::FactoryForInMemoryStoreForTest();
 
     service_ = std::make_unique<ProfileSyncService>(std::move(init_params));
-    service_->RegisterDataTypeController(
-        std::make_unique<syncer::FakeDataTypeController>(syncer::BOOKMARKS));
 
+    ON_CALL(*component_factory_, CreateCommonDataTypeControllers(_, _))
+        .WillByDefault(testing::InvokeWithoutArgs([=]() {
+          syncer::DataTypeController::TypeVector controllers;
+          controllers.push_back(
+              std::make_unique<syncer::FakeDataTypeController>(
+                  syncer::BOOKMARKS));
+          return controllers;
+        }));
     ON_CALL(*component_factory_, CreateSyncEngine(_, _, _, _))
         .WillByDefault(ReturnNewFakeSyncEngine());
     ON_CALL(*component_factory_, CreateDataTypeManager(_, _, _, _, _, _))
@@ -222,9 +227,15 @@
     init_params.signin_wrapper.reset();
 
     service_ = std::make_unique<ProfileSyncService>(std::move(init_params));
-    service_->RegisterDataTypeController(
-        std::make_unique<syncer::FakeDataTypeController>(syncer::BOOKMARKS));
 
+    ON_CALL(*component_factory_, CreateCommonDataTypeControllers(_, _))
+        .WillByDefault(testing::InvokeWithoutArgs([=]() {
+          syncer::DataTypeController::TypeVector controllers;
+          controllers.push_back(
+              std::make_unique<syncer::FakeDataTypeController>(
+                  syncer::BOOKMARKS));
+          return controllers;
+        }));
     ON_CALL(*component_factory_, CreateSyncEngine(_, _, _, _))
         .WillByDefault(ReturnNewFakeSyncEngine());
     ON_CALL(*component_factory_, CreateDataTypeManager(_, _, _, _, _, _))
@@ -1175,19 +1186,48 @@
       /*has_remaining_local_changes=*/false));
 }
 
-// The OpenTabsUIDelegate should only be accessable when PROXY_TABS is enabled.
-TEST_F(ProfileSyncServiceTest, GetOpenTabsUIDelegate) {
+// The OpenTabsUIDelegate should not be accessible when PROXY_TABS is not
+// enabled.
+TEST_F(ProfileSyncServiceTest, GetOpenTabsUIDelegateNullIfDisabled) {
   CreateService(ProfileSyncService::AUTO_START);
+
+  ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _))
+      .WillByDefault(testing::InvokeWithoutArgs([=]() {
+        auto controller =
+            std::make_unique<syncer::FakeDataTypeController>(syncer::SESSIONS);
+        // Progress the controller to RUNNING first, which is how the
+        // service determines whether a type is enabled.
+        controller->StartAssociating(base::DoNothing());
+        controller->FinishStart(syncer::DataTypeController::OK_FIRST_RUN);
+
+        syncer::DataTypeController::TypeVector controllers;
+        controllers.push_back(std::move(controller));
+        return controllers;
+      }));
+
   InitializeForNthSync();
   EXPECT_EQ(nullptr, service()->GetOpenTabsUIDelegate());
+}
 
-  auto controller =
-      std::make_unique<syncer::FakeDataTypeController>(syncer::PROXY_TABS);
-  // Progress the controller to RUNNING first, which is how the service
-  // determines whether a type is enabled.
-  controller->StartAssociating(base::DoNothing());
-  controller->FinishStart(syncer::DataTypeController::OK_FIRST_RUN);
-  service()->RegisterDataTypeController(std::move(controller));
+// The OpenTabsUIDelegate should be accessible when PROXY_TABS is enabled.
+TEST_F(ProfileSyncServiceTest, GetOpenTabsUIDelegateNotNullIfEnabled) {
+  CreateService(ProfileSyncService::AUTO_START);
+
+  ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _))
+      .WillByDefault(testing::InvokeWithoutArgs([=]() {
+        auto controller = std::make_unique<syncer::FakeDataTypeController>(
+            syncer::PROXY_TABS);
+        // Progress the controller to RUNNING first, which is how the
+        // service determines whether a type is enabled.
+        controller->StartAssociating(base::DoNothing());
+        controller->FinishStart(syncer::DataTypeController::OK_FIRST_RUN);
+
+        syncer::DataTypeController::TypeVector controllers;
+        controllers.push_back(std::move(controller));
+        return controllers;
+      }));
+
+  InitializeForNthSync();
   EXPECT_NE(nullptr, service()->GetOpenTabsUIDelegate());
 }
 
diff --git a/components/browser_sync/profile_sync_test_util.h b/components/browser_sync/profile_sync_test_util.h
index a576c343..a957396 100644
--- a/components/browser_sync/profile_sync_test_util.h
+++ b/components/browser_sync/profile_sync_test_util.h
@@ -164,7 +164,7 @@
   FakeSigninManagerType signin_manager_;
   FakeProfileOAuth2TokenService auth_service_;
   identity::IdentityManager identity_manager_;
-  syncer::SyncApiComponentFactoryMock component_factory_;
+  testing::NiceMock<syncer::SyncApiComponentFactoryMock> component_factory_;
   testing::NiceMock<sync_sessions::MockSyncSessionsClient>
       sync_sessions_client_;
   invalidation::FakeInvalidationService fake_invalidation_service_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 4d12e6c6..75bc7d52 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -24,6 +24,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
+#include "base/task_scheduler/lazy_task_runner.h"
 #include "base/time/default_tick_clock.h"
 #include "build/build_config.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
@@ -59,6 +60,17 @@
 
 namespace {
 
+#if defined(OS_CHROMEOS)
+// SequencedTaskRunner to get the network id. A SequencedTaskRunner is used
+// rather than parallel tasks to avoid having many threads getting the network
+// id concurrently.
+base::LazySequencedTaskRunner g_get_network_id_task_runner =
+    LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER(
+        base::TaskTraits(base::MayBlock(),
+                         base::TaskPriority::BACKGROUND,
+                         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
+#endif
+
 // Values of the UMA DataReductionProxy.Protocol.NotAcceptingTransform histogram
 // defined in metrics/histograms/histograms.xml. This enum must remain
 // synchronized with DataReductionProxyProtocolNotAcceptingTransformReason in
@@ -619,16 +631,18 @@
   connection_type_ = type;
   RecordNetworkChangeEvent(NETWORK_CHANGED);
 
-  if (!get_network_id_task_runner_) {
-    ContinueNetworkChanged(GetCurrentNetworkID());
+#if defined(OS_CHROMEOS)
+  if (get_network_id_asynchronously_) {
+    base::PostTaskAndReplyWithResult(
+        g_get_network_id_task_runner.Get().get(), FROM_HERE,
+        base::BindOnce(&DoGetCurrentNetworkID),
+        base::BindOnce(&DataReductionProxyConfig::ContinueNetworkChanged,
+                       weak_factory_.GetWeakPtr()));
     return;
   }
+#endif  // defined(OS_CHROMEOS)
 
-  base::PostTaskAndReplyWithResult(
-      get_network_id_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&DoGetCurrentNetworkID),
-      base::BindOnce(&DataReductionProxyConfig::ContinueNetworkChanged,
-                     weak_factory_.GetWeakPtr()));
+  ContinueNetworkChanged(GetCurrentNetworkID());
 }
 
 void DataReductionProxyConfig::ContinueNetworkChanged(
@@ -835,4 +849,10 @@
                         warmup_url_fetch_in_flight_core_proxy_);
 }
 
+#if defined(OS_CHROMEOS)
+void DataReductionProxyConfig::EnableGetNetworkIdAsynchronously() {
+  get_network_id_asynchronously_ = true;
+}
+#endif  // defined(OS_CHROMEOS)
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 46ad672..91efe18a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -19,6 +19,7 @@
 #include "base/optional.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "components/data_reduction_proxy/core/browser/secure_proxy_checker.h"
 #include "components/data_reduction_proxy/core/browser/warmup_url_fetcher.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
@@ -192,10 +193,14 @@
       std::pair<bool /* is_secure_proxy */, bool /*is_core_proxy */>>
   GetInFlightWarmupProxyDetails() const;
 
-  void set_get_network_id_task_runner(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-    get_network_id_task_runner_ = task_runner;
-  }
+#if defined(OS_CHROMEOS)
+  // Enables getting the network id asynchronously when
+  // GatherEstimatesForNextConnectionType(). This should always be called in
+  // production, because getting the network id involves a blocking call to
+  // recv() in AddressTrackerLinux, and the IO thread should never be blocked.
+  // TODO(https://crbug.com/821607): Remove after the bug is resolved.
+  void EnableGetNetworkIdAsynchronously();
+#endif  // defined(OS_CHROMEOS)
 
  protected:
   virtual base::TimeTicks GetTicksNow() const;
@@ -264,7 +269,7 @@
       net::NetworkChangeNotifier::ConnectionType type) override;
 
   // Invoked to continue network changed handling after the network id is
-  // retrieved. If |get_network_id_task_runner_| is set, the network id is
+  // retrieved. If |get_network_id_asynchronously_| is set, the network id is
   // fetched on the worker thread. Otherwise, OnNetworkChanged calls this
   // directly. This is a workaround for https://crbug.com/821607 where
   // net::GetWifiSSID() call gets stuck.
@@ -327,8 +332,10 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
 
-  // Optional task runner for GetCurrentNetworkID.
-  scoped_refptr<base::SingleThreadTaskRunner> get_network_id_task_runner_;
+#if defined(OS_CHROMEOS)
+  // Whether the network id should be obtained on a worker thread.
+  bool get_network_id_asynchronously_ = false;
+#endif
 
   // The caller must ensure that the |net_log_|, if set, outlives this instance.
   // It is used to create new instances of |net_log_with_source_| on secure
diff --git a/components/download/database/BUILD.gn b/components/download/database/BUILD.gn
index 73d775e..0163be2 100644
--- a/components/download/database/BUILD.gn
+++ b/components/download/database/BUILD.gn
@@ -18,7 +18,6 @@
     "download_db_impl.h",
     "download_info.cc",
     "download_info.h",
-    "download_namespace.cc",
     "download_namespace.h",
     "in_progress/download_entry.cc",
     "in_progress/download_entry.h",
@@ -29,8 +28,6 @@
     "in_progress/in_progress_info.h",
     "in_progress/ukm_info.cc",
     "in_progress/ukm_info.h",
-    "switches.cc",
-    "switches.h",
   ]
 
   deps = [
diff --git a/components/download/database/download_db_conversions.cc b/components/download/database/download_db_conversions.cc
index 17c2d6c..2d3382e 100644
--- a/components/download/database/download_db_conversions.cc
+++ b/components/download/database/download_db_conversions.cc
@@ -145,10 +145,7 @@
   download_pb::InProgressInfo proto;
   for (size_t i = 0; i < in_progress_info.url_chain.size(); ++i)
     proto.add_url_chain(in_progress_info.url_chain[i].spec());
-  proto.set_referrer_url(in_progress_info.referrer_url.spec());
   proto.set_site_url(in_progress_info.site_url.spec());
-  proto.set_tab_url(in_progress_info.tab_url.spec());
-  proto.set_tab_referrer_url(in_progress_info.tab_referrer_url.spec());
   proto.set_fetch_error_body(in_progress_info.fetch_error_body);
   for (const auto& header : in_progress_info.request_headers) {
     auto* proto_header = proto.add_request_headers();
@@ -156,8 +153,6 @@
   }
   proto.set_etag(in_progress_info.etag);
   proto.set_last_modified(in_progress_info.last_modified);
-  proto.set_mime_type(in_progress_info.mime_type);
-  proto.set_original_mime_type(in_progress_info.original_mime_type);
   proto.set_total_bytes(in_progress_info.total_bytes);
   base::Pickle current_path;
   in_progress_info.current_path.WriteToPickle(&current_path);
@@ -166,15 +161,8 @@
   in_progress_info.target_path.WriteToPickle(&target_path);
   proto.set_target_path(target_path.data(), target_path.size());
   proto.set_received_bytes(in_progress_info.received_bytes);
-  proto.set_start_time(
-      in_progress_info.start_time.is_null()
-          ? -1
-          : in_progress_info.start_time.ToDeltaSinceWindowsEpoch()
-                .InMilliseconds());
-  proto.set_end_time(in_progress_info.end_time.is_null()
-                         ? -1
-                         : in_progress_info.end_time.ToDeltaSinceWindowsEpoch()
-                               .InMilliseconds());
+  proto.set_end_time(
+      in_progress_info.end_time.ToDeltaSinceWindowsEpoch().InMilliseconds());
   for (size_t i = 0; i < in_progress_info.received_slices.size(); ++i) {
     download_pb::ReceivedSlice* slice = proto.add_received_slices();
     slice->set_received_bytes(
@@ -199,17 +187,12 @@
   InProgressInfo info;
   for (const auto& url : proto.url_chain())
     info.url_chain.emplace_back(url);
-  info.referrer_url = GURL(proto.referrer_url());
   info.site_url = GURL(proto.site_url());
-  info.tab_url = GURL(proto.tab_url());
-  info.tab_referrer_url = GURL(proto.tab_referrer_url());
   info.fetch_error_body = proto.fetch_error_body();
   for (const auto& header : proto.request_headers())
     info.request_headers.emplace_back(HttpRequestHeaderFromProto(header));
   info.etag = proto.etag();
   info.last_modified = proto.last_modified();
-  info.mime_type = proto.mime_type();
-  info.original_mime_type = proto.original_mime_type();
   info.total_bytes = proto.total_bytes();
   base::PickleIterator current_path(
       base::Pickle(proto.current_path().data(), proto.current_path().size()));
@@ -218,16 +201,8 @@
       base::Pickle(proto.target_path().data(), proto.target_path().size()));
   info.target_path.ReadFromPickle(&target_path);
   info.received_bytes = proto.received_bytes();
-  info.start_time =
-      proto.start_time() == -1
-          ? base::Time()
-          : base::Time::FromDeltaSinceWindowsEpoch(
-                base::TimeDelta::FromMilliseconds(proto.start_time()));
-  info.end_time =
-      proto.end_time() == -1
-          ? base::Time()
-          : base::Time::FromDeltaSinceWindowsEpoch(
-                base::TimeDelta::FromMilliseconds(proto.end_time()));
+  info.end_time = base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromMilliseconds(proto.end_time()));
 
   for (int i = 0; i < proto.received_slices_size(); ++i) {
     info.received_slices.emplace_back(proto.received_slices(i).offset(),
@@ -266,7 +241,6 @@
     const download_pb::DownloadInfo& proto) {
   DownloadInfo info;
   info.guid = proto.guid();
-  info.id = proto.id();
   if (proto.has_ukm_info())
     info.ukm_info = UkmInfoFromProto(proto.ukm_info());
   if (proto.has_in_progress_info())
@@ -278,7 +252,6 @@
     const DownloadInfo& info) {
   download_pb::DownloadInfo proto;
   proto.set_guid(info.guid);
-  proto.set_id(info.id);
   if (info.ukm_info.has_value()) {
     auto ukm_info = std::make_unique<download_pb::UkmInfo>(
         UkmInfoToProto(info.ukm_info.value()));
diff --git a/components/download/database/download_db_conversions_unittest.cc b/components/download/database/download_db_conversions_unittest.cc
index b82cd5e..80d6333 100644
--- a/components/download/database/download_db_conversions_unittest.cc
+++ b/components/download/database/download_db_conversions_unittest.cc
@@ -18,17 +18,11 @@
   info.target_path = base::FilePath(FILE_PATH_LITERAL("/tmp"));
   info.url_chain.emplace_back("http://foo");
   info.url_chain.emplace_back("http://foo2");
-  info.referrer_url = GURL("http://foo1.com");
   info.site_url = GURL("http://foo.com");
-  info.tab_url = GURL("http://foo.com");
-  info.tab_referrer_url = GURL("http://abc.com");
-  info.start_time = base::Time::NowFromSystemTime().LocalMidnight();
-  info.end_time = base::Time();
+  info.end_time = base::Time::NowFromSystemTime().LocalMidnight();
   info.etag = "A";
   info.last_modified = "Wed, 1 Oct 2018 07:00:00 GMT";
   info.received_bytes = 1000;
-  info.mime_type = "text/html";
-  info.original_mime_type = "text/html";
   info.total_bytes = 10000;
   info.state = DownloadItem::IN_PROGRESS;
   info.danger_type = DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
@@ -50,8 +44,6 @@
 
 DownloadInfo CreateDownloadInfo() {
   DownloadInfo info;
-  info.guid = "abcdefg";
-  info.id = 1234567;
   info.in_progress_info = CreateInProgressInfo();
   info.ukm_info = UkmInfo(DownloadSource::FROM_RENDERER, 100);
   return info;
diff --git a/components/download/database/download_db_entry.cc b/components/download/database/download_db_entry.cc
index 2a67927..702fdd7 100644
--- a/components/download/database/download_db_entry.cc
+++ b/components/download/database/download_db_entry.cc
@@ -22,8 +22,4 @@
   return download_info->guid;
 }
 
-bool DownloadDBEntry::operator!=(const DownloadDBEntry& other) const {
-  return !(*this == other);
-}
-
 }  // namespace download
diff --git a/components/download/database/download_db_entry.h b/components/download/database/download_db_entry.h
index 84f6130..cbe4003e 100644
--- a/components/download/database/download_db_entry.h
+++ b/components/download/database/download_db_entry.h
@@ -21,7 +21,6 @@
   ~DownloadDBEntry();
 
   bool operator==(const DownloadDBEntry& other) const;
-  bool operator!=(const DownloadDBEntry& other) const;
 
   // Gets a unique ID for this entry.
   std::string GetGuid() const;
diff --git a/components/download/database/download_db_impl.cc b/components/download/database/download_db_impl.cc
index e66b9568..bd957c6 100644
--- a/components/download/database/download_db_impl.cc
+++ b/components/download/database/download_db_impl.cc
@@ -26,7 +26,7 @@
 
 // Returns the prefix to all keys in the database.
 std::string GetDatabaseKeyPrefix(DownloadNamespace download_namespace) {
-  return DownloadNamespaceToString(download_namespace) + ",";
+  return std::to_string(static_cast<int>(download_namespace)) + ",";
 }
 
 // Check if an input string is under a given namespace.
@@ -75,7 +75,6 @@
   db_->Init(kDatabaseClientName, database_dir_, options,
             base::BindOnce(&DownloadDBImpl::OnDatabaseInitialized,
                            weak_factory_.GetWeakPtr(), std::move(callback)));
-  // TODO(qinmin): migrate all the data from InProgressCache into this database.
 }
 
 void DownloadDBImpl::DestroyAndReinitialize(InitializeCallback callback) {
diff --git a/components/download/database/download_db_impl_unittest.cc b/components/download/database/download_db_impl_unittest.cc
index 6c35db9..f853ff8f 100644
--- a/components/download/database/download_db_impl_unittest.cc
+++ b/components/download/database/download_db_impl_unittest.cc
@@ -31,9 +31,7 @@
 }
 
 std::string GetKey(const std::string& guid) {
-  return DownloadNamespaceToString(
-             DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD) +
-         "," + guid;
+  return "1," + guid;
 }
 
 }  // namespace
@@ -67,7 +65,7 @@
     DownloadDBEntry second = CreateDownloadDBEntry();
     DownloadDBEntry third = CreateDownloadDBEntry();
     db_entries_.insert(
-        std::make_pair("unknown," + first.GetGuid(),
+        std::make_pair("0," + first.GetGuid(),
                        DownloadDBConversions::DownloadDBEntryToProto(first)));
     db_entries_.insert(
         std::make_pair(GetKey(second.GetGuid()),
diff --git a/components/download/database/download_info.cc b/components/download/database/download_info.cc
index fec67b4..e299ff3 100644
--- a/components/download/database/download_info.cc
+++ b/components/download/database/download_info.cc
@@ -13,7 +13,7 @@
 DownloadInfo::~DownloadInfo() = default;
 
 bool DownloadInfo::operator==(const DownloadInfo& other) const {
-  return guid == other.guid && id == other.id && ukm_info == other.ukm_info &&
+  return guid == other.guid && ukm_info == other.ukm_info &&
          in_progress_info == other.in_progress_info;
 }
 
diff --git a/components/download/database/download_info.h b/components/download/database/download_info.h
index 2f882819..fbc2855eb 100644
--- a/components/download/database/download_info.h
+++ b/components/download/database/download_info.h
@@ -25,10 +25,6 @@
   // Download GUID.
   std::string guid;
 
-  // Download ID.
-  // Deprecated, only kept for the purpose of download extension API.
-  int id;
-
   // UKM information for reporting.
   base::Optional<UkmInfo> ukm_info;
 
diff --git a/components/download/database/download_namespace.cc b/components/download/database/download_namespace.cc
deleted file mode 100644
index ac9554a..0000000
--- a/components/download/database/download_namespace.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/database/download_namespace.h"
-
-namespace download {
-
-namespace {
-const char kBrowserDownloadNamespace[] = "download";
-const char kUnknownNamespace[] = "unknown";
-}  // namespace
-
-std::string DownloadNamespaceToString(DownloadNamespace download_namespace) {
-  switch (download_namespace) {
-    case DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD:
-      return kBrowserDownloadNamespace;
-    default:
-      return kUnknownNamespace;
-  }
-}
-
-DownloadNamespace DownloadNamespaceFromString(
-    const std::string& namespace_string) {
-  if (namespace_string == kBrowserDownloadNamespace)
-    return DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD;
-  return DownloadNamespace::NAMESPACE_UNKNOWN;
-}
-
-}  // namespace download
diff --git a/components/download/database/download_namespace.h b/components/download/database/download_namespace.h
index 923f61e..23994aa 100644
--- a/components/download/database/download_namespace.h
+++ b/components/download/database/download_namespace.h
@@ -5,8 +5,6 @@
 #ifndef COMPONENTS_DOWNLOAD_DATABASE_DOWNLOAD_NAMESPACE_H_
 #define COMPONENTS_DOWNLOAD_DATABASE_DOWNLOAD_NAMESPACE_H_
 
-#include <string>
-
 namespace download {
 
 // The namespace of the download, used for classifying the download.
@@ -17,14 +15,6 @@
   NAMESPACE_BROWSER_DOWNLOAD,
 };
 
-// Converts a namespace to its string representation.
-std::string DownloadNamespaceToString(DownloadNamespace download_namespace);
-
-// Converts a string representation of a namespace to its namespace, or
-// NAMESPACE_UNKNOWN if the string doesn't map to one.
-DownloadNamespace DownloadNamespaceFromString(
-    const std::string& namespace_string);
-
 }  // namespace download
 
 #endif  // COMPONENTS_DOWNLOAD_DATABASE_DOWNLOAD_NAMESPACE_H_
diff --git a/components/download/database/in_progress/in_progress_info.cc b/components/download/database/in_progress/in_progress_info.cc
index 15f6dd4..f9ae76e7 100644
--- a/components/download/database/in_progress/in_progress_info.cc
+++ b/components/download/database/in_progress/in_progress_info.cc
@@ -14,17 +14,13 @@
 
 bool InProgressInfo::operator==(const InProgressInfo& other) const {
   return url_chain == other.url_chain && site_url == other.site_url &&
-         referrer_url == other.referrer_url && tab_url == other.tab_url &&
-         tab_referrer_url == other.tab_referrer_url &&
          fetch_error_body == other.fetch_error_body &&
          request_headers == other.request_headers && etag == other.etag &&
          last_modified == other.last_modified &&
-         total_bytes == other.total_bytes && mime_type == other.mime_type &&
-         original_mime_type == other.original_mime_type &&
+         total_bytes == other.total_bytes &&
          current_path == other.current_path &&
          target_path == other.target_path &&
-         received_bytes == other.received_bytes &&
-         start_time == other.start_time && end_time == other.end_time &&
+         received_bytes == other.received_bytes && end_time == other.end_time &&
          received_slices == other.received_slices && hash == other.hash &&
          transient == other.transient && state == other.state &&
          danger_type == other.danger_type &&
diff --git a/components/download/database/in_progress/in_progress_info.h b/components/download/database/in_progress/in_progress_info.h
index 4f62954..6c1488d 100644
--- a/components/download/database/in_progress/in_progress_info.h
+++ b/components/download/database/in_progress/in_progress_info.h
@@ -30,18 +30,9 @@
   // The url chain.
   std::vector<GURL> url_chain;
 
-  // Referrer url.
-  GURL referrer_url;
-
   // Site url.
   GURL site_url;
 
-  // Tab url.
-  GURL tab_url;
-
-  // Tab referrer url.
-  GURL tab_referrer_url;
-
   // If the entity body of unsuccessful HTTP response, like HTTP 404, will be
   // downloaded.
   bool fetch_error_body = false;
@@ -61,12 +52,6 @@
   // The total number of bytes in the download.
   int64_t total_bytes = 0;
 
-  // Mime type.
-  std::string mime_type;
-
-  // Original mime type before all redirections.
-  std::string original_mime_type;
-
   //  destination info  --------------------------------------------------------
 
   // The current path to the download (potentially different from final if
@@ -79,9 +64,6 @@
   // The number of bytes received (so far).
   int64_t received_bytes = 0;
 
-  // The time when the download started.
-  base::Time start_time;
-
   // The time when the download completed.
   base::Time end_time;
 
@@ -111,11 +93,14 @@
   // Whether this download is paused.
   bool paused = false;
 
-  // Count for how many (extra) bytes were used (including resumption).
-  int64_t bytes_wasted = 0;
-
   // Whether the download is initiated on a metered network
   bool metered = false;
+
+  // Represents the origin information for this download. Used by offline pages.
+  std::string request_origin;
+
+  // Count for how many (extra) bytes were used (including resumption).
+  int64_t bytes_wasted = 0;
 };
 
 }  // namespace download
diff --git a/components/download/database/proto/download_entry.proto b/components/download/database/proto/download_entry.proto
index 026c2aa..af4c4bf 100644
--- a/components/download/database/proto/download_entry.proto
+++ b/components/download/database/proto/download_entry.proto
@@ -47,31 +47,25 @@
 // Information about an in progress download.
 message InProgressInfo {
   repeated string url_chain = 1;
-  optional string referrer_url = 2;
-  optional string site_url = 3;
-  optional string tab_url = 4;
-  optional string tab_referrer_url = 5;
-  optional bool fetch_error_body = 6;
-  repeated HttpRequestHeader request_headers = 7;
-  optional string etag = 8;
-  optional string last_modified = 9;
-  optional int64 total_bytes = 10;
-  optional string mime_type = 11;
-  optional string original_mime_type = 12;
-  optional bytes current_path = 13;  // Serialized pickles to support string16
-  optional bytes target_path = 14;   // Serialized pickles to support string16
-  optional int64 received_bytes = 15;
-  optional int64 start_time = 16;
-  optional int64 end_time = 17;
-  repeated ReceivedSlice received_slices = 18;
-  optional string hash = 19;
-  optional bool transient = 20;
-  optional int32 state = 21;
-  optional int32 danger_type = 22;
-  optional int32 interrupt_reason = 23;
-  optional bool paused = 24;
-  optional bool metered = 25;
-  optional int64 bytes_wasted = 26;
+  optional string site_url = 2;
+  optional bool fetch_error_body = 3;
+  repeated HttpRequestHeader request_headers = 4;
+  optional string etag = 5;
+  optional string last_modified = 6;
+  optional int64 total_bytes = 7;
+  optional bytes current_path = 8;  // Serialized pickles to support string16
+  optional bytes target_path = 9;   // Serialized pickles to support string16
+  optional int64 received_bytes = 10;
+  optional int64 end_time = 11;
+  repeated ReceivedSlice received_slices = 12;
+  optional string hash = 13;
+  optional bool transient = 14;
+  optional int32 state = 15;
+  optional int32 danger_type = 16;
+  optional int32 interrupt_reason = 17;
+  optional bool paused = 18;
+  optional bool metered = 19;
+  optional int64 bytes_wasted = 20;
 }
 
 // Stores various metadata related to a download.
diff --git a/components/download/database/switches.cc b/components/download/database/switches.cc
deleted file mode 100644
index 66416607..0000000
--- a/components/download/database/switches.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/database/switches.h"
-
-namespace download {
-
-namespace switches {
-
-// Enables using the default search engine country to show country specific
-// popular sites on the NTP.
-const char kEnableDownloadDB[] = "enable-download-db";
-
-}  // namespace switches
-
-}  // namespace download
diff --git a/components/download/database/switches.h b/components/download/database/switches.h
deleted file mode 100644
index 14ce4bd..0000000
--- a/components/download/database/switches.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DOWNLOAD_DATABASE_SWITCHES_H_
-#define COMPONENTS_DOWNLOAD_DATABASE_SWITCHES_H_
-
-namespace download {
-
-namespace switches {
-
-// Enables the use of download database to store download metadata.
-extern const char kEnableDownloadDB[];
-
-}  // namespace switches
-
-}  // namespace download
-
-#endif  // COMPONENTS_DOWNLOAD_DATABASE_SWITCHES_H_
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn
index 7e0ffb3..292fe15 100644
--- a/components/download/internal/common/BUILD.gn
+++ b/components/download/internal/common/BUILD.gn
@@ -16,8 +16,6 @@
     "base_file.cc",
     "base_file_win.cc",
     "download_create_info.cc",
-    "download_db_cache.cc",
-    "download_db_cache.h",
     "download_file_factory.cc",
     "download_file_impl.cc",
     "download_interrupt_reasons_impl.cc",
@@ -59,7 +57,6 @@
     "//components/download/database",
     "//components/download/public/common:interfaces",
     "//components/download/quarantine",
-    "//components/leveldb_proto",
     "//mojo/public/c/system",
     "//net",
     "//services/metrics/public/cpp:ukm_builders",
@@ -93,7 +90,6 @@
   sources = [
     "base_file_unittest.cc",
     "base_file_win_unittest.cc",
-    "download_db_cache_unittest.cc",
     "download_file_unittest.cc",
     "download_item_impl_unittest.cc",
     "download_stats_unittest.cc",
@@ -106,10 +102,7 @@
   deps = [
     ":for_tests",
     "//base/test:test_support",
-    "//components/download/database",
     "//components/download/public/common:test_support",
-    "//components/leveldb_proto",
-    "//components/leveldb_proto:test_support",
     "//components/ukm:test_support",
     "//crypto",
     "//net",
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS
index 13ed39c8..a5df1ad 100644
--- a/components/download/internal/common/DEPS
+++ b/components/download/internal/common/DEPS
@@ -3,7 +3,6 @@
   "+components/download/downloader/in_progress",
   "+components/download/public/common",
   "+components/download/quarantine",
-  "+components/leveldb_proto",
   "+components/ukm/test_ukm_recorder.h",
   "+crypto",
   "+mojo/public/c/system",
diff --git a/components/download/internal/common/download_db_cache.cc b/components/download/internal/common/download_db_cache.cc
deleted file mode 100644
index ca3fbfb4..0000000
--- a/components/download/internal/common/download_db_cache.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/internal/common/download_db_cache.h"
-
-#include "components/download/database/download_db.h"
-#include "components/download/database/download_db_entry.h"
-#include "components/download/public/common/download_utils.h"
-
-namespace download {
-
-namespace {
-
-bool GetFetchErrorBody(base::Optional<DownloadDBEntry> entry) {
-  if (!entry)
-    return false;
-
-  if (!entry->download_info)
-    return false;
-
-  base::Optional<InProgressInfo>& in_progress_info =
-      entry->download_info->in_progress_info;
-  if (!in_progress_info)
-    return false;
-
-  return in_progress_info->fetch_error_body;
-}
-
-DownloadUrlParameters::RequestHeadersType GetRequestHeadersType(
-    base::Optional<DownloadDBEntry> entry) {
-  DownloadUrlParameters::RequestHeadersType ret;
-  if (!entry)
-    return ret;
-
-  if (!entry->download_info)
-    return ret;
-
-  base::Optional<InProgressInfo>& in_progress_info =
-      entry->download_info->in_progress_info;
-  if (!in_progress_info)
-    return ret;
-
-  return in_progress_info->request_headers;
-}
-
-DownloadSource GetDownloadSource(base::Optional<DownloadDBEntry> entry) {
-  if (!entry)
-    return DownloadSource::UNKNOWN;
-
-  if (!entry->download_info)
-    return DownloadSource::UNKNOWN;
-
-  base::Optional<UkmInfo>& ukm_info = entry->download_info->ukm_info;
-  if (!ukm_info)
-    return DownloadSource::UNKNOWN;
-
-  return ukm_info->download_source;
-}
-
-void CleanUpInProgressEntry(DownloadDBEntry& entry) {
-  if (!entry.download_info)
-    return;
-
-  base::Optional<InProgressInfo>& in_progress_info =
-      entry.download_info->in_progress_info;
-  if (!in_progress_info)
-    return;
-
-  if (in_progress_info->state == DownloadItem::DownloadState::IN_PROGRESS) {
-    in_progress_info->state = DownloadItem::DownloadState::INTERRUPTED;
-    in_progress_info->interrupt_reason =
-        download::DOWNLOAD_INTERRUPT_REASON_CRASH;
-  }
-}
-
-}  // namespace
-
-DownloadDBCache::DownloadDBCache(std::unique_ptr<DownloadDB> download_db)
-    : initialized_(false),
-      download_db_(std::move(download_db)),
-      weak_factory_(this) {}
-
-DownloadDBCache::~DownloadDBCache() = default;
-
-void DownloadDBCache::Initialize(InitializeCallback callback) {
-  // TODO(qinmin): migrate all the data from InProgressCache into
-  // |download_db_|.
-  if (!initialized_) {
-    download_db_->Initialize(
-        base::BindOnce(&DownloadDBCache::OnDownloadDBInitialized,
-                       weak_factory_.GetWeakPtr(), std::move(callback)));
-    return;
-  }
-
-  std::unique_ptr<std::vector<DownloadDBEntry>> entries;
-  for (auto it = entries_.begin(); it != entries_.end(); ++it) {
-    entries->emplace_back(it->second);
-  }
-  std::move(callback).Run(std::move(entries));
-}
-
-base::Optional<DownloadDBEntry> DownloadDBCache::RetrieveEntry(
-    const std::string& guid) {
-  auto iter = entries_.find(guid);
-  if (iter != entries_.end())
-    return iter->second;
-  return base::nullopt;
-}
-
-void DownloadDBCache::AddOrReplaceEntry(const DownloadDBEntry& entry) {
-  if (!entry.download_info)
-    return;
-  const std::string& guid = entry.download_info->guid;
-  base::Optional<DownloadDBEntry> current = RetrieveEntry(guid);
-  if (!current || entry != current.value()) {
-    entries_.emplace(guid, entry);
-    download_db_->AddOrReplace(entry);
-  }
-}
-
-void DownloadDBCache::OnDownloadUpdated(DownloadItem* download) {
-  // TODO(crbug.com/778425): Properly handle fail/resume/retry for downloads
-  // that are in the INTERRUPTED state for a long time.
-  if (!download_db_)
-    return;
-
-  base::Optional<DownloadDBEntry> current = RetrieveEntry(download->GetGuid());
-  bool fetch_error_body = GetFetchErrorBody(current);
-  DownloadUrlParameters::RequestHeadersType request_header_type =
-      GetRequestHeadersType(current);
-  DownloadSource download_source = GetDownloadSource(current);
-  switch (download->GetState()) {
-    case DownloadItem::DownloadState::INTERRUPTED:
-      FALLTHROUGH;
-    case DownloadItem::DownloadState::IN_PROGRESS:
-      FALLTHROUGH;
-    case DownloadItem::DownloadState::COMPLETE: {
-      DownloadDBEntry entry = CreateDownloadDBEntryFromItem(
-          *download, download_source, fetch_error_body, request_header_type);
-      AddOrReplaceEntry(entry);
-      break;
-    }
-    case DownloadItem::DownloadState::CANCELLED:
-      OnDownloadRemoved(download);
-      break;
-    default:
-      break;
-  }
-}
-
-void DownloadDBCache::OnDownloadRemoved(DownloadItem* download) {
-  entries_.erase(download->GetGuid());
-  if (download_db_)
-    download_db_->Remove(download->GetGuid());
-}
-
-void DownloadDBCache::OnDownloadDBInitialized(InitializeCallback callback,
-                                              bool success) {
-  if (success) {
-    download_db_->LoadEntries(
-        base::BindOnce(&DownloadDBCache::OnDownloadDBEntriesLoaded,
-                       weak_factory_.GetWeakPtr(), std::move(callback)));
-  }
-  // TODO(qinmin): Recreate the database if |success| is false.
-  // http://crbug.com/847661.
-}
-
-void DownloadDBCache::OnDownloadDBEntriesLoaded(
-    InitializeCallback callback,
-    bool success,
-    std::unique_ptr<std::vector<DownloadDBEntry>> entries) {
-  if (success) {
-    initialized_ = true;
-    for (auto entry : *entries) {
-      CleanUpInProgressEntry(entry);
-      entries_.emplace(entry.download_info->guid, entry);
-    }
-    std::move(callback).Run(std::move(entries));
-  }
-  // TODO(qinmin): Recreate the database if |success| is false.
-  // http://crbug.com/847661.
-}
-
-}  //  namespace download
diff --git a/components/download/internal/common/download_db_cache.h b/components/download/internal/common/download_db_cache.h
deleted file mode 100644
index 563ff660..0000000
--- a/components/download/internal/common/download_db_cache.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DOWNLOAD_INTERNAL_COMMON_DOWNLOAD_DB_CACHE_H_
-#define COMPONENTS_DOWNLOAD_INTERNAL_COMMON_DOWNLOAD_DB_CACHE_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "components/download/public/common/download_export.h"
-#include "components/download/public/common/download_item.h"
-
-namespace download {
-
-class DownloadDB;
-struct DownloadDBEntry;
-
-// Responsible for caching the metadata of all in progress downloads.
-class COMPONENTS_DOWNLOAD_EXPORT DownloadDBCache
-    : public DownloadItem::Observer {
- public:
-  explicit DownloadDBCache(std::unique_ptr<DownloadDB> download_db);
-  ~DownloadDBCache() override;
-
-  using InitializeCallback =
-      base::OnceCallback<void(std::unique_ptr<std::vector<DownloadDBEntry>>)>;
-  void Initialize(InitializeCallback callback);
-
-  base::Optional<DownloadDBEntry> RetrieveEntry(const std::string& guid);
-  void AddOrReplaceEntry(const DownloadDBEntry& entry);
-
- private:
-  friend class InProgressDownloadManager;
-
-  // DownloadItem::Observer
-  void OnDownloadUpdated(DownloadItem* download) override;
-  void OnDownloadRemoved(DownloadItem* download) override;
-
-  // Called when the |download_db_| is initialized.
-  void OnDownloadDBInitialized(InitializeCallback callback, bool success);
-
-  // Called when all the download db entries are loaded.
-  void OnDownloadDBEntriesLoaded(
-      InitializeCallback callback,
-      bool success,
-      std::unique_ptr<std::vector<DownloadDBEntry>> entries);
-
-  // Whether this object has already been initialized.
-  bool initialized_;
-
-  // Database for storing in-progress metadata.
-  std::unique_ptr<DownloadDB> download_db_;
-
-  using DownloadDBEntryMap = std::map<std::string, DownloadDBEntry>;
-  // All in progress downloads stored in |download_db_|.
-  DownloadDBEntryMap entries_;
-
-  base::WeakPtrFactory<DownloadDBCache> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DownloadDBCache);
-};
-
-}  //  namespace download
-
-#endif  // COMPONENTS_DOWNLOAD_INTERNAL_COMMON_DOWNLOAD_DB_CACHE_H_
diff --git a/components/download/internal/common/download_db_cache_unittest.cc b/components/download/internal/common/download_db_cache_unittest.cc
deleted file mode 100644
index f29db1d..0000000
--- a/components/download/internal/common/download_db_cache_unittest.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/internal/common/download_db_cache.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/guid.h"
-#include "components/download/database/download_db_conversions.h"
-#include "components/download/database/download_db_entry.h"
-#include "components/download/database/download_db_impl.h"
-#include "components/leveldb_proto/testing/fake_db.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-
-namespace download {
-
-namespace {
-
-DownloadDBEntry CreateDownloadDBEntry() {
-  DownloadDBEntry entry;
-  DownloadInfo download_info;
-  download_info.guid = base::GenerateGUID();
-  entry.download_info = download_info;
-  return entry;
-}
-
-std::string GetKey(const std::string& guid) {
-  return DownloadNamespaceToString(
-             DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD) +
-         "," + guid;
-}
-
-}  // namespace
-
-class DownloadDBCacheTest : public testing::Test {
- public:
-  DownloadDBCacheTest() : db_(nullptr) {}
-
-  ~DownloadDBCacheTest() override = default;
-
-  void CreateDBCache() {
-    auto db = std::make_unique<
-        leveldb_proto::test::FakeDB<download_pb::DownloadDBEntry>>(
-        &db_entries_);
-    db_ = db.get();
-    auto download_db = std::make_unique<DownloadDBImpl>(
-        DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD,
-        base::FilePath(FILE_PATH_LITERAL("/test/db/fakepath")), std::move(db));
-    db_cache_ = std::make_unique<DownloadDBCache>(std::move(download_db));
-  }
-
-  void InitCallback(std::vector<DownloadDBEntry>* loaded_entries,
-                    std::unique_ptr<std::vector<DownloadDBEntry>> entries) {
-    loaded_entries->swap(*entries);
-  }
-
-  void PrepopulateSampleEntries() {
-    DownloadDBEntry first = CreateDownloadDBEntry();
-    DownloadDBEntry second = CreateDownloadDBEntry();
-    DownloadDBEntry third = CreateDownloadDBEntry();
-    db_entries_.insert(
-        std::make_pair("unknown," + first.GetGuid(),
-                       DownloadDBConversions::DownloadDBEntryToProto(first)));
-    db_entries_.insert(
-        std::make_pair(GetKey(second.GetGuid()),
-                       DownloadDBConversions::DownloadDBEntryToProto(second)));
-    db_entries_.insert(
-        std::make_pair(GetKey(third.GetGuid()),
-                       DownloadDBConversions::DownloadDBEntryToProto(third)));
-  }
-
- protected:
-  std::map<std::string, download_pb::DownloadDBEntry> db_entries_;
-  leveldb_proto::test::FakeDB<download_pb::DownloadDBEntry>* db_;
-  std::unique_ptr<DownloadDBCache> db_cache_;
-  DISALLOW_COPY_AND_ASSIGN(DownloadDBCacheTest);
-};
-
-TEST_F(DownloadDBCacheTest, InitializeAndRetrieve) {
-  PrepopulateSampleEntries();
-  CreateDBCache();
-  std::vector<DownloadDBEntry> loaded_entries;
-  db_cache_->Initialize(base::BindOnce(&DownloadDBCacheTest::InitCallback,
-                                       base::Unretained(this),
-                                       &loaded_entries));
-  db_->InitCallback(true);
-  db_->LoadCallback(true);
-  ASSERT_EQ(loaded_entries.size(), 2u);
-
-  for (auto db_entry : loaded_entries) {
-    ASSERT_EQ(db_entry, db_cache_->RetrieveEntry(db_entry.GetGuid()));
-    ASSERT_EQ(db_entry,
-              DownloadDBConversions::DownloadDBEntryFromProto(
-                  db_entries_.find(GetKey(db_entry.GetGuid()))->second));
-  }
-}
-
-TEST_F(DownloadDBCacheTest, AddOrReplace) {
-  PrepopulateSampleEntries();
-  CreateDBCache();
-  std::vector<DownloadDBEntry> loaded_entries;
-  db_cache_->Initialize(base::BindOnce(&DownloadDBCacheTest::InitCallback,
-                                       base::Unretained(this),
-                                       &loaded_entries));
-  db_->InitCallback(true);
-  db_->LoadCallback(true);
-  ASSERT_EQ(loaded_entries.size(), 2u);
-
-  DownloadDBEntry new_entry = CreateDownloadDBEntry();
-  db_cache_->AddOrReplaceEntry(new_entry);
-  ASSERT_EQ(new_entry, db_cache_->RetrieveEntry(new_entry.GetGuid()));
-}
-
-}  // namespace download
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc
index efd6eef..cc9f500 100644
--- a/components/download/internal/common/download_utils.cc
+++ b/components/download/internal/common/download_utils.cc
@@ -359,67 +359,6 @@
                        GetUniqueDownloadId());
 }
 
-DownloadDBEntry CreateDownloadDBEntryFromItem(
-    const DownloadItem& item,
-    DownloadSource download_source,
-    bool fetch_error_body,
-    const DownloadUrlParameters::RequestHeadersType& request_headers) {
-  DownloadDBEntry entry;
-  DownloadInfo download_info;
-  download_info.guid = item.GetGuid();
-  download_info.id = item.GetId();
-  InProgressInfo in_progress_info;
-  in_progress_info.url_chain = item.GetUrlChain();
-  in_progress_info.referrer_url = item.GetReferrerUrl();
-  in_progress_info.site_url = item.GetSiteUrl();
-  in_progress_info.tab_url = item.GetTabUrl();
-  in_progress_info.tab_referrer_url = item.GetTabReferrerUrl();
-  in_progress_info.fetch_error_body = fetch_error_body;
-  in_progress_info.request_headers = request_headers;
-  in_progress_info.etag = item.GetETag();
-  in_progress_info.last_modified = item.GetLastModifiedTime();
-  in_progress_info.mime_type = item.GetMimeType();
-  in_progress_info.original_mime_type = item.GetOriginalMimeType();
-  in_progress_info.total_bytes = item.GetTotalBytes();
-  in_progress_info.current_path = item.GetFullPath();
-  in_progress_info.target_path = item.GetTargetFilePath();
-  in_progress_info.received_bytes = item.GetReceivedBytes();
-  in_progress_info.start_time = item.GetStartTime();
-  in_progress_info.end_time = item.GetEndTime();
-  in_progress_info.received_slices = item.GetReceivedSlices();
-  in_progress_info.hash = item.GetHash();
-  in_progress_info.transient = item.IsTransient();
-  in_progress_info.state = item.GetState();
-  in_progress_info.danger_type = item.GetDangerType();
-  in_progress_info.interrupt_reason = item.GetLastReason();
-  in_progress_info.paused = item.IsPaused();
-  in_progress_info.bytes_wasted = item.GetBytesWasted();
-
-  download_info.in_progress_info = in_progress_info;
-
-  UkmInfo ukm_info(download_source, GetUniqueDownloadId());
-  download_info.ukm_info = ukm_info;
-  entry.download_info = download_info;
-  return entry;
-}
-
-base::Optional<DownloadEntry> CreateDownloadEntryFromDownloadDBEntry(
-    base::Optional<DownloadDBEntry> entry) {
-  if (!entry || !entry->download_info)
-    return base::Optional<DownloadEntry>();
-
-  base::Optional<InProgressInfo> in_progress_info =
-      entry->download_info->in_progress_info;
-  base::Optional<UkmInfo> ukm_info = entry->download_info->ukm_info;
-  if (!ukm_info || !in_progress_info)
-    return base::Optional<DownloadEntry>();
-
-  return base::Optional<DownloadEntry>(DownloadEntry(
-      entry->download_info->guid, std::string(), ukm_info->download_source,
-      in_progress_info->fetch_error_body, in_progress_info->request_headers,
-      ukm_info->ukm_download_id));
-}
-
 uint64_t GetUniqueDownloadId() {
   // Get a new UKM download_id that is not 0.
   uint64_t download_id = 0;
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc
index 93bbc12..1436d4f 100644
--- a/components/download/internal/common/in_progress_download_manager.cc
+++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -4,16 +4,10 @@
 
 #include "components/download/public/common/in_progress_download_manager.h"
 
-#include "base/command_line.h"
 #include "base/optional.h"
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/download/database/download_db_entry.h"
-#include "components/download/database/download_db_impl.h"
-#include "components/download/database/download_namespace.h"
 #include "components/download/database/in_progress/in_progress_cache_impl.h"
-#include "components/download/database/switches.h"
-#include "components/download/internal/common/download_db_cache.h"
 #include "components/download/internal/common/resource_downloader.h"
 #include "components/download/public/common/download_file.h"
 #include "components/download/public/common/download_item_impl.h"
@@ -30,32 +24,6 @@
 
 namespace {
 
-std::unique_ptr<DownloadItemImpl> CreateDownloadItemImpl(
-    DownloadItemImplDelegate* delegate,
-    const DownloadDBEntry entry) {
-  if (!entry.download_info)
-    return nullptr;
-
-  base::Optional<InProgressInfo> in_progress_info =
-      entry.download_info->in_progress_info;
-  if (!in_progress_info)
-    return nullptr;
-
-  return std::make_unique<DownloadItemImpl>(
-      delegate, entry.download_info->guid, entry.download_info->id,
-      in_progress_info->current_path, in_progress_info->target_path,
-      in_progress_info->url_chain, in_progress_info->referrer_url,
-      in_progress_info->site_url, in_progress_info->tab_url,
-      in_progress_info->tab_referrer_url, in_progress_info->mime_type,
-      in_progress_info->original_mime_type, in_progress_info->start_time,
-      in_progress_info->end_time, in_progress_info->etag,
-      in_progress_info->last_modified, in_progress_info->received_bytes,
-      in_progress_info->total_bytes, in_progress_info->hash,
-      in_progress_info->state, in_progress_info->danger_type,
-      in_progress_info->interrupt_reason, false, base::Time(),
-      in_progress_info->transient, in_progress_info->received_slices);
-}
-
 void OnUrlDownloadHandlerCreated(
     UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader,
     base::WeakPtr<InProgressDownloadManager> download_manager,
@@ -269,26 +237,14 @@
 void InProgressDownloadManager::Initialize(
     const base::FilePath& metadata_cache_dir,
     base::OnceClosure callback) {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableDownloadDB)) {
-    // TODO(qinmin): migrate all the data from InProgressCache into
-    // |download_db_|.
-    download_db_cache_ =
-        std::make_unique<DownloadDBCache>(std::make_unique<DownloadDBImpl>(
-            DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD, metadata_cache_dir));
-    download_db_cache_->Initialize(
-        base::BindOnce(&InProgressDownloadManager::OnDownloadDBInitialized,
-                       weak_factory_.GetWeakPtr(), std::move(callback)));
-  } else {
-    download_metadata_cache_ = std::make_unique<InProgressCacheImpl>(
-        metadata_cache_dir.empty()
-            ? base::FilePath()
-            : metadata_cache_dir.Append(kDownloadMetadataStoreFilename),
-        base::CreateSequencedTaskRunnerWithTraits(
-            {base::MayBlock(), base::TaskPriority::BACKGROUND,
-             base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));
-    download_metadata_cache_->Initialize(std::move(callback));
-  }
+  download_metadata_cache_ = std::make_unique<InProgressCacheImpl>(
+      metadata_cache_dir.empty() ? base::FilePath() :
+          metadata_cache_dir.Append(kDownloadMetadataStoreFilename),
+      base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::BACKGROUND,
+           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));
+
+  download_metadata_cache_->Initialize(std::move(callback));
 }
 
 void InProgressDownloadManager::ShutDown() {
@@ -302,20 +258,13 @@
 
 base::Optional<DownloadEntry> InProgressDownloadManager::GetInProgressEntry(
     DownloadItemImpl* download) {
-  if (!download || !download_metadata_cache_ || !download_db_cache_)
+  if (!download || !download_metadata_cache_)
     return base::Optional<DownloadEntry>();
 
-  if (download_metadata_cache_)
-    return download_metadata_cache_->RetrieveEntry(download->GetGuid());
-
-  return CreateDownloadEntryFromDownloadDBEntry(
-      download_db_cache_->RetrieveEntry(download->GetGuid()));
+  return download_metadata_cache_->RetrieveEntry(download->GetGuid());
 }
 
 void InProgressDownloadManager::ReportBytesWasted(DownloadItemImpl* download) {
-  if (download_db_cache_)
-    download_db_cache_->OnDownloadUpdated(download);
-
   if (!download_metadata_cache_)
     return;
   base::Optional<DownloadEntry> entry_opt =
@@ -413,23 +362,14 @@
     }
   }
 
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableDownloadDB)) {
-    download_db_cache_->AddOrReplaceEntry(CreateDownloadDBEntryFromItem(
-        *download, info->download_source, info->fetch_error_body,
-        info->request_headers));
-    download->RemoveObserver(download_db_cache_.get());
-    download->AddObserver(download_db_cache_.get());
-  } else {
-    if (!in_progress_download_observer_) {
-      in_progress_download_observer_ =
-          std::make_unique<InProgressDownloadObserver>(
-              download_metadata_cache_.get());
-    }
-    // May already observe this item, remove observer first.
-    download->RemoveObserver(in_progress_download_observer_.get());
-    download->AddObserver(in_progress_download_observer_.get());
+  if (!in_progress_download_observer_) {
+    in_progress_download_observer_ =
+        std::make_unique<InProgressDownloadObserver>(
+            download_metadata_cache_.get());
   }
+  // May already observe this item, remove observer first.
+  download->RemoveObserver(in_progress_download_observer_.get());
+  download->AddObserver(in_progress_download_observer_.get());
 
   std::unique_ptr<DownloadFile> download_file;
   if (info->result == DOWNLOAD_INTERRUPT_REASON_NONE) {
@@ -459,14 +399,4 @@
     on_started.Run(download, DOWNLOAD_INTERRUPT_REASON_NONE);
 }
 
-void InProgressDownloadManager::OnDownloadDBInitialized(
-    base::OnceClosure callback,
-    std::unique_ptr<std::vector<DownloadDBEntry>> entries) {
-  for (const auto& entry : *entries)
-    in_progress_downloads_.emplace_back(CreateDownloadItemImpl(this, entry));
-  // TODO(qinmin): merge the created DownloadItemImpls with those in
-  // DownloadManagerImpl.
-  std::move(callback).Run();
-}
-
 }  // namespace download
diff --git a/components/download/public/common/download_utils.h b/components/download/public/common/download_utils.h
index b7d56e4..7b69a6c 100644
--- a/components/download/public/common/download_utils.h
+++ b/components/download/public/common/download_utils.h
@@ -5,7 +5,6 @@
 #ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
 #define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_UTILS_H_
 
-#include "components/download/database/download_db_entry.h"
 #include "components/download/database/in_progress/download_entry.h"
 #include "components/download/public/common/download_export.h"
 #include "components/download/public/common/download_interrupt_reasons.h"
@@ -69,18 +68,6 @@
     bool fetch_error_body,
     const DownloadUrlParameters::RequestHeadersType& request_headers);
 
-// Helper functions for DownloadItem -> DownloadDBEntry for DownloadDB.
-COMPONENTS_DOWNLOAD_EXPORT DownloadDBEntry CreateDownloadDBEntryFromItem(
-    const DownloadItem& item,
-    DownloadSource download_source,
-    bool fetch_error_body,
-    const DownloadUrlParameters::RequestHeadersType& request_headers);
-
-// Helper function to convert DownloadDBEntry to DownloadEntry.
-// TODO(qinmin): remove this function after DownloadEntry is deprecated.
-COMPONENTS_DOWNLOAD_EXPORT base::Optional<DownloadEntry>
-CreateDownloadEntryFromDownloadDBEntry(base::Optional<DownloadDBEntry> entry);
-
 COMPONENTS_DOWNLOAD_EXPORT uint64_t GetUniqueDownloadId();
 
 }  // namespace download
diff --git a/components/download/public/common/in_progress_download_manager.h b/components/download/public/common/in_progress_download_manager.h
index 8adf06d..9dba8c6 100644
--- a/components/download/public/common/in_progress_download_manager.h
+++ b/components/download/public/common/in_progress_download_manager.h
@@ -27,11 +27,9 @@
 
 namespace download {
 
-class DownloadDBCache;
 class DownloadURLLoaderFactoryGetter;
 class DownloadUrlParameters;
 class InProgressCache;
-struct DownloadDBEntry;
 
 // Manager for handling all active downloads.
 class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
@@ -135,11 +133,6 @@
   void OnUrlDownloadHandlerCreated(
       UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader) override;
 
-  // Called download db is initialized.
-  void OnDownloadDBInitialized(
-      base::OnceClosure callback,
-      std::unique_ptr<std::vector<DownloadDBEntry>> entries);
-
   // Start a download with given ID.
   void StartDownloadWithId(
       std::unique_ptr<DownloadCreateInfo> info,
@@ -162,19 +155,12 @@
   // Cache for storing metadata about in progress downloads.
   std::unique_ptr<InProgressCache> download_metadata_cache_;
 
-  // Cache for DownloadDB.
-  std::unique_ptr<DownloadDBCache> download_db_cache_;
-
   // listens to information about in-progress download items.
   std::unique_ptr<DownloadItem::Observer> in_progress_download_observer_;
 
   // callback to check if an origin is secure.
   IsOriginSecureCallback is_origin_secure_cb_;
 
-  // A list of in-progress download items, could be null if DownloadManagerImpl
-  // is managing all downloads.
-  std::vector<std::unique_ptr<DownloadItem>> in_progress_downloads_;
-
   base::WeakPtrFactory<InProgressDownloadManager> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(InProgressDownloadManager);
diff --git a/components/nacl/loader/nacl_ipc_adapter.cc b/components/nacl/loader/nacl_ipc_adapter.cc
index 4727192..4c884f9 100644
--- a/components/nacl/loader/nacl_ipc_adapter.cc
+++ b/components/nacl/loader/nacl_ipc_adapter.cc
@@ -254,6 +254,25 @@
 #endif
 }
 
+std::unique_ptr<NaClDescWrapper> MakeShmRegionNaClDesc(
+    base::subtle::PlatformSharedMemoryRegion region) {
+  // Writable regions are not supported in NaCl.
+  DCHECK_NE(region.GetMode(),
+            base::subtle::PlatformSharedMemoryRegion::Mode::kWritable);
+  size_t size = region.GetSize();
+  base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle handle =
+      region.PassPlatformHandle();
+  return std::make_unique<NaClDescWrapper>(
+#if defined(OS_MACOSX)
+      NaClDescImcShmMachMake(handle.release(),
+#elif defined(OS_WIN)
+      NaClDescImcShmMake(handle.Take(),
+#else
+      NaClDescImcShmMake(handle.fd.release(),
+#endif
+                             size));
+}
+
 }  // namespace
 
 class NaClIPCAdapter::RewrittenMessage {
@@ -556,24 +575,26 @@
 
     // Now add any descriptors we found to rewritten_msg. |handles| is usually
     // empty, unless we read a message containing a FD or handle.
-    for (Handles::const_iterator iter = handles.begin();
-         iter != handles.end();
-         ++iter) {
+    for (ppapi::proxy::SerializedHandle& handle : handles) {
       std::unique_ptr<NaClDescWrapper> nacl_desc;
-      switch (iter->type()) {
+      switch (handle.type()) {
         case ppapi::proxy::SerializedHandle::SHARED_MEMORY: {
-          nacl_desc =
-              MakeShmNaClDesc(iter->shmem(), static_cast<size_t>(iter->size()));
+          nacl_desc = MakeShmNaClDesc(handle.shmem(),
+                                      static_cast<size_t>(handle.size()));
+          break;
+        }
+        case ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION: {
+          nacl_desc = MakeShmRegionNaClDesc(handle.TakeSharedMemoryRegion());
           break;
         }
         case ppapi::proxy::SerializedHandle::SOCKET: {
           nacl_desc.reset(new NaClDescWrapper(NaClDescSyncSocketMake(
 #if defined(OS_WIN)
-              iter->descriptor().GetHandle()
+              handle.descriptor().GetHandle()
 #else
-              iter->descriptor().fd
+              handle.descriptor().fd
 #endif
-              )));
+                  )));
           break;
         }
         case ppapi::proxy::SerializedHandle::FILE: {
@@ -581,15 +602,14 @@
           // required, wrap it in a NaClDescQuota.
           NaClDesc* desc = NaClDescIoMakeFromHandle(
 #if defined(OS_WIN)
-              iter->descriptor().GetHandle(),
+              handle.descriptor().GetHandle(),
 #else
-              iter->descriptor().fd,
+              handle.descriptor().fd,
 #endif
-              TranslatePepperFileReadWriteOpenFlags(iter->open_flags()));
-          if (desc && iter->file_io()) {
+              TranslatePepperFileReadWriteOpenFlags(handle.open_flags()));
+          if (desc && handle.file_io()) {
             desc = MakeNaClDescQuota(
-                locked_data_.nacl_msg_scanner_.GetFile(iter->file_io()),
-                desc);
+                locked_data_.nacl_msg_scanner_.GetFile(handle.file_io()), desc);
           }
           if (desc)
             nacl_desc.reset(new NaClDescWrapper(desc));
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 b77b9347..3db6b11 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified.cc
+++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -223,18 +223,18 @@
     const SavePageParams& save_page_params,
     std::unique_ptr<OfflinePageArchiver> archiver,
     content::WebContents* web_contents,
-    const SavePageCallback& callback) {
+    SavePageCallback callback) {
   // 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,
+    InformSavePageDone(std::move(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) {
-    InformSavePageDone(callback, SavePageResult::CONTENT_UNAVAILABLE,
+    InformSavePageDone(std::move(callback), SavePageResult::CONTENT_UNAVAILABLE,
                        save_page_params.client_id, kInvalidOfflineId);
     return;
   }
@@ -253,18 +253,19 @@
   archiver->CreateArchive(
       GetInternalArchiveDirectory(save_page_params.client_id.name_space),
       create_archive_params, web_contents,
-      base::Bind(&OfflinePageModelTaskified::OnCreateArchiveDone,
-                 weak_ptr_factory_.GetWeakPtr(), save_page_params, offline_id,
-                 GetCurrentTime(), callback));
+      base::BindOnce(&OfflinePageModelTaskified::OnCreateArchiveDone,
+                     weak_ptr_factory_.GetWeakPtr(), save_page_params,
+                     offline_id, GetCurrentTime(), std::move(callback)));
   pending_archivers_.push_back(std::move(archiver));
 }
 
 void OfflinePageModelTaskified::AddPage(const OfflinePageItem& page,
-                                        const AddPageCallback& callback) {
+                                        AddPageCallback callback) {
   auto task = std::make_unique<AddPageTask>(
       store_.get(), page,
       base::BindOnce(&OfflinePageModelTaskified::OnAddPageDone,
-                     weak_ptr_factory_.GetWeakPtr(), page, callback));
+                     weak_ptr_factory_.GetWeakPtr(), page,
+                     std::move(callback)));
   task_queue_.AddTask(std::move(task));
 }
 
@@ -461,11 +462,10 @@
   return &offline_event_logger_;
 }
 
-void OfflinePageModelTaskified::InformSavePageDone(
-    const SavePageCallback& callback,
-    SavePageResult result,
-    const ClientId& client_id,
-    int64_t offline_id) {
+void OfflinePageModelTaskified::InformSavePageDone(SavePageCallback callback,
+                                                   SavePageResult result,
+                                                   const ClientId& client_id,
+                                                   int64_t offline_id) {
   UMA_HISTOGRAM_ENUMERATION("OfflinePages.SavePageCount",
                             model_utils::ToNamespaceEnum(client_id.name_space),
                             OfflinePagesNamespaceEnumeration::RESULT_COUNT);
@@ -481,14 +481,14 @@
   if (result == SavePageResult::ARCHIVE_CREATION_FAILED)
     CreateArchivesDirectoryIfNeeded();
   if (!callback.is_null())
-    callback.Run(result, offline_id);
+    std::move(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,
+    SavePageCallback callback,
     OfflinePageArchiver* archiver,
     ArchiverResult archiver_result,
     const GURL& saved_url,
@@ -498,14 +498,15 @@
     const std::string& file_hash) {
   if (archiver_result != ArchiverResult::SUCCESSFULLY_CREATED) {
     SavePageResult result = ArchiverResultToSavePageResult(archiver_result);
-    InformSavePageDone(callback, result, save_page_params.client_id,
+    InformSavePageDone(std::move(callback), result, save_page_params.client_id,
                        offline_id);
     ErasePendingArchiver(archiver);
     return;
   }
   if (save_page_params.url != saved_url) {
     DVLOG(1) << "Saved URL does not match requested URL.";
-    InformSavePageDone(callback, SavePageResult::ARCHIVE_CREATION_FAILED,
+    InformSavePageDone(std::move(callback),
+                       SavePageResult::ARCHIVE_CREATION_FAILED,
                        save_page_params.client_id, offline_id);
     ErasePendingArchiver(archiver);
     return;
@@ -529,14 +530,15 @@
       policy_controller_->IsUserRequestedDownload(
           offline_page.client_id.name_space)) {
     // If the user intentionally downloaded the page, move it to a public place.
-    PublishArchive(offline_page, callback, archiver);
+    PublishArchive(offline_page, std::move(callback), archiver);
   } else {
     // For pages that we download on the user's behalf, we keep them in an
     // internal chrome directory, and add them here to the OfflinePageModel
     // database.
     AddPage(offline_page,
-            base::Bind(&OfflinePageModelTaskified::OnAddPageForSavePageDone,
-                       weak_ptr_factory_.GetWeakPtr(), callback, offline_page));
+            base::BindOnce(&OfflinePageModelTaskified::OnAddPageForSavePageDone,
+                           weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                           offline_page));
   }
   ErasePendingArchiver(archiver);
 }
@@ -552,21 +554,22 @@
 
 void OfflinePageModelTaskified::PublishArchive(
     const OfflinePageItem& offline_page,
-    const SavePageCallback& save_page_callback,
+    SavePageCallback save_page_callback,
     OfflinePageArchiver* archiver) {
   archiver->PublishArchive(
       offline_page, task_runner_, archive_manager_->GetPublicArchivesDir(),
       download_manager_.get(),
       base::BindOnce(&OfflinePageModelTaskified::PublishArchiveDone,
-                     weak_ptr_factory_.GetWeakPtr(), save_page_callback));
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(save_page_callback)));
 }
 
 void OfflinePageModelTaskified::PublishArchiveDone(
-    const SavePageCallback& save_page_callback,
+    SavePageCallback save_page_callback,
     const OfflinePageItem& offline_page,
     PublishArchiveResult* move_results) {
   if (move_results->move_result != SavePageResult::SUCCESS) {
-    save_page_callback.Run(move_results->move_result, 0LL);
+    std::move(save_page_callback).Run(move_results->move_result, 0LL);
     return;
   }
   OfflinePageItem page = offline_page;
@@ -574,8 +577,9 @@
   page.system_download_id = move_results->download_id;
 
   AddPage(page,
-          base::Bind(&OfflinePageModelTaskified::OnAddPageForSavePageDone,
-                     weak_ptr_factory_.GetWeakPtr(), save_page_callback, page));
+          base::BindOnce(&OfflinePageModelTaskified::OnAddPageForSavePageDone,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         std::move(save_page_callback), page));
 }
 
 void OfflinePageModelTaskified::PublishInternalArchive(
@@ -613,14 +617,14 @@
 }
 
 void OfflinePageModelTaskified::OnAddPageForSavePageDone(
-    const SavePageCallback& callback,
+    SavePageCallback callback,
     const OfflinePageItem& page_attempted,
     AddPageResult add_page_result,
     int64_t offline_id) {
   SavePageResult save_page_result =
       AddPageResultToSavePageResult(add_page_result);
-  InformSavePageDone(callback, save_page_result, page_attempted.client_id,
-                     offline_id);
+  InformSavePageDone(std::move(callback), save_page_result,
+                     page_attempted.client_id, offline_id);
   if (save_page_result == SavePageResult::SUCCESS) {
     ReportPageHistogramAfterSuccessfulSaving(page_attempted, GetCurrentTime());
     // TODO(romax): Just keep the same with logic in OPMImpl (which was wrong).
@@ -637,9 +641,9 @@
 }
 
 void OfflinePageModelTaskified::OnAddPageDone(const OfflinePageItem& page,
-                                              const AddPageCallback& callback,
+                                              AddPageCallback callback,
                                               AddPageResult result) {
-  callback.Run(result, page.offline_id);
+  std::move(callback).Run(result, page.offline_id);
   if (result == AddPageResult::SUCCESS) {
     for (Observer& observer : observers_)
       observer.OfflinePageAdded(this, 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 fbf9034d..e280745 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified.h
+++ b/components/offline_pages/core/model/offline_page_model_taskified.h
@@ -82,9 +82,8 @@
   void SavePage(const SavePageParams& save_page_params,
                 std::unique_ptr<OfflinePageArchiver> archiver,
                 content::WebContents* web_contents,
-                const SavePageCallback& callback) override;
-  void AddPage(const OfflinePageItem& page,
-               const AddPageCallback& callback) override;
+                SavePageCallback callback) override;
+  void AddPage(const OfflinePageItem& page, AddPageCallback callback) override;
   void MarkPageAccessed(int64_t offline_id) override;
 
   void DeletePagesByOfflineId(const std::vector<int64_t>& offline_ids,
@@ -164,18 +163,18 @@
   friend class OfflinePageModelTaskifiedTest;
 
   // Callbacks for saving pages.
-  void InformSavePageDone(const SavePageCallback& calback,
+  void InformSavePageDone(SavePageCallback calback,
                           SavePageResult result,
                           const ClientId& client_id,
                           int64_t offline_id);
-  void OnAddPageForSavePageDone(const SavePageCallback& callback,
+  void OnAddPageForSavePageDone(SavePageCallback callback,
                                 const OfflinePageItem& page_attempted,
                                 AddPageResult add_page_result,
                                 int64_t offline_id);
   void OnCreateArchiveDone(const SavePageParams& save_page_params,
                            int64_t offline_id,
                            const base::Time& start_time,
-                           const SavePageCallback& callback,
+                           SavePageCallback callback,
                            OfflinePageArchiver* archiver,
                            OfflinePageArchiver::ArchiverResult archiver_result,
                            const GURL& saved_url,
@@ -186,7 +185,7 @@
 
   // Callback for adding pages.
   void OnAddPageDone(const OfflinePageItem& page,
-                     const AddPageCallback& callback,
+                     AddPageCallback callback,
                      AddPageResult result);
 
   // Callbacks for deleting pages.
@@ -216,11 +215,11 @@
 
   // Methods for publishing the page to the public directory.
   void PublishArchive(const OfflinePageItem& offline_page,
-                      const SavePageCallback& callback,
+                      SavePageCallback callback,
                       OfflinePageArchiver* archiver);
 
   // Callback for when PublishArchive has completd.
-  void PublishArchiveDone(const SavePageCallback& save_page_callback,
+  void PublishArchiveDone(SavePageCallback save_page_callback,
                           const OfflinePageItem& offline_page,
                           PublishArchiveResult* archive_result);
 
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 b223d5a..9db23d93 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
@@ -111,7 +111,7 @@
                             const GURL& original_url,
                             const std::string& request_origin,
                             std::unique_ptr<OfflinePageArchiver> archiver,
-                            const SavePageCallback& callback);
+                            SavePageCallback callback);
   int64_t SavePageWithExpectedResult(
       const GURL& url,
       const ClientId& client_id,
@@ -283,14 +283,15 @@
     const GURL& original_url,
     const std::string& request_origin,
     std::unique_ptr<OfflinePageArchiver> archiver,
-    const SavePageCallback& callback) {
+    SavePageCallback callback) {
   OfflinePageModel::SavePageParams save_page_params;
   save_page_params.url = url;
   save_page_params.client_id = client_id;
   save_page_params.original_url = original_url;
   save_page_params.request_origin = request_origin;
   save_page_params.is_background = false;
-  model()->SavePage(save_page_params, std::move(archiver), nullptr, callback);
+  model()->SavePage(save_page_params, std::move(archiver), nullptr,
+                    std::move(callback));
   PumpLoop();
 }
 
diff --git a/components/offline_pages/core/offline_page_archiver.h b/components/offline_pages/core/offline_page_archiver.h
index 81fb7a5..d8b9c876 100644
--- a/components/offline_pages/core/offline_page_archiver.h
+++ b/components/offline_pages/core/offline_page_archiver.h
@@ -94,13 +94,13 @@
     bool use_page_problem_detectors;
   };
 
-  typedef base::Callback<void(OfflinePageArchiver* /* archiver */,
-                              ArchiverResult /* result */,
-                              const GURL& /* url */,
-                              const base::FilePath& /* file_path */,
-                              const base::string16& /* title */,
-                              int64_t /* file_size */,
-                              const std::string& /* digest */)>
+  typedef base::OnceCallback<void(OfflinePageArchiver* /* archiver */,
+                                  ArchiverResult /* result */,
+                                  const GURL& /* url */,
+                                  const base::FilePath& /* file_path */,
+                                  const base::string16& /* title */,
+                                  int64_t /* file_size */,
+                                  const std::string& /* digest */)>
       CreateArchiveCallback;
 
   virtual ~OfflinePageArchiver() {}
@@ -111,7 +111,7 @@
   virtual void CreateArchive(const base::FilePath& archives_dir,
                              const CreateArchiveParams& create_archive_params,
                              content::WebContents* web_contents,
-                             const CreateArchiveCallback& callback) = 0;
+                             CreateArchiveCallback callback) = 0;
 
   // Publishes the page on a background thread, then returns to the
   // OfflinePageModelTaskified's done callback.
diff --git a/components/offline_pages/core/offline_page_archiver_unittest.cc b/components/offline_pages/core/offline_page_archiver_unittest.cc
index a56f60b9..0abf1ae8 100644
--- a/components/offline_pages/core/offline_page_archiver_unittest.cc
+++ b/components/offline_pages/core/offline_page_archiver_unittest.cc
@@ -26,7 +26,7 @@
   void CreateArchive(const base::FilePath& archives_dir,
                      const CreateArchiveParams& create_archive_params,
                      content::WebContents* web_contents,
-                     const CreateArchiveCallback& callback) override {}
+                     CreateArchiveCallback callback) override {}
 };
 
 class OfflinePageArchiverTest
@@ -65,7 +65,7 @@
     return weak_ptr_factory_.GetWeakPtr();
   }
 
-  void PublishArchiveDone(const SavePageCallback& save_page_callback,
+  void PublishArchiveDone(SavePageCallback save_page_callback,
                           const OfflinePageItem& offline_page,
                           PublishArchiveResult* archive_result);
 
@@ -87,7 +87,7 @@
 }
 
 void OfflinePageArchiverTest::PublishArchiveDone(
-    const SavePageCallback& save_page_callback,
+    SavePageCallback save_page_callback,
     const OfflinePageItem& offline_page,
     PublishArchiveResult* archive_result) {
   publish_archive_result_ = *archive_result;
@@ -112,7 +112,7 @@
       offline_page, base::ThreadTaskRunnerHandle::Get(),
       public_archive_dir_path(), download_manager.get(),
       base::BindOnce(&OfflinePageArchiverTest::PublishArchiveDone,
-                     get_weak_ptr(), save_page_callback));
+                     get_weak_ptr(), std::move(save_page_callback)));
   PumpLoop();
 
   EXPECT_EQ(SavePageResult::SUCCESS, publish_archive_result().move_result);
diff --git a/components/offline_pages/core/offline_page_model.h b/components/offline_pages/core/offline_page_model.h
index d953922..1823818 100644
--- a/components/offline_pages/core/offline_page_model.h
+++ b/components/offline_pages/core/offline_page_model.h
@@ -29,18 +29,6 @@
 // Service for saving pages offline, storing the offline copy and metadata, and
 // retrieving them upon request.
 //
-// Example usage:
-//   class ArchiverImpl : public OfflinePageArchiver {
-//     // This is a class that knows how to create archiver
-//     void CreateArchiver(...) override;
-//     ...
-//   }
-//
-//   // In code using the OfflinePagesModel to save a page:
-//   std::unique_ptr<ArchiverImpl> archiver(new ArchiverImpl());
-//   // Callback is of type SavePageCallback.
-//   model->SavePage(url, std::move(archiver), callback);
-//
 // TODO(fgorski): Things to describe:
 // * how to cancel requests and what to expect
 class OfflinePageModel : public base::SupportsUserData, public KeyedService {
@@ -137,14 +125,26 @@
   // Attempts to save a page offline per |save_page_params|. Requires that the
   // model is loaded.  Generates a new offline id or uses the proposed offline
   // id in |save_page_params| and returns it.
+  //
+  // Example usage:
+  //   class ArchiverImpl : public OfflinePageArchiver {
+  //     // This is a class that knows how to create archiver
+  //     void CreateArchiver(...) override;
+  //     ...
+  //   }
+  //
+  //   // In code using the OfflinePagesModel to save a page:
+  //   std::unique_ptr<ArchiverImpl> archiver(new ArchiverImpl());
+  //   // Callback is of type SavePageCallback.
+  //   model->SavePage(url, std::move(archiver), std::move(callback));
   virtual void SavePage(const SavePageParams& save_page_params,
                         std::unique_ptr<OfflinePageArchiver> archiver,
                         content::WebContents* web_contents,
-                        const SavePageCallback& callback) = 0;
+                        SavePageCallback callback) = 0;
 
   // Adds a page entry to the metadata store.
   virtual void AddPage(const OfflinePageItem& page,
-                       const AddPageCallback& callback) = 0;
+                       AddPageCallback callback) = 0;
 
   // Marks that the offline page related to the passed |offline_id| has been
   // accessed. Its access info, including last access time and access count,
diff --git a/components/offline_pages/core/offline_page_test_archiver.cc b/components/offline_pages/core/offline_page_test_archiver.cc
index 656f452d..d78a5cc 100644
--- a/components/offline_pages/core/offline_page_test_archiver.cc
+++ b/components/offline_pages/core/offline_page_test_archiver.cc
@@ -39,9 +39,9 @@
     const base::FilePath& archives_dir,
     const CreateArchiveParams& create_archive_params,
     content::WebContents* web_contents,
-    const CreateArchiveCallback& callback) {
+    CreateArchiveCallback callback) {
   create_archive_called_ = true;
-  callback_ = callback;
+  callback_ = std::move(callback);
   archives_dir_ = archives_dir;
   create_archive_params_ = create_archive_params;
   if (!delayed_)
@@ -73,8 +73,9 @@
   }
   observer_->SetLastPathCreatedByArchiver(archive_path);
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(callback_, this, result_, url_, archive_path,
-                            result_title_, size_to_report_, digest_to_report_));
+      FROM_HERE,
+      base::BindOnce(std::move(callback_), this, result_, url_, archive_path,
+                     result_title_, size_to_report_, digest_to_report_));
 }
 
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/offline_page_test_archiver.h b/components/offline_pages/core/offline_page_test_archiver.h
index 03f8892..f494711 100644
--- a/components/offline_pages/core/offline_page_test_archiver.h
+++ b/components/offline_pages/core/offline_page_test_archiver.h
@@ -47,7 +47,7 @@
   void CreateArchive(const base::FilePath& archives_dir,
                      const CreateArchiveParams& create_archive_params,
                      content::WebContents* web_contents,
-                     const CreateArchiveCallback& callback) override;
+                     CreateArchiveCallback callback) override;
 
   void PublishArchive(
       const OfflinePageItem& offline_page,
diff --git a/components/offline_pages/core/offline_page_types.h b/components/offline_pages/core/offline_page_types.h
index 591052c..61a05192 100644
--- a/components/offline_pages/core/offline_page_types.h
+++ b/components/offline_pages/core/offline_page_types.h
@@ -94,8 +94,8 @@
 typedef std::vector<OfflinePageItem> MultipleOfflinePageItemResult;
 
 // TODO(carlosk): All or most of these should use base::OnceCallback.
-typedef base::Callback<void(SavePageResult, int64_t)> SavePageCallback;
-typedef base::Callback<void(AddPageResult, int64_t)> AddPageCallback;
+typedef base::OnceCallback<void(SavePageResult, int64_t)> SavePageCallback;
+typedef base::OnceCallback<void(AddPageResult, int64_t)> AddPageCallback;
 typedef base::Callback<void(DeletePageResult)> DeletePageCallback;
 typedef base::Callback<void(bool)> HasPagesCallback;
 typedef base::Callback<void(const MultipleOfflineIdResult&)>
diff --git a/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h b/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
index 87cefbd..bb64245d 100644
--- a/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
+++ b/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
@@ -14,15 +14,10 @@
  public:
   MockThumbnailFetcher();
   ~MockThumbnailFetcher() override;
-  MOCK_METHOD3(FetchSuggestionImageData_,
+  MOCK_METHOD3(FetchSuggestionImageData,
                void(const ClientId& client_id,
                     bool is_first_attempt,
-                    ImageDataFetchedCallback* callback));
-  void FetchSuggestionImageData(const ClientId& client_id,
-                                bool is_first_attempt,
-                                ImageDataFetchedCallback callback) override {
-    FetchSuggestionImageData_(client_id, is_first_attempt, &callback);
-  }
+                    ImageDataFetchedCallback callback));
 };
 
 }  // namespace offline_pages
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
index 20ec61e5..1477538 100644
--- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -76,17 +76,11 @@
   }
   ~MockOfflinePageModel() override = default;
   MOCK_METHOD1(StoreThumbnail, void(const OfflinePageThumbnail& thumb));
-  MOCK_METHOD2(HasThumbnailForOfflineId_,
+  MOCK_METHOD2(HasThumbnailForOfflineId,
                void(int64_t offline_id,
-                    base::OnceCallback<void(bool)>* callback));
+                    base::OnceCallback<void(bool)> callback));
   MOCK_METHOD2(AddPage,
-               void(const OfflinePageItem& page,
-                    const AddPageCallback& callback));
-  void HasThumbnailForOfflineId(
-      int64_t offline_id,
-      base::OnceCallback<void(bool)> callback) override {
-    HasThumbnailForOfflineId_(offline_id, &callback);
-  }
+               void(const OfflinePageItem& page, AddPageCallback callback));
 };
 
 class TestPrefetchBackgroundTask : public PrefetchBackgroundTask {
@@ -193,34 +187,24 @@
                             const char* client_id) {
     EXPECT_CALL(
         *thumbnail_fetcher_,
-        FetchSuggestionImageData_(
+        FetchSuggestionImageData(
             ClientId(kSuggestedArticlesNamespace, client_id), first_attempt, _))
-        .WillOnce(
-            testing::Invoke(testing::CallbackToFunctor(base::BindRepeating(
-                [](const std::string& thumbnail_data,
-                   scoped_refptr<base::TestMockTimeTaskRunner> task_runner,
-                   const ClientId& id, bool is_first_attemp,
-                   ThumbnailFetcher::ImageDataFetchedCallback* callback) {
-                  task_runner->PostTask(
-                      FROM_HERE,
-                      base::BindOnce(std::move(*callback), thumbnail_data));
-                },
-                thumbnail_data, task_runner()))));
+        .WillOnce([&, thumbnail_data](
+                      const ClientId& client_id, bool first_attempt,
+                      ThumbnailFetcher::ImageDataFetchedCallback callback) {
+          task_runner()->PostTask(
+              FROM_HERE, base::BindOnce(std::move(callback), thumbnail_data));
+        });
   }
 
   void ExpectHasThumbnailForOfflineId(int64_t offline_id, bool to_return) {
-    EXPECT_CALL(*offline_model_, HasThumbnailForOfflineId_(offline_id, _))
+    EXPECT_CALL(*offline_model_, HasThumbnailForOfflineId(offline_id, _))
         .WillOnce(
-            testing::Invoke(testing::CallbackToFunctor(base::BindRepeating(
-                [](bool to_return,
-                   scoped_refptr<base::TestMockTimeTaskRunner> task_runner,
-                   int64_t offline_id_,
-                   base::OnceCallback<void(bool)>* callback) {
-                  task_runner->PostTask(
-                      FROM_HERE,
-                      base::BindOnce(std::move(*callback), to_return));
-                },
-                to_return, task_runner()))));
+            [&, offline_id, to_return](
+                int64_t offline_id, base::OnceCallback<void(bool)> callback) {
+              task_runner()->PostTask(
+                  FROM_HERE, base::BindOnce(std::move(callback), to_return));
+            });
   }
 
   PrefetchDispatcherImpl* dispatcher() { return dispatcher_; }
@@ -574,7 +558,7 @@
 
 TEST_F(PrefetchDispatcherTest, ThumbnailAlreadyExists_ItemDownloaded) {
   ExpectHasThumbnailForOfflineId(kTestOfflineID, true);
-  EXPECT_CALL(*thumbnail_fetcher_, FetchSuggestionImageData_(_, _, _)).Times(0);
+  EXPECT_CALL(*thumbnail_fetcher_, FetchSuggestionImageData(_, _, _)).Times(0);
   EXPECT_CALL(*offline_model_, StoreThumbnail(_)).Times(0);
   prefetch_dispatcher()->ItemDownloaded(
       kTestOfflineID, ClientId(kSuggestedArticlesNamespace, kClientID));
@@ -626,13 +610,12 @@
   // callback, and store the page to added_page.
   OfflinePageItem added_page;
   EXPECT_CALL(*offline_model_, AddPage(_, _))
-      .WillOnce(testing::Invoke([&](const OfflinePageItem& page,
-                                    const AddPageCallback& callback) {
+      .WillOnce([&](const OfflinePageItem& page, AddPageCallback callback) {
         added_page = page;
         base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE,
-            base::BindOnce(callback, AddPageResult::SUCCESS, page.offline_id));
-      }));
+            FROM_HERE, base::BindOnce(std::move(callback),
+                                      AddPageResult::SUCCESS, page.offline_id));
+      });
 
   network_request_factory()->set_respond_to_generate_page_bundle(true);
   download_service()->SetTestFileData(kBodyContent);
diff --git a/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
index 69e80d3..ab0997e 100644
--- a/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
@@ -32,12 +32,11 @@
   TestOfflinePageModel() { ignore_result(archive_dir_.CreateUniqueTempDir()); }
   ~TestOfflinePageModel() override = default;
 
-  void AddPage(const OfflinePageItem& page,
-               const AddPageCallback& callback) override {
+  void AddPage(const OfflinePageItem& page, AddPageCallback callback) override {
     page_added_ = page.offline_id != kTestOfflineIDFailedToAdd;
     if (page_added_)
       last_added_page_ = page;
-    callback.Run(
+    std::move(callback).Run(
         page_added_ ? AddPageResult::SUCCESS : AddPageResult::STORE_FAILURE,
         page.offline_id);
   }
diff --git a/components/offline_pages/core/stub_offline_page_model.cc b/components/offline_pages/core/stub_offline_page_model.cc
index d217c07..6dcf6c9 100644
--- a/components/offline_pages/core/stub_offline_page_model.cc
+++ b/components/offline_pages/core/stub_offline_page_model.cc
@@ -22,9 +22,9 @@
     const SavePageParams& save_page_params,
     std::unique_ptr<OfflinePageArchiver> archiver,
     content::WebContents* web_contents,
-    const SavePageCallback& callback) {}
+    SavePageCallback callback) {}
 void StubOfflinePageModel::AddPage(const OfflinePageItem& page,
-                                   const AddPageCallback& callback) {}
+                                   AddPageCallback callback) {}
 void StubOfflinePageModel::MarkPageAccessed(int64_t offline_id) {}
 void StubOfflinePageModel::DeletePagesByOfflineId(
     const std::vector<int64_t>& offline_ids,
diff --git a/components/offline_pages/core/stub_offline_page_model.h b/components/offline_pages/core/stub_offline_page_model.h
index c99f6ae1..ee88e37f 100644
--- a/components/offline_pages/core/stub_offline_page_model.h
+++ b/components/offline_pages/core/stub_offline_page_model.h
@@ -29,9 +29,8 @@
   void SavePage(const SavePageParams& save_page_params,
                 std::unique_ptr<OfflinePageArchiver> archiver,
                 content::WebContents* web_contents,
-                const SavePageCallback& callback) override;
-  void AddPage(const OfflinePageItem& page,
-               const AddPageCallback& callback) override;
+                SavePageCallback callback) override;
+  void AddPage(const OfflinePageItem& page, AddPageCallback callback) override;
   void MarkPageAccessed(int64_t offline_id) override;
   void DeletePagesByOfflineId(const std::vector<int64_t>& offline_ids,
                               const DeletePageCallback& callback) override;
diff --git a/components/omnibox/browser/omnibox_controller.cc b/components/omnibox/browser/omnibox_controller.cc
index 756e6270..e2bc11ed 100644
--- a/components/omnibox/browser/omnibox_controller.cc
+++ b/components/omnibox/browser/omnibox_controller.cc
@@ -38,7 +38,7 @@
 }
 
 void OmniboxController::OnResultChanged(bool default_match_changed) {
-  const bool was_open = popup_ && popup_->IsDisplayingResults();
+  const bool was_open = popup_ && popup_->IsOpen();
   if (default_match_changed) {
     // The default match has changed, we need to let the OmniboxEditModel know
     // about new inline autocomplete text (blue highlight).
@@ -57,7 +57,7 @@
     popup_->OnResultChanged();
   }
 
-  if (was_open && !popup_->IsDisplayingResults()) {
+  if (was_open && !popup_->IsOpen()) {
     // Accept the temporary text as the user text, because it makes little sense
     // to have temporary text when the popup is closed.
     omnibox_edit_model_->AcceptTemporaryTextAsUserText();
@@ -76,7 +76,7 @@
 }
 
 void OmniboxController::ClearPopupKeywordMode() const {
-  if (popup_->IsDisplayingResults() &&
+  if (popup_->IsOpen() &&
       popup_->selected_line_state() == OmniboxPopupModel::KEYWORD)
     popup_->SetSelectedLineState(OmniboxPopupModel::NORMAL);
 }
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 5a9b51ef..3cbb036 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -225,8 +225,7 @@
   // URL" (which sounds as if it might be persistent) from seeing just that URL
   // forever afterwards.
   return (GetCurrentPermanentUrlText() != old_current_permanent_url) &&
-         (!has_focus() ||
-          (!user_input_in_progress_ && !PopupIsDisplayingResults()));
+         (!has_focus() || (!user_input_in_progress_ && !PopupIsOpen()));
 }
 
 GURL OmniboxEditModel::PermanentURL() const {
@@ -322,7 +321,7 @@
   *url_from_text = match_from_text.destination_url;
 
   GURL current_page_url = PermanentURL();
-  if (PopupIsDisplayingResults()) {
+  if (PopupIsOpen()) {
     AutocompleteMatch current_match = CurrentMatch(nullptr);
     if (!AutocompleteMatch::IsSearchType(current_match.type) &&
         current_match.destination_url.is_valid()) {
@@ -606,7 +605,7 @@
   // metrics_log.cc.  They also don't necessarily make sense if the omnibox
   // dropdown is closed or the user used a paste-and-go action.  (In most
   // cases when this happens, the user never modified the omnibox.)
-  const bool popup_open = PopupIsDisplayingResults();
+  const bool popup_open = PopupIsOpen();
   if (input_.from_omnibox_focus() || !popup_open || !pasted_text.empty()) {
     const base::TimeDelta default_time_delta =
         base::TimeDelta::FromMilliseconds(-1);
@@ -747,7 +746,7 @@
   keyword_mode_entry_method_ = entry_method;
   user_text_ = MaybeStripKeyword(user_text_);
 
-  if (PopupIsDisplayingResults())
+  if (PopupIsOpen())
     popup_model()->SetSelectedLineState(OmniboxPopupModel::KEYWORD);
   else
     StartAutocomplete(false, true);
@@ -1007,7 +1006,7 @@
 
 void OmniboxEditModel::OnUpOrDownKeyPressed(int count) {
   // NOTE: This purposefully doesn't trigger any code that resets paste_state_.
-  if (PopupIsDisplayingResults()) {
+  if (PopupIsOpen()) {
     // The popup is open, so the user should be able to interact with it
     // normally.
     popup_model()->Move(count);
@@ -1274,8 +1273,8 @@
 const char OmniboxEditModel::kCutOrCopyAllTextHistogram[] =
     "Omnibox.CutOrCopyAllText";
 
-bool OmniboxEditModel::PopupIsDisplayingResults() const {
-  return popup_model() && popup_model()->IsDisplayingResults();
+bool OmniboxEditModel::PopupIsOpen() const {
+  return popup_model() && popup_model()->IsOpen();
 }
 
 void OmniboxEditModel::InternalSetUserText(const base::string16& text) {
@@ -1304,7 +1303,7 @@
                                              GURL* alternate_nav_url) const {
   DCHECK(match);
 
-  if (query_in_progress() || PopupIsDisplayingResults()) {
+  if (query_in_progress() || PopupIsOpen()) {
     if (query_in_progress()) {
       // It's technically possible for |result| to be empty if no provider
       // returns a synchronous result but the query has not completed
diff --git a/components/omnibox/browser/omnibox_edit_model.h b/components/omnibox/browser/omnibox_edit_model.h
index cae0916..75ba220 100644
--- a/components/omnibox/browser/omnibox_edit_model.h
+++ b/components/omnibox/browser/omnibox_edit_model.h
@@ -388,9 +388,10 @@
   // AutomationProvider::AutocompleteEditIsQueryInProgress.
   bool query_in_progress() const { return !autocomplete_controller()->done(); }
 
-  // Returns true if the popup exists and is open with results.
-  // Virtual for testing, since test code may not have a popup model.
-  virtual bool PopupIsDisplayingResults() const;
+  // Returns true if the popup exists and is open.  (This is a convenience
+  // wrapper for the benefit of test code, which may not have a popup model.)
+  // Virtual for testing.
+  virtual bool PopupIsOpen() const;
 
   // Called whenever user_text_ should change.
   void InternalSetUserText(const base::string16& text);
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc
index 22266ea..06e633cb 100644
--- a/components/omnibox/browser/omnibox_edit_model_unittest.cc
+++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -28,26 +28,22 @@
       : OmniboxEditModel(view,
                          controller,
                          std::make_unique<TestOmniboxClient>()),
-        popup_is_displaying_results_(false) {}
+        popup_is_open_(false) {}
 
-  bool PopupIsDisplayingResults() const override {
-    return popup_is_displaying_results_;
-  };
+  bool PopupIsOpen() const override { return popup_is_open_; };
 
   AutocompleteMatch CurrentMatch(GURL*) const override {
     return current_match_;
   };
 
-  void SetPopupIsDisplayingResults(bool displaying_results) {
-    popup_is_displaying_results_ = displaying_results;
-  }
+  void SetPopupIsOpen(bool open) { popup_is_open_ = open; }
 
   void SetCurrentMatch(const AutocompleteMatch& match) {
     current_match_ = match;
   }
 
  private:
-  bool popup_is_displaying_results_;
+  bool popup_is_open_;
   AutocompleteMatch current_match_;
 
   DISALLOW_COPY_AND_ASSIGN(TestOmniboxEditModel);
@@ -174,7 +170,7 @@
     model()->ResetDisplayUrls();
 
     model()->SetInputInProgress(input[i].is_match_selected_in_popup);
-    model()->SetPopupIsDisplayingResults(input[i].is_match_selected_in_popup);
+    model()->SetPopupIsOpen(input[i].is_match_selected_in_popup);
     AutocompleteMatch match;
     match.type = AutocompleteMatchType::NAVSUGGEST;
     match.destination_url = GURL(input[i].match_destination_url);
diff --git a/components/omnibox/browser/omnibox_popup_model.cc b/components/omnibox/browser/omnibox_popup_model.cc
index f79fb26..98902b7 100644
--- a/components/omnibox/browser/omnibox_popup_model.cc
+++ b/components/omnibox/browser/omnibox_popup_model.cc
@@ -103,8 +103,8 @@
   }
 }
 
-bool OmniboxPopupModel::IsDisplayingResults() const {
-  return view_->IsOpen() && !result().empty();
+bool OmniboxPopupModel::IsOpen() const {
+  return view_->IsOpen();
 }
 
 void OmniboxPopupModel::SetSelectedLine(size_t line,
diff --git a/components/omnibox/browser/omnibox_popup_model.h b/components/omnibox/browser/omnibox_popup_model.h
index e20d4d47..d0dc574b 100644
--- a/components/omnibox/browser/omnibox_popup_model.h
+++ b/components/omnibox/browser/omnibox_popup_model.h
@@ -36,7 +36,7 @@
   };
 
   OmniboxPopupModel(OmniboxPopupView* popup_view, OmniboxEditModel* edit_model);
-  virtual ~OmniboxPopupModel();
+  ~OmniboxPopupModel();
 
   // Computes the maximum width, in pixels, that can be allocated for the two
   // parts of an autocomplete result, i.e. the contents and the description.
@@ -60,14 +60,11 @@
                                     int* contents_max_width,
                                     int* description_max_width);
 
-  // Returns true if the popup is currently open and contains matches.
-  // Virtual for testing, since test code may not have autocomplete results.
-  virtual bool IsDisplayingResults() const;
+  // Returns true if the popup is currently open.
+  bool IsOpen() const;
 
   OmniboxPopupView* view() const { return view_; }
 
-  OmniboxEditModel* edit_model() const { return edit_model_; }
-
   // Returns the AutocompleteController used by this popup.
   AutocompleteController* autocomplete_controller() const {
     return edit_model_->autocomplete_controller();
diff --git a/components/omnibox/browser/omnibox_popup_view.h b/components/omnibox/browser/omnibox_popup_view.h
index 0547114..5b19519 100644
--- a/components/omnibox/browser/omnibox_popup_view.h
+++ b/components/omnibox/browser/omnibox_popup_view.h
@@ -19,8 +19,7 @@
  public:
   virtual ~OmniboxPopupView() {}
 
-  // Returns true if the popup is currently open, regardless of whether or not
-  // it actually contains results.
+  // Returns true if the popup is currently open.
   virtual bool IsOpen() const = 0;
 
   // Invalidates one line of the autocomplete popup.
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index eb6fdd0..a1ca0fc 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -844,8 +844,7 @@
 void PrepareFrameAndViewForPrint::CopySelection(
     const WebPreferences& preferences) {
   ResizeForPrinting();
-  std::string html =
-      net::EscapeQueryParamValue(frame()->SelectionAsMarkup().Utf8(), false);
+  std::string html = frame()->SelectionAsMarkup().Utf8();
   RestoreSize();
   // Create a new WebView with the same settings as the current display one.
   // Except that we disable javascript (don't want any active content running
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc
index b72cabf..4f7981c5 100644
--- a/components/printing/test/print_render_frame_helper_browsertest.cc
+++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -1156,6 +1156,29 @@
   VerifyPagesPrinted(false);
 }
 
+// Test to verify that preview generated only for two pages.
+TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewForSelectedText2) {
+  LoadHTML(kMultipageHTML);
+  GetMainFrame()->SelectRange(blink::WebRange(1, 8),
+                              blink::WebLocalFrame::kHideSelectionHandle,
+                              blink::mojom::SelectionMenuBehavior::kHide);
+
+  // Fill in some dummy values.
+  base::DictionaryValue dict;
+  CreatePrintSettingsDictionary(&dict);
+  dict.SetBoolean(kSettingShouldPrintSelectionOnly, true);
+
+  OnPrintPreview(dict);
+
+  EXPECT_EQ(0, print_render_thread_->print_preview_pages_remaining());
+  VerifyDidPreviewPage(true, 0);
+  VerifyPreviewPageCount(2);
+  VerifyPrintPreviewCancelled(false);
+  VerifyPrintPreviewFailed(false);
+  VerifyPrintPreviewGenerated(true);
+  VerifyPagesPrinted(false);
+}
+
 // Tests that print preview fails and receiving error messages through
 // that channel all works.
 TEST_F(MAYBE_PrintRenderFrameHelperPreviewTest, PrintPreviewFail) {
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index 5a4e948..fb4709d0 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -132,6 +132,7 @@
     "driver/signin_manager_wrapper.h",
     "driver/startup_controller.cc",
     "driver/startup_controller.h",
+    "driver/sync_api_component_factory.cc",
     "driver/sync_api_component_factory.h",
     "driver/sync_client.cc",
     "driver/sync_client.h",
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h
index 7b89e7f..2862e152 100644
--- a/components/sync/driver/data_type_controller.h
+++ b/components/sync/driver/data_type_controller.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/location.h"
@@ -73,6 +74,7 @@
       base::Callback<void(ModelType, const StatusCounters&)>;
 
   using TypeMap = std::map<ModelType, std::unique_ptr<DataTypeController>>;
+  using TypeVector = std::vector<std::unique_ptr<DataTypeController>>;
 
   // Returns true if the start result should trigger an unrecoverable error.
   // Public so unit tests can use this function as well.
diff --git a/components/sync/driver/fake_sync_client.cc b/components/sync/driver/fake_sync_client.cc
index ffdef67..cd9be849 100644
--- a/components/sync/driver/fake_sync_client.cc
+++ b/components/sync/driver/fake_sync_client.cc
@@ -13,14 +13,6 @@
 
 namespace syncer {
 
-namespace {
-
-void DummyRegisterPlatformTypesCallback(SyncService* sync_service,
-                                        ModelTypeSet,
-                                        ModelTypeSet) {}
-
-}  // namespace
-
 FakeSyncClient::FakeSyncClient()
     : bridge_(nullptr),
       factory_(nullptr),
@@ -73,9 +65,11 @@
   return base::DoNothing();
 }
 
-SyncApiComponentFactory::RegisterDataTypesMethod
-FakeSyncClient::GetRegisterPlatformTypesCallback() {
-  return base::Bind(&DummyRegisterPlatformTypesCallback);
+DataTypeController::TypeVector FakeSyncClient::CreateDataTypeControllers(
+    LocalDeviceInfoProvider* local_device_info_provider) {
+  DCHECK(factory_);
+  return factory_->CreateCommonDataTypeControllers(
+      /*disabled_types=*/ModelTypeSet(), local_device_info_provider);
 }
 
 autofill::PersonalDataManager* FakeSyncClient::GetPersonalDataManager() {
diff --git a/components/sync/driver/fake_sync_client.h b/components/sync/driver/fake_sync_client.h
index 35cf7fac..3f1c760 100644
--- a/components/sync/driver/fake_sync_client.h
+++ b/components/sync/driver/fake_sync_client.h
@@ -34,8 +34,8 @@
   history::HistoryService* GetHistoryService() override;
   bool HasPasswordStore() override;
   base::Closure GetPasswordStateChangedCallback() override;
-  SyncApiComponentFactory::RegisterDataTypesMethod
-  GetRegisterPlatformTypesCallback() override;
+  DataTypeController::TypeVector CreateDataTypeControllers(
+      LocalDeviceInfoProvider* local_device_info_provider) override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   BookmarkUndoService* GetBookmarkUndoServiceIfExists() override;
   invalidation::InvalidationService* GetInvalidationService() override;
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc
index aca7443..68df8c28 100644
--- a/components/sync/driver/fake_sync_service.cc
+++ b/components/sync/driver/fake_sync_service.cc
@@ -152,9 +152,6 @@
   return nullptr;
 }
 
-void FakeSyncService::RegisterDataTypeController(
-    std::unique_ptr<DataTypeController> data_type_controller) {}
-
 void FakeSyncService::ReenableDatatype(ModelType type) {}
 
 syncer::SyncTokenStatus FakeSyncService::GetSyncTokenStatus() const {
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h
index 1efece9..b16d35f8 100644
--- a/components/sync/driver/fake_sync_service.h
+++ b/components/sync/driver/fake_sync_service.h
@@ -73,8 +73,6 @@
   bool IsCryptographerReady(const BaseTransaction* trans) const override;
   UserShare* GetUserShare() const override;
   LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const override;
-  void RegisterDataTypeController(
-      std::unique_ptr<DataTypeController> data_type_controller) override;
   void ReenableDatatype(ModelType type) override;
   SyncTokenStatus GetSyncTokenStatus() const override;
   std::string QuerySyncStatusSummaryString() override;
diff --git a/components/sync/driver/frontend_data_type_controller.cc b/components/sync/driver/frontend_data_type_controller.cc
index b39344e..533acd4 100644
--- a/components/sync/driver/frontend_data_type_controller.cc
+++ b/components/sync/driver/frontend_data_type_controller.cc
@@ -4,6 +4,8 @@
 
 #include "components/sync/driver/frontend_data_type_controller.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "components/sync/base/data_type_histogram.h"
@@ -248,8 +250,8 @@
 }
 
 void FrontendDataTypeController::set_model_associator(
-    AssociatorInterface* model_associator) {
-  model_associator_.reset(model_associator);
+    std::unique_ptr<AssociatorInterface> model_associator) {
+  model_associator_ = std::move(model_associator);
 }
 
 ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() const {
@@ -257,8 +259,8 @@
 }
 
 void FrontendDataTypeController::set_change_processor(
-    ChangeProcessor* change_processor) {
-  change_processor_.reset(change_processor);
+    std::unique_ptr<ChangeProcessor> change_processor) {
+  change_processor_ = std::move(change_processor);
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/frontend_data_type_controller.h b/components/sync/driver/frontend_data_type_controller.h
index 69b61aa..0e6a144 100644
--- a/components/sync/driver/frontend_data_type_controller.h
+++ b/components/sync/driver/frontend_data_type_controller.h
@@ -80,9 +80,10 @@
   virtual void RecordStartFailure(ConfigureResult result);
 
   virtual AssociatorInterface* model_associator() const;
-  virtual void set_model_associator(AssociatorInterface* associator);
+  virtual void set_model_associator(
+      std::unique_ptr<AssociatorInterface> associator);
   ChangeProcessor* GetChangeProcessor() const override;
-  virtual void set_change_processor(ChangeProcessor* processor);
+  virtual void set_change_processor(std::unique_ptr<ChangeProcessor> processor);
 
   // If the DTC is waiting for models to load, once the models are
   // loaded the datatype service will call this function on DTC to let
diff --git a/components/sync/driver/frontend_data_type_controller_mock.h b/components/sync/driver/frontend_data_type_controller_mock.h
index 3b530c6..f1779888 100644
--- a/components/sync/driver/frontend_data_type_controller_mock.h
+++ b/components/sync/driver/frontend_data_type_controller_mock.h
@@ -5,9 +5,12 @@
 #ifndef COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__
 #define COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__
 
+#include <memory>
 #include <string>
 
 #include "components/sync/driver/frontend_data_type_controller.h"
+#include "components/sync/driver/model_associator.h"
+#include "components/sync/model/change_processor.h"
 #include "components/sync/model/sync_error.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -33,9 +36,11 @@
   MOCK_METHOD0(CreateSyncComponents, void());
   MOCK_METHOD0(CleanUpState, void());
   MOCK_CONST_METHOD0(model_associator, AssociatorInterface*());
-  MOCK_METHOD1(set_model_associator, void(AssociatorInterface* associator));
+  MOCK_METHOD1(set_model_associator,
+               void(std::unique_ptr<AssociatorInterface> associator));
   MOCK_CONST_METHOD0(change_processor, ChangeProcessor*());
-  MOCK_METHOD1(set_change_processor, void(ChangeProcessor* processor));
+  MOCK_METHOD1(set_change_processor,
+               void(std::unique_ptr<ChangeProcessor> processor));
   MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time));
   MOCK_METHOD1(RecordStartFailure, void(ConfigureResult result));
 };
diff --git a/components/sync/driver/frontend_data_type_controller_unittest.cc b/components/sync/driver/frontend_data_type_controller_unittest.cc
index 1acd804..d378cd793 100644
--- a/components/sync/driver/frontend_data_type_controller_unittest.cc
+++ b/components/sync/driver/frontend_data_type_controller_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/sync/driver/frontend_data_type_controller.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
@@ -24,6 +26,7 @@
 using testing::_;
 using testing::DoAll;
 using testing::InvokeWithoutArgs;
+using testing::NiceMock;
 using testing::Return;
 using testing::SetArgPointee;
 using testing::StrictMock;
@@ -43,9 +46,9 @@
   void CreateSyncComponents() override {
     SyncApiComponentFactory::SyncComponents sync_components =
         sync_client_->GetSyncApiComponentFactory()
-            ->CreateBookmarkSyncComponents(nullptr, CreateErrorHandler());
-    model_associator_.reset(sync_components.model_associator);
-    change_processor_.reset(sync_components.change_processor);
+            ->CreateBookmarkSyncComponents(CreateErrorHandler());
+    model_associator_ = std::move(sync_components.model_associator);
+    change_processor_ = std::move(sync_components.change_processor);
   }
 
   // We mock the following methods because their default implementations do
@@ -65,11 +68,22 @@
 
 class SyncFrontendDataTypeControllerTest : public testing::Test {
  public:
-  SyncFrontendDataTypeControllerTest()
-      : model_associator_(new ModelAssociatorMock()),
-        change_processor_(new ChangeProcessorMock()),
-        components_factory_(model_associator_, change_processor_),
-        sync_client_(&components_factory_) {}
+  SyncFrontendDataTypeControllerTest() : sync_client_(&components_factory_) {
+    model_associator_deleter_ =
+        std::make_unique<NiceMock<ModelAssociatorMock>>();
+    change_processor_deleter_ =
+        std::make_unique<NiceMock<ChangeProcessorMock>>();
+    model_associator_ = model_associator_deleter_.get();
+    change_processor_ = change_processor_deleter_.get();
+
+    ON_CALL(components_factory_, CreateBookmarkSyncComponents(_))
+        .WillByDefault(testing::InvokeWithoutArgs([=]() {
+          SyncApiComponentFactory::SyncComponents components;
+          components.model_associator = std::move(model_associator_deleter_);
+          components.change_processor = std::move(change_processor_deleter_);
+          return components;
+        }));
+  }
 
   void SetUp() override {
     dtc_mock_ = std::make_unique<StrictMock<FrontendDataTypeControllerMock>>();
@@ -122,7 +136,9 @@
   base::MessageLoop message_loop_;
   ModelAssociatorMock* model_associator_;
   ChangeProcessorMock* change_processor_;
-  SyncApiComponentFactoryMock components_factory_;
+  std::unique_ptr<ModelAssociatorMock> model_associator_deleter_;
+  std::unique_ptr<ChangeProcessorMock> change_processor_deleter_;
+  NiceMock<SyncApiComponentFactoryMock> components_factory_;
   FakeSyncClient sync_client_;
   std::unique_ptr<FrontendDataTypeControllerFake> frontend_dtc_;
   std::unique_ptr<FrontendDataTypeControllerMock> dtc_mock_;
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc
index 13c1b21..0ee8f1a 100644
--- a/components/sync/driver/generic_change_processor_unittest.cc
+++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -15,7 +15,7 @@
 #include "components/sync/device_info/local_device_info_provider.h"
 #include "components/sync/driver/data_type_manager.h"
 #include "components/sync/driver/fake_sync_client.h"
-#include "components/sync/driver/sync_api_component_factory.h"
+#include "components/sync/driver/sync_api_component_factory_mock.h"
 #include "components/sync/engine/sync_encryption_handler.h"
 #include "components/sync/engine/sync_engine.h"
 #include "components/sync/model/data_type_error_handler_mock.h"
@@ -34,42 +34,6 @@
 
 namespace {
 
-// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor.
-class MockSyncApiComponentFactory : public SyncApiComponentFactory {
- public:
-  MockSyncApiComponentFactory() {}
-
-  // SyncApiComponentFactory implementation.
-  void RegisterDataTypes(
-      SyncService* sync_service,
-      const RegisterDataTypesMethod& register_platform_types_method) override {}
-  std::unique_ptr<DataTypeManager> CreateDataTypeManager(
-      ModelTypeSet initial_types,
-      const WeakHandle<DataTypeDebugInfoListener>& debug_info_listener,
-      const DataTypeController::TypeMap* controllers,
-      const DataTypeEncryptionHandler* encryption_handler,
-      ModelTypeConfigurer* configurer,
-      DataTypeManagerObserver* observer) override {
-    return nullptr;
-  };
-  std::unique_ptr<SyncEngine> CreateSyncEngine(
-      const std::string& name,
-      invalidation::InvalidationService* invalidator,
-      const base::WeakPtr<SyncPrefs>& sync_prefs,
-      const base::FilePath& sync_folder) override {
-    return nullptr;
-  }
-  std::unique_ptr<LocalDeviceInfoProvider> CreateLocalDeviceInfoProvider()
-      override {
-    return nullptr;
-  }
-  SyncComponents CreateBookmarkSyncComponents(
-      SyncService* sync_service,
-      std::unique_ptr<DataTypeErrorHandler> error_handler) override {
-    return SyncComponents(nullptr, nullptr);
-  }
-};
-
 class SyncGenericChangeProcessorTest : public testing::Test {
  public:
   // Most test cases will use this type.  For those that need a
@@ -151,7 +115,7 @@
 
   std::unique_ptr<TestUserShare> test_user_share_;
   FakeSyncClient sync_client_;
-  MockSyncApiComponentFactory sync_factory_;
+  testing::NiceMock<SyncApiComponentFactoryMock> sync_factory_;
 
   std::unique_ptr<GenericChangeProcessor> change_processor_;
 };
diff --git a/components/sync/driver/shared_change_processor_unittest.cc b/components/sync/driver/shared_change_processor_unittest.cc
index 8bd49309..b78c3338 100644
--- a/components/sync/driver/shared_change_processor_unittest.cc
+++ b/components/sync/driver/shared_change_processor_unittest.cc
@@ -18,7 +18,7 @@
 #include "components/sync/driver/fake_sync_client.h"
 #include "components/sync/driver/generic_change_processor.h"
 #include "components/sync/driver/generic_change_processor_factory.h"
-#include "components/sync/driver/sync_api_component_factory.h"
+#include "components/sync/driver/sync_api_component_factory_mock.h"
 #include "components/sync/engine/sync_engine.h"
 #include "components/sync/model/data_type_error_handler_mock.h"
 #include "components/sync/model/fake_syncable_service.h"
@@ -33,42 +33,6 @@
 using ::testing::NiceMock;
 using ::testing::StrictMock;
 
-class TestSyncApiComponentFactory : public SyncApiComponentFactory {
- public:
-  TestSyncApiComponentFactory() {}
-  ~TestSyncApiComponentFactory() override {}
-
-  // SyncApiComponentFactory implementation.
-  void RegisterDataTypes(
-      SyncService* sync_service,
-      const RegisterDataTypesMethod& register_platform_types_method) override {}
-  std::unique_ptr<DataTypeManager> CreateDataTypeManager(
-      ModelTypeSet initial_types,
-      const WeakHandle<DataTypeDebugInfoListener>& debug_info_listener,
-      const DataTypeController::TypeMap* controllers,
-      const DataTypeEncryptionHandler* encryption_handler,
-      ModelTypeConfigurer* configurer,
-      DataTypeManagerObserver* observer) override {
-    return nullptr;
-  }
-  std::unique_ptr<SyncEngine> CreateSyncEngine(
-      const std::string& name,
-      invalidation::InvalidationService* invalidator,
-      const base::WeakPtr<SyncPrefs>& sync_prefs,
-      const base::FilePath& sync_folder) override {
-    return nullptr;
-  }
-  std::unique_ptr<LocalDeviceInfoProvider> CreateLocalDeviceInfoProvider()
-      override {
-    return nullptr;
-  }
-  SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents(
-      SyncService* sync_service,
-      std::unique_ptr<DataTypeErrorHandler> error_handler) override {
-    return SyncApiComponentFactory::SyncComponents(nullptr, nullptr);
-  }
-};
-
 class SyncSharedChangeProcessorTest : public testing::Test,
                                       public FakeSyncClient {
  public:
@@ -159,7 +123,7 @@
   base::MessageLoop frontend_loop_;
   base::Thread model_thread_;
   TestUserShare test_user_share_;
-  TestSyncApiComponentFactory factory_;
+  NiceMock<SyncApiComponentFactoryMock> factory_;
 
   scoped_refptr<SharedChangeProcessor> shared_change_processor_;
 
diff --git a/components/sync/driver/sync_api_component_factory.cc b/components/sync/driver/sync_api_component_factory.cc
new file mode 100644
index 0000000..6c30588
--- /dev/null
+++ b/components/sync/driver/sync_api_component_factory.cc
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/driver/sync_api_component_factory.h"
+
+#include "components/sync/driver/model_associator.h"
+#include "components/sync/model/change_processor.h"
+
+namespace syncer {
+
+SyncApiComponentFactory::SyncComponents::SyncComponents() = default;
+
+SyncApiComponentFactory::SyncComponents::SyncComponents(SyncComponents&&) =
+    default;
+
+SyncApiComponentFactory::SyncComponents::~SyncComponents() = default;
+
+}  // namespace syncer
diff --git a/components/sync/driver/sync_api_component_factory.h b/components/sync/driver/sync_api_component_factory.h
index ecfe129..1143fc2 100644
--- a/components/sync/driver/sync_api_component_factory.h
+++ b/components/sync/driver/sync_api_component_factory.h
@@ -32,9 +32,7 @@
 class DataTypeManagerObserver;
 class LocalDeviceInfoProvider;
 class SyncEngine;
-class SyncClient;
 class SyncPrefs;
-class SyncService;
 class SyncableService;
 
 // This factory provides sync driver code with the model type specific sync/api
@@ -42,14 +40,6 @@
 class SyncApiComponentFactory {
  public:
   virtual ~SyncApiComponentFactory() {}
-  // Callback to allow platform-specific datatypes to register themselves as
-  // data type controllers.
-  // |disabled_types| and |enabled_types| control the disable/enable state of
-  // types that are on or off by default (respectively).
-  using RegisterDataTypesMethod =
-      base::Callback<void(SyncService* sync_service,
-                          ModelTypeSet disabled_types,
-                          ModelTypeSet enabled_types)>;
 
   // The various factory methods for the data type model associators
   // and change processors all return this struct.  This is needed
@@ -61,20 +51,23 @@
   // weak pointer to a SyncableService. All others continue to return
   // SyncComponents. It is safe to assume that the factory methods below are
   // called on the same thread in which the datatype resides.
-  //
-  // TODO(zea): Have all datatypes using the new API switch to returning
-  // SyncableService weak pointers instead of SyncComponents (crbug.com/100114).
   struct SyncComponents {
-    AssociatorInterface* model_associator;
-    ChangeProcessor* change_processor;
-    SyncComponents(AssociatorInterface* ma, ChangeProcessor* cp)
-        : model_associator(ma), change_processor(cp) {}
+    SyncComponents();
+    SyncComponents(SyncComponents&&);
+    ~SyncComponents();
+
+    std::unique_ptr<AssociatorInterface> model_associator;
+    std::unique_ptr<ChangeProcessor> change_processor;
   };
 
-  // Creates and registers enabled datatypes with the provided SyncClient.
-  virtual void RegisterDataTypes(
-      SyncService* sync_service,
-      const RegisterDataTypesMethod& register_platform_types_method) = 0;
+  // Creates and returns enabled datatypes and their controllers.
+  // |disabled_types| allows callers to prevent certain types from being
+  // created (e.g. to honor command-line flags).
+  // TODO(crbug.com/681921): Remove |local_device_info_provider| once the
+  // migration to USS is completed.
+  virtual DataTypeController::TypeVector CreateCommonDataTypeControllers(
+      ModelTypeSet disabled_types,
+      LocalDeviceInfoProvider* local_device_info_provider) = 0;
 
   virtual std::unique_ptr<DataTypeManager> CreateDataTypeManager(
       ModelTypeSet initial_types,
@@ -97,7 +90,6 @@
 
   // Legacy datatypes that need to be converted to the SyncableService API.
   virtual SyncComponents CreateBookmarkSyncComponents(
-      SyncService* sync_service,
       std::unique_ptr<DataTypeErrorHandler> error_handler) = 0;
 };
 
diff --git a/components/sync/driver/sync_api_component_factory_mock.cc b/components/sync/driver/sync_api_component_factory_mock.cc
index 351f45d6..e675211c 100644
--- a/components/sync/driver/sync_api_component_factory_mock.cc
+++ b/components/sync/driver/sync_api_component_factory_mock.cc
@@ -7,48 +7,18 @@
 #include <utility>
 
 #include "components/sync/device_info/local_device_info_provider_mock.h"
-#include "components/sync/driver/model_associator.h"
-#include "components/sync/model/change_processor.h"
-
-using testing::_;
-using testing::InvokeWithoutArgs;
-using testing::Return;
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace syncer {
 
-SyncApiComponentFactoryMock::SyncApiComponentFactoryMock() = default;
-
-SyncApiComponentFactoryMock::SyncApiComponentFactoryMock(
-    AssociatorInterface* model_associator,
-    ChangeProcessor* change_processor)
-    : model_associator_(model_associator),
-      change_processor_(change_processor) {}
-
-SyncApiComponentFactoryMock::~SyncApiComponentFactoryMock() {}
-
-SyncApiComponentFactory::SyncComponents
-SyncApiComponentFactoryMock::CreateBookmarkSyncComponents(
-    SyncService* sync_service,
-    std::unique_ptr<DataTypeErrorHandler> error_handler) {
-  return MakeSyncComponents();
+SyncApiComponentFactoryMock::SyncApiComponentFactoryMock() {
+  // To avoid returning nulls and crashes in many tests, we default to create
+  // a mock device info provider.
+  ON_CALL(*this, CreateLocalDeviceInfoProvider())
+      .WillByDefault(testing::Invoke(
+          []() { return std::make_unique<LocalDeviceInfoProviderMock>(); }));
 }
 
-SyncApiComponentFactory::SyncComponents
-SyncApiComponentFactoryMock::MakeSyncComponents() {
-  return SyncApiComponentFactory::SyncComponents(model_associator_.release(),
-                                                 change_processor_.release());
-}
-
-std::unique_ptr<LocalDeviceInfoProvider>
-SyncApiComponentFactoryMock::CreateLocalDeviceInfoProvider() {
-  if (local_device_)
-    return std::move(local_device_);
-  return std::make_unique<LocalDeviceInfoProviderMock>();
-}
-
-void SyncApiComponentFactoryMock::SetLocalDeviceInfoProvider(
-    std::unique_ptr<LocalDeviceInfoProvider> local_device) {
-  local_device_ = std::move(local_device);
-}
+SyncApiComponentFactoryMock::~SyncApiComponentFactoryMock() = default;
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_api_component_factory_mock.h b/components/sync/driver/sync_api_component_factory_mock.h
index e12922a..01325cf1 100644
--- a/components/sync/driver/sync_api_component_factory_mock.h
+++ b/components/sync/driver/sync_api_component_factory_mock.h
@@ -9,28 +9,29 @@
 #include <string>
 
 #include "components/sync/base/model_type.h"
+#include "components/sync/device_info/local_device_info_provider.h"
 #include "components/sync/driver/data_type_controller.h"
 #include "components/sync/driver/data_type_manager.h"
+#include "components/sync/driver/model_associator.h"
 #include "components/sync/driver/sync_api_component_factory.h"
 #include "components/sync/engine/sync_engine.h"
+#include "components/sync/model/change_processor.h"
 #include "components/sync/model/data_type_error_handler.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace syncer {
 
-class AssociatorInterface;
-class ChangeProcessor;
 class DataTypeEncryptionHandler;
 
 class SyncApiComponentFactoryMock : public SyncApiComponentFactory {
  public:
   SyncApiComponentFactoryMock();
-  SyncApiComponentFactoryMock(AssociatorInterface* model_associator,
-                              ChangeProcessor* change_processor);
   ~SyncApiComponentFactoryMock() override;
 
-  MOCK_METHOD2(RegisterDataTypes,
-               void(SyncService* sync_service, const RegisterDataTypesMethod&));
+  MOCK_METHOD2(CreateCommonDataTypeControllers,
+               DataTypeController::TypeVector(
+                   ModelTypeSet disabled_types,
+                   LocalDeviceInfoProvider* local_device_info_provider));
   MOCK_METHOD6(CreateDataTypeManager,
                std::unique_ptr<DataTypeManager>(
                    ModelTypeSet,
@@ -45,24 +46,11 @@
                    invalidation::InvalidationService* invalidator,
                    const base::WeakPtr<SyncPrefs>& sync_prefs,
                    const base::FilePath& sync_folder));
-
-  std::unique_ptr<LocalDeviceInfoProvider> CreateLocalDeviceInfoProvider()
-      override;
-  void SetLocalDeviceInfoProvider(
-      std::unique_ptr<LocalDeviceInfoProvider> local_device);
-
-  SyncComponents CreateBookmarkSyncComponents(
-      SyncService* sync_service,
-      std::unique_ptr<DataTypeErrorHandler> error_handler) override;
-
- private:
-  SyncApiComponentFactory::SyncComponents MakeSyncComponents();
-
-  std::unique_ptr<AssociatorInterface> model_associator_;
-  std::unique_ptr<ChangeProcessor> change_processor_;
-  // LocalDeviceInfoProvider is initially owned by this class,
-  // transferred to caller when CreateLocalDeviceInfoProvider is called.
-  std::unique_ptr<LocalDeviceInfoProvider> local_device_;
+  MOCK_METHOD0(CreateLocalDeviceInfoProvider,
+               std::unique_ptr<LocalDeviceInfoProvider>());
+  MOCK_METHOD1(
+      CreateBookmarkSyncComponents,
+      SyncComponents(std::unique_ptr<DataTypeErrorHandler> error_handler));
 };
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_client.h b/components/sync/driver/sync_client.h
index 01c1efd..3d2ff8bd 100644
--- a/components/sync/driver/sync_client.h
+++ b/components/sync/driver/sync_client.h
@@ -44,6 +44,7 @@
 
 namespace syncer {
 
+class LocalDeviceInfoProvider;
 class SyncService;
 class SyncableService;
 
@@ -77,10 +78,11 @@
   virtual history::HistoryService* GetHistoryService() = 0;
   virtual bool HasPasswordStore() = 0;
 
-  // Returns a callback that will register the types specific to the current
-  // platform.
-  virtual SyncApiComponentFactory::RegisterDataTypesMethod
-  GetRegisterPlatformTypesCallback() = 0;
+  // Returns a vector with all supported datatypes and their controllers.
+  // TODO(crbug.com/681921): Remove |local_device_info_provider| once the
+  // migration to USS is completed.
+  virtual DataTypeController::TypeVector CreateDataTypeControllers(
+      LocalDeviceInfoProvider* local_device_info_provider) = 0;
 
   // Returns a callback that will be invoked when password sync state has
   // potentially been changed.
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h
index 165281388..0ccd430 100644
--- a/components/sync/driver/sync_service.h
+++ b/components/sync/driver/sync_service.h
@@ -29,7 +29,6 @@
 namespace syncer {
 
 class BaseTransaction;
-class DataTypeController;
 class JsController;
 class LocalDeviceInfoProvider;
 class GlobalIdMapper;
@@ -264,13 +263,6 @@
   // Returns DeviceInfo provider for the local device.
   virtual LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const = 0;
 
-  // Registers a data type controller with the sync service.  This
-  // makes the data type controller available for use, it does not
-  // enable or activate the synchronization of the data type (see
-  // ActivateDataType).  Takes ownership of the pointer.
-  virtual void RegisterDataTypeController(
-      std::unique_ptr<DataTypeController> data_type_controller) = 0;
-
   // Called to re-enable a type disabled by DisableDatatype(..). Note, this does
   // not change the preferred state of a datatype, and is not persisted across
   // restarts.
diff --git a/components/sync_bookmarks/bookmark_data_type_controller.cc b/components/sync_bookmarks/bookmark_data_type_controller.cc
index 1a2e494..a0aa9782 100644
--- a/components/sync_bookmarks/bookmark_data_type_controller.cc
+++ b/components/sync_bookmarks/bookmark_data_type_controller.cc
@@ -4,11 +4,15 @@
 
 #include "components/sync_bookmarks/bookmark_data_type_controller.h"
 
+#include <utility>
+
 #include "base/metrics/histogram.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/history/core/browser/history_service.h"
+#include "components/sync/driver/model_associator.h"
 #include "components/sync/driver/sync_api_component_factory.h"
 #include "components/sync/driver/sync_client.h"
+#include "components/sync/model/change_processor.h"
 
 using bookmarks::BookmarkModel;
 
@@ -48,9 +52,9 @@
   DCHECK(CalledOnValidThread());
   syncer::SyncApiComponentFactory::SyncComponents sync_components =
       sync_client_->GetSyncApiComponentFactory()->CreateBookmarkSyncComponents(
-          sync_client_->GetSyncService(), CreateErrorHandler());
-  set_model_associator(sync_components.model_associator);
-  set_change_processor(sync_components.change_processor);
+          CreateErrorHandler());
+  set_model_associator(std::move(sync_components.model_associator));
+  set_change_processor(std::move(sync_components.change_processor));
 }
 
 void BookmarkDataTypeController::BookmarkModelChanged() {
diff --git a/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc b/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
index 0da3441..0a68afa3 100644
--- a/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
+++ b/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/sync_bookmarks/bookmark_data_type_controller.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -37,6 +38,7 @@
 using testing::_;
 using testing::DoAll;
 using testing::InvokeWithoutArgs;
+using testing::NiceMock;
 using testing::Return;
 using testing::SetArgPointee;
 
@@ -64,18 +66,27 @@
   }
   syncer::SyncService* GetSyncService() override { return &service_; }
   syncer::SyncApiComponentFactory* GetSyncApiComponentFactory() override {
-    return profile_sync_factory_.get();
+    return &components_factory_;
   }
 
   void SetUp() override {
-    model_associator_ = new ModelAssociatorMock();
-    change_processor_ = new ChangeProcessorMock();
+    model_associator_deleter_ =
+        std::make_unique<NiceMock<ModelAssociatorMock>>();
+    change_processor_deleter_ =
+        std::make_unique<NiceMock<ChangeProcessorMock>>();
+    model_associator_ = model_associator_deleter_.get();
+    change_processor_ = change_processor_deleter_.get();
     history_service_ = std::make_unique<HistoryMock>();
-    profile_sync_factory_ =
-        std::make_unique<syncer::SyncApiComponentFactoryMock>(
-            model_associator_, change_processor_);
     bookmark_dtc_ =
         std::make_unique<BookmarkDataTypeController>(base::DoNothing(), this);
+
+    ON_CALL(components_factory_, CreateBookmarkSyncComponents(_))
+        .WillByDefault(testing::InvokeWithoutArgs([=]() {
+          syncer::SyncApiComponentFactory::SyncComponents components;
+          components.model_associator = std::move(model_associator_deleter_);
+          components.change_processor = std::move(change_processor_deleter_);
+          return components;
+        }));
   }
 
  protected:
@@ -131,13 +142,15 @@
   }
 
   base::MessageLoop message_loop_;
-  std::unique_ptr<syncer::SyncApiComponentFactoryMock> profile_sync_factory_;
+  testing::NiceMock<syncer::SyncApiComponentFactoryMock> components_factory_;
   std::unique_ptr<BookmarkModel> bookmark_model_;
   std::unique_ptr<HistoryMock> history_service_;
   std::unique_ptr<BookmarkDataTypeController> bookmark_dtc_;
   syncer::FakeSyncService service_;
   ModelAssociatorMock* model_associator_;
   ChangeProcessorMock* change_processor_;
+  std::unique_ptr<ModelAssociatorMock> model_associator_deleter_;
+  std::unique_ptr<ChangeProcessorMock> change_processor_deleter_;
   StartCallbackMock start_callback_;
   ModelLoadCallbackMock model_load_callback_;
 };
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index 03425b5..b5de025 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -109,19 +109,12 @@
     "resources/bitmap_allocation.h",
     "resources/platform_color.h",
     "resources/release_callback.h",
-    "resources/resource.cc",
-    "resources/resource.h",
-    "resources/resource_fence.h",
     "resources/resource_id.h",
-    "resources/resource_metadata.cc",
-    "resources/resource_metadata.h",
     "resources/resource_settings.cc",
     "resources/resource_settings.h",
     "resources/resource_sizes.h",
-    "resources/resource_type.h",
     "resources/return_callback.h",
     "resources/returned_resource.h",
-    "resources/shared_bitmap_manager.h",
     "resources/single_release_callback.cc",
     "resources/single_release_callback.h",
     "resources/transferable_resource.cc",
diff --git a/components/viz/common/resources/resource.cc b/components/viz/common/resources/resource.cc
deleted file mode 100644
index 5ba7cf75..0000000
--- a/components/viz/common/resources/resource.cc
+++ /dev/null
@@ -1,61 +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/viz/common/resources/resource.h"
-
-#include "build/build_config.h"
-#include "components/viz/common/quads/shared_bitmap.h"
-
-namespace viz {
-namespace internal {
-
-Resource::Resource(const gfx::Size& size,
-                   ResourceType type,
-                   ResourceFormat format,
-                   const gfx::ColorSpace& color_space)
-    : locked_for_external_use(false),
-      marked_for_deletion(false),
-      read_lock_fences_enabled(false),
-      is_overlay_candidate(false),
-#if defined(OS_ANDROID)
-      is_backed_by_surface_texture(false),
-      wants_promotion_hint(false),
-#endif
-      size(size),
-      type(type),
-      format(format),
-      color_space(color_space) {
-}
-
-Resource::Resource(Resource&& other) = default;
-Resource::~Resource() = default;
-Resource& Resource::operator=(Resource&& other) = default;
-
-void Resource::SetLocallyUsed() {
-  synchronization_state_ = LOCALLY_USED;
-  sync_token_.Clear();
-}
-
-void Resource::SetSynchronized() {
-  synchronization_state_ = SYNCHRONIZED;
-}
-
-void Resource::UpdateSyncToken(const gpu::SyncToken& sync_token) {
-  DCHECK(is_gpu_resource_type());
-  // An empty sync token may be used if commands are guaranteed to have run on
-  // the gpu process or in case of context loss.
-  sync_token_ = sync_token;
-  synchronization_state_ = sync_token.HasData() ? NEEDS_WAIT : SYNCHRONIZED;
-}
-
-int8_t* Resource::GetSyncTokenData() {
-  return sync_token_.GetData();
-}
-
-bool Resource::ShouldWaitSyncToken() const {
-  return synchronization_state_ == NEEDS_WAIT;
-}
-
-}  // namespace internal
-}  // namespace viz
diff --git a/components/viz/common/resources/resource.h b/components/viz/common/resources/resource.h
deleted file mode 100644
index 1d04dfa9..0000000
--- a/components/viz/common/resources/resource.h
+++ /dev/null
@@ -1,202 +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_VIZ_COMMON_RESOURCES_RESOURCE_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_H_
-
-#include <memory>
-
-#include "build/build_config.h"
-#include "components/viz/common/quads/shared_bitmap.h"
-#include "components/viz/common/resources/release_callback.h"
-#include "components/viz/common/resources/resource_fence.h"
-#include "components/viz/common/resources/resource_format.h"
-#include "components/viz/common/resources/resource_id.h"
-#include "components/viz/common/resources/resource_type.h"
-#include "components/viz/common/viz_common_export.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace gfx {
-class GpuMemoryBuffer;
-}
-
-namespace viz {
-namespace internal {
-
-// The data structure used to track state of Gpu and Software-based
-// resources both in the client and the service, for resources transferred
-// between the two. This is an implementation detail of the resource tracking
-// for client and service libraries and should not be used directly from
-// external client code.
-struct VIZ_COMMON_EXPORT Resource {
-  enum SynchronizationState {
-    // The LOCALLY_USED state is the state each resource defaults to when
-    // constructed or modified or read. This state indicates that the
-    // resource has not been properly synchronized and it would be an error
-    // to return this resource to a client.
-    LOCALLY_USED,
-
-    // The NEEDS_WAIT state is the state that indicates a resource has been
-    // modified but it also has an associated sync token assigned to it.
-    // The sync token has not been waited on with the local context. When
-    // a sync token arrives from a client, it is automatically initialized as
-    // NEEDS_WAIT as well since we still need to wait on it before the resource
-    // is synchronized on the current context. It is an error to use the
-    // resource locally for reading or writing if the resource is in this state.
-    NEEDS_WAIT,
-
-    // The SYNCHRONIZED state indicates that the resource has been properly
-    // synchronized locally. This can either synchronized externally (such
-    // as the case of software rasterized bitmaps), or synchronized
-    // internally using a sync token that has been waited upon. In the
-    // former case where the resource was synchronized externally, a
-    // corresponding sync token will not exist. In the latter case which was
-    // synchronized from the NEEDS_WAIT state, a corresponding sync token will
-    // exist which is associated with the resource. This sync token is still
-    // valid and still associated with the resource and can be passed as an
-    // external resource for others to wait on.
-    SYNCHRONIZED,
-  };
-
-  Resource(const gfx::Size& size,
-           ResourceType type,
-           ResourceFormat format,
-           const gfx::ColorSpace& color_space);
-
-  Resource(Resource&& other);
-
-  ~Resource();
-
-  Resource& operator=(Resource&& other);
-
-  bool is_gpu_resource_type() const { return type != ResourceType::kBitmap; }
-
-  bool needs_sync_token() const {
-    return type != ResourceType::kBitmap &&
-           synchronization_state_ == LOCALLY_USED;
-  }
-
-  const gpu::SyncToken& sync_token() const { return sync_token_; }
-
-  SynchronizationState synchronization_state() const {
-    return synchronization_state_;
-  }
-
-  void SetLocallyUsed();
-  void SetSynchronized();
-  void UpdateSyncToken(const gpu::SyncToken& sync_token);
-  // If true the texture-backed or GpuMemoryBuffer-backed resource needs its
-  // SyncToken waited on in order to be synchronized for use.
-  bool ShouldWaitSyncToken() const;
-  int8_t* GetSyncTokenData();
-
-  // Bitfield flags. ======
-  // When true, the resource is currently being used externally.
-  bool locked_for_external_use : 1;
-  // When the resource should be deleted until it is actually reaped.
-  bool marked_for_deletion : 1;
-  // Tracks if a gpu fence needs to be used for reading a GpuMemoryBuffer-
-  // backed or texture-backed resource.
-  bool read_lock_fences_enabled : 1;
-  // When true, the resource should be considered for being displayed in an
-  // overlay.
-  bool is_overlay_candidate : 1;
-#if defined(OS_ANDROID)
-  // Indicates whether this resource may not be overlayed on Android, since
-  // it's not backed by a SurfaceView.  This may be set in combination with
-  // |is_overlay_candidate|, to find out if switching the resource to a
-  // a SurfaceView would result in overlay promotion.  It's good to find this
-  // out in advance, since one has no fallback path for displaying a
-  // SurfaceView except via promoting it to an overlay.  Ideally, one _could_
-  // promote SurfaceTexture via the overlay path, even if one ended up just
-  // drawing a quad in the compositor.  However, for now, we use this flag to
-  // refuse to promote so that the compositor will draw the quad.
-  bool is_backed_by_surface_texture : 1;
-  // Indicates that this resource would like a promotion hint.
-  bool wants_promotion_hint : 1;
-#endif
-
-  // In the service, this is the id of the client the resource comes from.
-  int child_id = 0;
-  // In the service, this is the id of the resource in the client's namespace.
-  ResourceId id_in_child = 0;
-  // Texture id for texture-backed resources.
-  GLuint gl_id = 0;
-  // The mailbox associated with resources received from the client to the
-  // service. The mailbox has the IPC-capable data for sharing the resource
-  // backing between modules/GL contexts/processes.
-  gpu::Mailbox mailbox;
-  // Reference-counts to know when a resource can be released through the
-  // |release_callback| after it is deleted, and for verifying correct use
-  // of the resource.
-  int lock_for_read_count = 0;
-  int imported_count = 0;
-  // A fence used for accessing a GpuMemoryBuffer-backed or texture-backed
-  // resource for reading, that ensures any writing done to the resource has
-  // been completed. This is implemented and used to implement transferring
-  // ownership of the resource from the client to the service, and in the GL
-  // drawing code before reading from the texture.
-  scoped_refptr<ResourceFence> read_lock_fence;
-  // Size of the resource in pixels.
-  gfx::Size size;
-  // The texture target for GpuMemoryBuffer- and texture-backed resources.
-  GLenum target = GL_TEXTURE_2D;
-  // The min/mag filter of the resource when it was given to/created by the
-  // ResourceProvider, for texture-backed resources. Used to restore
-  // the filter before releasing the resource. Not used for GpuMemoryBuffer-
-  // backed resources as they are always internally created, so not released.
-  // TODO(skyostil): Use a separate sampler object for filter state.
-  GLenum original_filter = GL_LINEAR;
-  // The current mag filter for GpuMemoryBuffer- and texture-backed resources.
-  GLenum filter = GL_LINEAR;
-  // The current min filter for GpuMemoryBuffer- and texture-backed resources.
-  GLenum min_filter = GL_LINEAR;
-  // The type of backing for the resource (such as gpu vs software).
-  ResourceType type = ResourceType::kBitmap;
-  // This is the the actual format of the underlying GpuMemoryBuffer, if any,
-  // and might not correspond to ResourceFormat. This format is needed to
-  // allocate the GpuMemoryBuffer and scanout the buffer as a hardware overlay.
-  gfx::BufferFormat buffer_format = gfx::BufferFormat::RGBA_8888;
-  // The format as seen from the compositor and might not correspond to
-  // buffer_format (e.g: A resouce that was created from a YUV buffer could be
-  // seen as RGB from the compositor/GL). This is used to derive the GL texture
-  // format for texture-backed resources, the image format for GpuMemoryBuffer-
-  // backed resources, or the SkColorType used for software-backed resources.
-  ResourceFormat format = ResourceFormat::RGBA_8888;
-  // The name of the shared memory for software-backed resources. Present when
-  // the type is kBitmap, and empty otherwise.
-  SharedBitmapId shared_bitmap_id;
-  // A pointer to the shared memory structure for software-backed resources, but
-  // not present if the resources isn't shared memory. This is null until the
-  // resource is mapped for use in the display compositor.
-  std::unique_ptr<SharedBitmap> shared_bitmap;
-  // A GUID for reporting the |shared_bitmap| to memory tracing. The GUID is
-  // known by other components in the system as well to give the same id for
-  // this shared memory bitmap everywhere. This is empty until the resource is
-  // mapped for use in the display compositor.
-  base::UnguessableToken shared_bitmap_tracing_guid;
-  // The color space for all resource types, to control how the resource should
-  // be drawn to output device.
-  gfx::ColorSpace color_space;
-
- private:
-  // Tracks if a sync token needs to be waited on before using the resource.
-  SynchronizationState synchronization_state_ = SYNCHRONIZED;
-  // A SyncToken associated with a texture-backed or GpuMemoryBuffer-backed
-  // resource. It is given from a child to the service, and waited on in order
-  // to use the resource, and this is tracked by the |synchronization_state_|.
-  gpu::SyncToken sync_token_;
-
-  DISALLOW_COPY_AND_ASSIGN(Resource);
-};
-
-}  // namespace internal
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_H_
diff --git a/components/viz/common/resources/resource_type.h b/components/viz/common/resources/resource_type.h
deleted file mode 100644
index a9f8ae3..0000000
--- a/components/viz/common/resources/resource_type.h
+++ /dev/null
@@ -1,18 +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_VIZ_COMMON_RESOURCES_RESOURCE_TYPE_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_TYPE_H_
-
-namespace viz {
-
-// Types of resources that can be sent to the viz compositing service.
-enum class ResourceType {
-  kTexture,
-  kBitmap,
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_TYPE_H_
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index c7e69233..b8a1019ec 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -67,12 +67,16 @@
     "display/program_binding.h",
     "display/renderer_utils.cc",
     "display/renderer_utils.h",
+    "display/resource_fence.h",
+    "display/resource_metadata.cc",
+    "display/resource_metadata.h",
     "display/scoped_gpu_memory_buffer_texture.cc",
     "display/scoped_gpu_memory_buffer_texture.h",
     "display/scoped_render_pass_texture.cc",
     "display/scoped_render_pass_texture.h",
     "display/shader.cc",
     "display/shader.h",
+    "display/shared_bitmap_manager.h",
     "display/skia_output_surface.cc",
     "display/skia_output_surface.h",
     "display/skia_renderer.cc",
diff --git a/components/viz/service/display/DEPS b/components/viz/service/display/DEPS
index 2735fde..d866c452 100644
--- a/components/viz/service/display/DEPS
+++ b/components/viz/service/display/DEPS
@@ -13,6 +13,7 @@
   "+gpu/GLES2",
   "+gpu/vulkan",
   "+media/base",
+  "+mojo/public/cpp/system",
   "+skia",
   "+third_party/khronos",
   "+third_party/skia",
diff --git a/components/viz/service/display/display_perftest.cc b/components/viz/service/display/display_perftest.cc
index ab7d0199..8368e0e 100644
--- a/components/viz/service/display/display_perftest.cc
+++ b/components/viz/service/display/display_perftest.cc
@@ -13,11 +13,11 @@
 #include "components/viz/common/quads/draw_quad.h"
 #include "components/viz/common/quads/render_pass.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/service/display/display.h"
 #include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/display/output_surface.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
 #include "components/viz/test/fake_output_surface.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc
index 4fc64451..f6e22f45 100644
--- a/components/viz/service/display/display_resource_provider.cc
+++ b/components/viz/service/display/display_resource_provider.cc
@@ -13,7 +13,7 @@
 #include "components/viz/common/gpu/context_provider.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/resources/resource_sizes.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "gpu/command_buffer/client/context_support.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
@@ -64,6 +64,9 @@
       shared_bitmap_manager_(shared_bitmap_manager),
       tracing_id_(g_next_display_resource_provider_tracing_id.GetNext()) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  // If no ContextProvider, then we are doing software compositing and a
+  // SharedBitmapManager must be given.
+  DCHECK(compositor_context_provider || shared_bitmap_manager);
 
   // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
   // Don't register a dump provider in these cases.
@@ -104,14 +107,10 @@
     const auto& resource = resource_entry.second;
 
     bool backing_memory_allocated = false;
-    switch (resource.type) {
-      case ResourceType::kTexture:
-        backing_memory_allocated = !!resource.gl_id;
-        break;
-      case ResourceType::kBitmap:
-        backing_memory_allocated = !!resource.shared_bitmap;
-        break;
-    }
+    if (resource.transferable.is_software)
+      backing_memory_allocated = !!resource.shared_bitmap;
+    else
+      backing_memory_allocated = !!resource.gl_id;
 
     if (!backing_memory_allocated) {
       // Don't log unallocated resources - they have no backing memory.
@@ -128,9 +127,9 @@
 
     // Texture resources may not come with a size, in which case don't report
     // one.
-    if (!resource.size.IsEmpty()) {
+    if (!resource.transferable.size.IsEmpty()) {
       uint64_t total_bytes = ResourceSizes::UncheckedSizeInBytesAligned<size_t>(
-          resource.size, resource.format);
+          resource.transferable.size, resource.transferable.format);
       dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
                       base::trace_event::MemoryAllocatorDump::kUnitsBytes,
                       static_cast<uint64_t>(total_bytes));
@@ -140,17 +139,13 @@
     // prevent double counting the memory.
     base::trace_event::MemoryAllocatorDumpGuid guid;
     base::UnguessableToken shared_memory_guid;
-    switch (resource.type) {
-      case ResourceType::kTexture:
-        DCHECK(resource.gl_id);
-        guid = gl::GetGLTextureClientGUIDForTracing(
-            compositor_context_provider_->ContextSupport()
-                ->ShareGroupTracingGUID(),
-            resource.gl_id);
-        break;
-      case ResourceType::kBitmap:
-        shared_memory_guid = resource.shared_bitmap_tracing_guid;
-        break;
+    if (resource.transferable.is_software) {
+      shared_memory_guid = resource.shared_bitmap_tracing_guid;
+    } else {
+      guid = gl::GetGLTextureClientGUIDForTracing(
+          compositor_context_provider_->ContextSupport()
+              ->ShareGroupTracingGUID(),
+          resource.gl_id);
     }
 
     DCHECK(!shared_memory_guid.is_empty() || !guid.empty());
@@ -185,14 +180,14 @@
     if (it->second.marked_for_deletion)
       continue;
 
-    const internal::Resource* resource = LockForRead(id);
+    const ChildResource* resource = LockForRead(id);
     // TODO(ericrk): We should never fail LockForRead, but we appear to be
     // doing so on Android in rare cases. Handle this gracefully until a better
     // solution can be found. https://crbug.com/811858
     if (!resource)
       return;
 
-    DCHECK(resource->wants_promotion_hint);
+    DCHECK(resource->transferable.wants_promotion_hint);
 
     // Insist that this is backed by a GPU texture.
     if (resource->is_gpu_resource_type()) {
@@ -210,8 +205,8 @@
 }
 
 bool DisplayResourceProvider::IsBackedBySurfaceTexture(ResourceId id) {
-  internal::Resource* resource = GetResource(id);
-  return resource->is_backed_by_surface_texture;
+  ChildResource* resource = GetResource(id);
+  return resource->transferable.is_backed_by_surface_texture;
 }
 
 bool DisplayResourceProvider::WantsPromotionHintForTesting(ResourceId id) {
@@ -224,28 +219,28 @@
 #endif
 
 bool DisplayResourceProvider::IsOverlayCandidate(ResourceId id) {
-  internal::Resource* resource = TryGetResource(id);
+  ChildResource* resource = TryGetResource(id);
   // TODO(ericrk): We should never fail TryGetResource, but we appear to
   // be doing so on Android in rare cases. Handle this gracefully until a
   // better solution can be found. https://crbug.com/811858
-  return resource && resource->is_overlay_candidate;
+  return resource && resource->transferable.is_overlay_candidate;
 }
 
-ResourceType DisplayResourceProvider::GetResourceType(ResourceId id) {
-  return GetResource(id)->type;
+bool DisplayResourceProvider::IsResourceSoftwareBacked(ResourceId id) {
+  return GetResource(id)->transferable.is_software;
 }
 
 GLenum DisplayResourceProvider::GetResourceTextureTarget(ResourceId id) {
-  return GetResource(id)->target;
+  return GetResource(id)->transferable.mailbox_holder.texture_target;
 }
 
 gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) {
-  internal::Resource* resource = GetResource(id);
-  return resource->buffer_format;
+  ChildResource* resource = GetResource(id);
+  return resource->transferable.buffer_format;
 }
 
 void DisplayResourceProvider::WaitSyncToken(ResourceId id) {
-  internal::Resource* resource = TryGetResource(id);
+  ChildResource* resource = TryGetResource(id);
   // TODO(ericrk): We should never fail TryGetResource, but we appear to
   // be doing so on Android in rare cases. Handle this gracefully until a
   // better solution can be found. https://crbug.com/811858
@@ -256,7 +251,7 @@
   // Now that the resource is synced, we may send it a promotion hint.  We could
   // sync all |wants_promotion_hint| resources elsewhere, and send 'no' to all
   // resources that weren't used.  However, there's no real advantage.
-  if (resource->wants_promotion_hint)
+  if (resource->transferable.wants_promotion_hint)
     wants_promotion_hints_set_.insert(id);
 #endif  // OS_ANDROID
 }
@@ -287,26 +282,25 @@
 }
 
 void DisplayResourceProvider::ReceiveFromChild(
-    int child,
+    int child_id,
     const std::vector<TransferableResource>& resources) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   GLES2Interface* gl = ContextGL();
-  Child& child_info = children_.find(child)->second;
+  Child& child_info = children_.find(child_id)->second;
   DCHECK(!child_info.marked_for_deletion);
   for (std::vector<TransferableResource>::const_iterator it = resources.begin();
        it != resources.end(); ++it) {
     auto resource_in_map_it = child_info.child_to_parent_map.find(it->id);
     if (resource_in_map_it != child_info.child_to_parent_map.end()) {
-      internal::Resource* resource = GetResource(resource_in_map_it->second);
+      ChildResource* resource = GetResource(resource_in_map_it->second);
       resource->marked_for_deletion = false;
       resource->imported_count++;
       continue;
     }
 
-    if ((!it->is_software && !gl) ||
-        (it->is_software && !shared_bitmap_manager_)) {
+    if (it->is_software != !gl || it->mailbox_holder.mailbox.IsZero()) {
       TRACE_EVENT0(
-          "cc", "DisplayResourceProvider::ReceiveFromChild dropping invalid");
+          "viz", "DisplayResourceProvider::ReceiveFromChild dropping invalid");
       std::vector<ReturnedResource> to_return;
       to_return.push_back(it->ToReturnedResource());
       child_info.return_callback.Run(to_return);
@@ -314,34 +308,12 @@
     }
 
     ResourceId local_id = next_id_++;
-    internal::Resource* resource = nullptr;
     if (it->is_software) {
       DCHECK(IsBitmapFormatSupported(it->format));
-      resource = InsertResource(
-          local_id, internal::Resource(it->size, ResourceType::kBitmap,
-                                       it->format, it->color_space));
-      resource->shared_bitmap_id = it->mailbox_holder.mailbox;
+      InsertResource(local_id, ChildResource(child_id, *it));
     } else {
-      resource = InsertResource(
-          local_id, internal::Resource(it->size, ResourceType::kTexture,
-                                       it->format, it->color_space));
-      resource->target = it->mailbox_holder.texture_target;
-      resource->filter = it->filter;
-      resource->original_filter = it->filter;
-      resource->min_filter = it->filter;
-      resource->buffer_format = it->buffer_format;
-      resource->mailbox = it->mailbox_holder.mailbox;
-      resource->UpdateSyncToken(it->mailbox_holder.sync_token);
-      resource->read_lock_fences_enabled = it->read_lock_fences_enabled;
-      resource->is_overlay_candidate = it->is_overlay_candidate;
-#if defined(OS_ANDROID)
-      resource->is_backed_by_surface_texture = it->is_backed_by_surface_texture;
-      resource->wants_promotion_hint = it->wants_promotion_hint;
-#endif
+      InsertResource(local_id, ChildResource(child_id, *it));
     }
-    resource->child_id = child;
-    resource->imported_count = 1;
-    resource->id_in_child = it->id;
     child_info.child_to_parent_map[it->id] = local_id;
   }
 }
@@ -377,20 +349,21 @@
 }
 
 bool DisplayResourceProvider::InUse(ResourceId id) {
-  internal::Resource* resource = GetResource(id);
+  ChildResource* resource = GetResource(id);
   return resource->lock_for_read_count > 0 || resource->locked_for_external_use;
 }
 
-internal::Resource* DisplayResourceProvider::InsertResource(
+DisplayResourceProvider::ChildResource* DisplayResourceProvider::InsertResource(
     ResourceId id,
-    internal::Resource resource) {
+    ChildResource resource) {
   auto result =
       resources_.insert(ResourceMap::value_type(id, std::move(resource)));
   DCHECK(result.second);
   return &result.first->second;
 }
 
-internal::Resource* DisplayResourceProvider::GetResource(ResourceId id) {
+DisplayResourceProvider::ChildResource* DisplayResourceProvider::GetResource(
+    ResourceId id) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(id);
   auto it = resources_.find(id);
@@ -398,7 +371,8 @@
   return &it->second;
 }
 
-internal::Resource* DisplayResourceProvider::TryGetResource(ResourceId id) {
+DisplayResourceProvider::ChildResource* DisplayResourceProvider::TryGetResource(
+    ResourceId id) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!id)
     return nullptr;
@@ -410,10 +384,11 @@
 
 void DisplayResourceProvider::PopulateSkBitmapWithResource(
     SkBitmap* sk_bitmap,
-    const internal::Resource* resource) {
-  DCHECK(IsBitmapFormatSupported(resource->format));
-  SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
-                                                resource->size.height());
+    const ChildResource* resource) {
+  DCHECK(IsBitmapFormatSupported(resource->transferable.format));
+  SkImageInfo info =
+      SkImageInfo::MakeN32Premul(resource->transferable.size.width(),
+                                 resource->transferable.size.height());
   bool pixels_installed = sk_bitmap->installPixels(
       info, resource->shared_bitmap->pixels(), info.minRowBytes());
   DCHECK(pixels_installed);
@@ -422,7 +397,7 @@
 void DisplayResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
                                                      DeleteStyle style) {
   TRACE_EVENT0("viz", "DosplayResourceProvider::DeleteResourceInternal");
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
 
   if (resource->gl_id) {
     GLES2Interface* gl = ContextGL();
@@ -433,8 +408,7 @@
   resources_.erase(it);
 }
 
-void DisplayResourceProvider::WaitSyncTokenInternal(
-    internal::Resource* resource) {
+void DisplayResourceProvider::WaitSyncTokenInternal(ChildResource* resource) {
   DCHECK(resource);
   if (!resource->ShouldWaitSyncToken())
     return;
@@ -453,43 +427,44 @@
   return context_provider ? context_provider->ContextGL() : nullptr;
 }
 
-const internal::Resource* DisplayResourceProvider::LockForRead(ResourceId id) {
+const DisplayResourceProvider::ChildResource*
+DisplayResourceProvider::LockForRead(ResourceId id) {
   // TODO(ericrk): We should never fail TryGetResource, but we appear to be
   // doing so on Android in rare cases. Handle this gracefully until a better
   // solution can be found. https://crbug.com/811858
-  internal::Resource* resource = TryGetResource(id);
+  ChildResource* resource = TryGetResource(id);
   if (!resource)
     return nullptr;
 
   // Mailbox sync_tokens must be processed by a call to WaitSyncToken() prior to
   // calling LockForRead().
-  DCHECK_NE(internal::Resource::NEEDS_WAIT, resource->synchronization_state());
+  DCHECK_NE(NEEDS_WAIT, resource->synchronization_state());
 
   if (resource->is_gpu_resource_type() && !resource->gl_id) {
-    DCHECK(!resource->mailbox.IsZero());
-
     GLES2Interface* gl = ContextGL();
     DCHECK(gl);
-    resource->gl_id =
-        gl->CreateAndConsumeTextureCHROMIUM(resource->mailbox.name);
+    resource->gl_id = gl->CreateAndConsumeTextureCHROMIUM(
+        resource->transferable.mailbox_holder.mailbox.name);
     resource->SetLocallyUsed();
   }
 
-  if (!resource->shared_bitmap && !resource->is_gpu_resource_type() &&
-      shared_bitmap_manager_) {
+  if (!resource->shared_bitmap && !resource->is_gpu_resource_type()) {
+    const SharedBitmapId& shared_bitmap_id =
+        resource->transferable.mailbox_holder.mailbox;
     std::unique_ptr<SharedBitmap> bitmap =
         shared_bitmap_manager_->GetSharedBitmapFromId(
-            resource->size, resource->format, resource->shared_bitmap_id);
+            resource->transferable.size, resource->transferable.format,
+            shared_bitmap_id);
     if (bitmap) {
       resource->shared_bitmap = std::move(bitmap);
       resource->shared_bitmap_tracing_guid =
           shared_bitmap_manager_->GetSharedBitmapTracingGUIDFromId(
-              resource->shared_bitmap_id);
+              shared_bitmap_id);
     }
   }
 
   resource->lock_for_read_count++;
-  if (resource->read_lock_fences_enabled) {
+  if (resource->transferable.read_lock_fences_enabled) {
     if (current_read_lock_fence_.get())
       current_read_lock_fence_->Set();
     resource->read_lock_fence = current_read_lock_fence_;
@@ -507,7 +482,7 @@
   if (it == resources_.end())
     return;
 
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   DCHECK_GT(resource->lock_for_read_count, 0);
   resource->lock_for_read_count--;
   TryReleaseResource(it);
@@ -518,7 +493,7 @@
   auto it = resources_.find(id);
   DCHECK(it != resources_.end());
 
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   ResourceMetadata metadata;
   // Make sure there is no outstanding LockForExternalUse without calling
   // UnlockForExternalUse.
@@ -526,14 +501,15 @@
   // TODO(penghuang): support software resource.
   DCHECK(resource->is_gpu_resource_type());
 
-  metadata.mailbox = resource->mailbox;
+  metadata.mailbox = resource->transferable.mailbox_holder.mailbox;
   metadata.backend_format = GrBackendFormat::MakeGL(
-      TextureStorageFormat(resource->format), resource->target);
-  metadata.size = resource->size;
+      TextureStorageFormat(resource->transferable.format),
+      resource->transferable.mailbox_holder.texture_target);
+  metadata.size = resource->transferable.size;
   metadata.mip_mapped = GrMipMapped::kNo;
   metadata.origin = kTopLeft_GrSurfaceOrigin;
-  metadata.color_type =
-      ResourceFormatToClosestSkColorType(!IsSoftware(), resource->format);
+  metadata.color_type = ResourceFormatToClosestSkColorType(
+      !IsSoftware(), resource->transferable.format);
   metadata.alpha_type = kPremul_SkAlphaType;
   metadata.color_space = nullptr;
   metadata.sync_token = resource->sync_token();
@@ -550,7 +526,7 @@
   DCHECK(it != resources_.end());
   DCHECK(sync_token.verified_flush());
 
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   DCHECK(resource->locked_for_external_use);
   // TODO(penghuang): support software resource.
   DCHECK(resource->is_gpu_resource_type());
@@ -569,7 +545,7 @@
 
 void DisplayResourceProvider::TryReleaseResource(ResourceMap::iterator it) {
   ResourceId id = it->first;
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   if (resource->marked_for_deletion && !resource->lock_for_read_count &&
       !resource->locked_for_external_use) {
     if (!resource->child_id) {
@@ -604,18 +580,14 @@
   if (it == resources_.end())
     return GL_TEXTURE_2D;
 
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   DCHECK(resource->lock_for_read_count);
 
   ScopedSetActiveTexture scoped_active_tex(gl, unit);
-  GLenum target = resource->target;
+  GLenum target = resource->transferable.mailbox_holder.texture_target;
   gl->BindTexture(target, resource->gl_id);
-  GLenum min_filter = filter;
-  if (min_filter != resource->min_filter) {
-    gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter);
-    resource->min_filter = min_filter;
-  }
   if (filter != resource->filter) {
+    gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
     gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
     resource->filter = filter;
   }
@@ -624,17 +596,17 @@
 }
 
 bool DisplayResourceProvider::ReadLockFenceHasPassed(
-    const internal::Resource* resource) {
+    const ChildResource* resource) {
   return !resource->read_lock_fence || resource->read_lock_fence->HasPassed();
 }
 
 #if defined(OS_ANDROID)
 void DisplayResourceProvider::DeletePromotionHint(ResourceMap::iterator it,
                                                   DeleteStyle style) {
-  internal::Resource* resource = &it->second;
+  ChildResource* resource = &it->second;
   // If this resource was interested in promotion hints, then remove it from
   // the set of resources that we'll notify.
-  if (resource->wants_promotion_hint)
+  if (resource->transferable.wants_promotion_hint)
     wants_promotion_hints_set_.erase(it->first);
 }
 #endif
@@ -661,9 +633,9 @@
   for (ResourceId local_id : unused) {
     auto it = resources_.find(local_id);
     CHECK(it != resources_.end());
-    internal::Resource& resource = it->second;
+    ChildResource& resource = it->second;
 
-    ResourceId child_id = resource.id_in_child;
+    ResourceId child_id = resource.transferable.id;
     DCHECK(child_info->child_to_parent_map.count(child_id));
 
     bool is_lost = (resource.is_gpu_resource_type() && lost_context_provider_);
@@ -688,15 +660,16 @@
     }
 
     if (resource.is_gpu_resource_type() &&
-        resource.filter != resource.original_filter) {
-      DCHECK(resource.target);
+        resource.filter != resource.transferable.filter) {
+      DCHECK(resource.transferable.mailbox_holder.texture_target);
       DCHECK(resource.gl_id);
       DCHECK(gl);
-      gl->BindTexture(resource.target, resource.gl_id);
-      gl->TexParameteri(resource.target, GL_TEXTURE_MIN_FILTER,
-                        resource.original_filter);
-      gl->TexParameteri(resource.target, GL_TEXTURE_MAG_FILTER,
-                        resource.original_filter);
+      gl->BindTexture(resource.transferable.mailbox_holder.texture_target,
+                      resource.gl_id);
+      gl->TexParameteri(resource.transferable.mailbox_holder.texture_target,
+                        GL_TEXTURE_MIN_FILTER, resource.transferable.filter);
+      gl->TexParameteri(resource.transferable.mailbox_holder.texture_target,
+                        GL_TEXTURE_MAG_FILTER, resource.transferable.filter);
       resource.SetLocallyUsed();
     }
 
@@ -795,8 +768,7 @@
     DisplayResourceProvider* resource_provider,
     ResourceId resource_id)
     : resource_provider_(resource_provider), resource_id_(resource_id) {
-  const internal::Resource* resource =
-      resource_provider->LockForRead(resource_id);
+  const ChildResource* resource = resource_provider->LockForRead(resource_id);
   // TODO(ericrk): We should never fail LockForRead, but we appear to be
   // doing so on Android in rare cases. Handle this gracefully until a better
   // solution can be found. https://crbug.com/811858
@@ -804,9 +776,9 @@
     return;
 
   texture_id_ = resource->gl_id;
-  target_ = resource->target;
-  size_ = resource->size;
-  color_space_ = resource->color_space;
+  target_ = resource->transferable.mailbox_holder.texture_target;
+  size_ = resource->transferable.size;
+  color_space_ = resource->transferable.color_space;
 }
 
 DisplayResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
@@ -836,42 +808,50 @@
     DisplayResourceProvider* resource_provider,
     ResourceId resource_id)
     : resource_provider_(resource_provider), resource_id_(resource_id) {
-  const internal::Resource* resource =
-      resource_provider->LockForRead(resource_id);
+  const ChildResource* resource = resource_provider->LockForRead(resource_id);
   DCHECK(resource);
-  if (resource_provider_->resource_sk_image_.find(resource_id) !=
-      resource_provider_->resource_sk_image_.end()) {
-    // Use cached sk_image.
-    sk_image_ =
-        resource_provider_->resource_sk_image_.find(resource_id)->second;
-  } else if (resource->gl_id) {
+
+  // Use cached SkImage if possible.
+  auto it = resource_provider_->resource_sk_image_.find(resource_id);
+  if (it != resource_provider_->resource_sk_image_.end()) {
+    sk_image_ = it->second;
+    return;
+  }
+
+  if (resource->is_gpu_resource_type()) {
+    DCHECK(resource->gl_id);
     GrGLTextureInfo texture_info;
     texture_info.fID = resource->gl_id;
-    texture_info.fTarget = resource->target;
-    texture_info.fFormat = TextureStorageFormat(resource->format);
-    GrBackendTexture backend_texture(resource->size.width(),
-                                     resource->size.height(), GrMipMapped::kNo,
-                                     texture_info);
+    texture_info.fTarget = resource->transferable.mailbox_holder.texture_target;
+    texture_info.fFormat = TextureStorageFormat(resource->transferable.format);
+    GrBackendTexture backend_texture(resource->transferable.size.width(),
+                                     resource->transferable.size.height(),
+                                     GrMipMapped::kNo, texture_info);
     sk_image_ = SkImage::MakeFromTexture(
         resource_provider->compositor_context_provider_->GrContext(),
         backend_texture, kTopLeft_GrSurfaceOrigin,
         ResourceFormatToClosestSkColorType(!resource_provider->IsSoftware(),
-                                           resource->format),
+                                           resource->transferable.format),
         kPremul_SkAlphaType, nullptr);
-  } else if (resource->shared_bitmap) {
-    SkBitmap sk_bitmap;
-    resource_provider->PopulateSkBitmapWithResource(&sk_bitmap, resource);
-    sk_bitmap.setImmutable();
-    sk_image_ = SkImage::MakeFromBitmap(sk_bitmap);
-  } else {
-    // During render process shutdown, ~RenderMessageFilter which calls
-    // ~HostSharedBitmapClient (which deletes shared bitmaps from child)
-    // can race with OnBeginFrameDeadline which draws a frame.
-    // In these cases, shared bitmaps (and this read lock) won't be valid.
-    // Renderers need to silently handle locks failing until this race
-    // is fixed.  DCHECK that this is the only case where there are no pixels.
-    DCHECK(!resource->shared_bitmap_id.IsZero());
+    return;
   }
+
+  if (!resource->shared_bitmap) {
+    // If a CompositorFrameSink is destroyed, it destroys all SharedBitmapIds
+    // that it registered. In this case, a CompositorFrame can be drawn with
+    // SharedBitmapIds that are not known in the viz service. As well, a
+    // misbehaved client can use SharedBitampIds that it did not report to
+    // the service. Then the |shared_bitmap| will be null, and this read lock
+    // will not be valid. Software-compositing users of this read lock must
+    // check for valid() to deal with this scenario.
+    sk_image_ = nullptr;
+    return;
+  }
+
+  SkBitmap sk_bitmap;
+  resource_provider->PopulateSkBitmapWithResource(&sk_bitmap, resource);
+  sk_bitmap.setImmutable();
+  sk_image_ = SkImage::MakeFromBitmap(sk_bitmap);
 }
 
 DisplayResourceProvider::ScopedReadLockSkImage::~ScopedReadLockSkImage() {
@@ -882,8 +862,7 @@
     DisplayResourceProvider* resource_provider,
     ResourceId resource_id)
     : resource_provider_(resource_provider), resource_id_(resource_id) {
-  const internal::Resource* resource =
-      resource_provider->LockForRead(resource_id);
+  const ChildResource* resource = resource_provider->LockForRead(resource_id);
   DCHECK(resource);
   resource_provider->PopulateSkBitmapWithResource(&sk_bitmap_, resource);
 }
@@ -957,4 +936,38 @@
 DisplayResourceProvider::Child::Child(const Child& other) = default;
 DisplayResourceProvider::Child::~Child() = default;
 
+DisplayResourceProvider::ChildResource::ChildResource(
+    int child_id,
+    const TransferableResource& transferable)
+    : child_id(child_id),
+      transferable(transferable),
+      filter(transferable.filter) {
+  if (is_gpu_resource_type())
+    UpdateSyncToken(transferable.mailbox_holder.sync_token);
+  else
+    SetSynchronized();
+}
+
+DisplayResourceProvider::ChildResource::ChildResource(ChildResource&& other) =
+    default;
+DisplayResourceProvider::ChildResource::~ChildResource() = default;
+
+void DisplayResourceProvider::ChildResource::SetLocallyUsed() {
+  synchronization_state_ = LOCALLY_USED;
+  sync_token_.Clear();
+}
+
+void DisplayResourceProvider::ChildResource::SetSynchronized() {
+  synchronization_state_ = SYNCHRONIZED;
+}
+
+void DisplayResourceProvider::ChildResource::UpdateSyncToken(
+    const gpu::SyncToken& sync_token) {
+  DCHECK(is_gpu_resource_type());
+  // An empty sync token may be used if commands are guaranteed to have run on
+  // the gpu process or in case of context loss.
+  sync_token_ = sync_token;
+  synchronization_state_ = sync_token.HasData() ? NEEDS_WAIT : SYNCHRONIZED;
+}
+
 }  // namespace viz
diff --git a/components/viz/service/display/display_resource_provider.h b/components/viz/service/display/display_resource_provider.h
index 30f20ace..6fce3fa 100644
--- a/components/viz/service/display/display_resource_provider.h
+++ b/components/viz/service/display/display_resource_provider.h
@@ -16,21 +16,22 @@
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "build/build_config.h"
-#include "components/viz/common/resources/resource.h"
-#include "components/viz/common/resources/resource_fence.h"
+#include "components/viz/common/quads/shared_bitmap.h"
 #include "components/viz/common/resources/resource_id.h"
-#include "components/viz/common/resources/resource_metadata.h"
 #include "components/viz/common/resources/return_callback.h"
 #include "components/viz/common/resources/transferable_resource.h"
 #include "components/viz/service/display/overlay_candidate.h"
+#include "components/viz/service/display/resource_fence.h"
+#include "components/viz/service/display/resource_metadata.h"
 #include "components/viz/service/viz_service_export.h"
+#include "gpu/command_buffer/common/sync_token.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/khronos/GLES2/gl2ext.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace gfx {
 class ColorSpace;
-class Size;
 }  // namespace gfx
 
 namespace gpu {
@@ -89,7 +90,7 @@
   size_t CountPromotionHintRequestsForTesting();
 #endif
 
-  ResourceType GetResourceType(ResourceId id);
+  bool IsResourceSoftwareBacked(ResourceId id);
   GLenum GetResourceTextureTarget(ResourceId id);
   // Return the format of the underlying buffer that can be used for scanout.
   gfx::BufferFormat GetBufferFormat(ResourceId id);
@@ -290,6 +291,40 @@
                                      const ResourceIdSet& resources_from_child);
 
  private:
+  enum DeleteStyle {
+    NORMAL,
+    FOR_SHUTDOWN,
+  };
+
+  enum SynchronizationState {
+    // The LOCALLY_USED state is the state each resource defaults to when
+    // constructed or modified or read. This state indicates that the
+    // resource has not been properly synchronized and it would be an error
+    // to return this resource to a client.
+    LOCALLY_USED,
+
+    // The NEEDS_WAIT state is the state that indicates a resource has been
+    // modified but it also has an associated sync token assigned to it.
+    // The sync token has not been waited on with the local context. When
+    // a sync token arrives from a client, it is automatically initialized as
+    // NEEDS_WAIT as well since we still need to wait on it before the resource
+    // is synchronized on the current context. It is an error to use the
+    // resource locally for reading or writing if the resource is in this state.
+    NEEDS_WAIT,
+
+    // The SYNCHRONIZED state indicates that the resource has been properly
+    // synchronized locally. This can either synchronized externally (such
+    // as the case of software rasterized bitmaps), or synchronized
+    // internally using a sync token that has been waited upon. In the
+    // former case where the resource was synchronized externally, a
+    // corresponding sync token will not exist. In the latter case which was
+    // synchronized from the NEEDS_WAIT state, a corresponding sync token will
+    // exist which is associated with the resource. This sync token is still
+    // valid and still associated with the resource and can be passed as an
+    // external resource for others to wait on.
+    SYNCHRONIZED,
+  };
+
   struct Child {
     Child();
     Child(const Child& other);
@@ -301,34 +336,111 @@
     bool needs_sync_tokens = true;
   };
 
-  enum DeleteStyle {
-    NORMAL,
-    FOR_SHUTDOWN,
+  // The data structure used to track state of Gpu and Software-based
+  // resources and the service, for resources transferred
+  // between the two. This is an implementation detail of the resource tracking
+  // for client and service libraries and should not be used directly from
+  // external client code.
+  struct ChildResource {
+    ChildResource(int child_id, const TransferableResource& transferable);
+    ChildResource(ChildResource&& other);
+    ~ChildResource();
+
+    bool is_gpu_resource_type() const { return !transferable.is_software; }
+    bool needs_sync_token() const {
+      return is_gpu_resource_type() && synchronization_state_ == LOCALLY_USED;
+    }
+    const gpu::SyncToken& sync_token() const { return sync_token_; }
+    SynchronizationState synchronization_state() const {
+      return synchronization_state_;
+    }
+    // If true the gpu resource needs its SyncToken waited on in order to be
+    // synchronized for use.
+    bool ShouldWaitSyncToken() const {
+      return synchronization_state_ == NEEDS_WAIT;
+    }
+
+    void SetLocallyUsed();
+    void SetSynchronized();
+    void UpdateSyncToken(const gpu::SyncToken& sync_token);
+
+    // This is the id of the client the resource comes from.
+    const int child_id;
+    // Data received from the client that describes the resource fully.
+    const TransferableResource transferable;
+
+    // The number of times the resource has been received from a client. It must
+    // have this many number of references returned back to the client in order
+    // for it to know it is no longer in use in the service. This is used to
+    // avoid races where a resource is in flight to the service while also being
+    // returned to the client. It starts with an initial count of 1, for the
+    // first time the resource is received.
+    int imported_count = 1;
+
+    // The number of active users of a resource in the display compositor. While
+    // a resource is in use, it will not be returned back to the client even if
+    // the ResourceId is deleted.
+    int lock_for_read_count = 0;
+    // When true, the resource is currently being used externally. This is a
+    // parallel counter to |lock_for_read_count| which can only go to 1.
+    bool locked_for_external_use = false;
+
+    // When the resource should be deleted until it is actually reaped.
+    bool marked_for_deletion = false;
+
+    // Texture id for texture-backed resources, when the mailbox is mapped into
+    // a client GL id in this process.
+    GLuint gl_id = 0;
+    // The current min/mag filter for GL texture-backed resources. The original
+    // filter as given from the client is saved in |transferable|.
+    GLenum filter;
+    // A pointer to the shared memory structure for software-backed resources,
+    // when it is mapped into memory in this process.
+    std::unique_ptr<SharedBitmap> shared_bitmap;
+    // A GUID for reporting the |shared_bitmap| to memory tracing. The GUID is
+    // known by other components in the system as well to give the same id for
+    // this shared memory bitmap everywhere. This is empty until the resource is
+    // mapped for use in the display compositor.
+    base::UnguessableToken shared_bitmap_tracing_guid;
+
+    // A fence used for accessing a gpu resource for reading, that ensures any
+    // writing done to the resource has been completed. This is implemented and
+    // used to implement transferring ownership of the resource from the client
+    // to the service, and in the GL drawing code before reading from the
+    // texture.
+    scoped_refptr<ResourceFence> read_lock_fence;
+
+   private:
+    // Tracks if a sync token needs to be waited on before using the resource.
+    SynchronizationState synchronization_state_;
+    // A SyncToken associated with a texture-backed or GpuMemoryBuffer-backed
+    // resource. It is given from a child to the service, and waited on in order
+    // to use the resource, and this is tracked by the |synchronization_state_|.
+    gpu::SyncToken sync_token_;
   };
 
   using ChildMap = std::unordered_map<int, Child>;
-  using ResourceMap = std::unordered_map<ResourceId, internal::Resource>;
+  using ResourceMap = std::unordered_map<ResourceId, ChildResource>;
 
-  internal::Resource* InsertResource(ResourceId id,
-                                     internal::Resource resource);
-  internal::Resource* GetResource(ResourceId id);
+  ChildResource* InsertResource(ResourceId id, ChildResource resource);
+  ChildResource* GetResource(ResourceId id);
 
   // TODO(ericrk): TryGetResource is part of a temporary workaround for cases
   // where resources which should be available are missing. This version may
   // return nullptr if a resource is not found. https://crbug.com/811858
-  internal::Resource* TryGetResource(ResourceId id);
+  ChildResource* TryGetResource(ResourceId id);
 
   void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
-                                    const internal::Resource* resource);
+                                    const ChildResource* resource);
 
   void DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style);
 
-  void WaitSyncTokenInternal(internal::Resource* resource);
+  void WaitSyncTokenInternal(ChildResource* resource);
 
   // Returns null if we do not have a ContextProvider.
   gpu::gles2::GLES2Interface* ContextGL() const;
 
-  const internal::Resource* LockForRead(ResourceId id);
+  const ChildResource* LockForRead(ResourceId id);
   void UnlockForRead(ResourceId id);
 
   // Lock a resource for external use.
@@ -345,7 +457,7 @@
   // specified filter for both minification and magnification. Returns the
   // texture target used. The resource must be locked for reading.
   GLenum BindForSampling(ResourceId resource_id, GLenum unit, GLenum filter);
-  bool ReadLockFenceHasPassed(const internal::Resource* resource);
+  bool ReadLockFenceHasPassed(const ChildResource* resource);
 #if defined(OS_ANDROID)
   void DeletePromotionHint(ResourceMap::iterator it, DeleteStyle style);
 #endif
diff --git a/components/viz/service/display/display_resource_provider_unittest.cc b/components/viz/service/display/display_resource_provider_unittest.cc
index a10b30a7..eec1b8a6 100644
--- a/components/viz/service/display/display_resource_provider_unittest.cc
+++ b/components/viz/service/display/display_resource_provider_unittest.cc
@@ -27,8 +27,8 @@
 #include "components/viz/common/resources/bitmap_allocation.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/resources/returned_resource.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "components/viz/common/resources/single_release_callback.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "components/viz/test/test_context_provider.h"
 #include "components/viz/test/test_gles2_interface.h"
 #include "components/viz/test/test_gpu_memory_buffer_manager.h"
@@ -349,9 +349,9 @@
       child_context_provider_->BindToCurrentThread();
       gpu_memory_buffer_manager_ =
           std::make_unique<TestGpuMemoryBufferManager>();
-    } else {
-      shared_bitmap_manager_ = std::make_unique<TestSharedBitmapManager>();
     }
+    // SharedBitmapManager may always be present, even if gpu compositing.
+    shared_bitmap_manager_ = std::make_unique<TestSharedBitmapManager>();
 
     resource_provider_ = std::make_unique<DisplayResourceProvider>(
         context_provider_.get(), shared_bitmap_manager_.get());
@@ -869,11 +869,9 @@
 }
 
 TEST_P(DisplayResourceProviderTest, LostMailboxInParent) {
-  gpu::Mailbox gpu_mailbox;
   gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
                             gpu::CommandBufferId::FromUnsafeValue(0x12), 0x34);
-  auto tran = TransferableResource::MakeGL(gpu_mailbox, GL_LINEAR,
-                                           GL_TEXTURE_2D, sync_token);
+  auto tran = CreateResource(RGBA_8888);
   tran.id = 11;
 
   std::vector<ReturnedResource> returned_to_child;
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 0dba3cd7..8adc4653 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -41,7 +41,6 @@
 #include "components/viz/common/quads/stream_video_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/resources/platform_color.h"
-#include "components/viz/common/resources/resource_fence.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/resources/resource_id.h"
 #include "components/viz/common/skia_helper.h"
@@ -50,6 +49,7 @@
 #include "components/viz/service/display/layer_quad.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/resource_fence.h"
 #include "components/viz/service/display/scoped_render_pass_texture.h"
 #include "components/viz/service/display/static_geometry_binding.h"
 #include "components/viz/service/display/texture_deleter.h"
diff --git a/components/viz/common/resources/resource_fence.h b/components/viz/service/display/resource_fence.h
similarity index 76%
rename from components/viz/common/resources/resource_fence.h
rename to components/viz/service/display/resource_fence.h
index 369d84f..ebfc658 100644
--- a/components/viz/common/resources/resource_fence.h
+++ b/components/viz/service/display/resource_fence.h
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FENCE_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FENCE_H_
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_FENCE_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_FENCE_H_
+
+#include "base/memory/ref_counted.h"
 
 namespace viz {
 
@@ -26,4 +28,4 @@
 
 }  // namespace viz
 
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FENCE_H_
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_FENCE_H_
diff --git a/components/viz/common/resources/resource_metadata.cc b/components/viz/service/display/resource_metadata.cc
similarity index 87%
rename from components/viz/common/resources/resource_metadata.cc
rename to components/viz/service/display/resource_metadata.cc
index 4b9649b4..c746e42 100644
--- a/components/viz/common/resources/resource_metadata.cc
+++ b/components/viz/service/display/resource_metadata.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 "components/viz/common/resources/resource_metadata.h"
+#include "components/viz/service/display/resource_metadata.h"
 
 namespace viz {
 
diff --git a/components/viz/common/resources/resource_metadata.h b/components/viz/service/display/resource_metadata.h
similarity index 77%
rename from components/viz/common/resources/resource_metadata.h
rename to components/viz/service/display/resource_metadata.h
index 86d91f1..8da82ee 100644
--- a/components/viz/common/resources/resource_metadata.h
+++ b/components/viz/service/display/resource_metadata.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 COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_METADATA_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_METADATA_H_
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_METADATA_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_METADATA_H_
 
-#include "components/viz/common/viz_common_export.h"
+#include "components/viz/service/viz_service_export.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
@@ -15,9 +15,9 @@
 
 namespace viz {
 
-// Metadata for a Resoource. It is used by SkiaRenderer to get resource metedata
-// from DisplayResourceProvider, and make a promise SkImage from it.
-struct VIZ_COMMON_EXPORT ResourceMetadata {
+// Metadata for a resource named by a ResourceId in DisplayResourceProvider.
+// Used to construct a promise SkImage for a ResourceId.
+struct VIZ_SERVICE_EXPORT ResourceMetadata {
   ResourceMetadata();
   ResourceMetadata(ResourceMetadata&& other);
   ~ResourceMetadata();
@@ -54,4 +54,4 @@
 
 }  // namespace viz
 
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_METADATA_H_
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_RESOURCE_METADATA_H_
diff --git a/components/viz/common/resources/shared_bitmap_manager.h b/components/viz/service/display/shared_bitmap_manager.h
similarity index 84%
rename from components/viz/common/resources/shared_bitmap_manager.h
rename to components/viz/service/display/shared_bitmap_manager.h
index 27f853d..4ac13de 100644
--- a/components/viz/common/resources/shared_bitmap_manager.h
+++ b/components/viz/service/display/shared_bitmap_manager.h
@@ -2,15 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_VIZ_COMMON_RESOURCES_SHARED_BITMAP_MANAGER_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_SHARED_BITMAP_MANAGER_H_
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SHARED_BITMAP_MANAGER_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_SHARED_BITMAP_MANAGER_H_
 
 #include <memory>
 
 #include "base/macros.h"
 #include "components/viz/common/quads/shared_bitmap.h"
 #include "mojo/public/cpp/system/buffer.h"
-#include "ui/gfx/geometry/size.h"
+
+namespace gfx {
+class Size;
+}
 
 namespace viz {
 
@@ -39,4 +42,4 @@
 
 }  // namespace viz
 
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_SHARED_BITMAP_MANAGER_H_
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_SHARED_BITMAP_MANAGER_H_
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 2ffeb3b2..c5c5ffb4d 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -19,13 +19,13 @@
 #include "components/viz/common/quads/tile_draw_quad.h"
 #include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/resources/platform_color.h"
-#include "components/viz/common/resources/resource_fence.h"
 #include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/resource_metadata.h"
 #include "components/viz/common/skia_helper.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_frame.h"
 #include "components/viz/service/display/renderer_utils.h"
+#include "components/viz/service/display/resource_fence.h"
+#include "components/viz/service/display/resource_metadata.h"
 #include "components/viz/service/display/skia_output_surface.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "skia/ext/opacity_filter_canvas.h"
@@ -63,8 +63,7 @@
 
 bool IsTextureResource(DisplayResourceProvider* resource_provider,
                        ResourceId resource_id) {
-  return resource_provider->GetResourceType(resource_id) ==
-         ResourceType::kTexture;
+  return !resource_provider->IsResourceSoftwareBacked(resource_id);
 }
 
 }  // namespace
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc
index bc958f62..649a15e 100644
--- a/components/viz/service/display/software_renderer.cc
+++ b/components/viz/service/display/software_renderer.cc
@@ -169,8 +169,7 @@
 }
 
 bool SoftwareRenderer::IsSoftwareResource(ResourceId resource_id) const {
-  return resource_provider_->GetResourceType(resource_id) ==
-         ResourceType::kBitmap;
+  return resource_provider_->IsResourceSoftwareBacked(resource_id);
 }
 
 void SoftwareRenderer::DoDrawQuad(const DrawQuad* quad,
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 35e590c..ae4d58e 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -3007,10 +3007,14 @@
   }
 
   for (size_t i = 0u; i < num_resource_ids; ++i) {
-    TransferableResource resource;
+    auto resource = TransferableResource::MakeSoftware(
+        SharedBitmap::GenerateId(), gfx::Size(1, 1), RGBA_8888);
     resource.id = resource_ids[i];
-    // ResourceProvider is software, so only software resources are valid.
-    resource.is_software = valid;
+    if (!valid) {
+      // ResourceProvider is software, so only software resources are valid. Do
+      // this to cause the resource to be rejected.
+      resource.is_software = false;
+    }
     frame.resource_list.push_back(resource);
     auto* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
     const gfx::Rect rect;
diff --git a/components/viz/service/display/sync_query_collection.cc b/components/viz/service/display/sync_query_collection.cc
index 60af0839..f68e15d 100644
--- a/components/viz/service/display/sync_query_collection.cc
+++ b/components/viz/service/display/sync_query_collection.cc
@@ -6,7 +6,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "cc/base/container_util.h"
-#include "components/viz/common/resources/resource_fence.h"
+#include "components/viz/service/display/resource_fence.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS
index 4ce72f0..ecc45a9e 100644
--- a/components/viz/service/display_embedder/DEPS
+++ b/components/viz/service/display_embedder/DEPS
@@ -9,6 +9,8 @@
   "+components/viz/service/display/output_surface_frame.h",
   "+components/viz/service/display/output_surface.h",
   "+components/viz/service/display/overlay_candidate_validator.h",
+  "+components/viz/service/display/resource_metadata.h",
+  "+components/viz/service/display/shared_bitmap_manager.h",
   "+components/viz/service/display/skia_output_surface.h",
   "+components/viz/service/display/software_output_device.h",
   "+gpu/config/gpu_feature_info.h",
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager.h b/components/viz/service/display_embedder/server_shared_bitmap_manager.h
index 1ed6aff..21a699ff 100644
--- a/components/viz/service/display_embedder/server_shared_bitmap_manager.h
+++ b/components/viz/service/display_embedder/server_shared_bitmap_manager.h
@@ -13,7 +13,7 @@
 #include "base/memory/shared_memory.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "components/viz/service/viz_service_export.h"
 
 namespace viz {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index ac7b616..3fdbb0a 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -9,9 +9,9 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/resources/resource_format_utils.h"
-#include "components/viz/common/resources/resource_metadata.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/resource_metadata.h"
 #include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h"
 #include "components/viz/service/display_embedder/viz_process_context_provider.h"
 #include "components/viz/service/gl/gpu_service_impl.h"
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 82462b0b..91c1d234 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -10,9 +10,9 @@
 #include "base/threading/thread_checker.h"
 #include "build/build_config.h"
 #include "components/viz/common/quads/render_pass.h"
-#include "components/viz/common/resources/resource_metadata.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/resource_metadata.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/ipc/common/surface_handle.h"
 #include "gpu/ipc/in_process_command_buffer.h"
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
index fae027a..f90172e 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -9,9 +9,9 @@
 
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "components/viz/common/surfaces/surface_info.h"
 #include "components/viz/service/display/display.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "components/viz/service/surfaces/surface.h"
 #include "components/viz/service/surfaces/surface_reference.h"
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index bad389a..281c45fe 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -9,8 +9,8 @@
 
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "components/viz/service/display/display.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 #include "components/viz/service/display_embedder/display_provider.h"
 #include "components/viz/service/display_embedder/external_begin_frame_controller_impl.h"
 #include "components/viz/service/frame_sinks/compositor_frame_sink_impl.h"
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index 932cfb4..79d3838 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -73,8 +73,9 @@
   if (!LayerTreeFrameSink::BindToClient(client))
     return false;
 
+  shared_bitmap_manager_ = std::make_unique<TestSharedBitmapManager>();
   frame_sink_manager_ =
-      std::make_unique<FrameSinkManagerImpl>(&shared_bitmap_manager_);
+      std::make_unique<FrameSinkManagerImpl>(shared_bitmap_manager_.get());
 
   std::unique_ptr<OutputSurface> display_output_surface =
       test_client_->CreateDisplayOutputSurface(context_provider());
@@ -102,7 +103,7 @@
   }
 
   display_ = std::make_unique<Display>(
-      &shared_bitmap_manager_, renderer_settings_, frame_sink_id_,
+      shared_bitmap_manager_.get(), renderer_settings_, frame_sink_id_,
       std::move(display_output_surface), std::move(scheduler),
       compositor_task_runner_);
 
@@ -126,11 +127,13 @@
 }
 
 void TestLayerTreeFrameSink::DetachFromClient() {
+  // This acts like the |shared_bitmap_manager_| is a global object, while
+  // in fact it is tied to the lifetime of this class and is destroyed below:
   // The shared_bitmap_manager_ has ownership of shared memory for each
   // SharedBitmapId that has been reported from the client. Since the client is
   // gone that memory can be freed. If we don't then it would leak.
   for (const auto& id : owned_bitmaps_)
-    shared_bitmap_manager_.ChildDeletedSharedBitmap(id);
+    shared_bitmap_manager_->ChildDeletedSharedBitmap(id);
   owned_bitmaps_.clear();
 
   if (display_begin_frame_source_) {
@@ -144,6 +147,7 @@
   begin_frame_source_ = nullptr;
   parent_local_surface_id_allocator_ = nullptr;
   frame_sink_manager_ = nullptr;
+  shared_bitmap_manager_ = nullptr;
   test_client_ = nullptr;
   LayerTreeFrameSink::DetachFromClient();
 }
@@ -212,13 +216,13 @@
     mojo::ScopedSharedBufferHandle buffer,
     const SharedBitmapId& id) {
   bool ok =
-      shared_bitmap_manager_.ChildAllocatedSharedBitmap(std::move(buffer), id);
+      shared_bitmap_manager_->ChildAllocatedSharedBitmap(std::move(buffer), id);
   DCHECK(ok);
   owned_bitmaps_.insert(id);
 }
 
 void TestLayerTreeFrameSink::DidDeleteSharedBitmap(const SharedBitmapId& id) {
-  shared_bitmap_manager_.ChildDeletedSharedBitmap(id);
+  shared_bitmap_manager_->ChildDeletedSharedBitmap(id);
   owned_bitmaps_.erase(id);
 }
 
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h
index 8758649..b5896626 100644
--- a/components/viz/test/test_layer_tree_frame_sink.h
+++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -137,6 +137,7 @@
   FrameSinkId frame_sink_id_;
   // TODO(danakj): These don't need to be stored in unique_ptrs when
   // LayerTreeFrameSink is owned/destroyed on the compositor thread.
+  std::unique_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
   std::unique_ptr<FrameSinkManagerImpl> frame_sink_manager_;
   std::unique_ptr<ParentLocalSurfaceIdAllocator>
       parent_local_surface_id_allocator_;
@@ -153,8 +154,6 @@
   BeginFrameSource* display_begin_frame_source_ = nullptr;  // Not owned.
   ExternalBeginFrameSource external_begin_frame_source_;
 
-  TestSharedBitmapManager shared_bitmap_manager_;
-
   // Uses surface_manager_, begin_frame_source_, shared_bitmap_manager_.
   std::unique_ptr<Display> display_;
 
diff --git a/components/viz/test/test_shared_bitmap_manager.cc b/components/viz/test/test_shared_bitmap_manager.cc
index 516c960..a173281 100644
--- a/components/viz/test/test_shared_bitmap_manager.cc
+++ b/components/viz/test/test_shared_bitmap_manager.cc
@@ -14,13 +14,16 @@
 
 TestSharedBitmapManager::TestSharedBitmapManager() = default;
 
-TestSharedBitmapManager::~TestSharedBitmapManager() = default;
+TestSharedBitmapManager::~TestSharedBitmapManager() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
 
 std::unique_ptr<SharedBitmap> TestSharedBitmapManager::GetSharedBitmapFromId(
     const gfx::Size&,
     ResourceFormat,
     const SharedBitmapId& id) {
-  base::AutoLock lock(lock_);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (bitmap_map_.find(id) == bitmap_map_.end())
     return nullptr;
   uint8_t* pixels = static_cast<uint8_t*>(bitmap_map_[id]->memory());
@@ -30,7 +33,6 @@
 base::UnguessableToken
 TestSharedBitmapManager::GetSharedBitmapTracingGUIDFromId(
     const SharedBitmapId& id) {
-  base::AutoLock lock(lock_);
   if (bitmap_map_.find(id) == bitmap_map_.end())
     return {};
   return bitmap_map_[id]->mapped_id();
@@ -39,6 +41,8 @@
 bool TestSharedBitmapManager::ChildAllocatedSharedBitmap(
     mojo::ScopedSharedBufferHandle buffer,
     const SharedBitmapId& id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   // TestSharedBitmapManager is both the client and service side. So the
   // notification here should be about a bitmap that was previously allocated
   // with AllocateSharedBitmap().
@@ -65,6 +69,8 @@
 
 void TestSharedBitmapManager::ChildDeletedSharedBitmap(
     const SharedBitmapId& id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   notified_set_.erase(id);
   bitmap_map_.erase(id);
   owned_map_.erase(id);
diff --git a/components/viz/test/test_shared_bitmap_manager.h b/components/viz/test/test_shared_bitmap_manager.h
index eae822b..e46da32f 100644
--- a/components/viz/test/test_shared_bitmap_manager.h
+++ b/components/viz/test/test_shared_bitmap_manager.h
@@ -8,8 +8,8 @@
 #include <map>
 #include <set>
 
-#include "base/synchronization/lock.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "base/sequence_checker.h"
+#include "components/viz/service/display/shared_bitmap_manager.h"
 
 namespace base {
 class SharedMemory;
@@ -34,7 +34,8 @@
   void ChildDeletedSharedBitmap(const SharedBitmapId& id) override;
 
  private:
-  base::Lock lock_;
+  SEQUENCE_CHECKER(sequence_checker_);
+
   std::map<SharedBitmapId, base::SharedMemory*> bitmap_map_;
   std::map<SharedBitmapId, std::unique_ptr<base::SharedMemory>> owned_map_;
   std::set<SharedBitmapId> notified_set_;
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 089946e6..4ab51921 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -192,7 +192,7 @@
                                            R"HTML(<!DOCTYPE html>
           <html>
           <body>
-            <input type="text" style="width: 30px;" value=")HTML") +
+            <input type="text" style="width: 150px;" value=")HTML") +
                                        net::EscapeForHTML(kInputContents) +
                                        std::string(R"HTML(">
           </body>
@@ -240,7 +240,9 @@
   ExecuteScript(std::wstring(L"let textField = document.querySelector('input');"
                              L"textField.focus();"
                              L"textField.setSelectionRange(") +
-                caret_offset + L"," + caret_offset + L");");
+                caret_offset + L"," + caret_offset +
+                L");"
+                L"textField.scrollLeft = 1000;");
   waiter.WaitForNotification();
 }
 
@@ -1314,11 +1316,11 @@
 }
 
 IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
-                       DISABLED_TestCharacterExtentsInScrollableInputField) {
+                       TestCharacterExtentsInScrollableInputField) {
   Microsoft::WRL::ComPtr<IAccessibleText> input_text;
   SetUpScrollableInputField(&input_text);
 
-  constexpr LONG visible_characters_start = 20;
+  constexpr LONG visible_characters_start = 21;
   LONG n_characters;
   ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
   ASSERT_EQ(kContentsLength, n_characters);
@@ -1338,7 +1340,7 @@
     // of 0 is not used because it signifies an invalid size.
     EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
         0, coordinate_type, &x, &y, &width, &height));
-    EXPECT_LT(0, x) << "at offset 0";
+    EXPECT_LT(0, x + width) << "at offset 0";
     EXPECT_LT(0, y) << "at offset 0";
     EXPECT_EQ(1, width) << "at offset 0";
     EXPECT_LT(1, height) << "at offset 0";
@@ -1346,7 +1348,8 @@
     // Test that characters at the start of the input field are offscreen by
     // checking that their x coordinate is at the start of the field and their
     // width is 1.
-    for (LONG offset = 1; offset < visible_characters_start; ++offset) {
+    // Exclude the character that is partly visible.
+    for (LONG offset = 1; offset < (visible_characters_start - 1); ++offset) {
       previous_x = x;
       previous_y = y;
       previous_height = height;
@@ -1356,7 +1359,7 @@
       EXPECT_EQ(previous_x, x) << "at offset " << offset;
       EXPECT_EQ(previous_y, y) << "at offset " << offset;
       EXPECT_EQ(1, width) << "at offset " << offset;
-      EXPECT_LT(previous_height, height) << "at offset " << offset;
+      EXPECT_EQ(previous_height, height) << "at offset " << offset;
     }
 
     // Test that non offscreen characters have increasing x coordinates and a
@@ -1369,8 +1372,10 @@
     EXPECT_EQ(previous_height, height)
         << "at offset " << visible_characters_start;
 
-    for (LONG offset = visible_characters_start + 1; offset < n_characters;
-         ++offset) {
+    // Exclude the dot at the end of the text field, because it has a width of
+    // one anyway.
+    for (LONG offset = visible_characters_start + 1;
+         offset < (n_characters - 1); ++offset) {
       previous_x = x;
       previous_y = y;
       previous_height = height;
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 64868046c..eb3e154 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -426,47 +426,52 @@
         local_start > 0 ? character_offsets[local_start - 1] : 0;
     int end_pixel_offset =
         local_end > 0 ? character_offsets[local_end - 1] : 0;
+    int max_pixel_offset = character_offsets_length > 0
+                               ? character_offsets[character_offsets_length - 1]
+                               : 0;
 
-    gfx::Rect child_rect = child->GetPageBoundsRect();
     auto text_direction = static_cast<ax::mojom::TextDirection>(
         child->GetIntAttribute(ax::mojom::IntAttribute::kTextDirection));
-    gfx::Rect child_overlap_rect;
+    gfx::RectF child_overlap_rect;
     switch (text_direction) {
       case ax::mojom::TextDirection::kNone:
       case ax::mojom::TextDirection::kLtr: {
-        int left = child_rect.x() + start_pixel_offset;
-        int right = child_rect.x() + end_pixel_offset;
-        child_overlap_rect = gfx::Rect(left, child_rect.y(),
-                                       right - left, child_rect.height());
+        int height = child->GetLocation().height();
+        child_overlap_rect =
+            gfx::RectF(start_pixel_offset, 0,
+                       end_pixel_offset - start_pixel_offset, height);
         break;
       }
       case ax::mojom::TextDirection::kRtl: {
-        int right = child_rect.right() - start_pixel_offset;
-        int left = child_rect.right() - end_pixel_offset;
-        child_overlap_rect = gfx::Rect(left, child_rect.y(),
-                                       right - left, child_rect.height());
+        int right = max_pixel_offset - start_pixel_offset;
+        int left = max_pixel_offset - end_pixel_offset;
+        int height = child->GetLocation().height();
+        child_overlap_rect = gfx::RectF(left, 0, right - left, height);
         break;
       }
       case ax::mojom::TextDirection::kTtb: {
-        int top = child_rect.y() + start_pixel_offset;
-        int bottom = child_rect.y() + end_pixel_offset;
-        child_overlap_rect = gfx::Rect(child_rect.x(), top,
-                                       child_rect.width(), bottom - top);
+        int width = child->GetLocation().width();
+        child_overlap_rect = gfx::RectF(0, start_pixel_offset, width,
+                                        end_pixel_offset - start_pixel_offset);
         break;
       }
       case ax::mojom::TextDirection::kBtt: {
-        int bottom = child_rect.bottom() - start_pixel_offset;
-        int top = child_rect.bottom() - end_pixel_offset;
-        child_overlap_rect = gfx::Rect(child_rect.x(), top,
-                                       child_rect.width(), bottom - top);
+        int bottom = max_pixel_offset - start_pixel_offset;
+        int top = max_pixel_offset - end_pixel_offset;
+        int width = child->GetLocation().width();
+        child_overlap_rect = gfx::RectF(0, top, width, bottom - top);
         break;
       }
     }
 
-    if (bounds.width() == 0 && bounds.height() == 0)
-      bounds = child_overlap_rect;
-    else
-      bounds.Union(child_overlap_rect);
+    gfx::Rect absolute_child_rect = child->RelativeToAbsoluteBounds(
+        child_overlap_rect, false /* frame_only */, nullptr /* offscreen */,
+        true /* clip_bounds */);
+    if (bounds.width() == 0 && bounds.height() == 0) {
+      bounds = absolute_child_rect;
+    } else {
+      bounds.Union(absolute_child_rect);
+    }
   }
 
   return bounds;
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index 4bf51fd3..30bd9916 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -280,7 +280,7 @@
   }
 
   bool has_web_ui_bindings() const {
-    return enabled_bindings_ & BINDINGS_POLICY_WEB_UI;
+    return enabled_bindings_ & kWebUIBindingsPolicyMask;
   }
 
   bool can_read_raw_cookies() const {
@@ -587,14 +587,19 @@
   state->second->GrantScheme(scheme);
 }
 
-void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id) {
+void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id,
+                                                        int bindings) {
+  // Only WebUI bindings should come through here.
+  CHECK(bindings & kWebUIBindingsPolicyMask);
+  CHECK_EQ(0, bindings & ~kWebUIBindingsPolicyMask);
+
   base::AutoLock lock(lock_);
 
   SecurityStateMap::iterator state = security_state_.find(child_id);
   if (state == security_state_.end())
     return;
 
-  state->second->GrantBindings(BINDINGS_POLICY_WEB_UI);
+  state->second->GrantBindings(bindings);
 
   // Web UI bindings need the ability to request chrome: URLs.
   state->second->GrantScheme(kChromeUIScheme);
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h
index 81cf618..5f0738f1 100644
--- a/content/browser/child_process_security_policy_impl.h
+++ b/content/browser/child_process_security_policy_impl.h
@@ -151,8 +151,9 @@
   // Revokes all permissions granted to the given file.
   void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file);
 
-  // Grant the child process the ability to use Web UI Bindings.
-  void GrantWebUIBindings(int child_id);
+  // Grant the child process the ability to use Web UI Bindings where |bindings|
+  // is either BINDINGS_POLICY_WEB_UI or BINDINGS_POLICY_MOJO_WEB_UI or both.
+  void GrantWebUIBindings(int child_id, int bindings);
 
   // Grant the child process the ability to read raw cookies.
   void GrantReadRawCookies(int child_id);
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index 499cf3a..2961b5030 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "base/test/mock_log.h"
 #include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/common/bindings_policy.h"
 #include "content/public/common/url_constants.h"
 #include "content/test/test_content_browser_client.h"
 #include "storage/browser/fileapi/file_permission_policy.h"
@@ -834,18 +835,40 @@
       ChildProcessSecurityPolicyImpl::GetInstance();
 
   GURL url("chrome://thumb/http://www.google.com/");
-
-  p->Add(kRendererID);
-
-  EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
-  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
-  EXPECT_TRUE(p->CanRedirectToURL(url));
-  p->GrantWebUIBindings(kRendererID);
-  EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
-  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
-  EXPECT_TRUE(p->CanRedirectToURL(url));
-
-  p->Remove(kRendererID);
+  {
+    p->Add(kRendererID);
+    EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
+    EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->GrantWebUIBindings(kRendererID, BINDINGS_POLICY_WEB_UI);
+    EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+    EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->Remove(kRendererID);
+  }
+  {
+    p->Add(kRendererID);
+    EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
+    EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->GrantWebUIBindings(kRendererID, BINDINGS_POLICY_MOJO_WEB_UI);
+    EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+    EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->Remove(kRendererID);
+  }
+  {
+    p->Add(kRendererID);
+    EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
+    EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->GrantWebUIBindings(kRendererID,
+                          BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
+    EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+    EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+    EXPECT_TRUE(p->CanRedirectToURL(url));
+    p->Remove(kRendererID);
+  }
 }
 
 TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) {
@@ -859,7 +882,8 @@
 
   p->GrantRequestURL(kRendererID, url);
   p->GrantReadFile(kRendererID, file);
-  p->GrantWebUIBindings(kRendererID);
+  p->GrantWebUIBindings(kRendererID,
+                        BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
 
   EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
   EXPECT_TRUE(p->CanRedirectToURL(url));
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 5c9ae5eb..3e5f7688 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -278,7 +278,7 @@
       ozone_platform->GetOverlayManager();
   if (!command_line->HasSwitch(switches::kEnableHardwareOverlays) &&
       overlay_manager->SupportsOverlays()) {
-    enable_overlay_flag = "single-fullscreen,single-on-top";
+    enable_overlay_flag = "single-fullscreen,single-on-top,underlay";
   }
   if (!enable_overlay_flag.empty()) {
     std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates =
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 2a3d60c1..05c182e 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -23,7 +23,6 @@
 #include "build/build_config.h"
 #include "components/download/database/in_progress/download_entry.h"
 #include "components/download/database/in_progress/in_progress_cache_impl.h"
-#include "components/download/database/switches.h"
 #include "components/download/public/common/download_create_info.h"
 #include "components/download/public/common/download_file.h"
 #include "components/download/public/common/download_interrupt_reasons.h"
@@ -518,18 +517,6 @@
   }
 }
 
-void DownloadManagerImpl::OnHistoryQueryComplete(
-    base::OnceClosure load_history_downloads_cb) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          download::switches::kEnableDownloadDB) &&
-      !in_progress_cache_initialized_) {
-    load_history_downloads_cb_ = std::move(load_history_downloads_cb);
-  } else {
-    std::move(load_history_downloads_cb).Run();
-  }
-}
-
 void DownloadManagerImpl::CheckForFileRemoval(
     download::DownloadItemImpl* download_item) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index 13e2808..041492c4 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -128,8 +128,6 @@
   int NonMaliciousInProgressCount() const override;
   BrowserContext* GetBrowserContext() const override;
   void CheckForHistoryFilesRemoval() override;
-  void OnHistoryQueryComplete(
-      base::OnceClosure load_history_downloads_cb) override;
   download::DownloadItem* GetDownload(uint32_t id) override;
   download::DownloadItem* GetDownloadByGuid(const std::string& guid) override;
 
@@ -316,9 +314,6 @@
 
   std::unique_ptr<download::InProgressDownloadManager> in_progress_manager_;
 
-  // Callback to run to load all history downloads.
-  base::OnceClosure load_history_downloads_cb_;
-
   base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl);
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 1162ff7..eee2ddc 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -86,7 +86,7 @@
               ->GetController()
               ->GetBrowserContext(),
           url);
-  if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) &&
+  if ((enabled_bindings & kWebUIBindingsPolicyMask) &&
       !is_allowed_in_web_ui_renderer) {
     // Log the URL to help us diagnose any future failures of this CHECK.
     FrameTreeNode* root_node =
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 0088be85..d3a04d77 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2221,10 +2221,11 @@
                "frame_tree_node", frame_tree_node_->frame_tree_node_id(),
                "bindings flags", bindings_flags);
 
+  int webui_bindings = bindings_flags & kWebUIBindingsPolicyMask;
+
   // Ensure we aren't granting WebUI bindings to a process that has already
   // been used for non-privileged views.
-  if (bindings_flags & BINDINGS_POLICY_WEB_UI &&
-      GetProcess()->HasConnection() &&
+  if (webui_bindings && GetProcess()->HasConnection() &&
       !ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
           GetProcess()->GetID())) {
     // This process has no bindings yet. Make sure it does not have more
@@ -2236,9 +2237,9 @@
       return;
   }
 
-  if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
+  if (webui_bindings) {
     ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
-        GetProcess()->GetID());
+        GetProcess()->GetID(), webui_bindings);
   }
 
   enabled_bindings_ |= bindings_flags;
@@ -3649,7 +3650,7 @@
       if (std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
         network::mojom::URLLoaderFactoryPtr factory_for_webui =
             CreateWebUIURLLoaderBinding(this, scheme);
-        if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI) {
+        if (enabled_bindings_ & kWebUIBindingsPolicyMask) {
           // If the renderer has webui bindings, then don't give it access to
           // network loader for security reasons.
           default_factory_info = factory_for_webui.PassInterface();
diff --git a/content/browser/frame_host/webui_navigation_browsertest.cc b/content/browser/frame_host/webui_navigation_browsertest.cc
index 23f8a793..7add7719 100644
--- a/content/browser/frame_host/webui_navigation_browsertest.cc
+++ b/content/browser/frame_host/webui_navigation_browsertest.cc
@@ -6,6 +6,7 @@
 #include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/bindings_policy.h"
 #include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/browser_test_utils.h"
@@ -28,6 +29,107 @@
     ASSERT_TRUE(embedded_test_server()->Start());
   }
 
+  // Verify that no web content can be loaded in a process that has WebUI
+  // bindings, regardless of what scheme the content was loaded from.
+  void TestWebFrameInWebUIProcessDisallowed(int bindings) {
+    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                              ->GetFrameTree()
+                              ->root();
+    GURL data_url("data:text/html,a data url document");
+    EXPECT_TRUE(NavigateToURL(shell(), data_url));
+    EXPECT_EQ(data_url, root->current_frame_host()->GetLastCommittedURL());
+    EXPECT_FALSE(
+        ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+            root->current_frame_host()->GetProcess()->GetID()));
+
+    // Grant WebUI bindings to the process. This will ensure that if there is
+    // a mistake in the navigation logic and a process gets somehow WebUI
+    // bindings, it cannot include web content regardless of the scheme of the
+    // document.
+    ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
+        root->current_frame_host()->GetProcess()->GetID(), bindings);
+    EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+        root->current_frame_host()->GetProcess()->GetID()));
+    {
+      GURL web_url(embedded_test_server()->GetURL("/title2.html"));
+      std::string script = base::StringPrintf(
+          "var frame = document.createElement('iframe');\n"
+          "frame.src = '%s';\n"
+          "document.body.appendChild(frame);\n",
+          web_url.spec().c_str());
+
+      TestNavigationObserver navigation_observer(shell()->web_contents());
+      EXPECT_TRUE(ExecuteScript(shell(), script));
+      navigation_observer.Wait();
+
+      EXPECT_EQ(1U, root->child_count());
+      EXPECT_FALSE(navigation_observer.last_navigation_succeeded());
+    }
+  }
+
+  // Verify that a WebUI document in a subframe is allowed to target a new
+  // window and navigate it to web content.
+  void TestWebUISubframeNewWindowToWebAllowed(int bindings) {
+    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                              ->GetFrameTree()
+                              ->root();
+
+    // TODO(nasko): Replace this URL with one with a custom WebUI object that
+    // doesn't have restrictive CSP, so the test can successfully add an
+    // iframe which gets WebUI bindings in the renderer process.
+    GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" +
+                           std::string(kChromeUIBlobInternalsHost));
+    EXPECT_TRUE(NavigateToURL(shell(), chrome_url));
+    RenderFrameHost* webui_rfh = root->current_frame_host();
+    scoped_refptr<SiteInstance> webui_site_instance =
+        webui_rfh->GetSiteInstance();
+
+    ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
+        webui_rfh->GetProcess()->GetID(), bindings);
+
+    EXPECT_EQ(chrome_url, webui_rfh->GetLastCommittedURL());
+    EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+        webui_rfh->GetProcess()->GetID()));
+
+    // Create a subframe with a WebUI document in it.
+    {
+      std::string script = base::StringPrintf(
+          "var frame = document.createElement('iframe');\n"
+          "frame.src = '%s';\n"
+          "document.body.appendChild(frame);\n",
+          chrome_url.spec().c_str());
+
+      TestNavigationObserver navigation_observer(shell()->web_contents());
+      EXPECT_TRUE(ExecuteScript(shell(), script));
+      navigation_observer.Wait();
+
+      EXPECT_EQ(1U, root->child_count());
+      EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
+    }
+
+    // Add a link that targets a new window and click it.
+    GURL web_url(embedded_test_server()->GetURL("/title2.html"));
+    std::string script = base::StringPrintf(
+        "var a = document.createElement('a');"
+        "a.href = '%s'; a.target = '_blank'; a.click()",
+        web_url.spec().c_str());
+
+    ShellAddedObserver new_shell_observer;
+    EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));
+    Shell* new_shell = new_shell_observer.GetShell();
+    WaitForLoadStop(new_shell->web_contents());
+
+    EXPECT_EQ(web_url, new_shell->web_contents()->GetLastCommittedURL());
+
+    // TODO(nasko): Verify the SiteInstance is different once
+    // https://crbug.com/776900 is fixed.
+    // Without a WebUI object which requires WebUI bindings, the RenderFrame is
+    // not notified that it has WebUI bindings. This in turn causes link clicks
+    // to use the BeginNavigation path, where otherwise the WebUI bindings will
+    // cause the OpenURL path to be taken. When using BeginNavigation, the
+    // navigation is committed same process, since it is renderer initiated.
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(WebUINavigationBrowserTest);
 };
@@ -101,44 +203,6 @@
   }
 }
 
-// Verify that no web content can be loaded in a process that has WebUI
-// bindings, regardless of what scheme the content was loaded from.
-IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
-                       WebFrameInWebUIProcessDisallowed) {
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetFrameTree()
-                            ->root();
-  GURL data_url("data:text/html,a data url document");
-  EXPECT_TRUE(NavigateToURL(shell(), data_url));
-  EXPECT_EQ(data_url, root->current_frame_host()->GetLastCommittedURL());
-  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
-      root->current_frame_host()->GetProcess()->GetID()));
-
-  // Grant WebUI bindings to the process. This will ensure that if there is
-  // a mistake in the navigation logic and a process gets somehow WebUI
-  // bindings, it cannot include web content regardless of the scheme of the
-  // document.
-  ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
-      root->current_frame_host()->GetProcess()->GetID());
-  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
-      root->current_frame_host()->GetProcess()->GetID()));
-  {
-    GURL web_url(embedded_test_server()->GetURL("/title2.html"));
-    std::string script = base::StringPrintf(
-        "var frame = document.createElement('iframe');\n"
-        "frame.src = '%s';\n"
-        "document.body.appendChild(frame);\n",
-        web_url.spec().c_str());
-
-    TestNavigationObserver navigation_observer(shell()->web_contents());
-    EXPECT_TRUE(ExecuteScript(shell(), script));
-    navigation_observer.Wait();
-
-    EXPECT_EQ(1U, root->child_count());
-    EXPECT_FALSE(navigation_observer.last_navigation_succeeded());
-  }
-}
-
 // Verify that a WebUI document in the main frame is allowed to navigate to
 // web content and it properly does cross-process navigation.
 IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
@@ -171,68 +235,36 @@
       root->current_frame_host()->GetSiteInstance()));
 }
 
-// Verify that a WebUI document in a subframe is allowed to target a new
-// window and navigate it to web content.
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+                       WebFrameInWebUIProcessDisallowed) {
+  TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_WEB_UI);
+}
+
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+                       WebFrameInMojoWebUIProcessDisallowed) {
+  TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_MOJO_WEB_UI);
+}
+
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+                       WebFrameInHybridWebUIProcessDisallowed) {
+  TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_MOJO_WEB_UI |
+                                       BINDINGS_POLICY_WEB_UI);
+}
+
 IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
                        WebUISubframeNewWindowToWebAllowed) {
-  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
-                            ->GetFrameTree()
-                            ->root();
+  TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_WEB_UI);
+}
 
-  // TODO(nasko): Replace this URL with one with a custom WebUI object that
-  // doesn't have restrictive CSP, so the test can successfully add an
-  // iframe which gets WebUI bindings in the renderer process.
-  GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" +
-                         std::string(kChromeUIBlobInternalsHost));
-  EXPECT_TRUE(NavigateToURL(shell(), chrome_url));
-  RenderFrameHost* webui_rfh = root->current_frame_host();
-  scoped_refptr<SiteInstance> webui_site_instance =
-      webui_rfh->GetSiteInstance();
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+                       MojoWebUISubframeNewWindowToWebAllowed) {
+  TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_MOJO_WEB_UI);
+}
 
-  ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
-      webui_rfh->GetProcess()->GetID());
-
-  EXPECT_EQ(chrome_url, webui_rfh->GetLastCommittedURL());
-  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
-      webui_rfh->GetProcess()->GetID()));
-
-  // Create a subframe with a WebUI document in it.
-  {
-    std::string script = base::StringPrintf(
-        "var frame = document.createElement('iframe');\n"
-        "frame.src = '%s';\n"
-        "document.body.appendChild(frame);\n",
-        chrome_url.spec().c_str());
-
-    TestNavigationObserver navigation_observer(shell()->web_contents());
-    EXPECT_TRUE(ExecuteScript(shell(), script));
-    navigation_observer.Wait();
-
-    EXPECT_EQ(1U, root->child_count());
-    EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
-  }
-
-  // Add a link that targets a new window and click it.
-  GURL web_url(embedded_test_server()->GetURL("/title2.html"));
-  std::string script = base::StringPrintf(
-      "var a = document.createElement('a');"
-      "a.href = '%s'; a.target = '_blank'; a.click()",
-      web_url.spec().c_str());
-
-  ShellAddedObserver new_shell_observer;
-  EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));
-  Shell* new_shell = new_shell_observer.GetShell();
-  WaitForLoadStop(new_shell->web_contents());
-
-  EXPECT_EQ(web_url, new_shell->web_contents()->GetLastCommittedURL());
-
-  // TODO(nasko): Verify the SiteInstance is different once
-  // https://crbug.com/776900 is fixed.
-  // Without a WebUI object which requires WebUI bindings, the RenderFrame is
-  // not notified that it has WebUI bindings. This in turn causes link clicks
-  // to use the BeginNavigation path, where otherwise the WebUI bindings will
-  // cause the OpenURL path to be taken. When using BeginNavigation, the
-  // navigation is committed same process, since it is renderer initiated.
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+                       HybridWebUISubframeNewWindowToWebAllowed) {
+  TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_MOJO_WEB_UI |
+                                         BINDINGS_POLICY_WEB_UI);
 }
 
 }  // namespace content
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index fd3bac82..316b99e 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -189,6 +189,7 @@
     switches::kDisableGLExtensions,
     switches::kDisableLogging,
     switches::kDisableShaderNameHashing,
+    switches::kDisableSkiaRuntimeOpts,
     switches::kDisableWebRtcHWEncoding,
 #if defined(OS_WIN)
     switches::kEnableAcceleratedVpxDecode,
@@ -202,6 +203,8 @@
     switches::kEnableLowEndDeviceMode,
     switches::kDisableLowEndDeviceMode,
     switches::kRunAllCompositorStagesBeforeDraw,
+    switches::kSkiaFontCacheLimitMb,
+    switches::kSkiaResourceCacheLimitMb,
     switches::kTestGLLib,
     switches::kTraceToConsole,
     switches::kUseFakeJpegDecodeAccelerator,
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
index e27cc29..6a1008a 100644
--- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
+++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -76,6 +76,9 @@
 void PictureInPictureWindowControllerImpl::Close() {
   DCHECK(window_);
 
+  if (!window_->IsVisible())
+    return;
+
   window_->Hide();
   initiator_->SetHasPictureInPictureVideo(false);
 
diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc
index a951584..60928166 100644
--- a/content/browser/renderer_host/clipboard_host_impl.cc
+++ b/content/browser/renderer_host/clipboard_host_impl.cc
@@ -4,100 +4,30 @@
 
 #include "content/browser/renderer_host/clipboard_host_impl.h"
 
-#include <limits>
 #include <utility>
 
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/pickle.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
-#include "content/browser/blob_storage/chrome_blob_storage_context.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "ipc/ipc_message_macros.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/clipboard/custom_data_helper.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
-#include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
 
 namespace content {
-namespace {
 
-void ReleaseSharedMemoryPixels(void* addr, void* context) {
-  MojoResult result = MojoUnmapBuffer(context);
-  DCHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-void OnReadAndEncodeImageFinished(
-    scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
-    std::vector<uint8_t> png_data,
-    ClipboardHostImpl::ReadImageCallback callback) {
-  // |blob_storage_context| must be accessed only on the IO thread.
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  blink::mojom::SerializedBlobPtr blob;
-  if (png_data.size() < std::numeric_limits<uint32_t>::max()) {
-    std::unique_ptr<content::BlobHandle> blob_handle =
-        blob_storage_context->CreateMemoryBackedBlob(
-            reinterpret_cast<char*>(png_data.data()), png_data.size(), "");
-    if (blob_handle) {
-      std::string blob_uuid = blob_handle->GetUUID();
-      blob = blink::mojom::SerializedBlob::New(
-          blob_uuid, ui::Clipboard::kMimeTypePNG,
-          static_cast<int64_t>(png_data.size()),
-          blob_handle->PassBlob().PassInterface());
-    }
-  }
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::BindOnce(std::move(callback), std::move(blob)));
-}
-
-void ReadAndEncodeImage(
-    scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
-    const SkBitmap& bitmap,
-    ClipboardHostImpl::ReadImageCallback callback) {
-  std::vector<uint8_t> png_data;
-  if (!gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                            base::BindOnce(std::move(callback), nullptr));
-    return;
-  }
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&OnReadAndEncodeImageFinished,
-                     std::move(blob_storage_context), std::move(png_data),
-                     std::move(callback)));
-}
-
-}  // namespace
-
-ClipboardHostImpl::ClipboardHostImpl(
-    scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
+ClipboardHostImpl::ClipboardHostImpl()
     : clipboard_(ui::Clipboard::GetForCurrentThread()),
-      blob_storage_context_(std::move(blob_storage_context)),
       clipboard_writer_(
-          new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-}
+          new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}
 
-void ClipboardHostImpl::Create(
-    scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
-    blink::mojom::ClipboardHostRequest request) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ClipboardHostImpl::Create(blink::mojom::ClipboardHostRequest request) {
   mojo::MakeStrongBinding(
-      base::WrapUnique<ClipboardHostImpl>(
-          new ClipboardHostImpl(std::move(blob_storage_context))),
+      base::WrapUnique<ClipboardHostImpl>(new ClipboardHostImpl()),
       std::move(request));
 }
 
@@ -107,14 +37,12 @@
 
 void ClipboardHostImpl::GetSequenceNumber(ui::ClipboardType clipboard_type,
                                           GetSequenceNumberCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::move(callback).Run(clipboard_->GetSequenceNumber(clipboard_type));
 }
 
 void ClipboardHostImpl::ReadAvailableTypes(
     ui::ClipboardType clipboard_type,
     ReadAvailableTypesCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::vector<base::string16> types;
   bool contains_filenames;
   clipboard_->ReadAvailableTypes(clipboard_type, &types, &contains_filenames);
@@ -124,7 +52,6 @@
 void ClipboardHostImpl::IsFormatAvailable(blink::mojom::ClipboardFormat format,
                                           ui::ClipboardType clipboard_type,
                                           IsFormatAvailableCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   bool result = false;
   switch (format) {
     case blink::mojom::ClipboardFormat::kPlaintext:
@@ -155,8 +82,6 @@
 
 void ClipboardHostImpl::ReadText(ui::ClipboardType clipboard_type,
                                  ReadTextCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   base::string16 result;
   if (clipboard_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
                                     clipboard_type)) {
@@ -172,8 +97,6 @@
 
 void ClipboardHostImpl::ReadHtml(ui::ClipboardType clipboard_type,
                                  ReadHtmlCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   base::string16 markup;
   std::string src_url_str;
   uint32_t fragment_start = 0;
@@ -186,8 +109,6 @@
 
 void ClipboardHostImpl::ReadRtf(ui::ClipboardType clipboard_type,
                                 ReadRtfCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   std::string result;
   clipboard_->ReadRTF(clipboard_type, &result);
   std::move(callback).Run(result);
@@ -195,27 +116,13 @@
 
 void ClipboardHostImpl::ReadImage(ui::ClipboardType clipboard_type,
                                   ReadImageCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  SkBitmap bitmap = clipboard_->ReadImage(clipboard_type);
-
-  if (bitmap.isNull()) {
-    std::move(callback).Run(nullptr);
-    return;
-  }
-  base::PostTaskWithTraits(
-      FROM_HERE,
-      {base::MayBlock(), base::TaskPriority::BACKGROUND,
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(&ReadAndEncodeImage, blob_storage_context_,
-                     std::move(bitmap), std::move(callback)));
+  SkBitmap result = clipboard_->ReadImage(clipboard_type);
+  std::move(callback).Run(result);
 }
 
 void ClipboardHostImpl::ReadCustomData(ui::ClipboardType clipboard_type,
                                        const base::string16& type,
                                        ReadCustomDataCallback callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   base::string16 result;
   clipboard_->ReadCustomData(clipboard_type, type, &result);
   std::move(callback).Run(result);
@@ -223,26 +130,22 @@
 
 void ClipboardHostImpl::WriteText(ui::ClipboardType,
                                   const base::string16& text) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   clipboard_writer_->WriteText(text);
 }
 
 void ClipboardHostImpl::WriteHtml(ui::ClipboardType,
                                   const base::string16& markup,
                                   const GURL& url) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   clipboard_writer_->WriteHTML(markup, url.spec());
 }
 
 void ClipboardHostImpl::WriteSmartPasteMarker(ui::ClipboardType) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   clipboard_writer_->WriteWebSmartPaste();
 }
 
 void ClipboardHostImpl::WriteCustomData(
     ui::ClipboardType,
     const base::flat_map<base::string16, base::string16>& data) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Pickle pickle;
   ui::WriteCustomDataToPickle(data, &pickle);
   clipboard_writer_->WritePickledData(
@@ -252,41 +155,14 @@
 void ClipboardHostImpl::WriteBookmark(ui::ClipboardType,
                                       const std::string& url,
                                       const base::string16& title) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   clipboard_writer_->WriteBookmark(title, url);
 }
 
-void ClipboardHostImpl::WriteImage(
-    ui::ClipboardType,
-    const gfx::Size& size,
-    mojo::ScopedSharedBufferHandle shared_buffer_handle) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  SkBitmap bitmap;
-  // Let Skia do some sanity checking for (no negative widths/heights, no
-  // overflows while calculating bytes per row, etc).
-  if (!bitmap.setInfo(
-          SkImageInfo::MakeN32Premul(size.width(), size.height()))) {
-    return;
-  }
-
-  auto mapped = shared_buffer_handle->Map(bitmap.computeByteSize());
-  if (!mapped) {
-    return;
-  }
-
-  if (!bitmap.installPixels(bitmap.info(), mapped.get(), bitmap.rowBytes(),
-                            &ReleaseSharedMemoryPixels, mapped.get())) {
-    return;
-  }
-
-  // On success, SkBitmap now owns the SharedMemory.
-  mapped.release();
+void ClipboardHostImpl::WriteImage(ui::ClipboardType, const SkBitmap& bitmap) {
   clipboard_writer_->WriteImage(bitmap);
 }
 
 void ClipboardHostImpl::CommitWrite(ui::ClipboardType) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   clipboard_writer_.reset(
       new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
 }
diff --git a/content/browser/renderer_host/clipboard_host_impl.h b/content/browser/renderer_host/clipboard_host_impl.h
index 7199ebc..f9c6a3d 100644
--- a/content/browser/renderer_host/clipboard_host_impl.h
+++ b/content/browser/renderer_host/clipboard_host_impl.h
@@ -5,50 +5,35 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
 #define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
 
-#include <stdint.h>
-
 #include <memory>
 #include <string>
-#include <vector>
 
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
-#include "content/public/browser/browser_associated_interface.h"
-#include "content/public/browser/browser_message_filter.h"
 #include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
 #include "ui/base/clipboard/clipboard.h"
 
 class GURL;
 
-namespace gfx {
-class Size;
-}
-
 namespace ui {
 class ScopedClipboardWriter;
 }  // namespace ui
 
 namespace content {
 
-class ChromeBlobStorageContext;
 class ClipboardHostImplTest;
 
 class CONTENT_EXPORT ClipboardHostImpl : public blink::mojom::ClipboardHost {
  public:
   ~ClipboardHostImpl() override;
 
-  static void Create(
-      scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
-      blink::mojom::ClipboardHostRequest request);
+  static void Create(blink::mojom::ClipboardHostRequest request);
 
  private:
   friend class ClipboardHostImplTest;
 
-  explicit ClipboardHostImpl(
-      scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
+  ClipboardHostImpl();
 
   // content::mojom::ClipboardHost
   void GetSequenceNumber(ui::ClipboardType clipboard_type,
@@ -82,15 +67,13 @@
                      const std::string& url,
                      const base::string16& title) override;
   void WriteImage(ui::ClipboardType clipboard_type,
-                  const gfx::Size& size_in_pixels,
-                  mojo::ScopedSharedBufferHandle shared_buffer_handle) override;
+                  const SkBitmap& bitmap) override;
   void CommitWrite(ui::ClipboardType clipboard_type) override;
 #if defined(OS_MACOSX)
   void WriteStringToFindPboard(const base::string16& text) override;
 #endif
 
   ui::Clipboard* clipboard_;  // Not owned
-  scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
   std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
 };
 
diff --git a/content/browser/renderer_host/clipboard_host_impl_unittest.cc b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index 704acc6..a3a0e92 100644
--- a/content/browser/renderer_host/clipboard_host_impl_unittest.cc
+++ b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -6,41 +6,31 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <string.h>
 
-#include "base/memory/ref_counted.h"
-#include "base/process/process_handle.h"
 #include "base/run_loop.h"
-#include "content/browser/blob_storage/chrome_blob_storage_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "mojo/public/cpp/system/platform_handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/test/test_clipboard.h"
-#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/skia_util.h"
 
 namespace content {
 
 class ClipboardHostImplTest : public ::testing::Test {
  protected:
   ClipboardHostImplTest()
-      : host_(new ClipboardHostImpl(nullptr)),
-        clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
+      : clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
 
   ~ClipboardHostImplTest() override {
     ui::Clipboard::DestroyClipboardForCurrentThread();
   }
 
-  void CallWriteImage(const gfx::Size& size,
-                      mojo::ScopedSharedBufferHandle shared_memory,
-                      size_t shared_memory_size) {
-    host_->WriteImage(
-        ui::CLIPBOARD_TYPE_COPY_PASTE, size,
-        shared_memory->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY));
+  void CallWriteImage(const SkBitmap& bitmap) {
+    host_.WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap);
   }
 
   void CallCommitWrite() {
-    host_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+    host_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
     base::RunLoop().RunUntilIdle();
   }
 
@@ -48,27 +38,16 @@
 
  private:
   const TestBrowserThreadBundle thread_bundle_;
-  const std::unique_ptr<ClipboardHostImpl> host_;
+  ClipboardHostImpl host_;
   ui::Clipboard* const clipboard_;
 };
 
 // Test that it actually works.
 TEST_F(ClipboardHostImplTest, SimpleImage) {
-  static const uint32_t bitmap_data[] = {
-      0x33333333, 0xdddddddd, 0xeeeeeeee, 0x00000000, 0x88888888, 0x66666666,
-      0x55555555, 0xbbbbbbbb, 0x44444444, 0xaaaaaaaa, 0x99999999, 0x77777777,
-      0xffffffff, 0x11111111, 0x22222222, 0xcccccccc,
-  };
-
-  mojo::ScopedSharedBufferHandle shared_memory =
-      mojo::SharedBufferHandle::Create(sizeof(bitmap_data));
-  mojo::ScopedSharedBufferMapping mapping =
-      shared_memory->Map(sizeof(bitmap_data));
-
-  memcpy(mapping.get(), bitmap_data, sizeof(bitmap_data));
-
-  CallWriteImage(gfx::Size(4, 4), std::move(shared_memory),
-                 sizeof(bitmap_data));
+  SkBitmap bitmap;
+  bitmap.allocN32Pixels(3, 2);
+  bitmap.eraseARGB(255, 0, 255, 0);
+  CallWriteImage(bitmap);
   uint64_t sequence_number =
       clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
   CallCommitWrite();
@@ -81,26 +60,7 @@
       ui::Clipboard::GetBitmapFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
 
   SkBitmap actual = clipboard()->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE);
-  EXPECT_EQ(sizeof(bitmap_data), actual.computeByteSize());
-  EXPECT_EQ(0,
-            memcmp(bitmap_data, actual.getAddr32(0, 0), sizeof(bitmap_data)));
-}
-
-// Test with a size that would overflow a naive 32-bit row bytes calculation.
-TEST_F(ClipboardHostImplTest, ImageSizeOverflows32BitRowBytes) {
-  mojo::ScopedSharedBufferHandle shared_memory =
-      mojo::SharedBufferHandle::Create(0x20000000);
-
-  mojo::ScopedSharedBufferMapping mapping = shared_memory->Map(0x20000000);
-
-  CallWriteImage(gfx::Size(0x20000000, 1), std::move(shared_memory),
-                 0x20000000);
-  uint64_t sequence_number =
-      clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
-  CallCommitWrite();
-
-  EXPECT_EQ(sequence_number,
-            clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE));
+  EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap, actual));
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index d22da30..a679605 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -18,7 +18,6 @@
 #include "base/sequenced_task_runner_helpers.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
 #include "content/common/render_message_filter.mojom.h"
 #include "content/public/browser/browser_associated_interface.h"
 #include "content/public/browser/browser_message_filter.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index a8be65ae..c31a0bf 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1924,13 +1924,8 @@
         base::Bind(&CreateProcessResourceCoordinator, base::Unretained(this)));
   }
 
-  BrowserContext* browser_context = GetBrowserContext();
-  scoped_refptr<ChromeBlobStorageContext> blob_storage_context =
-      ChromeBlobStorageContext::GetFor(browser_context);
-
   AddUIThreadInterface(registry.get(),
-                       base::BindRepeating(&ClipboardHostImpl::Create,
-                                           std::move(blob_storage_context)));
+                       base::BindRepeating(&ClipboardHostImpl::Create));
 
   media::VideoDecodePerfHistory* video_perf_history =
       GetBrowserContext()->GetVideoDecodePerfHistory();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 99f24a6..d73c9081 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -213,8 +213,7 @@
 class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
  public:
   FakeWindowEventDispatcher(aura::WindowTreeHost* host)
-      : WindowEventDispatcher(host),
-        processed_touch_event_count_(0) {}
+      : WindowEventDispatcher(host, true), processed_touch_event_count_(0) {}
 
   void ProcessedTouchEvent(
       uint32_t unique_event_id,
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc
index 4287b55..023efaef 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -96,6 +96,8 @@
           is_main_script, registration->update_via_cache()))
     resource_request.load_flags |= net::LOAD_BYPASS_CACHE;
 
+  resource_request.headers.SetHeader("Service-Worker", "script");
+
   // Create response readers only when we have to do the byte-for-byte check.
   std::unique_ptr<ServiceWorkerResponseReader> compare_reader;
   std::unique_ptr<ServiceWorkerResponseReader> copy_reader;
diff --git a/content/browser/shared_worker/OWNERS b/content/browser/shared_worker/OWNERS
index 595a385..6bda8b5 100644
--- a/content/browser/shared_worker/OWNERS
+++ b/content/browser/shared_worker/OWNERS
@@ -1,3 +1,4 @@
+falken@chromium.org
 horo@chromium.org
 nhiroki@chromium.org
 
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index 876a25a1..6bf2c6f 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -25,6 +25,7 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/webui/content_web_ui_controller_factory.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
+#include "content/public/common/bindings_policy.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_features.h"
@@ -42,6 +43,13 @@
 #include "url/url_util.h"
 
 namespace content {
+namespace {
+
+GURL GetWebUIURL(std::string host) {
+  return GURL(std::string(kChromeUIScheme) + "://" + host);
+}
+
+}  // namespace
 
 const char kPrivilegedScheme[] = "privileged";
 
@@ -621,6 +629,7 @@
 
 // Test to ensure that pages that require certain privileges are grouped
 // in processes with similar pages.
+// TODO(nasko): Remove. See https://crbug.com/847127.
 TEST_F(SiteInstanceTest, ProcessSharingByType) {
   // This test shouldn't run with --site-per-process mode, which prohibits
   // the renderer process reuse this test explicitly exercises.
@@ -660,13 +669,13 @@
             extension2_instance->GetProcess());
 
   // Create some WebUI instances and make sure they share a process.
-  scoped_refptr<SiteInstanceImpl> webui1_instance(CreateSiteInstance(
-      browser_context.get(), GURL(kChromeUIScheme + std::string("://gpu"))));
-  policy->GrantWebUIBindings(webui1_instance->GetProcess()->GetID());
+  scoped_refptr<SiteInstanceImpl> webui1_instance(
+      CreateSiteInstance(browser_context.get(), GetWebUIURL(kChromeUIGpuHost)));
+  policy->GrantWebUIBindings(webui1_instance->GetProcess()->GetID(),
+                             BINDINGS_POLICY_WEB_UI);
 
   scoped_refptr<SiteInstanceImpl> webui2_instance(CreateSiteInstance(
-      browser_context.get(),
-      GURL(kChromeUIScheme + std::string("://media-internals"))));
+      browser_context.get(), GetWebUIURL(kChromeUIMediaInternalsHost)));
 
   std::unique_ptr<RenderProcessHost> dom_host(webui1_instance->GetProcess());
   EXPECT_EQ(webui1_instance->GetProcess(), webui2_instance->GetProcess());
@@ -724,7 +733,7 @@
 
   // Simulate granting WebUI bindings for the process.
   ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
-      webui_host->GetID());
+      webui_host->GetID(), BINDINGS_POLICY_WEB_UI);
 
   EXPECT_TRUE(webui_instance->HasProcess());
   EXPECT_FALSE(webui_instance->HasWrongProcessForURL(webui_url));
@@ -1024,7 +1033,7 @@
 
   // Scheme must be HTTP or HTTPS.
   EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
-      url::Origin::Create(GURL(kChromeUIScheme + std::string("://gpu")))));
+      url::Origin::Create(GetWebUIURL(kChromeUIGpuHost))));
   EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
       url::Origin::Create(GURL("http://a.com"))));
   EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
diff --git a/content/browser/web_package/signed_exchange_consts.h b/content/browser/web_package/signed_exchange_consts.h
index 575c281..4f02828 100644
--- a/content/browser/web_package/signed_exchange_consts.h
+++ b/content/browser/web_package/signed_exchange_consts.h
@@ -15,8 +15,8 @@
 // Field names defined in the application/signed-exchange content type:
 // https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
 
-constexpr char kCertSha256Key[] = "certSha256";
-constexpr char kCertUrl[] = "certUrl";
+constexpr char kCertSha256Key[] = "cert-sha256";
+constexpr char kCertUrl[] = "cert-url";
 constexpr char kDateKey[] = "date";
 constexpr char kExpiresKey[] = "expires";
 constexpr char kHeadersKey[] = "headers";
@@ -26,7 +26,7 @@
 constexpr char kSig[] = "sig";
 constexpr char kStatusKey[] = ":status";
 constexpr char kUrlKey[] = ":url";
-constexpr char kValidityUrlKey[] = "validityUrl";
+constexpr char kValidityUrlKey[] = "validity-url";
 constexpr char kCertChainCborMagic[] = u8"\U0001F4DC\u26D3";  // "📜⛓"
 constexpr char kCertKey[] = "cert";
 constexpr char kOcspKey[] = "ocsp";
diff --git a/content/browser/web_package/signed_exchange_envelope_unittest.cc b/content/browser/web_package/signed_exchange_envelope_unittest.cc
index 7506b58..4e232f3c 100644
--- a/content/browser/web_package/signed_exchange_envelope_unittest.cc
+++ b/content/browser/web_package/signed_exchange_envelope_unittest.cc
@@ -22,11 +22,11 @@
 const char kSignatureString[] =
     "sig1;"
     " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-    "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+    "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
     " integrity=\"mi\";"
-    " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-    " certUrl=\"https://example.com/oldcerts\";"
-    " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+    " validity-url=\"https://example.com/resource.validity.1511128380\";"
+    " cert-url=\"https://example.com/oldcerts\";"
+    " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
     " date=1511128380; expires=1511733180";
 
 cbor::CBORValue CBORByteString(const char* str) {
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc
index 7bb22de9d..21c2189a 100644
--- a/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -337,7 +337,7 @@
 
 TEST_P(SignedExchangeHandlerTest, CertSha256Mismatch) {
   // The certificate is for "127.0.0.1". And the SHA 256 hash of the certificate
-  // is different from the certSha256 of the signature in the htxg file. So the
+  // is different from the cert-sha256 of the signature in the htxg file. So the
   // certification verification must fail.
   mock_cert_fetcher_factory_->ExpectFetch(
       GURL("https://cert.example.org/cert.msg"),
diff --git a/content/browser/web_package/signed_exchange_signature_header_field.cc b/content/browser/web_package/signed_exchange_signature_header_field.cc
index 0295fb5..5a6f0b2 100644
--- a/content/browser/web_package/signed_exchange_signature_header_field.cc
+++ b/content/browser/web_package/signed_exchange_signature_header_field.cc
@@ -19,60 +19,51 @@
 
 namespace {
 
-// This covers the characters allowed in Numbers, Labels, and Binary Content.
-constexpr char kTokenChars[] =
-    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_+-*/";
+// This covers the characters allowed in Integers and Identifiers.
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.5
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.8
+constexpr char kTokenChars[] = "0123456789abcdefghijklmnopqrstuvwxyz_-*/";
 
-struct ParameterisedLabel {
-  std::string label;
+struct ParameterisedIdentifier {
+  std::string identifier;
   std::map<std::string, std::string> params;
 };
 
 // Parser for (a subset of) Structured Headers defined in [SH].
-// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-02
+// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04
 class StructuredHeaderParser {
  public:
   explicit StructuredHeaderParser(const base::StringPiece& str)
       : input_(str), failed_(false) {}
 
+  // Callers should call this after ParseSomething(), to check if parser has
+  // consumed all the input successfully.
   bool ParsedSuccessfully() const { return !failed_ && input_.empty(); }
 
-  // Parses a List ([SH] 4.8) of Strings.
-  void ParseStringList(std::vector<std::string>* values) {
-    values->push_back(ReadString());
+  // Parses a Parameterised List ([SH] 4.3).
+  void ParseParameterisedList(std::vector<ParameterisedIdentifier>* values) {
+    values->push_back(ParameterisedIdentifier());
+    ParseParameterisedIdentifier(&values->back());
     while (!failed_) {
       SkipWhitespaces();
       if (!ConsumeChar(','))
         break;
       SkipWhitespaces();
-      values->push_back(ReadString());
+      values->push_back(ParameterisedIdentifier());
+      ParseParameterisedIdentifier(&values->back());
     }
   }
 
-  // Parses a List ([SH] 4.8) of Parameterised Labels.
-  void ParseParameterisedLabelList(std::vector<ParameterisedLabel>* values) {
-    values->push_back(ParameterisedLabel());
-    ParseParameterisedLabel(&values->back());
-    while (!failed_) {
-      SkipWhitespaces();
-      if (!ConsumeChar(','))
-        break;
-      SkipWhitespaces();
-      values->push_back(ParameterisedLabel());
-      ParseParameterisedLabel(&values->back());
-    }
-  }
-
-  // Parses a Parameterised Label ([SH] 4.4).
-  void ParseParameterisedLabel(ParameterisedLabel* out) {
-    std::string label = ReadToken();
-    if (label.empty()) {
-      DVLOG(1) << "ParseParameterisedLabel: Label expected, got '"
+  // Parses a Parameterised Identifier ([SH] 4.3.2).
+  void ParseParameterisedIdentifier(ParameterisedIdentifier* out) {
+    std::string identifier = ReadToken();
+    if (identifier.empty()) {
+      DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '"
                << input_.front() << "'";
       failed_ = true;
       return;
     }
-    out->label = label;
+    out->identifier = identifier;
 
     while (!failed_) {
       SkipWhitespaces();
@@ -82,7 +73,7 @@
 
       std::string name = ReadToken();
       if (name.empty()) {
-        DVLOG(1) << "ParseParameterisedLabel: Label expected, got '"
+        DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '"
                  << input_.front() << "'";
         failed_ = true;
         return;
@@ -91,7 +82,8 @@
       if (ConsumeChar('='))
         value = ReadItem();
       if (!out->params.insert(std::make_pair(name, value)).second) {
-        DVLOG(1) << "ParseParameterisedLabel: duplicated parameter: " << name;
+        DVLOG(1) << "ParseParameterisedIdentifier: duplicated parameter: "
+                 << name;
         failed_ = true;
         return;
       }
@@ -120,7 +112,7 @@
     return false;
   }
 
-  // [SH] 4.2. Strings
+  // [SH] 4.7. Strings
   std::string ReadString() {
     std::string s;
     if (!ConsumeChar('"')) {
@@ -150,25 +142,31 @@
     return s;
   }
 
-  // [SH] 4.5. Binary Content
+  // [SH] 4.9. Binary Content
   std::string ReadBinary() {
     if (!ConsumeChar('*')) {
       DVLOG(1) << "ReadBinary: '*' expected, got '" << input_.front() << "'";
       failed_ = true;
       return std::string();
     }
-    std::string base64 = ReadToken();
-    // Binary Content does not have padding, so we have to add it.
-    base64.resize((base64.size() + 3) / 4 * 4, '=');
+    size_t len = input_.find('*');
+    if (len == base::StringPiece::npos) {
+      DVLOG(1) << "ReadBinary: missing closing '*'";
+      failed_ = true;
+      return std::string();
+    }
+    base::StringPiece base64 = input_.substr(0, len);
     std::string binary;
     if (!base::Base64Decode(base64, &binary)) {
       DVLOG(1) << "ReadBinary: failed to decode base64: " << base64;
       failed_ = true;
     }
+    input_.remove_prefix(len);
+    ConsumeChar('*');
     return binary;
   }
 
-  // [SH] 4.6. Items
+  // [SH] 4.4. Items
   std::string ReadItem() {
     if (input_.empty()) {
       DVLOG(1) << "ReadItem: unexpected EOF";
@@ -180,7 +178,7 @@
         return ReadString();
       case '*':
         return ReadBinary();
-      default:  // label or number
+      default:  // identifier or integer
         return ReadToken();
     }
   }
@@ -200,8 +198,8 @@
                      "SignedExchangeSignatureHeaderField::ParseSignature");
 
   StructuredHeaderParser parser(signature_str);
-  std::vector<ParameterisedLabel> values;
-  parser.ParseParameterisedLabelList(&values);
+  std::vector<ParameterisedIdentifier> values;
+  parser.ParseParameterisedList(&values);
   if (!parser.ParsedSuccessfully()) {
     signed_exchange_utils::ReportErrorAndEndTraceEvent(
         devtools_proxy, "SignedExchangeSignatureHeaderField::ParseSignature",
@@ -214,7 +212,7 @@
   for (auto& value : values) {
     signatures.push_back(Signature());
     Signature& sig = signatures.back();
-    sig.label = value.label;
+    sig.label = value.identifier;
     sig.sig = value.params[kSig];
     if (sig.sig.empty()) {
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
@@ -232,19 +230,19 @@
     sig.cert_url = GURL(value.params[kCertUrl]);
     if (!sig.cert_url.is_valid() || sig.cert_url.has_ref()) {
       // TODO(https://crbug.com/819467) : When we will support "ed25519Key", the
-      // params may not have "certUrl".
+      // params may not have "cert-url".
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeSignatureHeaderField::ParseSignature",
-          "'certUrl' parameter is not a valid URL.");
+          "'cert-url' parameter is not a valid URL.");
       return base::nullopt;
     }
     const std::string cert_sha256_string = value.params[kCertSha256Key];
     if (cert_sha256_string.size() != crypto::kSHA256Length) {
       // TODO(https://crbug.com/819467) : When we will support "ed25519Key", the
-      // params may not have "certSha256".
+      // params may not have "cert-sha256".
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeSignatureHeaderField::ParseSignature",
-          "'certSha256' parameter is not a SHA-256 digest.");
+          "'cert-sha256' parameter is not a SHA-256 digest.");
       return base::nullopt;
     }
     net::SHA256HashValue cert_sha256;
@@ -256,13 +254,13 @@
     if (!sig.validity_url.is_valid()) {
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeSignatureHeaderField::ParseSignature",
-          "'validityUrl' parameter is not a valid URL.");
+          "'validity-url' parameter is not a valid URL.");
       return base::nullopt;
     }
     if (sig.validity_url.has_ref()) {
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeSignatureHeaderField::ParseSignature",
-          "'validityUrl' parameter can't have a fragment.");
+          "'validity-url' parameter can't have a fragment.");
       return base::nullopt;
     }
     if (!base::StringToUint64(value.params[kDateKey], &sig.date)) {
@@ -289,12 +287,12 @@
     base::Optional<SignedExchangeVersion>* version_param) {
   DCHECK(version_param);
   StructuredHeaderParser parser(content_type);
-  ParameterisedLabel parameterised_label;
-  parser.ParseParameterisedLabel(&parameterised_label);
+  ParameterisedIdentifier parameterised_identifier;
+  parser.ParseParameterisedIdentifier(&parameterised_identifier);
   if (!parser.ParsedSuccessfully())
     return false;
-  const auto it = parameterised_label.params.find("v");
-  if (it == parameterised_label.params.end()) {
+  const auto it = parameterised_identifier.params.find("v");
+  if (it == parameterised_identifier.params.end()) {
     *version_param = base::nullopt;
   } else {
     if (it->second == "b1")
diff --git a/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc b/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
index cd32523b..58c71e8 100644
--- a/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
+++ b/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
@@ -18,19 +18,19 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180,"
       "sig2;"
       " sig=*MEQCIGjZRqTRf9iKNkGFyzRMTFgwf/BrY2ZNIP/dykhUV0aYAiBTXg+8wujoT4n/W+"
-      "cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg;"
+      "cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg==*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/newcerts\";"
-      " certSha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/newcerts\";"
+      " cert-sha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw=*;"
       " date=1511128380; expires=1511733180";
 
   const uint8_t decoded_sig1[] = {
@@ -90,11 +90,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       // no integrity= param
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -105,12 +105,12 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -121,11 +121,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https:://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https:://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -136,11 +136,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts#test\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts#test\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -151,11 +151,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -166,11 +166,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https:://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https:://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -181,11 +181,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380#test\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"https://example.com/resource.validity.1511128380#test\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -196,11 +196,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
+      " validity-url=\"resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -211,11 +211,11 @@
   const char hdr_string[] =
       "sig1;"
       " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
-      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
       " integrity=\"mi\";"
-      " validityUrl=\"https://example.com/resource.validity.1511128380\";"
-      " certUrl=\"https://example.com/oldcerts\";"
-      " certSha256=*W7uB969dFW3Mb5ZefPS9;"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefPS9;"
       " date=1511128380; expires=1511733180";
   auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
       hdr_string, nullptr /* devtools_proxy */);
@@ -229,6 +229,21 @@
   EXPECT_FALSE(signatures.has_value());
 }
 
+TEST_F(SignedExchangeSignatureHeaderFieldTest, AsteriskInTheMiddleOfBinary) {
+  const char hdr_string[] =
+      "sig1;"
+      " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+      "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+      " integrity=\"mi\";"
+      " validity-url=\"https://example.com/resource.validity.1511128380\";"
+      " cert-url=\"https://example.com/oldcerts\";"
+      " cert-sha256=*W7uB969dFW3Mb5ZefP*S9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+      " date=1511128380; expires=1511733180";
+  auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+      hdr_string, nullptr /* devtools_proxy */);
+  EXPECT_FALSE(signatures.has_value());
+}
+
 TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_None) {
   const char content_type[] = "application/signed-exchange";
   base::Optional<SignedExchangeVersion> version;
diff --git a/content/browser/web_package/signed_exchange_signature_verifier.cc b/content/browser/web_package/signed_exchange_signature_verifier.cc
index e7e8bae..4ff7f5f 100644
--- a/content/browser/web_package/signed_exchange_signature_verifier.cc
+++ b/content/browser/web_package/signed_exchange_signature_verifier.cc
@@ -94,7 +94,7 @@
 }
 
 // Generate a CBOR map value as specified in
-// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
+// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#signature-validity
 // Step 7.4.
 base::Optional<cbor::CBORValue> GenerateSignedMessageCBOR(
     const SignedExchangeEnvelope& header) {
@@ -105,8 +105,8 @@
   // 7.4. "The bytes of the canonical CBOR serialization (Section 3.4) of
   // a CBOR map mapping:" [spec text]
   cbor::CBORValue::MapValue map;
-  // 7.4.1. "If certSha256 is set: The text string "certSha256" to the byte
-  // string value of certSha256." [spec text]
+  // 7.4.1. "If cert-sha256 is set: The text string "cert-sha256" to the byte
+  // string value of cert-sha256." [spec text]
   if (header.signature().cert_sha256.has_value()) {
     map.insert_or_assign(
         cbor::CBORValue(kCertSha256Key),
@@ -116,8 +116,8 @@
                               sizeof(header.signature().cert_sha256->data)),
             cbor::CBORValue::Type::BYTE_STRING));
   }
-  // 7.4.2. "The text string "validityUrl" to the byte string value of
-  // validityUrl." [spec text]
+  // 7.4.2. "The text string "validity-url" to the byte string value of
+  // validity-url." [spec text]
   map.insert_or_assign(cbor::CBORValue(kValidityUrlKey),
                        cbor::CBORValue(header.signature().validity_url.spec(),
                                        cbor::CBORValue::Type::BYTE_STRING));
@@ -310,7 +310,7 @@
   if (!header.signature().cert_sha256.has_value()) {
     signed_exchange_utils::ReportErrorAndEndTraceEvent(
         devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
-        "No certSha256 set.");
+        "No cert-sha256 set.");
     return Result::kErrNoCertificateSHA256;
   }
 
@@ -320,7 +320,7 @@
           certificate->cert_buffer())) {
     signed_exchange_utils::ReportErrorAndEndTraceEvent(
         devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
-        "certSha256 mismatch.");
+        "cert-sha256 mismatch.");
     return Result::kErrCertificateSHA256Mismatch;
   }
 
diff --git a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
index 3567c54..2ba3d3d 100644
--- a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
+++ b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -62,18 +62,19 @@
 const uint64_t kSignatureHeaderDate = 1517892341;
 const uint64_t kSignatureHeaderExpires = 1517895941;
 
+// See content/testdata/htxg/README on how to generate this data.
 // clang-format off
 constexpr char kSignatureHeaderRSA[] =
-    "sig; "
-    "sig=*RhjjWuXi87riQUu90taBHFJgTo8XBhiCe9qTJMP7/XVPu2diRGipo06HoGsyXkidHiiW"
-    "743JgoNmO7CjfeVXLXQgKDxtGidATtPsVadAT4JpBDZJWSUg5qAbWcASXjyO38Uhq9gJkeu4w"
-    "1MRMGkvpgVXNjYhi5/9NUer1xEUuJh5UbIDhGrfMihwj+c30nW+qz0n5lCrYonk+Sc0jGcLgc"
-    "aDLptqRhOG5S+avwKmbQoqtD0JSc/53L5xXjppyvSA2fRmoDlqVQpX4uzRKq9cny7fZ3qgpZ/"
-    "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w;"
-    "validityUrl=\"https://example.com/resource.validity.msg\"; "
+    "label; "
+    "sig=*C0Oh9FEKos7Vk1bLyMazdZpgBTpPhIgnY3CDqyECut1HdMP2Ye8kxZXkT9BLQSv48leG"
+    "NS/hePxRtwJJybWMan/hFMhcz+s8aHxLT6E2e87iI9tNh29NPGGFVgiJ+hljSH/QAPP8sFIBb"
+    "pD/VGWy6NgpsSHft8DVlqhloBZMR9MUPXe36tdaOf5krUbY76Daj5kVQ0LZxrZhbzb97Bstvg"
+    "gVnTQe/RV1ElOql/xhYvsYxNgM0+Bkmu2hSWFMlLHMQ29LhMHS7oYUfuqqP2qhBj7VEArgDsC"
+    "hQ1W5r8K4WaI9krdvG3UsXlFufKbqGIQ2zKbeUWJUHoelkjb/ixBhwg==*; "
+    "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
-    "certUrl=\"https://example.com/cert.msg\"; "
-    "certSha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k; "
+    "cert-url=\"https://example.com/cert.msg\"; "
+    "cert-sha256=*tJGJP8ej7KCEW8VnVK3bKwpBza/oLrtWA75z5ZPptuc=*; "
     "date=1517892341; expires=1517895941";
 // clang-format on
 
@@ -81,12 +82,12 @@
 // clang-format off
 constexpr char kSignatureHeaderECDSAP256[] =
     "label; "
-    "sig=*MEYCIQDQYQAHAlpznkP/btvuNnvGY5ycO+NOOTFXsoBjF22UhAIhAMyzyMikudaQeIPYB"
-    "fh2JdqZVBwgsQ6a3Cn8lFA0XYGW; "
-    "validityUrl=\"https://example.com/resource.validity.msg\"; "
+    "sig=*MEUCIQCycBCSrsmT04lZBFklDiAdp2UkMoLhLKLv/79a39qqbgIgNI8ApHxPUPuXiko7"
+    "IPehUcU9i+jHGEYO3f0fKFn3dIg=*; "
+    "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
-    "certUrl=\"https://example.com/cert.msg\"; "
-    "certSha256=*CfDj40tr5B7oo6IaWwQF2L1uDgsHH0fA2YOCB7E0tAQ; "
+    "cert-url=\"https://example.com/cert.msg\"; "
+    "cert-sha256=*CfDj40tr5B7oo6IaWwQF2L1uDgsHH0fA2YOCB7E0tAQ=*; "
     "date=1517892341; expires=1517895941";
 // clang-format on
 
@@ -94,12 +95,12 @@
 // clang-format off
 constexpr char kSignatureHeaderECDSAP384[] =
     "label; "
-    "sig=*MGQCMDtOqWBsWjx1+WZta9tBpuuMJMLMwp8/eHu+PwNw95qCMMjD1xJiLIm0HUtFzdzSC"
-    "wIwVxSUD9IB2t4JIHz6IJPddqR1ex38kkSvOYSmFEwqVPRM1sqAcEtvwdpSU+cLJYbS; "
-    "validityUrl=\"https://example.com/resource.validity.msg\"; "
+    "sig=*MGUCMQCIdT4ipb0lb8AW+oxxXlv1F8kdhwoL9jsOJww2C3zTCM71Zsvu7U/BxcBCT5H7I"
+    "mkCMEatuNz+wa0q6pg2Zr3lYZ8Jy4xZbDJHVILmBqGMKxUVDGT3aw8/yJXPLPgSU6f6ZQ==*; "
+    "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
-    "certUrl=\"https://example.com/cert.msg\"; "
-    "certSha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA; "
+    "cert-url=\"https://example.com/cert.msg\"; "
+    "cert-sha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA=*; "
     "date=1517892341; expires=1517895941";
 // clang-format on
 
@@ -112,38 +113,37 @@
     "743JgoNmO7CjfeVXLXQgKDxtGidATtPsVadAT4JpBDZJWSUg5qAbWcASXjyO38Uhq9gJkeu4w"
     "1MRMGkvpgVXNjYhi5/9NUer1xEUuJh5UbIDhGrfMihwj+c30nW+qz0n5lCrYonk+Sc0jGcLgc"
     "aDLptqRhOG5S+avwKmbQoqtD0JSc/53L5xXjppyvSA2fRmoDlqVQpX4uzRKq9cny7fZ3qgpZ/"
-    "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w;"
-    "validityUrl=\"https://example.com/resource.validity.msg\"; "
+    "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w==*;"
+    "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
-    "certUrl=\"https://example.com/cert.msg\"; "
-    "certSha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k; "
+    "cert-url=\"https://example.com/cert.msg\"; "
+    "cert-sha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k=*; "
     "date=1517892341; expires=1518497142";
 // clang-format on
 
 constexpr char kCertPEMRSA[] = R"(
 -----BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIUde2ndSB4271TAGDk0Ft+WuCCGnMwDQYJKoZIhvcNAQEL
-BQAwUDELMAkGA1UEBhMCSlAxEjAQBgNVBAgTCU1pbmF0by1rdTEOMAwGA1UEBxMF
-VG9reW8xEDAOBgNVBAoTB1Rlc3QgQ0ExCzAJBgNVBAsTAkNBMB4XDTE4MDIwNTA0
-NDUwMFoXDTE5MDIwNTA0NDUwMFowbzELMAkGA1UEBhMCSlAxEjAQBgNVBAgTCU1p
-bmF0by1rdTEOMAwGA1UEBxMFVG9reW8xFDASBgNVBAoTC2V4YW1wbGUuY29tMRIw
-EAYDVQQLEwl3ZWJzZXJ2ZXIxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJv0UV5pK/XMtmHuDHUSvU+mNghsDQsKYSeB
-r/CySBIbLWtkeC7oxuYT2R+Mz4vVs0WQ1f3F/e3HIIQxWmy5VYErER13c53yeCNF
-fcBkwpuCZKEO1BURX+WgjYPnzLYX1xDnpBM++TuEZKdxzUVjs/jQjMNB8sbRYzng
-IIbA4HiRUtPvnGjLmY0HxZyskb52yeTWg40jWPdLaC8GMEZXGKynAnGEMl3c/dVw
-8+nKS1VVe6k32Ubfl1NlaqbOXi0xHHMUhLY/l8Lu49E0ivPS7BWL/0nMR9EAmu+I
-AgK9OD7VRoMA0LEKBzIQUEuK70JxLkV7GNvrtnOX83+EwwdfBdUCAwEAAaOBqTCB
-pjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
-MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDzp/0BrXKIfDGe3KfJLyBH8azW2MB8G
-A1UdIwQYMBaAFNAPhK4UBktJcx6TIk5QKwZPit4ZMCcGA1UdEQQgMB6CC2V4YW1w
-bGUuY29tgg93d3cuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAKSQbsOW
-IX2JDv+Vg1lvbOFx+JqwdhvYTkOF4Z9YbRtlqEIZbc8KWjAOzDB1xVJxhSjD+f8+
-vrj7YN/ggCQk6DzuF4lkztBDO95Fxmx4EeIKdKt83WP09Os/2yIOKToOnHkmauBB
-ijY8oxNs+XxKrPX7DN5QQQhiTsZcL625fcnIwPb0DeeuCT7bJYPv8OojMDTR1uDt
-SQ53HYt0aLun+Br3lCwW8cnpxuezJhg0gNezYp/8gC4kByqoT26atpls08eWUdFD
-U0/55zFz2OzNoAHaoBzMRxn4ZSc3+lxl0K1+cCP8ivhwkxdz/vhz5RfOjpSinxqt
-wYxI2+BLS6X5NpI=
+MIIDyTCCArGgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDYwNTE3
+MTA0NloXDTI3MDYwMzE3MTA0NlowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBANOUHzO0uxUyd3rYUArq33olXC0N1AYNM0wFTjUqUrElLiX48+5hERkG
+hGwC8VG5Zr/2Jw/wtarLiDjg2OfPdwyMp3S7MBTgvXWZ989MUHpx6b0cWM298iOg
+/VeinMphFLDfPDHFWZ7RXBqfk6MGLhI5GgvoooYw2jUmP+elnoizIL/OB08sIYra
+AVrwasoRd+yOmyvQnzw3mZNKpWjeX7NhZCg2nG8B8u78agwAYVWupHnJS2GwhLzy
+19AxU/HmaI9kyyMGmRtbRZ0roCyMDOgEEcWUSYNRP33KLi31uKYqOSblvzmC7kA7
+k5yca3VXlgqg4gnjr9tbOMzMcpeqeaMCAwEAAaOBijCBhzAMBgNVHRMBAf8EAjAA
+MB0GA1UdDgQWBBQYDOtRudM2qckEr/kvFPCZZtJ21DAfBgNVHSMEGDAWgBSbJguK
+mKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
+GAYDVR0RBBEwD4INKi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAvXK0
+UF19i7JkSSdomQwB18WRFaKG8VZpSFsKbEECPRHoxktMl/Pd04wk+W0fZFq433j3
+4D+cjTB6OxAVdPIPSex8U40fYMl9C13K1tejf4o/+rcLxEDdVfv7PUkogrliXzSE
+MCYdcTwruV7hjC2/Ib0t/kdxblRt4dD2I1jdntsFy/VfET/m0J2qRhJWlfYEzCFe
+Hn8H/PZIiIsso5pm2RodTqi9w4/+1r8Yyfmk8TF+EoWDYtbZ+ScgtCH5fldS+onI
+hHgjz/tniqjbY0MRFr9ZxrohmtgOBOvROEKH06c92oOmj2ahyFpM/yU9PL/JvNmF
+SaMW1eOzjHemIWKTMw==
 -----END CERTIFICATE-----)";
 
 constexpr char kCertPEMECDSAP256[] = R"(
@@ -283,12 +283,12 @@
 
   SignedExchangeEnvelope header;
   header.set_request_method("GET");
-  header.set_request_url(GURL("https://example.com/index.html"));
+  header.set_request_url(GURL("https://test.example.org/test/"));
   header.set_response_code(net::HTTP_OK);
   header.AddResponseHeader("content-type", "text/html; charset=utf-8");
   header.AddResponseHeader("content-encoding", "mi-sha256");
   header.AddResponseHeader(
-      "mi", "mi-sha256=4ld4G-h-sQSoLBD39ndIO15O_82NXSzq9UMFEYI02JQ");
+      "mi", "mi-sha256=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RI");
   header.SetSignatureForTesting((*signature)[0]);
 
   TestVerifierGivenValidInput(header, certlist[0]);
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc
index cf09e88..bbcc2257 100644
--- a/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -22,8 +22,10 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_controller.h"
 #include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/bindings_policy.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
@@ -32,7 +34,6 @@
 #include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 
 namespace content {
@@ -101,8 +102,11 @@
 // WebUIController that sets up mojo bindings.
 class TestWebUIController : public WebUIController {
  public:
-  TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
+  TestWebUIController(WebUI* web_ui,
+                      base::RunLoop* run_loop,
+                      int bindings = BINDINGS_POLICY_MOJO_WEB_UI)
       : WebUIController(web_ui), run_loop_(run_loop) {
+    web_ui->SetBindings(bindings);
     WebUIDataSource* data_source = WebUIDataSource::Create("mojo-web-ui");
     data_source->SetRequestFilter(base::Bind(&GetResource));
     WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
@@ -160,6 +164,14 @@
                                                const GURL& url) const override {
     if (url.query() == "ping")
       return new PingTestWebUIController(web_ui, run_loop_);
+    if (url.query() == "webui_bindings")
+      return new TestWebUIController(web_ui, run_loop_, BINDINGS_POLICY_WEB_UI);
+    if (url.query() == "hybrid") {
+      return new TestWebUIController(
+          web_ui, run_loop_,
+          BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
+    }
+
     return new TestWebUIController(web_ui, run_loop_);
   }
   WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
@@ -198,6 +210,24 @@
 
   TestWebUIControllerFactory* factory() { return &factory_; }
 
+  void NavigateWithNewWebUI(const std::string& path) {
+    // Load an invalid URL first so that a new WebUI is set up when we load
+    // the URL we're actually interested in.
+    EXPECT_FALSE(NavigateToURL(shell(), GURL()));
+
+    constexpr char kChromeUIMojoWebUIOrigin[] = "chrome://mojo-web-ui/";
+    EXPECT_TRUE(NavigateToURL(shell(), GURL(kChromeUIMojoWebUIOrigin + path)));
+  }
+
+  // Run |script| and return a boolean result.
+  bool RunBoolFunction(const std::string& script) {
+    bool result = false;
+    EXPECT_TRUE(ExecuteScriptAndExtractBool(
+        shell()->web_contents(), "domAutomationController.send(" + script + ")",
+        &result));
+    return result;
+  }
+
  private:
   TestWebUIControllerFactory factory_;
 
@@ -225,7 +255,6 @@
     return;
 
   g_got_message = false;
-  ASSERT_TRUE(embedded_test_server()->Start());
   base::RunLoop run_loop;
   factory()->set_run_loop(&run_loop);
   GURL test_url("chrome://mojo-web-ui/web_ui_mojo.html?ping");
@@ -249,28 +278,47 @@
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIMojoTest, NativeMojoAvailable) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  const GURL kTestWebUIUrl("chrome://mojo-web-ui/web_ui_mojo_native.html");
-  NavigateToURL(shell(), kTestWebUIUrl);
+  // Mojo bindings should be enabled.
+  NavigateWithNewWebUI("web_ui_mojo_native.html");
+  EXPECT_TRUE(RunBoolFunction("isNativeMojoAvailable()"));
 
-  bool is_native_mojo_available = false;
-  const std::string kTestScript("isNativeMojoAvailable()");
-  ASSERT_TRUE(ExecuteScriptAndExtractBool(
-      shell()->web_contents(),
-      "domAutomationController.send(" + kTestScript + ")",
-      &is_native_mojo_available));
-  EXPECT_TRUE(is_native_mojo_available);
+  // Now navigate again with normal WebUI bindings and ensure chrome.send is
+  // available.
+  NavigateWithNewWebUI("web_ui_mojo_native.html?webui_bindings");
+  EXPECT_FALSE(RunBoolFunction("isNativeMojoAvailable()"));
+
+  // Now navigate again both WebUI and Mojo bindings and ensure chrome.send is
+  // available.
+  NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+  EXPECT_TRUE(RunBoolFunction("isNativeMojoAvailable()"));
 
   // Now navigate again with WebUI disabled and ensure the native bindings are
   // not available.
   factory()->set_web_ui_enabled(false);
-  const std::string kTestNonWebUIUrl("/web_ui_mojo_native.html");
-  NavigateToURL(shell(), embedded_test_server()->GetURL(kTestNonWebUIUrl));
-  ASSERT_TRUE(ExecuteScriptAndExtractBool(
-      shell()->web_contents(),
-      "domAutomationController.send(" + kTestScript + ")",
-      &is_native_mojo_available));
-  EXPECT_FALSE(is_native_mojo_available);
+  NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+  EXPECT_FALSE(RunBoolFunction("isNativeMojoAvailable()"));
+}
+
+IN_PROC_BROWSER_TEST_F(WebUIMojoTest, ChromeSendAvailable) {
+  // chrome.send is not available on mojo-only WebUIs.
+  NavigateWithNewWebUI("web_ui_mojo_native.html");
+  EXPECT_FALSE(RunBoolFunction("isChromeSendAvailable()"));
+
+  // Now navigate again with normal WebUI bindings and ensure chrome.send is
+  // available.
+  NavigateWithNewWebUI("web_ui_mojo_native.html?webui_bindings");
+  EXPECT_TRUE(RunBoolFunction("isChromeSendAvailable()"));
+
+  // Now navigate again both WebUI and Mojo bindings and ensure chrome.send is
+  // available.
+  NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+  EXPECT_TRUE(RunBoolFunction("isChromeSendAvailable()"));
+
+  // Now navigate again with WebUI disabled and ensure that chrome.send is
+  // not available.
+  factory()->set_web_ui_enabled(false);
+  NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+  EXPECT_FALSE(RunBoolFunction("isChromeSendAvailable()"));
 }
 
 }  // namespace
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 16f38a8e..858650c 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -195,8 +195,6 @@
     "input_messages.h",
     "inter_process_time_ticks_converter.cc",
     "inter_process_time_ticks_converter.h",
-    "layer_tree_settings_factory.cc",
-    "layer_tree_settings_factory.h",
     "mac/attributed_string_coder.h",
     "mac/attributed_string_coder.mm",
     "mac/font_loader.h",
@@ -274,6 +272,8 @@
     "service_worker/service_worker_utils.h",
     "single_request_url_loader_factory.cc",
     "single_request_url_loader_factory.h",
+    "skia_utils.cc",
+    "skia_utils.h",
     "swapped_out_messages.cc",
     "swapped_out_messages.h",
     "task_scheduler.cc",
diff --git a/content/common/layer_tree_settings_factory.cc b/content/common/layer_tree_settings_factory.cc
deleted file mode 100644
index 5c33f1dc..0000000
--- a/content/common/layer_tree_settings_factory.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/layer_tree_settings_factory.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "cc/base/switches.h"
-
-namespace content {
-
-// static
-void LayerTreeSettingsFactory::SetBrowserControlsSettings(
-    cc::LayerTreeSettings& settings,
-    const base::CommandLine& cmd) {
-  if (cmd.HasSwitch(cc::switches::kBrowserControlsShowThreshold)) {
-    std::string top_threshold_str =
-        cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsShowThreshold);
-    double show_threshold;
-    if (base::StringToDouble(top_threshold_str, &show_threshold) &&
-        show_threshold >= 0.f && show_threshold <= 1.f)
-      settings.top_controls_show_threshold = show_threshold;
-  }
-
-  if (cmd.HasSwitch(cc::switches::kBrowserControlsHideThreshold)) {
-    std::string top_threshold_str =
-        cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsHideThreshold);
-    double hide_threshold;
-    if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
-        hide_threshold >= 0.f && hide_threshold <= 1.f)
-      settings.top_controls_hide_threshold = hide_threshold;
-  }
-}
-
-}  // namespace content
diff --git a/content/common/layer_tree_settings_factory.h b/content/common/layer_tree_settings_factory.h
deleted file mode 100644
index cc808f7..0000000
--- a/content/common/layer_tree_settings_factory.h
+++ /dev/null
@@ -1,27 +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_COMMON_LAYER_TREE_SETTINGS_FACTORY_H_
-#define CONTENT_COMMON_LAYER_TREE_SETTINGS_FACTORY_H_
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "cc/trees/layer_tree_settings.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// LayerTreeSettingsFactory holds utilities functions to generate
-// LayerTreeSettings.
-class CONTENT_EXPORT LayerTreeSettingsFactory {
-  // TODO(xingliu): Refactor LayerTreeSettings generation logic.
-  // crbug.com/577985
- public:
-  static void SetBrowserControlsSettings(cc::LayerTreeSettings& settings,
-                                         const base::CommandLine& command_line);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_COMMON_LAYER_TREE_SETTINGS_FACTORY_H_
diff --git a/content/common/skia_utils.cc b/content/common/skia_utils.cc
new file mode 100644
index 0000000..9aec407
--- /dev/null
+++ b/content/common/skia_utils.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/skia_utils.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/sys_info.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "build/build_config.h"
+#include "content/public/common/content_switches.h"
+#include "skia/ext/event_tracer_impl.h"
+#include "skia/ext/skia_memory_dump_provider.h"
+#include "third_party/skia/include/core/SkGraphics.h"
+
+namespace content {
+namespace {
+
+// Maximum allocation size allowed for image scaling filters that
+// require pre-scaling. Skia will fallback to a filter that doesn't
+// require pre-scaling if the default filter would require an
+// allocation that exceeds this limit.
+const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
+
+}  // namespace
+
+void InitializeSkia() {
+  // Make sure that any switches used here are propagated to the renderer and
+  // GPU processes.
+  const base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+  if (!cmd.HasSwitch(switches::kDisableSkiaRuntimeOpts)) {
+    SkGraphics::Init();
+  }
+
+  const int kMB = 1024 * 1024;
+  size_t font_cache_limit;
+#if defined(OS_ANDROID)
+  font_cache_limit = base::SysInfo::IsLowEndDevice() ? kMB : 8 * kMB;
+  SkGraphics::SetFontCacheLimit(font_cache_limit);
+#else
+  if (cmd.HasSwitch(switches::kSkiaFontCacheLimitMb)) {
+    if (base::StringToSizeT(
+            cmd.GetSwitchValueASCII(switches::kSkiaFontCacheLimitMb),
+            &font_cache_limit)) {
+      SkGraphics::SetFontCacheLimit(font_cache_limit * kMB);
+    }
+  }
+
+  size_t resource_cache_limit;
+  if (cmd.HasSwitch(switches::kSkiaResourceCacheLimitMb)) {
+    if (base::StringToSizeT(
+            cmd.GetSwitchValueASCII(switches::kSkiaResourceCacheLimitMb),
+            &resource_cache_limit)) {
+      SkGraphics::SetResourceCacheTotalByteLimit(resource_cache_limit * kMB);
+    }
+  }
+#endif
+
+  InitSkiaEventTracer();
+  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+      skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
+
+  SkGraphics::SetResourceCacheSingleAllocationByteLimit(
+      kImageCacheSingleAllocationByteLimit);
+}
+
+}  // namespace content
diff --git a/content/common/skia_utils.h b/content/common/skia_utils.h
new file mode 100644
index 0000000..53b6878c
--- /dev/null
+++ b/content/common/skia_utils.h
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_SKIA_UTILS_H_
+#define CONTENT_COMMON_SKIA_UTILS_H_
+
+namespace content {
+
+// Common utility code for skia initialization done in the renderer process, and
+// also in the GPU process for viz/oop-r which runs skia in the GPU process.
+void InitializeSkia();
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_SKIA_UTILS_H_
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 97ca63c..7e2a848 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -33,7 +33,6 @@
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
-#include "skia/ext/event_tracer_impl.h"
 
 #if defined(USE_OZONE)
 #include "ui/ozone/public/ozone_platform.h"
@@ -228,8 +227,6 @@
   GetServiceManagerConnection()->AddConnectionFilter(std::move(filter));
 
   StartServiceManagerConnection();
-
-  InitSkiaEventTracer();
 }
 
 void GpuChildThread::CreateVizMainService(
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 5baf86f..835e1c14 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -24,6 +24,7 @@
 #include "components/viz/service/main/viz_main_impl.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/content_switches_internal.h"
+#include "content/common/skia_utils.h"
 #include "content/gpu/gpu_child_thread.h"
 #include "content/gpu/gpu_process.h"
 #include "content/public/common/content_client.h"
@@ -330,6 +331,8 @@
 
   gpu_process.set_main_thread(child_thread);
 
+  InitializeSkia();
+
 #if defined(OS_ANDROID)
   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
       tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
diff --git a/content/public/browser/download_manager.h b/content/public/browser/download_manager.h
index 09476abd..0708c4157 100644
--- a/content/public/browser/download_manager.h
+++ b/content/public/browser/download_manager.h
@@ -223,11 +223,6 @@
   // finish asynchronously after this method returns.
   virtual void CheckForHistoryFilesRemoval() = 0;
 
-  // Called when download history query completes. Call
-  // |load_history_downloads_cb| to load all the history downloads.
-  virtual void OnHistoryQueryComplete(
-      base::OnceClosure load_history_downloads_cb) = 0;
-
   // Get the download item for |id| if present, no matter what type of download
   // it is or state it's in.
   // DEPRECATED: Don't add new callers for GetDownload(uint32_t). Instead keep
diff --git a/content/public/common/bindings_policy.h b/content/public/common/bindings_policy.h
index 07920915..688adba144 100644
--- a/content/public/common/bindings_policy.h
+++ b/content/public/common/bindings_policy.h
@@ -11,21 +11,28 @@
 // to renderers.
 enum BindingsPolicy {
   // HTML-based UI bindings that allows the JS content to send JSON-encoded
-  // data back to the browser process and to access Mojo system API. The Mojo
+  // data back to the browser process.
+  // These bindings should not be exposed to normal web content.
+  BINDINGS_POLICY_WEB_UI = 1 << 0,
+  // HTML-based UI bindings that allows access to Mojo system API. The Mojo
   // system API provides the ability to create Mojo primitives such as message
   // and data pipes, as well as connecting to named services exposed by the
-  // browser. These bindings should not be exposed to normal web contents.
-  BINDINGS_POLICY_WEB_UI = 1 << 0,
+  // browser.
+  // These bindings should not be exposed to normal web content.
+  BINDINGS_POLICY_MOJO_WEB_UI = 1 << 1,
   // DOM automation bindings that allows the JS content to send JSON-encoded
   // data back to automation in the parent process.  (By default this isn't
   // allowed unless the app has been started up with the --dom-automation
   // switch.)
-  BINDINGS_POLICY_DOM_AUTOMATION = 1 << 1,
+  BINDINGS_POLICY_DOM_AUTOMATION = 1 << 2,
   // Bindings that allows the JS content to retrieve a variety of internal
   // metrics. (By default this isn't allowed unless the app has been started up
   // with the --enable-stats-collection-bindings switch.)
-  BINDINGS_POLICY_STATS_COLLECTION = 1 << 2,
+  BINDINGS_POLICY_STATS_COLLECTION = 1 << 3,
 };
+
+constexpr int kWebUIBindingsPolicyMask =
+    BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI;
 }
 
 #endif  // CONTENT_PUBLIC_COMMON_BINDINGS_POLICY_H_
diff --git a/content/public/test/mock_download_manager.cc b/content/public/test/mock_download_manager.cc
index a9442ac..bcf0247 100644
--- a/content/public/test/mock_download_manager.cc
+++ b/content/public/test/mock_download_manager.cc
@@ -153,9 +153,4 @@
   return MockCreateDownloadItem(adapter);
 }
 
-void MockDownloadManager::OnHistoryQueryComplete(
-    base::OnceClosure load_history_downloads_cb) {
-  std::move(load_history_downloads_cb).Run();
-}
-
 }  // namespace content
diff --git a/content/public/test/mock_download_manager.h b/content/public/test/mock_download_manager.h
index 9b06b8d..109c898ed 100644
--- a/content/public/test/mock_download_manager.h
+++ b/content/public/test/mock_download_manager.h
@@ -168,9 +168,6 @@
   MOCK_METHOD0(CheckForHistoryFilesRemoval, void());
   MOCK_METHOD1(GetDownload, download::DownloadItem*(uint32_t id));
   MOCK_METHOD1(GetDownloadByGuid, download::DownloadItem*(const std::string&));
-
-  void OnHistoryQueryComplete(
-      base::OnceClosure load_history_downloads_cb) override;
 };
 
 }  // namespace content
diff --git a/content/renderer/device_sensors/device_orientation_event_pump.cc b/content/renderer/device_sensors/device_orientation_event_pump.cc
index c1c4388a..3f5a7955 100644
--- a/content/renderer/device_sensors/device_orientation_event_pump.cc
+++ b/content/renderer/device_sensors/device_orientation_event_pump.cc
@@ -102,6 +102,12 @@
   }
 
   absolute_orientation_sensor_.Stop();
+
+  // Reset the cached data because DeviceOrientationDispatcher resets its
+  // data when stopping. If we don't reset here as well, then when starting back
+  // up we won't notify DeviceOrientationDispatcher of the orientation, since
+  // we think it hasn't changed.
+  data_ = device::OrientationData();
 }
 
 void DeviceOrientationEventPump::SendFakeDataForTesting(void* fake_data) {
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 840c847..612213c 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -52,7 +52,6 @@
 #include "components/viz/common/resources/single_release_callback.h"
 #include "components/viz/common/switches.h"
 #include "content/common/content_switches_internal.h"
-#include "content/common/layer_tree_settings_factory.h"
 #include "content/common/render_frame_metadata.mojom.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
@@ -410,7 +409,23 @@
       cmd.HasSwitch(switches::kEnableOOPRasterization);
 
   // Build LayerTreeSettings from command line args.
-  LayerTreeSettingsFactory::SetBrowserControlsSettings(settings, cmd);
+  if (cmd.HasSwitch(cc::switches::kBrowserControlsShowThreshold)) {
+    std::string top_threshold_str =
+        cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsShowThreshold);
+    double show_threshold;
+    if (base::StringToDouble(top_threshold_str, &show_threshold) &&
+        show_threshold >= 0.f && show_threshold <= 1.f)
+      settings.top_controls_show_threshold = show_threshold;
+  }
+
+  if (cmd.HasSwitch(cc::switches::kBrowserControlsHideThreshold)) {
+    std::string top_threshold_str =
+        cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsHideThreshold);
+    double hide_threshold;
+    if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
+        hide_threshold >= 0.f && hide_threshold <= 1.f)
+      settings.top_controls_hide_threshold = hide_threshold;
+  }
 
   settings.use_layer_lists = cmd.HasSwitch(cc::switches::kEnableLayerLists);
 
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 4b172fe..65cfaa3c 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4915,7 +4915,7 @@
 
 void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
                                              int world_id) {
-  if ((enabled_bindings_ & BINDINGS_POLICY_WEB_UI) && IsMainFrame() &&
+  if ((enabled_bindings_ & BINDINGS_POLICY_MOJO_WEB_UI) && IsMainFrame() &&
       world_id == ISOLATED_WORLD_ID_GLOBAL) {
     // We only allow these bindings to be installed when creating the main
     // world context of the main frame.
@@ -5892,11 +5892,10 @@
     bool is_initial_navigation = render_view_->history_list_length_ == 0;
     bool should_fork =
         HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
-        (cumulative_bindings & BINDINGS_POLICY_WEB_UI) ||
+        (cumulative_bindings & kWebUIBindingsPolicyMask) ||
         url.SchemeIs(kViewSourceScheme) ||
         (frame_->IsViewSourceModeEnabled() &&
          info.navigation_type != blink::kWebNavigationTypeReload);
-
     if (!should_fork && url.SchemeIs(url::kFileScheme)) {
       // Fork non-file to file opens.  Note that this may fork unnecessarily if
       // another tab (hosting a file or not) targeted this one before its
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 449e2cd..39dcada 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -147,7 +147,6 @@
 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
 #include "services/ui/public/cpp/gpu/gpu.h"
 #include "services/ui/public/interfaces/constants.mojom.h"
-#include "skia/ext/event_tracer_impl.h"
 #include "skia/ext/skia_memory_dump_provider.h"
 #include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
@@ -220,12 +219,6 @@
 const int64_t kInitialIdleHandlerDelayMs = 1000;
 const int64_t kLongIdleHandlerDelayMs = 30 * 1000;
 
-// Maximum allocation size allowed for image scaling filters that
-// require pre-scaling. Skia will fallback to a filter that doesn't
-// require pre-scaling if the default filter would require an
-// allocation that exceeds this limit.
-const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
-
 #if defined(OS_ANDROID)
 // Unique identifier for each output surface created.
 uint32_t g_next_layer_tree_frame_sink_id = 1;
@@ -877,10 +870,6 @@
       base::Bind(&RenderThreadImpl::OnRendererInterfaceRequest,
                  base::Unretained(this)));
 
-  InitSkiaEventTracer();
-  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
-
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
 
@@ -1303,14 +1292,12 @@
     isolate->IsolateInBackgroundNotification();
   }
 
-
   main_thread_scheduler_->SetFreezingWhenBackgroundedEnabled(
       GetContentClient()->renderer()->AllowFreezingWhenProcessBackgrounded());
 
-  SkGraphics::SetResourceCacheSingleAllocationByteLimit(
-      kImageCacheSingleAllocationByteLimit);
-
-  // Hook up blink's codecs so skia can call them
+  // Hook up blink's codecs so skia can call them. Since only the renderer
+  // processes should be doing image decoding, this is not done in the common
+  // skia initialization code for the GPU.
   SkGraphics::SetImageGeneratorFromEncodedDataFactory(
       blink::WebImageGenerator::CreateAsSkImageGenerator);
 
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index 0638db7..645592b 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -25,6 +25,7 @@
 #include "content/common/content_constants_internal.h"
 #include "content/common/content_switches_internal.h"
 #include "content/common/service_manager/service_manager_connection_impl.h"
+#include "content/common/skia_utils.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/main_function_params.h"
 #include "content/public/renderer/content_renderer_client.h"
@@ -35,7 +36,6 @@
 #include "ppapi/buildflags/buildflags.h"
 #include "services/service_manager/sandbox/switches.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
-#include "third_party/skia/include/core/SkGraphics.h"
 #include "third_party/webrtc_overrides/init_webrtc.h"  // nogncheck
 #include "ui/base/ui_base_switches.h"
 
@@ -121,46 +121,17 @@
   }
 #endif
 
-  const base::CommandLine& process_command_line =
-      *base::CommandLine::ForCurrentProcess();
-
 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
     !defined(OS_FUCHSIA)
   // This call could already have been made from zygote_main_linux.cc. However
   // we need to do it here if Zygote is disabled.
-  if (process_command_line.HasSwitch(switches::kNoZygote)) {
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote)) {
     SkFontConfigInterface::SetGlobal(
         sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD()));
   }
 #endif
 
-  if (!process_command_line.HasSwitch(switches::kDisableSkiaRuntimeOpts)) {
-    SkGraphics::Init();
-  }
-
-  const int kMB = 1024 * 1024;
-  size_t font_cache_limit;
-#if defined(OS_ANDROID)
-  font_cache_limit = base::SysInfo::IsLowEndDevice() ? kMB : 8 * kMB;
-  SkGraphics::SetFontCacheLimit(font_cache_limit);
-#else
-  if (process_command_line.HasSwitch(switches::kSkiaFontCacheLimitMb)) {
-    if (base::StringToSizeT(process_command_line.GetSwitchValueASCII(
-                                switches::kSkiaFontCacheLimitMb),
-                            &font_cache_limit)) {
-      SkGraphics::SetFontCacheLimit(font_cache_limit * kMB);
-    }
-  }
-
-  size_t resource_cache_limit;
-  if (process_command_line.HasSwitch(switches::kSkiaResourceCacheLimitMb)) {
-    if (base::StringToSizeT(process_command_line.GetSwitchValueASCII(
-                                switches::kSkiaResourceCacheLimitMb),
-                            &resource_cache_limit)) {
-      SkGraphics::SetResourceCacheTotalByteLimit(resource_cache_limit * kMB);
-    }
-  }
-#endif
+  InitializeSkia();
 
   // This function allows pausing execution using the --renderer-startup-dialog
   // flag allowing us to attach a debugger.
diff --git a/content/renderer/shared_worker/OWNERS b/content/renderer/shared_worker/OWNERS
index 595a385..6bda8b5 100644
--- a/content/renderer/shared_worker/OWNERS
+++ b/content/renderer/shared_worker/OWNERS
@@ -1,3 +1,4 @@
+falken@chromium.org
 horo@chromium.org
 nhiroki@chromium.org
 
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index 4f0261e..8ae2aa3 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -193,10 +193,8 @@
 
 void LayoutTestContentBrowserClient::BindClipboardHost(
     blink::mojom::ClipboardHostRequest request) {
-  if (!mock_clipboard_host_) {
-    mock_clipboard_host_ =
-        std::make_unique<MockClipboardHost>(browser_context());
-  }
+  if (!mock_clipboard_host_)
+    mock_clipboard_host_ = std::make_unique<MockClipboardHost>();
   mock_clipboard_host_->Bind(std::move(request));
 }
 
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc
index 691b465..0d69324 100644
--- a/content/shell/test_runner/pixel_dump.cc
+++ b/content/shell/test_runner/pixel_dump.cc
@@ -17,7 +17,6 @@
 #include "cc/paint/paint_flags.h"
 #include "cc/paint/skia_paint_canvas.h"
 #include "content/shell/test_runner/layout_test_runtime_flags.h"
-#include "mojo/public/cpp/system/data_pipe_drainer.h"
 #include "services/service_manager/public/cpp/connector.h"
 // FIXME: Including platform_canvas.h here is a layering violation.
 #include "skia/ext/platform_canvas.h"
@@ -30,38 +29,12 @@
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_page_popup.h"
 #include "third_party/blink/public/web/web_print_params.h"
-#include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/geometry/point.h"
 
 namespace test_runner {
 
 namespace {
 
-class BitmapDataPipeDrainer : public mojo::DataPipeDrainer::Client {
- public:
-  BitmapDataPipeDrainer(mojo::ScopedDataPipeConsumerHandle handle,
-                        base::OnceCallback<void(const SkBitmap&)> callback)
-      : callback_(std::move(callback)), drainer_(this, std::move(handle)) {}
-
-  void OnDataAvailable(const void* data, size_t num_bytes) override {
-    const unsigned char* ptr = static_cast<const unsigned char*>(data);
-    data_.insert(data_.end(), ptr, ptr + num_bytes);
-  }
-
-  void OnDataComplete() override {
-    SkBitmap bitmap;
-    if (!gfx::PNGCodec::Decode(data_.data(), data_.size(), &bitmap))
-      bitmap.reset();
-    std::move(callback_).Run(bitmap);
-    delete this;
-  }
-
- private:
-  base::OnceCallback<void(const SkBitmap&)> callback_;
-  mojo::DataPipeDrainer drainer_;
-  std::vector<unsigned char> data_;
-};
-
 class CaptureCallback : public base::RefCountedThreadSafe<CaptureCallback> {
  public:
   explicit CaptureCallback(base::OnceCallback<void(const SkBitmap&)> callback);
@@ -226,14 +199,9 @@
     return;
   }
 
-  blink::mojom::SerializedBlobPtr serialized_blob;
-  clipboard->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE, &serialized_blob);
-  blink::mojom::BlobPtr blob(std::move(serialized_blob->blob));
-  mojo::DataPipe pipe;
-  blob->ReadAll(std::move(pipe.producer_handle), nullptr);
-  // Self-destructs after draining the pipe.
-  new BitmapDataPipeDrainer(std::move(pipe.consumer_handle),
-                            std::move(callback));
+  SkBitmap bitmap;
+  clipboard->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE, &bitmap);
+  std::move(callback).Run(bitmap);
 }
 
 }  // namespace test_runner
diff --git a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/1.txt b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/1.txt
index f4adb702..e3e6559 100644
--- a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/1.txt
+++ b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/1.txt
@@ -1 +1,14 @@
-sig1; sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY; integrity="mi"; validityUrl="https://example.com/resource.validity.1511128380"; certUrl="https://example.com/oldcerts"; certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI; date=1511128380; expires=1511733180,sig2; sig=*MEQCIGjZRqTRf9iKNkGFyzRMTFgwf/BrY2ZNIP/dykhUV0aYAiBTXg+8wujoT4n/W+cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg; integrity="mi"; validityUrl="https://example.com/resource.validity.1511128380"; certUrl="https://example.com/newcerts"; certSha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw; date=1511128380; expires=1511733180
+sig1;
+  sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;
+  integrity="mi";
+  validity-url="https://example.com/resource.validity.1511128380";
+  cert-url="https://example.com/oldcerts";
+  cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;
+  date=1511128380; expires=1511733180,
+sig2;
+  sig=*MEQCIGjZRqTRf9iKNkGFyzRMTFgwf/BrY2ZNIP/dykhUV0aYAiBTXg+8wujoT4n/W+cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg=*;
+  integrity="mi";
+  validity-url="https://example.com/resource.validity.1511128380";
+  cert-url="https://example.com/newcerts";
+  cert-sha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw=*;
+  date=1511128380; expires=1511733180
diff --git a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/2.txt b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/2.txt
index 65d20c810..373db57 100644
--- a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/2.txt
+++ b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/2.txt
@@ -1 +1,6 @@
-srisig;sig=*lGZVaJJM5f2oGczFlLmBdKTDL+QADza4BgeO494ggACYJOvrof6uh5OJCcwKrk7DK+LBch0jssDYPp5CLc1SDA;integrity="mi";validityUrl="https://example.com/resource.validity.1511128380";ed25519Key=*zsSevyFsxyZHiUluVBDd4eypdRLTqyWRVOJuuKUz+A8;date=1511128380;expires=1511733180
+srisig;
+  sig=*lGZVaJJM5f2oGczFlLmBdKTDL+QADza4BgeO494ggACYJOvrof6uh5OJCcwKrk7DK+LBch0jssDYPp5CLc1SDA=*
+  integrity="mi";
+  validity-url="https://example.com/resource.validity.1511128380";
+  ed25519key=*zsSevyFsxyZHiUluVBDd4eypdRLTqyWRVOJuuKUz+A8=*
+  date=1511128380; expires=1511733180
diff --git a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/3.txt b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/3.txt
index 2081eab..b8aecd1 100644
--- a/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/3.txt
+++ b/content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/3.txt
@@ -1 +1,7 @@
-thirdpartysig; sig=*MEYCIQCNxJzn6Rh2fNxsobktir8TkiaJYQFhWTuWI1i4PewQaQIhAMs2TVjc4rTshDtXbgQEOwgj2mRXALhfXPztXgPupii+; integrity="mi"; validityUrl="https://thirdparty.example.com/resource.validity.1511161860"; certUrl="https://thirdparty.example.com/certs"; certSha256=*UeOwUPkvxlGRTyvHcsMUN0A2oNsZbU8EUvg8A9ZAnNc; date=1511133060; expires=1511478660
+thirdpartysig;
+  sig=*MEYCIQCNxJzn6Rh2fNxsobktir8TkiaJYQFhWTuWI1i4PewQaQIhAMs2TVjc4rTshDtXbgQEOwgj2mRXALhfXPztXgPupii+=*;
+  integrity="mi";
+  validity-url="https://thirdparty.example.com/resource.validity.1511161860";
+  cert-url="https://thirdparty.example.com/certs";
+  cert-sha256=*UeOwUPkvxlGRTyvHcsMUN0A2oNsZbU8EUvg8A9ZAnNc=*;
+  date=1511133060; expires=1511478660
diff --git a/content/test/data/htxg/README b/content/test/data/htxg/README
index ed56bd1..537dbb1 100644
--- a/content/test/data/htxg/README
+++ b/content/test/data/htxg/README
@@ -12,9 +12,12 @@
 # Install gen-certurl command from [1]
 go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-certurl
 
-# Install gen-signedexchange command from [2]
+# Install gen-signedexchange command from [2],
 go get github.com/nyaxt/webpackage/go/signedexchange/cmd/gen-signedexchange
-
+# and cherry-pick the following changes from [1].
+https://github.com/WICG/webpackage/commit/c173772a4fb3c923d705a319e5e9f2fb1fd569d7
+https://github.com/WICG/webpackage/commit/2635cc5d8fc3177092806ce19826e9cd8f8461c9
+https://github.com/WICG/webpackage/commit/2e88a4422a565221178891f50ed68c71cbcb6086
 
 # Get the private key of "*.example.org".
 sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' \
@@ -105,6 +108,13 @@
 ./gen-signedexchange \
   -uri https://test.example.org/test/ \
   -content test.html \
+  -certificate /tmp/wildcard_example.org.public.pem \
+  -privateKey /tmp/wildcard_example.org.private.pem \
+  -date 2018-02-06T04:45:41Z
+
+./gen-signedexchange \
+  -uri https://test.example.org/test/ \
+  -content test.html \
   -certificate ./prime256v1-sha256.crt \
   -privateKey ./prime256v1.key \
   -date 2018-02-06T04:45:41Z
diff --git a/content/test/data/htxg/test.example.com_invalid_test.htxg b/content/test/data/htxg/test.example.com_invalid_test.htxg
index 1349415..724c35a9 100644
--- a/content/test/data/htxg/test.example.com_invalid_test.htxg
+++ b/content/test/data/htxg/test.example.com_invalid_test.htxg
Binary files differ
diff --git a/content/test/data/htxg/test.example.org_hello.txt.htxg b/content/test/data/htxg/test.example.org_hello.txt.htxg
index b3ddc29..fa37fa1 100644
--- a/content/test/data/htxg/test.example.org_hello.txt.htxg
+++ b/content/test/data/htxg/test.example.org_hello.txt.htxg
Binary files differ
diff --git a/content/test/data/htxg/test.example.org_test.htxg b/content/test/data/htxg/test.example.org_test.htxg
index 8bd13b4..f16bff5e 100644
--- a/content/test/data/htxg/test.example.org_test.htxg
+++ b/content/test/data/htxg/test.example.org_test.htxg
Binary files differ
diff --git a/content/test/data/web_ui_mojo_native.js b/content/test/data/web_ui_mojo_native.js
index 36ab189..1b88c2a 100644
--- a/content/test/data/web_ui_mojo_native.js
+++ b/content/test/data/web_ui_mojo_native.js
@@ -8,3 +8,7 @@
       'createMessagePipe' in Mojo && 'writeMessage' in MojoHandle.prototype &&
       'cancel' in MojoWatcher.prototype;
 };
+
+window.isChromeSendAvailable = () => {
+  return 'chrome' in self && 'send' in chrome;
+};
diff --git a/content/test/mock_clipboard_host.cc b/content/test/mock_clipboard_host.cc
index 23a088e..29a4d2a 100644
--- a/content/test/mock_clipboard_host.cc
+++ b/content/test/mock_clipboard_host.cc
@@ -5,54 +5,12 @@
 #include "content/test/mock_clipboard_host.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/gfx/codec/png_codec.h"
 
 namespace content {
 
-namespace {
+MockClipboardHost::MockClipboardHost() = default;
 
-void ReleaseSharedMemoryPixels(void* addr, void* context) {
-  MojoResult result = MojoUnmapBuffer(context);
-  DCHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-blink::mojom::SerializedBlobPtr ConstructSerializedBlobOnIO(
-    size_t data_size,
-    std::unique_ptr<BlobHandle> blob_handle) {
-  blink::mojom::SerializedBlobPtr blob;
-  if (blob_handle) {
-    blob = blink::mojom::SerializedBlob::New(
-        blob_handle->GetUUID(), "image/png", static_cast<int64_t>(data_size),
-        blob_handle->PassBlob().PassInterface());
-  }
-  return blob;
-}
-
-void ReplyToReadImage(blink::mojom::ClipboardHost::ReadImageCallback callback,
-                      size_t data_size,
-                      std::vector<unsigned char> owner_buffer,
-                      std::unique_ptr<BlobHandle> blob_handle) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // Unfortunately, we cannot call blob_handle->PassBlob() on UI,
-  // since that binds a blob ptr which only works on IO. If we do,
-  // future access to that blob will be handled by Mojo on the wrong
-  // thread.
-  BrowserThread::PostTaskAndReplyWithResult(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&ConstructSerializedBlobOnIO, data_size,
-                     std::move(blob_handle)),
-      std::move(callback));
-}
-
-}  // namespace
-
-MockClipboardHost::MockClipboardHost(BrowserContext* browser_context)
-    : browser_context_(browser_context) {}
-
-MockClipboardHost::~MockClipboardHost() {}
+MockClipboardHost::~MockClipboardHost() = default;
 
 void MockClipboardHost::Bind(blink::mojom::ClipboardHostRequest request) {
   bindings_.AddBinding(this, std::move(request));
@@ -128,28 +86,7 @@
 
 void MockClipboardHost::ReadImage(ui::ClipboardType clipboard_type,
                                   ReadImageCallback callback) {
-  if (image_.isNull() || !browser_context_) {
-    std::move(callback).Run(nullptr);
-    return;
-  }
-  std::vector<unsigned char> png_data;
-  if (!gfx::PNGCodec::FastEncodeBGRASkBitmap(image_, false, &png_data)) {
-    std::move(callback).Run(nullptr);
-    return;
-  }
-  if (png_data.size() >= std::numeric_limits<uint32_t>::max()) {
-    std::move(callback).Run(nullptr);
-    return;
-  }
-
-  char* char_data = reinterpret_cast<char*>(png_data.data());
-  size_t size = png_data.size();
-  // We pass png_data to retain encoded data until CreateMemoryBackedBlob
-  // takes a copy of it.
-  BrowserContext::CreateMemoryBackedBlob(
-      browser_context_, char_data, size, "",
-      base::BindOnce(&ReplyToReadImage, std::move(callback), size,
-                     std::move(png_data)));
+  std::move(callback).Run(image_);
 }
 
 void MockClipboardHost::ReadCustomData(ui::ClipboardType clipboard_type,
@@ -195,22 +132,10 @@
                                       const std::string& url,
                                       const base::string16& title) {}
 
-void MockClipboardHost::WriteImage(
-    ui::ClipboardType,
-    const gfx::Size& size,
-    mojo::ScopedSharedBufferHandle shared_buffer_handle) {
+void MockClipboardHost::WriteImage(ui::ClipboardType, const SkBitmap& bitmap) {
   if (needs_reset_)
     Reset();
-  if (!image_.setInfo(SkImageInfo::MakeN32Premul(size.width(), size.height())))
-    return;
-  auto mapped = shared_buffer_handle->Map(image_.computeByteSize());
-  if (!mapped)
-    return;
-  if (!image_.installPixels(image_.info(), mapped.get(), image_.rowBytes(),
-                            &ReleaseSharedMemoryPixels, mapped.get())) {
-    return;
-  }
-  mapped.release();
+  image_ = bitmap;
 }
 
 void MockClipboardHost::CommitWrite(ui::ClipboardType) {
diff --git a/content/test/mock_clipboard_host.h b/content/test/mock_clipboard_host.h
index 9d300df..81f0ad025 100644
--- a/content/test/mock_clipboard_host.h
+++ b/content/test/mock_clipboard_host.h
@@ -14,13 +14,9 @@
 
 namespace content {
 
-class BrowserContext;
-
 class MockClipboardHost : public blink::mojom::ClipboardHost {
  public:
-  // |browser_context| could be null, in which case reading images
-  // is not supported.
-  explicit MockClipboardHost(BrowserContext* browser_context);
+  MockClipboardHost();
   ~MockClipboardHost() override;
 
   void Bind(blink::mojom::ClipboardHostRequest request);
@@ -59,14 +55,12 @@
                      const std::string& url,
                      const base::string16& title) override;
   void WriteImage(ui::ClipboardType clipboard_type,
-                  const gfx::Size& size_in_pixels,
-                  mojo::ScopedSharedBufferHandle shared_buffer_handle) override;
+                  const SkBitmap& bitmap) override;
   void CommitWrite(ui::ClipboardType clipboard_type) override;
 #if defined(OS_MACOSX)
   void WriteStringToFindPboard(const base::string16& text) override;
 #endif
 
-  BrowserContext* browser_context_;
   mojo::BindingSet<blink::mojom::ClipboardHost> bindings_;
   uint64_t sequence_number_ = 0;
   base::string16 plain_text_;
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index d2b48a9..72e440c2 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -157,7 +157,7 @@
   url_loader_factory_ = blink::WebURLLoaderMockFactory::Create();
   // Mock out clipboard calls so that tests don't mess
   // with each other's copies/pastes when running in parallel.
-  mock_clipboard_host_ = std::make_unique<MockClipboardHost>(nullptr);
+  mock_clipboard_host_ = std::make_unique<MockClipboardHost>();
 
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
   gin::V8Initializer::LoadV8Snapshot(kSnapshotType);
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom
index 4946470..f8a7a89b 100644
--- a/device/vr/public/mojom/vr_service.mojom
+++ b/device/vr/public/mojom/vr_service.mojom
@@ -28,6 +28,10 @@
   SCREEN = 3
 };
 
+struct XRSessionOptions {
+  bool exclusive;
+};
+
 struct XRInputSourceDescription {
   XRPointerOrigin pointer_origin;
   XRHandedness handedness;
@@ -272,7 +276,8 @@
   // WebVR.
   // TODO(https://crbug.com/842025): Refactor VR device interfaces to better
   // reflect WebXR.
-  RequestSession() => (bool success);
+  RequestSession(XRSessionOptions options) => (bool success);
+  SupportsSession(XRSessionOptions options) => (bool supports_session);
 
   // The returned transport_options is marked optional: it's null for
   // a failure result but must be non-null for a success result.
diff --git a/device/vr/vr_display_impl.h b/device/vr/vr_display_impl.h
index cdcfea1..20e7a9ed 100644
--- a/device/vr/vr_display_impl.h
+++ b/device/vr/vr_display_impl.h
@@ -46,9 +46,12 @@
 
   void RequestSession(mojom::VRDisplayHost::RequestSessionCallback callback);
 
+  mojom::VRDisplayInfoPtr GetVRDisplayInfo();
+
   // XrSessionController
   void SetFrameDataRestricted(bool paused) override;
   void StopSession() override;
+  device::VRDeviceBase* device() { return device_; };
 
  private:
   // mojom::VRMagicWindowProvider
diff --git a/docs/security/side-channel-threat-model.md b/docs/security/side-channel-threat-model.md
index f74f104..8a845b89 100644
--- a/docs/security/side-channel-threat-model.md
+++ b/docs/security/side-channel-threat-model.md
@@ -196,7 +196,8 @@
 With SI, Chrome tends to spawn more renderer processes, which tends to lead to
 greater overall memory usage (conservative estimates seem to be about 10%). On
 many Android devices, it is more than 10%, and this additional cost can be
-prohibitive.
+prohibitive. However, each renderer is smaller and shorter-lived under Site
+Isolation.
 
 ##### Plug-Ins
 
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
index 06a2633..7f5cf4c7 100644
--- a/infra/config/global/cr-buildbucket.cfg
+++ b/infra/config/global/cr-buildbucket.cfg
@@ -1166,6 +1166,9 @@
     builders { mixins: "ios-ci" name: "ios-simulator-full-configs" }
     builders { mixins: "ios-ci" name: "ios-simulator-xcode-clang" }
     builders { mixins: "ios-ci" mixins: "fyi-ci" name: "ios-simulator-cronet" }
+    builders { mixins: "ios-ci" mixins: "fyi-ci" name: "ios12-sdk-device" }
+    builders { mixins: "ios-ci" mixins: "fyi-ci" name: "ios12-sdk-simulator" }
+    builders { mixins: "ios-ci" mixins: "fyi-ci" name: "ios12-sdk-xcode-clang" }
 
     # Win bots.
     builders {
@@ -2494,9 +2497,9 @@
     }
     builders { mixins: "ios-try" name: "ios-device" }
     builders { mixins: "ios-try" name: "ios-device-xcode-clang" }
-    # TODO(crbug.com/836626): delete dimensions: "cores:" when bug is fixed.
-    builders { mixins: "ios-try" dimensions: "cores:" name: "ios-simulator" }
+    builders { mixins: "ios-try" name: "ios-simulator" }
     builders { mixins: "ios-try" name: "ios-simulator-cronet" }
+    builders { mixins: "ios-try" name: "ios12-sdk-simulator" }
     builders { mixins: "ios-try" name: "ios-simulator-full-configs" }
     builders { mixins: "ios-try" name: "ios-simulator-eg" }
     builders { mixins: "ios-try" name: "ios-simulator-xcode-clang" }
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg
index b52cdde..4fb179a3 100644
--- a/infra/config/global/luci-milo.cfg
+++ b/infra/config/global/luci-milo.cfg
@@ -2423,6 +2423,21 @@
     category: "iOS"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/ios12-sdk-device"
+    category: "iOS|iOS12"
+    short_name: "dev"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.ci/ios12-sdk-simulator"
+    category: "iOS|iOS12"
+    short_name: "sim"
+  }
+  builders {
+    name: "buildbucket/luci.chromium.ci/ios12-sdk-xcode-clang"
+    category: "iOS|iOS12"
+    short_name: "xcode"
+  }
+  builders {
     name: "buildbot/chromium.fyi/Jumbo Linux x64"
     name: "buildbucket/luci.chromium.ci/Jumbo Linux x64"
     category: "jumbo"
@@ -4175,6 +4190,9 @@
     name: "buildbucket/luci.chromium.try/ios-simulator-xcode-clang"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/ios12-sdk-simulator"
+  }
+  builders {
     name: "buildbot/tryserver.chromium.mac/mac_chromium_10.10"
   }
   builders {
@@ -4810,6 +4828,9 @@
     name: "buildbucket/luci.chromium.try/ios-simulator-xcode-clang"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/ios12-sdk-simulator"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/mac-jumbo-rel"
   }
   builders {
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
index 5b3a59e5..ec6632c 100644
--- a/infra/config/global/luci-scheduler.cfg
+++ b/infra/config/global/luci-scheduler.cfg
@@ -155,6 +155,9 @@
   triggers: "ios-simulator"
   triggers: "ios-simulator-full-configs"
   triggers: "ios-simulator-xcode-clang"
+  triggers: "ios12-sdk-device"
+  triggers: "ios12-sdk-simulator"
+  triggers: "ios12-sdk-xcode-clang"
   triggers: "linux-blink-heap-incremental-marking"
   triggers: "linux-blink-heap-verification"
   triggers: "linux-chromeos-dbg"
@@ -735,6 +738,36 @@
   }
 }
 
+job {
+  id: "ios12-sdk-device"
+  acl_sets: "default"
+  buildbucket: {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "luci.chromium.ci"
+    builder: "ios12-sdk-device"
+  }
+}
+
+job {
+  id: "ios12-sdk-simulator"
+  acl_sets: "default"
+  buildbucket: {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "luci.chromium.ci"
+    builder: "ios12-sdk-simulator"
+  }
+}
+
+job {
+  id: "ios12-sdk-xcode-clang"
+  acl_sets: "default"
+  buildbucket: {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "luci.chromium.ci"
+    builder: "ios12-sdk-xcode-clang"
+  }
+}
+
 ################################################################################
 # Linux Builders. Sorted alphabetically except builder-Testers must follow their
 # builder-Builders.
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 7b11d37..15067298 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -223,6 +223,12 @@
      flag_descriptions::kAutofillCreditCardUploadName,
      flag_descriptions::kAutofillCreditCardUploadDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(autofill::kAutofillUpstream)},
+    {"enable-autofill-credit-card-downstream-google-pay-branding",
+     flag_descriptions::kAutofillDownstreamUseGooglePayBrandingOniOSName,
+     flag_descriptions::kAutofillDownstreamUseGooglePayBrandingOniOSDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(
+         autofill::features::kAutofillDownstreamUseGooglePayBrandingOniOS)},
     {"enable-autofill-credit-card-upload-google-pay-branding",
      flag_descriptions::kAutofillUpstreamUseGooglePayBrandingOnMobileName,
      flag_descriptions::
diff --git a/ios/chrome/browser/autofill/autofill_controller.mm b/ios/chrome/browser/autofill/autofill_controller.mm
index f7fffeb..d04a76c 100644
--- a/ios/chrome/browser/autofill/autofill_controller.mm
+++ b/ios/chrome/browser/autofill/autofill_controller.mm
@@ -128,9 +128,10 @@
     // such as separators ... see blink::WebAutofillClient::MenuItemIDSeparator
     // for example. We can't include that enum because it's from WebKit, but
     // fortunately almost all the entries we are interested in (profile or
-    // autofill entries) are zero or positive. The only negative entry we are
+    // autofill entries) are zero or positive. Negative entries we are
     // interested in is autofill::POPUP_ITEM_ID_CLEAR_FORM, used to show the
-    // "clear form" button.
+    // "clear form" button and autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING, used
+    // to show the "Google Pay" branding.
     NSString* value = nil;
     NSString* displayDescription = nil;
     if (popup_suggestions[i].frontend_id >= 0) {
@@ -143,6 +144,10 @@
                autofill::POPUP_ITEM_ID_CLEAR_FORM) {
       // Show the "clear form" button.
       value = base::SysUTF16ToNSString(popup_suggestions[i].value);
+    } else if (popup_suggestions[i].frontend_id ==
+               autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING) {
+      // Show "GPay branding" icon
+      value = base::SysUTF16ToNSString(popup_suggestions[i].value);
     }
 
     if (!value)
diff --git a/ios/chrome/browser/autofill/form_suggestion_label.h b/ios/chrome/browser/autofill/form_suggestion_label.h
index 11dfaa0..8a2b74f1 100644
--- a/ios/chrome/browser/autofill/form_suggestion_label.h
+++ b/ios/chrome/browser/autofill/form_suggestion_label.h
@@ -17,11 +17,14 @@
 // Designated initializer. Initializes with |proposedFrame| and |client| for
 // |suggestion|. Its width will be adjusted according to the length of
 // |suggestion| and width in |proposedFrame| is ignored.
+// |userInteractionEnabled| is a boolean that denotes whether user interaction
+// is enabled on the suggestion.
 - (id)initWithSuggestion:(FormSuggestion*)suggestion
-           proposedFrame:(CGRect)proposedFrame
-                   index:(NSUInteger)index
-          numSuggestions:(NSUInteger)numSuggestions
-                  client:(id<FormSuggestionViewClient>)client;
+             proposedFrame:(CGRect)proposedFrame
+                     index:(NSUInteger)index
+    userInteractionEnabled:(BOOL)userInteractionEnabled
+            numSuggestions:(NSUInteger)numSuggestions
+                    client:(id<FormSuggestionViewClient>)client;
 
 @end
 
diff --git a/ios/chrome/browser/autofill/form_suggestion_label.mm b/ios/chrome/browser/autofill/form_suggestion_label.mm
index 033232a..12ffaeb 100644
--- a/ios/chrome/browser/autofill/form_suggestion_label.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_label.mm
@@ -75,19 +75,22 @@
   // Client of this view.
   __weak id<FormSuggestionViewClient> client_;
   FormSuggestion* suggestion_;
+  BOOL userInteractionEnabled_;
 }
 
 - (id)initWithSuggestion:(FormSuggestion*)suggestion
-           proposedFrame:(CGRect)proposedFrame
-                   index:(NSUInteger)index
-          numSuggestions:(NSUInteger)numSuggestions
-                  client:(id<FormSuggestionViewClient>)client {
+             proposedFrame:(CGRect)proposedFrame
+                     index:(NSUInteger)index
+    userInteractionEnabled:(BOOL)userInteractionEnabled
+            numSuggestions:(NSUInteger)numSuggestions
+                    client:(id<FormSuggestionViewClient>)client {
   // TODO(jimblackler): implement sizeThatFits: and layoutSubviews, and perform
   // layout in those methods instead of in the designated initializer.
   self = [super initWithFrame:CGRectZero];
   if (self) {
     suggestion_ = suggestion;
     client_ = client;
+    userInteractionEnabled_ = userInteractionEnabled;
 
     const CGFloat frameHeight = CGRectGetHeight(proposedFrame);
     CGFloat currentX = kBorderWidth;
@@ -131,7 +134,9 @@
 
     self.frame = CGRectMake(proposedFrame.origin.x, proposedFrame.origin.y,
                             currentX, proposedFrame.size.height);
-    [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
+    if (userInteractionEnabled_) {
+      [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
+    }
     [[self layer] setCornerRadius:kCornerRadius];
 
     [self setClipsToBounds:YES];
@@ -158,16 +163,22 @@
 #pragma mark UIResponder
 
 - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
-  [self setBackgroundColor:UIColorFromRGB(kBackgroundPressedColor)];
+  if (userInteractionEnabled_) {
+    [self setBackgroundColor:UIColorFromRGB(kBackgroundPressedColor)];
+  }
 }
 
 - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
-  [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
+  if (userInteractionEnabled_) {
+    [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
+  }
 }
 
 - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
-  [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
-  [client_ didSelectSuggestion:suggestion_];
+  if (userInteractionEnabled_) {
+    [self setBackgroundColor:UIColorFromRGB(kBackgroundNormalColor)];
+    [client_ didSelectSuggestion:suggestion_];
+  }
 }
 
 @end
diff --git a/ios/chrome/browser/autofill/form_suggestion_view.mm b/ios/chrome/browser/autofill/form_suggestion_view.mm
index d6ffd709..1c16b6c 100644
--- a/ios/chrome/browser/autofill/form_suggestion_view.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_view.mm
@@ -5,6 +5,8 @@
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
 
 #include "base/i18n/rtl.h"
+#include "base/logging.h"
+#include "components/autofill/core/browser/popup_item_ids.h"
 #import "components/autofill/ios/browser/form_suggestion.h"
 #import "ios/chrome/browser/autofill/form_suggestion_label.h"
 #import "ios/chrome/browser/autofill/form_suggestion_view_client.h"
@@ -53,12 +55,16 @@
           // the width.
           CGRect proposedFrame =
               CGRectMake(currentX, kSuggestionVerticalMargin, 0, labelHeight);
+          BOOL userInteractionEnabled =
+              suggestion.identifier !=
+              autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING;
           UIView* label = [[FormSuggestionLabel alloc]
-              initWithSuggestion:suggestion
-                   proposedFrame:proposedFrame
-                           index:idx
-                  numSuggestions:[_suggestions count]
-                          client:client];
+                  initWithSuggestion:suggestion
+                       proposedFrame:proposedFrame
+                               index:idx
+              userInteractionEnabled:userInteractionEnabled
+                      numSuggestions:[_suggestions count]
+                              client:client];
           [self addSubview:label];
           currentX +=
               CGRectGetWidth([label frame]) + kSuggestionHorizontalMargin;
@@ -71,6 +77,26 @@
   return self;
 }
 
+- (void)willMoveToSuperview:(UIView*)newSuperview {
+  FormSuggestion* firstSuggestion = [_suggestions firstObject];
+  if (firstSuggestion.identifier ==
+      autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING) {
+    UIView* firstLabel = [self.subviews firstObject];
+    DCHECK(firstLabel);
+    const CGFloat firstLabelWidth =
+        CGRectGetWidth([firstLabel frame]) + kSuggestionHorizontalMargin;
+    dispatch_time_t popTime =
+        dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC);
+    __weak FormSuggestionView* weakSelf = self;
+    dispatch_after(popTime, dispatch_get_main_queue(), ^{
+      [weakSelf setContentOffset:CGPointMake(firstLabelWidth,
+                                             weakSelf.contentOffset.y)
+                        animated:YES];
+    });
+  }
+  [super willMoveToSuperview:newSuperview];
+}
+
 - (void)layoutSubviews {
   [super layoutSubviews];
 
diff --git a/ios/chrome/browser/history/history_backend_client_impl.cc b/ios/chrome/browser/history/history_backend_client_impl.cc
index 22f8a062..f200a71 100644
--- a/ios/chrome/browser/history/history_backend_client_impl.cc
+++ b/ios/chrome/browser/history/history_backend_client_impl.cc
@@ -4,40 +4,40 @@
 
 #include "ios/chrome/browser/history/history_backend_client_impl.h"
 
-#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/history_bookmark_model.h"
+#include "components/bookmarks/browser/model_loader.h"
 #include "components/bookmarks/browser/url_and_title.h"
 #include "url/gurl.h"
 
 HistoryBackendClientImpl::HistoryBackendClientImpl(
-    bookmarks::BookmarkModel* bookmark_model)
-    : bookmark_model_(bookmark_model) {
-}
+    bookmarks::ModelLoader* model_loader)
+    : model_loader_(model_loader) {}
 
 HistoryBackendClientImpl::~HistoryBackendClientImpl() {
 }
 
 bool HistoryBackendClientImpl::IsBookmarked(const GURL& url) {
-  if (!bookmark_model_)
+  if (!model_loader_)
     return false;
 
   // HistoryBackendClient is used to determine if an URL is bookmarked. The data
   // is loaded on a separate thread and may not be done when this method is
   // called, therefore blocks until the bookmarks have finished loading.
-  bookmark_model_->BlockTillLoaded();
-  return bookmark_model_->IsBookmarked(url);
+  model_loader_->BlockTillLoaded();
+  return model_loader_->history_bookmark_model()->IsBookmarked(url);
 }
 
 void HistoryBackendClientImpl::GetBookmarks(
     std::vector<history::URLAndTitle>* bookmarks) {
-  if (!bookmark_model_)
+  if (!model_loader_)
     return;
 
   // HistoryBackendClient is used to determine the set of bookmarked URLs. The
   // data is loaded on a separate thread and may not be done when this method is
   // called, therefore blocks until the bookmarks have finished loading.
   std::vector<bookmarks::UrlAndTitle> url_and_titles;
-  bookmark_model_->BlockTillLoaded();
-  bookmark_model_->GetBookmarks(&url_and_titles);
+  model_loader_->BlockTillLoaded();
+  model_loader_->history_bookmark_model()->GetBookmarks(&url_and_titles);
 
   bookmarks->reserve(bookmarks->size() + url_and_titles.size());
   for (const auto& url_and_title : url_and_titles) {
diff --git a/ios/chrome/browser/history/history_backend_client_impl.h b/ios/chrome/browser/history/history_backend_client_impl.h
index eba9ea9..56a4d36 100644
--- a/ios/chrome/browser/history/history_backend_client_impl.h
+++ b/ios/chrome/browser/history/history_backend_client_impl.h
@@ -8,17 +8,18 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
 #include "components/history/core/browser/history_backend_client.h"
 
 class GURL;
 
 namespace bookmarks {
-class BookmarkModel;
+class ModelLoader;
 }
 
 class HistoryBackendClientImpl : public history::HistoryBackendClient {
  public:
-  explicit HistoryBackendClientImpl(bookmarks::BookmarkModel* bookmark_model);
+  explicit HistoryBackendClientImpl(bookmarks::ModelLoader* model_loader);
   ~HistoryBackendClientImpl() override;
 
  private:
@@ -28,9 +29,8 @@
   bool ShouldReportDatabaseError() override;
   bool IsWebSafe(const GURL& url) override;
 
-  // BookmarkModel instance providing access to bookmarks. May be null during
-  // testing but must outlive HistoryBackendClientImpl if non-null.
-  bookmarks::BookmarkModel* bookmark_model_;
+  // ModelLoader is used to access bookmarks. May be null during testing.
+  scoped_refptr<bookmarks::ModelLoader> model_loader_;
 
   DISALLOW_COPY_AND_ASSIGN(HistoryBackendClientImpl);
 };
diff --git a/ios/chrome/browser/history/history_client_impl.cc b/ios/chrome/browser/history/history_client_impl.cc
index 182afdc2..838ff8a 100644
--- a/ios/chrome/browser/history/history_client_impl.cc
+++ b/ios/chrome/browser/history/history_client_impl.cc
@@ -14,15 +14,24 @@
 #include "url/gurl.h"
 
 HistoryClientImpl::HistoryClientImpl(bookmarks::BookmarkModel* bookmark_model)
-    : bookmark_model_(bookmark_model), is_bookmark_model_observer_(false) {
+    : bookmark_model_(bookmark_model) {
+  if (bookmark_model_)
+    bookmark_model_->AddObserver(this);
 }
 
 HistoryClientImpl::~HistoryClientImpl() {
+  StopObservingBookmarkModel();
+}
+
+void HistoryClientImpl::StopObservingBookmarkModel() {
+  if (!bookmark_model_)
+    return;
+  bookmark_model_->RemoveObserver(this);
+  bookmark_model_ = nullptr;
 }
 
 void HistoryClientImpl::OnHistoryServiceCreated(
     history::HistoryService* history_service) {
-  DCHECK(!is_bookmark_model_observer_);
   if (bookmark_model_) {
     on_bookmarks_removed_ =
         base::Bind(&history::HistoryService::URLsNoLongerBookmarked,
@@ -31,28 +40,12 @@
         history_service->AddFaviconsChangedCallback(
             base::Bind(&bookmarks::BookmarkModel::OnFaviconsChanged,
                        base::Unretained(bookmark_model_)));
-    bookmark_model_->AddObserver(this);
-    is_bookmark_model_observer_ = true;
   }
 }
 
 void HistoryClientImpl::Shutdown() {
-  // It's possible that bookmarks haven't loaded and history is waiting for
-  // bookmarks to complete loading. In such a situation history can't shutdown
-  // (meaning if we invoked HistoryService::Cleanup now, we would deadlock). To
-  // break the deadlock we tell BookmarkModel it's about to be deleted so that
-  // it can release the signal history is waiting on, allowing history to
-  // shutdown (HistoryService::Cleanup to complete). In such a scenario history
-  // sees an incorrect view of bookmarks, but it's better than a deadlock.
-  if (bookmark_model_) {
-    if (is_bookmark_model_observer_) {
-      is_bookmark_model_observer_ = false;
-      bookmark_model_->RemoveObserver(this);
-      favicons_changed_subscription_.reset();
-      on_bookmarks_removed_.Reset();
-    }
-    bookmark_model_->Shutdown();
-  }
+  favicons_changed_subscription_.reset();
+  StopObservingBookmarkModel();
 }
 
 bool HistoryClientImpl::CanAddURL(const GURL& url) {
@@ -64,25 +57,32 @@
 
 std::unique_ptr<history::HistoryBackendClient>
 HistoryClientImpl::CreateBackendClient() {
-  return std::make_unique<HistoryBackendClientImpl>(bookmark_model_);
+  return std::make_unique<HistoryBackendClientImpl>(
+      bookmark_model_ ? bookmark_model_->model_loader() : nullptr);
 }
 
 void HistoryClientImpl::BookmarkModelChanged() {
 }
 
+void HistoryClientImpl::BookmarkModelBeingDeleted(
+    bookmarks::BookmarkModel* model) {
+  DCHECK_EQ(model, bookmark_model_);
+  StopObservingBookmarkModel();
+}
+
 void HistoryClientImpl::BookmarkNodeRemoved(
     bookmarks::BookmarkModel* model,
     const bookmarks::BookmarkNode* parent,
     int old_index,
     const bookmarks::BookmarkNode* node,
     const std::set<GURL>& no_longer_bookmarked) {
-  if (!on_bookmarks_removed_.is_null())
+  if (on_bookmarks_removed_)
     on_bookmarks_removed_.Run(no_longer_bookmarked);
 }
 
 void HistoryClientImpl::BookmarkAllUserNodesRemoved(
     bookmarks::BookmarkModel* model,
     const std::set<GURL>& removed_urls) {
-  if (!on_bookmarks_removed_.is_null())
+  if (on_bookmarks_removed_)
     on_bookmarks_removed_.Run(removed_urls);
 }
diff --git a/ios/chrome/browser/history/history_client_impl.h b/ios/chrome/browser/history/history_client_impl.h
index e69d5be..10f1338 100644
--- a/ios/chrome/browser/history/history_client_impl.h
+++ b/ios/chrome/browser/history/history_client_impl.h
@@ -28,6 +28,8 @@
   ~HistoryClientImpl() override;
 
  private:
+  void StopObservingBookmarkModel();
+
   // history::HistoryClient implementation.
   void OnHistoryServiceCreated(
       history::HistoryService* history_service) override;
@@ -39,8 +41,7 @@
 
   // bookmarks::BaseBookmarkModelObserver implementation.
   void BookmarkModelChanged() override;
-
-  // bookmarks::BookmarkModelObserver implementation.
+  void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override;
   void BookmarkNodeRemoved(bookmarks::BookmarkModel* model,
                            const bookmarks::BookmarkNode* parent,
                            int old_index,
@@ -50,9 +51,8 @@
                                    const std::set<GURL>& removed_urls) override;
 
   // BookmarkModel instance providing access to bookmarks. May be null during
-  // testing but must outlive HistoryClientImpl if non-null.
+  // testing, and is null while shutting down.
   bookmarks::BookmarkModel* bookmark_model_;
-  bool is_bookmark_model_observer_;
 
   // Callback invoked when URLs are removed from BookmarkModel.
   base::Callback<void(const std::set<GURL>&)> on_bookmarks_removed_;
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index 4cb03eb..478c6cf 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -23,6 +23,12 @@
     "Offers uploading Autofilled credit cards to Google Payments after form "
     "submission.";
 
+const char kAutofillDownstreamUseGooglePayBrandingOniOSName[] =
+    "Enable Google Pay branding when offering credit card downstream";
+const char kAutofillDownstreamUseGooglePayBrandingOniOSDescription[] =
+    "When enabled, shows the Google Pay logo animation when showing payments"
+    "credit card suggestions in downstream keyboard accessory";
+
 const char kAutofillDynamicFormsName[] = "Autofill dynamic forms";
 const char kAutofillDynamicFormsDescription[] =
     "Refills forms that dynamically change after an initial fill";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 20f4e9cc..3e42adb6c 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -15,6 +15,11 @@
 extern const char kAutofillCreditCardUploadName[];
 extern const char kAutofillCreditCardUploadDescription[];
 
+// Title and description for the flag to control GPay branding in credit card
+// downstream keyboard accessory.
+extern const char kAutofillDownstreamUseGooglePayBrandingOniOSName[];
+extern const char kAutofillDownstreamUseGooglePayBrandingOniOSDescription[];
+
 // Title and description for the flag to control the dynamic autofill.
 extern const char kAutofillDynamicFormsName[];
 extern const char kAutofillDynamicFormsDescription[];
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h
index 7392fed4..216e975 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.h
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -47,8 +47,8 @@
   history::HistoryService* GetHistoryService() override;
   bool HasPasswordStore() override;
   base::Closure GetPasswordStateChangedCallback() override;
-  syncer::SyncApiComponentFactory::RegisterDataTypesMethod
-  GetRegisterPlatformTypesCallback() override;
+  syncer::DataTypeController::TypeVector CreateDataTypeControllers(
+      syncer::LocalDeviceInfoProvider* local_device_info_provider) override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   invalidation::InvalidationService* GetInvalidationService() override;
   BookmarkUndoService* GetBookmarkUndoServiceIfExists() override;
@@ -85,8 +85,6 @@
 
   std::unique_ptr<sync_sessions::SyncSessionsClient> sync_sessions_client_;
 
-  base::WeakPtrFactory<IOSChromeSyncClient> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(IOSChromeSyncClient);
 };
 
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
index d7a8a0e..5732afc 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -71,6 +71,14 @@
 
 namespace {
 
+syncer::ModelTypeSet GetDisabledTypesFromCommandLine() {
+  std::string disabled_types_str =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kDisableSyncTypes);
+
+  return syncer::ModelTypeSetFromString(disabled_types_str);
+}
+
 // iOS implementation of SyncSessionsClient. Needs to be in a separate class
 // due to possible multiple inheritance issues, wherein IOSChromeSyncClient
 // might inherit from other interfaces with same methods.
@@ -137,8 +145,7 @@
 IOSChromeSyncClient::IOSChromeSyncClient(ios::ChromeBrowserState* browser_state)
     : browser_state_(browser_state),
       sync_sessions_client_(
-          std::make_unique<SyncSessionsClientImpl>(browser_state)),
-      weak_ptr_factory_(this) {}
+          std::make_unique<SyncSessionsClientImpl>(browser_state)) {}
 
 IOSChromeSyncClient::~IOSChromeSyncClient() {}
 
@@ -158,7 +165,6 @@
     component_factory_.reset(new browser_sync::ProfileSyncComponentsFactoryImpl(
         this, ::GetChannel(), ::GetVersionString(),
         ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET,
-        *base::CommandLine::ForCurrentProcess(),
         prefs::kSavingBrowserHistoryDisabled,
         web::WebThread::GetTaskRunnerForThread(web::WebThread::UI), db_thread_,
         web_data_service_, password_store_));
@@ -213,10 +219,12 @@
       base::Unretained(browser_state_));
 }
 
-syncer::SyncApiComponentFactory::RegisterDataTypesMethod
-IOSChromeSyncClient::GetRegisterPlatformTypesCallback() {
+syncer::DataTypeController::TypeVector
+IOSChromeSyncClient::CreateDataTypeControllers(
+    syncer::LocalDeviceInfoProvider* local_device_info_provider) {
   // The iOS port does not have any platform-specific datatypes.
-  return syncer::SyncApiComponentFactory::RegisterDataTypesMethod();
+  return component_factory_->CreateCommonDataTypeControllers(
+      GetDisabledTypesFromCommandLine(), local_device_info_provider);
 }
 
 BookmarkUndoService* IOSChromeSyncClient::GetBookmarkUndoServiceIfExists() {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
index 44819db..fb12eb81 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include "base/logging.h"
+#include "base/mac/foundation_util.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/strings/sys_string_conversions.h"
@@ -28,6 +29,9 @@
 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller.h"
+#import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.h"
+#import "ios/chrome/browser/ui/table_view/table_view_presentation_controller.h"
+#import "ios/chrome/browser/ui/table_view/table_view_presentation_controller_delegate.h"
 #include "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/browser/ui/url_loader.h"
 #import "ios/chrome/browser/ui/util/form_sheet_navigation_controller.h"
@@ -46,7 +50,8 @@
 
 @interface BookmarkInteractionController ()<
     BookmarkEditViewControllerDelegate,
-    BookmarkHomeViewControllerDelegate> {
+    BookmarkHomeViewControllerDelegate,
+    TableViewPresentationControllerDelegate> {
   // The browser state of the current user.
   ios::ChromeBrowserState* _currentBrowserState;  // weak
 
@@ -74,9 +79,20 @@
 
 @property(nonatomic, readonly, weak) id<ApplicationCommands> dispatcher;
 
+// The transitioning delegate that is used when presenting
+// |self.bookmarkBrowser|.
 @property(nonatomic, strong)
     BookmarkTransitioningDelegate* bookmarkTransitioningDelegate;
 
+// The UINavigationController subclass that is used to wrap
+// |self.bookmarkBrowser|.
+@property(nonatomic, strong)
+    TableViewNavigationController* bookmarkNavigationController;
+
+// The delegate provided to |self.bookmarkNavigationController|.
+@property(nonatomic, strong)
+    TableViewNavigationControllerDelegate* bookmarkNavigationControllerDelegate;
+
 // Builds a controller and brings it on screen.
 - (void)presentBookmarkForBookmarkedTab:(Tab*)tab;
 
@@ -96,6 +112,9 @@
 @synthesize bookmarkBrowser = _bookmarkBrowser;
 @synthesize bookmarkEditor = _bookmarkEditor;
 @synthesize bookmarkModel = _bookmarkModel;
+@synthesize bookmarkNavigationController = _bookmarkNavigationController;
+@synthesize bookmarkNavigationControllerDelegate =
+    _bookmarkNavigationControllerDelegate;
 @synthesize bookmarkTransitioningDelegate = _bookmarkTransitioningDelegate;
 @synthesize mediator = _mediator;
 @synthesize dispatcher = _dispatcher;
@@ -197,11 +216,15 @@
     TableViewNavigationController* navController =
         [[TableViewNavigationController alloc]
             initWithTable:self.bookmarkBrowser];
+    self.bookmarkNavigationController = navController;
     if (replacementViewControllers) {
       [navController setViewControllers:replacementViewControllers];
     }
 
     navController.toolbarHidden = YES;
+    self.bookmarkNavigationControllerDelegate =
+        [[TableViewNavigationControllerDelegate alloc] init];
+    navController.delegate = self.bookmarkNavigationControllerDelegate;
     self.bookmarkTransitioningDelegate =
         [[BookmarkTransitioningDelegate alloc] init];
     navController.transitioningDelegate = self.bookmarkTransitioningDelegate;
@@ -209,6 +232,13 @@
     [_parentController presentViewController:navController
                                     animated:YES
                                   completion:nil];
+
+    TableViewPresentationController* presentationController =
+        base::mac::ObjCCastStrict<TableViewPresentationController>(
+            navController.presentationController);
+    self.bookmarkNavigationControllerDelegate.modalController =
+        presentationController;
+    presentationController.modalDelegate = self;
   } else {
     FormSheetNavigationController* navController =
         [[FormSheetNavigationController alloc]
@@ -253,6 +283,8 @@
                            self.bookmarkBrowser.homeDelegate = nil;
                            self.bookmarkBrowser = nil;
                            self.bookmarkTransitioningDelegate = nil;
+                           self.bookmarkNavigationController = nil;
+                           self.bookmarkNavigationControllerDelegate = nil;
 
                            if (!openUrlsAfterDismissal) {
                              return;
@@ -364,6 +396,27 @@
   }  // end for
 }
 
+#pragma mark - TableViewPresentationControllerDelegate
+
+- (BOOL)presentationControllerShouldDismissOnTouchOutside:
+    (TableViewPresentationController*)controller {
+  BOOL shouldDismissOnTouchOutside = YES;
+
+  ChromeTableViewController* tableViewController =
+      base::mac::ObjCCast<ChromeTableViewController>(
+          self.bookmarkNavigationController.topViewController);
+  if (tableViewController) {
+    shouldDismissOnTouchOutside =
+        [tableViewController shouldBeDismissedOnTouchOutside];
+  }
+  return shouldDismissOnTouchOutside;
+}
+
+- (void)presentationControllerWillDismiss:
+    (TableViewPresentationController*)controller {
+  [self dismissBookmarkModalControllerAnimated:YES];
+}
+
 #pragma mark - Private
 
 - (void)openURLInCurrentTab:(const GURL&)url {
diff --git a/ios/chrome/browser/ui/keyboard_commands_egtest.mm b/ios/chrome/browser/ui/keyboard_commands_egtest.mm
index b98f09b..7726165 100644
--- a/ios/chrome/browser/ui/keyboard_commands_egtest.mm
+++ b/ios/chrome/browser/ui/keyboard_commands_egtest.mm
@@ -210,16 +210,10 @@
   [self verifyKeyboardCommandsAreRegistered];
 
   UIResponder* firstResponder = GetFirstResponder();
-  if (@available(iOS 11.3, *)) {
-    GREYAssert([firstResponder isKindOfClass:NSClassFromString(@"WKWebView")],
-               @"Expected first responder to be a WKWebView. Instead, is a %@",
-               NSStringFromClass([firstResponder class]));
-  } else {
-    GREYAssert(
-        [firstResponder isKindOfClass:NSClassFromString(@"WKContentView")],
-        @"Expected first responder to be a WKContentView. Instead, is a %@",
-        NSStringFromClass([firstResponder class]));
-  }
+  GREYAssert(
+      [firstResponder isKindOfClass:NSClassFromString(@"WKContentView")],
+      @"Expected first responder to be a WKContentView. Instead, is a %@",
+      NSStringFromClass([firstResponder class]));
 }
 
 @end
diff --git a/ios/chrome/browser/ui/reading_list/OWNERS b/ios/chrome/browser/ui/reading_list/OWNERS
index 33da4bf..66536df 100644
--- a/ios/chrome/browser/ui/reading_list/OWNERS
+++ b/ios/chrome/browser/ui/reading_list/OWNERS
@@ -1,5 +1,4 @@
 gambard@chromium.org
-kkhorimoto@chromium.org
 noyau@chromium.org
 olivierrobin@chromium.org
 
diff --git a/ios/chrome/browser/ui/table_view/BUILD.gn b/ios/chrome/browser/ui/table_view/BUILD.gn
index 67ed7b59..c0f5692 100644
--- a/ios/chrome/browser/ui/table_view/BUILD.gn
+++ b/ios/chrome/browser/ui/table_view/BUILD.gn
@@ -14,8 +14,11 @@
     "table_view_navigation_controller.mm",
     "table_view_navigation_controller_constants.h",
     "table_view_navigation_controller_constants.mm",
+    "table_view_navigation_controller_delegate.h",
+    "table_view_navigation_controller_delegate.mm",
   ]
   deps = [
+    ":presentation",
     ":styler",
     "//base",
     "//ios/chrome/browser/ui/list_model",
@@ -40,8 +43,10 @@
   sources = [
     "table_view_animator.h",
     "table_view_animator.mm",
+    "table_view_modal_presenting.h",
     "table_view_presentation_controller.h",
     "table_view_presentation_controller.mm",
+    "table_view_presentation_controller_delegate.h",
   ]
   deps = [
     "//ios/chrome/browser/ui:ui_util",
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h
index dea570b..9d69bb33 100644
--- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h
+++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.h
@@ -58,7 +58,15 @@
 // Methods for reconfiguring and reloading the table view are provided by
 // ChromeTableViewConsumer.
 
-#pragma mark UIScrollViewDelegate
+#pragma mark - Presentation Controller integration
+
+// Returns YES if this view controller should be dismissed when the user touches
+// outside the bounds of the table view.  Defaults to YES.  Subclasses should
+// override this to return NO if they allow the user to edit data, so that
+// accidental touches outside the table view cannot lose user data.
+- (BOOL)shouldBeDismissedOnTouchOutside;
+
+#pragma mark - UIScrollViewDelegate
 
 // Updates the MDCFlexibleHeader with changes to the table view scroll
 // state. Must be called by subclasses if they override this method in order to
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm
index 79695cc..ab50564b 100644
--- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm
+++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller.mm
@@ -112,6 +112,12 @@
   return [self.tableViewModel numberOfSections];
 }
 
+#pragma mark - Presentation Controller integration
+
+- (BOOL)shouldBeDismissedOnTouchOutside {
+  return YES;
+}
+
 #pragma mark - UITableViewDelegate
 
 - (UIView*)tableView:(UITableView*)tableView
diff --git a/ios/chrome/browser/ui/table_view/table_view_modal_presenting.h b/ios/chrome/browser/ui/table_view/table_view_modal_presenting.h
new file mode 100644
index 0000000..f1cbdee
--- /dev/null
+++ b/ios/chrome/browser/ui/table_view/table_view_modal_presenting.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 IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODAL_PRESENTING_H_
+#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODAL_PRESENTING_H_
+
+// TableViewModalPresenting provides methods that allow presented UI to modify
+// whether their presentations are modal or not.
+@protocol TableViewModalPresenting
+
+// Tells the delegate how to handle touches that are outside the bounds of the
+// presented UI.  If set to YES, presentations will be dismissed when the user
+// touches outside of the table view's bounds.  Callers should set this to NO if
+// user-edited data is currently visible on screen, which could potentially
+// otherwise be lost during an inadvertent touch.  If a |transitionCoordinator|
+// is provided, any changes in UI will be animated alongside that transition.
+// Otherwise, UI changes will be made immediately without animation.
+- (void)setShouldDismissOnTouchOutside:(BOOL)shouldDismiss
+             withTransitionCoordinator:
+                 (id<UIViewControllerTransitionCoordinator>)
+                     transitionCoordinator;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODAL_PRESENTING_H_
diff --git a/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm b/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm
index 283bd1be..9b4e2e92 100644
--- a/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm
+++ b/ios/chrome/browser/ui/table_view/table_view_navigation_controller.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller.h"
 
+#include "base/mac/foundation_util.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 
diff --git a/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.h b/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.h
new file mode 100644
index 0000000..c1d21987
--- /dev/null
+++ b/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.h
@@ -0,0 +1,24 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_NAVIGATION_CONTROLLER_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_NAVIGATION_CONTROLLER_DELEGATE_H_
+
+#import <UIKit/UIKit.h>
+
+@protocol TableViewModalPresenting;
+
+// TableViewNavigationControllerDelegate serves as a delegate for
+// TableViewNavigationController. It uses |modalController| to update the modal
+// presentation state when view controllers are pushed onto or popped off of the
+// navigation stack.
+@interface TableViewNavigationControllerDelegate
+    : NSObject<UINavigationControllerDelegate>
+
+// An object which controls the modal presentation of the navigation controller.
+@property(nonatomic, weak) id<TableViewModalPresenting> modalController;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_NAVIGATION_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.mm b/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.mm
new file mode 100644
index 0000000..dd4621f
--- /dev/null
+++ b/ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.mm
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_delegate.h"
+
+#include "base/mac/foundation_util.h"
+#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h"
+#import "ios/chrome/browser/ui/table_view/table_view_modal_presenting.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation TableViewNavigationControllerDelegate
+@synthesize modalController = _modalController;
+
+- (void)navigationController:(UINavigationController*)navigationController
+      willShowViewController:(UIViewController*)viewController
+                    animated:(BOOL)animated {
+  BOOL shouldDismissOnTouchOutside = YES;
+
+  ChromeTableViewController* tableViewController =
+      base::mac::ObjCCast<ChromeTableViewController>(viewController);
+  if (tableViewController) {
+    shouldDismissOnTouchOutside =
+        [tableViewController shouldBeDismissedOnTouchOutside];
+  }
+
+  id<UIViewControllerTransitionCoordinator> transitionCoordinator = nil;
+  if (animated) {
+    transitionCoordinator = navigationController.transitionCoordinator;
+  }
+
+  [self.modalController
+      setShouldDismissOnTouchOutside:shouldDismissOnTouchOutside
+           withTransitionCoordinator:transitionCoordinator];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.h b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.h
index c99fbcf9..74e115bf 100644
--- a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.h
+++ b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.h
@@ -7,7 +7,17 @@
 
 #import <UIKit/UIKit.h>
 
-@interface TableViewPresentationController : UIPresentationController
+#import "ios/chrome/browser/ui/table_view/table_view_modal_presenting.h"
+
+@protocol TableViewPresentationControllerDelegate;
+
+@interface TableViewPresentationController
+    : UIPresentationController<TableViewModalPresenting>
+
+// This controller's delegate.
+@property(nonatomic, weak) id<TableViewPresentationControllerDelegate>
+    modalDelegate;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_PRESENTATION_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
index 371c3f9..bb9dd43 100644
--- a/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
+++ b/ios/chrome/browser/ui/table_view/table_view_presentation_controller.mm
@@ -7,9 +7,9 @@
 #include <algorithm>
 
 #import "ios/chrome/browser/ui/image_util/image_util.h"
-#import "ios/chrome/browser/ui/util/constraints_ui_util.h"
-
 #include "ios/chrome/browser/ui/rtl_geometry.h"
+#import "ios/chrome/browser/ui/table_view/table_view_presentation_controller_delegate.h"
+#import "ios/chrome/browser/ui/util/constraints_ui_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -58,6 +58,7 @@
 
 @implementation TableViewPresentationController
 @synthesize dimmingShield = _dimmingShield;
+@synthesize modalDelegate = _modalDelegate;
 @synthesize shadowContainer = _shadowContainer;
 @synthesize shadowImage = _shadowImage;
 @synthesize tableViewContainer = _tableViewContainer;
@@ -85,6 +86,10 @@
 - (void)presentationTransitionWillBegin {
   // The dimming view is added first, so that all other views are layered on top
   // of it.
+  BOOL shieldIsModal =
+      self.modalDelegate &&
+      ![self.modalDelegate
+          presentationControllerShouldDismissOnTouchOutside:self];
   self.dimmingShield = [[UIView alloc] init];
   self.dimmingShield.backgroundColor = [UIColor clearColor];
   self.dimmingShield.frame = self.containerView.bounds;
@@ -98,6 +103,7 @@
   self.shadowImage =
       [[UIImageView alloc] initWithImage:StretchableImageNamed(@"menu_shadow")];
   self.shadowImage.translatesAutoresizingMaskIntoConstraints = NO;
+  self.shadowImage.alpha = 0.0;
   [self.shadowContainer addSubview:self.shadowImage];
   AddSameConstraintsToSidesWithInsets(
       self.shadowContainer, self.shadowImage,
@@ -131,10 +137,12 @@
   BOOL animationQueued = [self.presentedViewController.transitionCoordinator
       animateAlongsideTransition:^(
           id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
-        self.shadowImage.alpha = 1.0;
+        [self updateDimmingShieldForModal:shieldIsModal];
       }
                       completion:nil];
-  self.shadowImage.alpha = animationQueued ? 0.0 : 1.0;
+  if (!animationQueued) {
+    [self updateDimmingShieldForModal:shieldIsModal];
+  }
 }
 
 - (void)presentationTransitionDidEnd:(BOOL)completed {
@@ -148,6 +156,7 @@
       animateAlongsideTransition:^(
           id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
         self.shadowImage.alpha = 0.0;
+        self.dimmingShield.backgroundColor = [UIColor clearColor];
       }
                       completion:nil];
 }
@@ -169,6 +178,25 @@
   self.presentedViewController.view.frame = self.tableViewContainer.bounds;
 }
 
+#pragma mark - TableViewModalPresenting
+
+- (void)setShouldDismissOnTouchOutside:(BOOL)shouldDismiss
+             withTransitionCoordinator:
+                 (id<UIViewControllerTransitionCoordinator>)
+                     transitionCoordinator {
+  if (transitionCoordinator) {
+    auto animation =
+        ^(id<UIViewControllerTransitionCoordinatorContext> context) {
+          [self updateDimmingShieldForModal:!shouldDismiss];
+        };
+    [transitionCoordinator animateAlongsideTransitionInView:self.containerView
+                                                  animation:animation
+                                                 completion:nil];
+  } else {
+    [self updateDimmingShieldForModal:!shouldDismiss];
+  }
+}
+
 #pragma mark - Private Methods
 
 - (void)cleanUpPresentationContainerViews {
@@ -182,11 +210,34 @@
   self.dimmingShield = nil;
 }
 
+// Updates |self.shadowImage.alpha| and |self.dimmingShield.backgroundColor| as
+// appropriate for the given |modal| mode.  This method will animate the changes
+// if it is called from within an animation block.
+- (void)updateDimmingShieldForModal:(BOOL)modal {
+  if (modal) {
+    self.dimmingShield.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
+    self.shadowImage.alpha = 0.0;
+  } else {
+    self.dimmingShield.backgroundColor = [UIColor clearColor];
+    self.shadowImage.alpha = 1.0;
+  }
+}
+
 #pragma mark - Actions
 
 - (void)handleShieldTap {
-  [self.presentedViewController dismissViewControllerAnimated:YES
-                                                   completion:nil];
+  if (self.modalDelegate) {
+    // If a delegate is set, ask it for permission to dismiss, then ask it to
+    // handle the dismissal.
+    if ([self.modalDelegate
+            presentationControllerShouldDismissOnTouchOutside:self]) {
+      [self.modalDelegate presentationControllerWillDismiss:self];
+    }
+  } else {
+    // If no delegate is set, handle the dismissal directly.
+    [self.presentedViewController dismissViewControllerAnimated:YES
+                                                     completion:nil];
+  }
 }
 
 #pragma mark - Adaptivity
diff --git a/ios/chrome/browser/ui/table_view/table_view_presentation_controller_delegate.h b/ios/chrome/browser/ui/table_view/table_view_presentation_controller_delegate.h
new file mode 100644
index 0000000..9daf904
--- /dev/null
+++ b/ios/chrome/browser/ui/table_view/table_view_presentation_controller_delegate.h
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_PRESENTATION_CONTROLLER_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_PRESENTATION_CONTROLLER_DELEGATE_H_
+
+@class TableViewPresentationController;
+
+@protocol TableViewPresentationControllerDelegate
+
+// Returns YES if the presentation controller should dismiss its presented view
+// controller when the user touches outside the bounds of the presented view.
+- (BOOL)presentationControllerShouldDismissOnTouchOutside:
+    (TableViewPresentationController*)controller;
+
+// Informs the delegate that the user took an action that will result in the
+// dismissal of the presented view.  It is the delegate's responsibility to call
+// |dismissViewController:animated:|.
+- (void)presentationControllerWillDismiss:
+    (TableViewPresentationController*)controller;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_PRESENTATION_CONTROLLER_DELEGATE_H_
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 5618b5c..208080d 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -876,6 +876,8 @@
 void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
     base::Pickle* m,
     const param_type& p) {
+  // This serialization must be kept in sync with
+  // nacl_message_scanner.cc::WriteHandle().
   const bool valid = p.IsValid();
   WriteParam(m, valid);
 
@@ -1259,8 +1261,6 @@
                                                 const param_type& p) {
   DCHECK(!p.is_empty());
 
-  // This serialization must be kept in sync with
-  // nacl_message_scanner.cc:WriteHandle().
   ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
   ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
 }
diff --git a/media/blink/DEPS b/media/blink/DEPS
index ac48eba..c0f8ccc7 100644
--- a/media/blink/DEPS
+++ b/media/blink/DEPS
@@ -4,7 +4,6 @@
   "+cc/layers/video_layer.h",
   "+components/scheduler",  # Only allowed in tests.
   "+components/viz/common/gpu/context_provider.h",
-  "+components/viz/common/resources/shared_bitmap_manager.h",
   "+components/viz/common/surfaces/frame_sink_id.h",
   "+gin",
   "+media",
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc
index 3310d5a..767b405 100644
--- a/media/filters/decrypting_audio_decoder.cc
+++ b/media/filters/decrypting_audio_decoder.cc
@@ -94,7 +94,7 @@
 
   if (state_ == kUninitialized) {
     if (!cdm_context->GetDecryptor()) {
-      MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor";
+      DVLOG(1) << __func__ << ": no decryptor";
       base::ResetAndReturn(&init_cb_).Run(false);
       return;
     }
@@ -206,8 +206,7 @@
   DCHECK(decode_cb_.is_null());  // No Decode() before initialization finished.
 
   if (!success) {
-    MEDIA_LOG(DEBUG, media_log_)
-        << GetDisplayName() << ": failed to init decoder on decryptor";
+    DVLOG(1) << __func__ << ": failed to init audio decoder on decryptor";
     base::ResetAndReturn(&init_cb_).Run(false);
     decryptor_ = NULL;
     state_ = kError;
@@ -276,10 +275,11 @@
   if (status == Decryptor::kNoKey) {
     std::string key_id =
         scoped_pending_buffer_to_decode->decrypt_config()->key_id();
-    std::string missing_key_id = base::HexEncode(key_id.data(), key_id.size());
-    DVLOG(1) << "DeliverFrame() - no key for key ID " << missing_key_id;
-    MEDIA_LOG(DEBUG, media_log_)
-        << GetDisplayName() << ": no key for key ID " << missing_key_id;
+    std::string log_message =
+        "no key for key ID " + base::HexEncode(key_id.data(), key_id.size()) +
+        "; will resume decoding after new usable key is available";
+    DVLOG(1) << __func__ << ": " << log_message;
+    MEDIA_LOG(INFO, media_log_) << GetDisplayName() << ": " << log_message;
 
     // Set |pending_buffer_to_decode_| back as we need to try decoding the
     // pending buffer again when new key is added to the decryptor.
diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc
index 853c9ce..12de15c 100644
--- a/media/filters/decrypting_demuxer_stream.cc
+++ b/media/filters/decrypting_demuxer_stream.cc
@@ -58,7 +58,7 @@
   InitializeDecoderConfig();
 
   if (!cdm_context->GetDecryptor()) {
-    DVLOG(2) << __func__ << ": no decryptor";
+    DVLOG(1) << __func__ << ": no decryptor";
     state_ = kUninitialized;
     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
     return;
@@ -273,10 +273,12 @@
 
   if (status == Decryptor::kNoKey) {
     std::string key_id = pending_buffer_to_decrypt_->decrypt_config()->key_id();
-    std::string missing_key_id = base::HexEncode(key_id.data(), key_id.size());
-    DVLOG(1) << "DeliverBuffer() - no key for key ID " << missing_key_id;
-    MEDIA_LOG(INFO, media_log_)
-        << GetDisplayName() << ": no key for key ID " << missing_key_id;
+
+    std::string log_message =
+        "no key for key ID " + base::HexEncode(key_id.data(), key_id.size()) +
+        "; will resume decrypting after new usable key is available";
+    DVLOG(1) << __func__ << ": " << log_message;
+    MEDIA_LOG(INFO, media_log_) << GetDisplayName() << ": " << log_message;
 
     if (need_to_try_again_if_nokey) {
       // The |state_| is still kPendingDecrypt.
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc
index 03d1dad..132e58e 100644
--- a/media/filters/decrypting_video_decoder.cc
+++ b/media/filters/decrypting_video_decoder.cc
@@ -80,7 +80,7 @@
 
   if (state_ == kUninitialized) {
     if (!cdm_context->GetDecryptor()) {
-      MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no decryptor";
+      DVLOG(1) << __func__ << ": no decryptor";
       base::ResetAndReturn(&init_cb_).Run(false);
       return;
     }
@@ -186,8 +186,7 @@
   DCHECK(decode_cb_.is_null());  // No Decode() before initialization finished.
 
   if (!success) {
-    MEDIA_LOG(DEBUG, media_log_)
-        << GetDisplayName() << ": failed to init decoder on decryptor";
+    DVLOG(1) << __func__ << ": failed to init video decoder on decryptor";
     base::ResetAndReturn(&init_cb_).Run(false);
     decryptor_ = NULL;
     state_ = kError;
@@ -259,10 +258,11 @@
   if (status == Decryptor::kNoKey) {
     std::string key_id =
         scoped_pending_buffer_to_decode->decrypt_config()->key_id();
-    std::string missing_key_id = base::HexEncode(key_id.data(), key_id.size());
-    DVLOG(1) << "DeliverFrame() - no key for key ID " << missing_key_id;
-    MEDIA_LOG(INFO, media_log_)
-        << GetDisplayName() << ": no key for key ID " << missing_key_id;
+    std::string log_message =
+        "no key for key ID " + base::HexEncode(key_id.data(), key_id.size()) +
+        "; will resume decoding after new usable key is available";
+    DVLOG(1) << __func__ << ": " << log_message;
+    MEDIA_LOG(INFO, media_log_) << GetDisplayName() << ": " << log_message;
 
     // Set |pending_buffer_to_decode_| back as we need to try decoding the
     // pending buffer again when new key is added to the decryptor.
diff --git a/mojo/public/tools/bindings/generators/js_templates/union_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/union_definition.tmpl
index 518cd906..ad857b2c 100644
--- a/mojo/public/tools/bindings/generators/js_templates/union_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/union_definition.tmpl
@@ -70,7 +70,7 @@
   ];
 
   var result = mutator_.mutateUnionField(this, mutators);
-  generated[result.field] = result.value;
+  this[result.field] = result.value;
   return this;
 }
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 9581979d..4466b1c 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -5531,6 +5531,10 @@
     ]
   }
 
+  if (enable_built_in_dns) {
+    sources += [ "url_request/http_with_dns_over_https_unittest.cc" ]
+  }
+
   if (use_v8_in_net) {
     deps += [ ":net_with_v8" ]
   } else {
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc
index 2848b56..33b22781 100644
--- a/net/base/address_tracker_linux.cc
+++ b/net/base/address_tracker_linux.cc
@@ -14,6 +14,7 @@
 #include "base/logging.h"
 #include "base/message_loop/message_loop_current.h"
 #include "base/posix/eintr_wrapper.h"
+#include "base/threading/scoped_blocking_call.h"
 #include "base/threading/thread_restrictions.h"
 #include "net/base/network_interfaces_linux.h"
 
@@ -290,24 +291,28 @@
   *tunnel_changed = false;
   char buffer[4096];
   bool first_loop = true;
-  for (;;) {
-    int rv = HANDLE_EINTR(recv(netlink_fd_,
-                               buffer,
-                               sizeof(buffer),
-                               // Block the first time through loop.
-                               first_loop ? 0 : MSG_DONTWAIT));
-    first_loop = false;
-    if (rv == 0) {
-      LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
-      return;
+  {
+    // If the loop below takes a long time to run, a new thread should added to
+    // the current thread pool to ensure forward progress of all tasks.
+    base::ScopedBlockingCall blocking_call(base::BlockingType::MAY_BLOCK);
+
+    for (;;) {
+      int rv = HANDLE_EINTR(recv(netlink_fd_, buffer, sizeof(buffer),
+                                 // Block the first time through loop.
+                                 first_loop ? 0 : MSG_DONTWAIT));
+      first_loop = false;
+      if (rv == 0) {
+        LOG(ERROR) << "Unexpected shutdown of NETLINK socket.";
+        return;
+      }
+      if (rv < 0) {
+        if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+          break;
+        PLOG(ERROR) << "Failed to recv from netlink socket";
+        return;
+      }
+      HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
     }
-    if (rv < 0) {
-      if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
-        break;
-      PLOG(ERROR) << "Failed to recv from netlink socket";
-      return;
-    }
-    HandleMessage(buffer, rv, address_changed, link_changed, tunnel_changed);
   }
   if (*link_changed || *address_changed)
     UpdateCurrentConnectionType();
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 619c3a1..127fda81a 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -20,6 +20,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
+#include "base/task_scheduler/lazy_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/default_tick_clock.h"
 #include "base/trace_event/trace_event.h"
@@ -51,6 +52,17 @@
 
 namespace {
 
+#if defined(OS_CHROMEOS)
+// SequencedTaskRunner to get the network id. A SequencedTaskRunner is used
+// rather than parallel tasks to avoid having many threads getting the network
+// id concurrently.
+base::LazySequencedTaskRunner g_get_network_id_task_runner =
+    LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER(
+        base::TaskTraits(base::MayBlock(),
+                         base::TaskPriority::BACKGROUND,
+                         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
+#endif
+
 NetworkQualityObservationSource ProtocolSourceToObservationSource(
     SocketPerformanceWatcherFactory::Protocol protocol) {
   switch (protocol) {
@@ -702,28 +714,30 @@
 void NetworkQualityEstimator::GatherEstimatesForNextConnectionType() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (!get_network_id_task_runner_) {
-    ContinueGatherEstimatesForNextConnectionType(GetCurrentNetworkID());
+#if defined(OS_CHROMEOS)
+  if (get_network_id_asynchronously_) {
+    // Doing PostTaskAndReplyWithResult by handle because it requires the result
+    // type have a default constructor and nqe::internal::NetworkID does not
+    // have that.
+    g_get_network_id_task_runner.Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            [](scoped_refptr<base::TaskRunner> reply_task_runner,
+               base::OnceCallback<void(const nqe::internal::NetworkID&)>
+                   reply_callback) {
+              reply_task_runner->PostTask(
+                  FROM_HERE, base::BindOnce(std::move(reply_callback),
+                                            DoGetCurrentNetworkID()));
+            },
+            base::ThreadTaskRunnerHandle::Get(),
+            base::BindOnce(&NetworkQualityEstimator::
+                               ContinueGatherEstimatesForNextConnectionType,
+                           weak_ptr_factory_.GetWeakPtr())));
     return;
   }
+#endif  // defined(OS_CHROMEOS)
 
-  // Doing PostTaskAndReplyWithResult by handle because it requires the result
-  // type have a default constructor and nqe::internal::NetworkID does not have
-  // that.
-  get_network_id_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          [](scoped_refptr<base::TaskRunner> reply_task_runner,
-             base::OnceCallback<void(const nqe::internal::NetworkID&)>
-                 reply_callback) {
-            reply_task_runner->PostTask(
-                FROM_HERE, base::BindOnce(std::move(reply_callback),
-                                          DoGetCurrentNetworkID()));
-          },
-          base::ThreadTaskRunnerHandle::Get(),
-          base::BindOnce(&NetworkQualityEstimator::
-                             ContinueGatherEstimatesForNextConnectionType,
-                         weak_ptr_factory_.GetWeakPtr())));
+  ContinueGatherEstimatesForNextConnectionType(GetCurrentNetworkID());
 }
 
 void NetworkQualityEstimator::ContinueGatherEstimatesForNextConnectionType(
@@ -1684,6 +1698,12 @@
   ReadCachedNetworkQualityEstimate();
 }
 
+#if defined(OS_CHROMEOS)
+void NetworkQualityEstimator::EnableGetNetworkIdAsynchronously() {
+  get_network_id_asynchronously_ = true;
+}
+#endif  // defined(OS_CHROMEOS)
+
 base::Optional<base::TimeDelta> NetworkQualityEstimator::GetHttpRTT() const {
   DCHECK(thread_checker_.CalledOnValidThread());
 
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
index 342462fc..df96745 100644
--- a/net/nqe/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -21,6 +21,7 @@
 #include "base/optional.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "net/base/net_export.h"
 #include "net/base/network_change_notifier.h"
 #include "net/log/net_log_with_source.h"
@@ -41,7 +42,6 @@
 
 namespace base {
 class TickClock;
-class TaskRunner;
 }  // namespace base
 
 namespace net {
@@ -214,14 +214,18 @@
 
   const NetworkQualityEstimatorParams* params() { return params_.get(); }
 
+#if defined(OS_CHROMEOS)
+  // Enables getting the network id asynchronously when
+  // GatherEstimatesForNextConnectionType(). This should always be called in
+  // production, because getting the network id involves a blocking call to
+  // recv() in AddressTrackerLinux, and the IO thread should never be blocked.
+  // TODO(https://crbug.com/821607): Remove after the bug is resolved.
+  void EnableGetNetworkIdAsynchronously();
+#endif  // defined(OS_CHROMEOS)
+
   typedef nqe::internal::Observation Observation;
   typedef nqe::internal::ObservationBuffer ObservationBuffer;
 
-  void set_get_network_id_task_runner(
-      scoped_refptr<base::TaskRunner> task_runner) {
-    get_network_id_task_runner_ = task_runner;
-  }
-
  protected:
   // NetworkChangeNotifier::ConnectionTypeObserver implementation:
   void OnConnectionTypeChanged(
@@ -490,7 +494,7 @@
   void GatherEstimatesForNextConnectionType();
 
   // Invoked to continue GatherEstimatesForNextConnectionType work after getting
-  // network id. If |get_network_id_task_runner_| is set, the network id is
+  // network id. If |get_network_id_asynchronously_| is set, the network id is
   // fetched on a worker thread. Otherwise, GatherEstimatesForNextConnectionType
   // calls this directly. This is a workaround for https://crbug.com/821607
   // where net::GetWifiSSID() call gets stuck.
@@ -627,8 +631,10 @@
   // Time when the last RTT observation from a socket watcher was received.
   base::TimeTicks last_socket_watcher_rtt_notification_;
 
-  // Optional task runner to get network id.
-  scoped_refptr<base::TaskRunner> get_network_id_task_runner_;
+#if defined(OS_CHROMEOS)
+  // Whether the network id should be obtained on a worker thread.
+  bool get_network_id_asynchronously_ = false;
+#endif
 
   base::WeakPtrFactory<NetworkQualityEstimator> weak_ptr_factory_;
 
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 8e7fd38..005bb26 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -278,7 +278,6 @@
   CleanupIdleSockets(false);
 
   request->net_log().BeginEvent(NetLogEventType::SOCKET_POOL);
-  Group* group = GetOrCreateGroup(group_name);
 
   int rv = RequestSocketInternal(group_name, *request);
   if (rv != ERR_IO_PENDING) {
@@ -290,6 +289,7 @@
     CHECK(!request->handle()->is_initialized());
     request.reset();
   } else {
+    Group* group = GetOrCreateGroup(group_name);
     group->InsertPendingRequest(std::move(request));
     // Have to do this asynchronously, as closing sockets in higher level pools
     // call back in to |this|, which will cause all sorts of fun and exciting
@@ -362,30 +362,35 @@
     const Request& request) {
   ClientSocketHandle* const handle = request.handle();
   const bool preconnecting = !handle;
-  Group* group = GetOrCreateGroup(group_name);
 
-  if (!(request.flags() & NO_IDLE_SOCKETS)) {
-    // Try to reuse a socket.
-    if (AssignIdleSocketToRequest(request, group))
-      return OK;
-  }
+  Group* group = nullptr;
+  GroupMap::iterator group_it = group_map_.find(group_name);
+  if (group_it != group_map_.end()) {
+    group = group_it->second;
 
-  // If there are more ConnectJobs than pending requests, don't need to do
-  // anything.  Can just wait for the extra job to connect, and then assign it
-  // to the request.
-  if (!preconnecting && group->TryToUseUnassignedConnectJob())
-    return ERR_IO_PENDING;
+    if (!(request.flags() & NO_IDLE_SOCKETS)) {
+      // Try to reuse a socket.
+      if (AssignIdleSocketToRequest(request, group))
+        return OK;
+    }
 
-  // Can we make another active socket now?
-  if (!group->HasAvailableSocketSlot(max_sockets_per_group_) &&
-      request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) {
-    // TODO(willchan): Consider whether or not we need to close a socket in a
-    // higher layered group. I don't think this makes sense since we would just
-    // reuse that socket then if we needed one and wouldn't make it down to this
-    // layer.
-    request.net_log().AddEvent(
-        NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP);
-    return ERR_IO_PENDING;
+    // If there are more ConnectJobs than pending requests, don't need to do
+    // anything.  Can just wait for the extra job to connect, and then assign it
+    // to the request.
+    if (!preconnecting && group->TryToUseUnassignedConnectJob())
+      return ERR_IO_PENDING;
+
+    // Can we make another active socket now?
+    if (!group->HasAvailableSocketSlot(max_sockets_per_group_) &&
+        request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) {
+      // TODO(willchan): Consider whether or not we need to close a socket in a
+      // higher layered group. I don't think this makes sense since we would
+      // just reuse that socket then if we needed one and wouldn't make it down
+      // to this layer.
+      request.net_log().AddEvent(
+          NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP);
+      return ERR_IO_PENDING;
+    }
   }
 
   if (ReachedMaxSocketsLimit() &&
@@ -394,14 +399,16 @@
     // here.  Only reason for them now seems to be preconnects.
     if (idle_socket_count() > 0) {
       // There's an idle socket in this pool. Either that's because there's
-      // still one in this group, but we got here due to preconnecting bypassing
-      // idle sockets, or because there's an idle socket in another group.
+      // still one in this group, but we got here due to preconnecting
+      // bypassing idle sockets, or because there's an idle socket in another
+      // group.
       bool closed = CloseOneIdleSocketExceptInGroup(group);
       if (preconnecting && !closed)
         return ERR_PRECONNECT_MAX_SOCKET_LIMIT;
     } else {
-      // We could check if we really have a stalled group here, but it requires
-      // a scan of all groups, so just flip a flag here, and do the check later.
+      // We could check if we really have a stalled group here, but it
+      // requires a scan of all groups, so just flip a flag here, and do the
+      // check later.
       request.net_log().AddEvent(
           NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS);
       return ERR_IO_PENDING;
@@ -419,14 +426,15 @@
     if (!preconnecting) {
       HandOutSocket(connect_job->PassSocket(), ClientSocketHandle::UNUSED,
                     connect_job->connect_timing(), handle, base::TimeDelta(),
-                    group, request.net_log());
+                    GetOrCreateGroup(group_name), request.net_log());
     } else {
-      AddIdleSocket(connect_job->PassSocket(), group);
+      AddIdleSocket(connect_job->PassSocket(), GetOrCreateGroup(group_name));
     }
   } else if (rv == ERR_IO_PENDING) {
     // If we don't have any sockets in this group, set a timer for potentially
     // creating a new one.  If the SYN is lost, this backup socket may complete
     // before the slow socket, improving end user latency.
+    Group* group = GetOrCreateGroup(group_name);
     if (connect_backup_jobs_enabled_ && group->IsEmpty()) {
       group->StartBackupJobTimer(group_name, this);
     }
@@ -442,6 +450,7 @@
       connect_job->GetAdditionalErrorState(handle);
       error_socket = connect_job->PassSocket();
     }
+    Group* group = GetOrCreateGroup(group_name);
     if (error_socket) {
       HandOutSocket(std::move(error_socket), ClientSocketHandle::UNUSED,
                     connect_job->connect_timing(), handle, base::TimeDelta(),
diff --git a/net/url_request/http_with_dns_over_https_unittest.cc b/net/url_request/http_with_dns_over_https_unittest.cc
new file mode 100644
index 0000000..050e4ff
--- /dev/null
+++ b/net/url_request/http_with_dns_over_https_unittest.cc
@@ -0,0 +1,230 @@
+// 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 "net/dns/dns_client.h"
+#include "net/dns/dns_transaction.h"
+#include "net/dns/host_resolver_impl.h"
+#include "net/http/http_stream_factory_test_util.h"
+#include "net/log/net_log.h"
+#include "net/socket/transport_client_socket_pool.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/test/test_with_scoped_task_environment.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace net {
+namespace {
+
+const size_t kHeaderSize = sizeof(dns_protocol::Header);
+const char kTestBody[] = "<html><body>TEST RESPONSE</body></html>";
+
+class TestHostResolverProc : public HostResolverProc {
+ public:
+  TestHostResolverProc() : HostResolverProc(nullptr) {}
+
+  int Resolve(const std::string& hostname,
+              AddressFamily address_family,
+              HostResolverFlags host_resolver_flags,
+              AddressList* addrlist,
+              int* os_error) override {
+    return ERR_NAME_NOT_RESOLVED;
+  }
+
+ private:
+  ~TestHostResolverProc() override {}
+};
+
+class HttpWithDnsOverHttpsTest : public TestWithScopedTaskEnvironment {
+ public:
+  HttpWithDnsOverHttpsTest()
+      : resolver_(HostResolver::Options(), nullptr),
+        request_context_(true),
+        doh_server_(EmbeddedTestServer::Type::TYPE_HTTPS),
+        test_server_(EmbeddedTestServer::Type::TYPE_HTTPS),
+        doh_queries_served_(0),
+        test_requests_served_(0) {
+    doh_server_.RegisterRequestHandler(
+        base::BindRepeating(&HttpWithDnsOverHttpsTest::HandleDefaultConnect,
+                            base::Unretained(this)));
+    test_server_.RegisterRequestHandler(
+        base::BindRepeating(&HttpWithDnsOverHttpsTest::HandleDefaultConnect,
+                            base::Unretained(this)));
+    EXPECT_TRUE(doh_server_.Start());
+    EXPECT_TRUE(test_server_.Start());
+    GURL url(doh_server_.GetURL("/dns_query"));
+    std::unique_ptr<DnsClient> dns_client(DnsClient::CreateClient(nullptr));
+    DnsConfig config;
+    config.nameservers.push_back(IPEndPoint());
+    config.dns_over_https_servers.emplace_back(url, true);
+    dns_client->SetConfig(config);
+    resolver_.SetRequestContext(&request_context_);
+    resolver_.set_proc_params_for_test(
+        HostResolverImpl::ProcTaskParams(new TestHostResolverProc(), 1));
+    resolver_.SetDnsClient(std::move(dns_client));
+    request_context_.set_host_resolver(&resolver_);
+    request_context_.Init();
+  }
+
+  URLRequestContext* context() { return &request_context_; }
+
+  std::unique_ptr<test_server::HttpResponse> HandleDefaultConnect(
+      const test_server::HttpRequest& request) {
+    if (request.relative_url.compare("/dns_query") == 0) {
+      doh_queries_served_++;
+      uint8_t id1 = request.content[0];
+      uint8_t id2 = request.content[1];
+      std::unique_ptr<test_server::BasicHttpResponse> http_response(
+          new test_server::BasicHttpResponse);
+      const uint8_t header_data[] = {
+          id1,  id2,   // - Same ID as before
+          0x81, 0x80,  // - Different flags, we'll look at this below
+          0x00, 0x01,  // - 1 question
+          0x00, 0x01,  // - 1 answer
+          0x00, 0x00,  // - No authority records
+          0x00, 0x00,  // - No additional records
+      };
+      std::string question = request.content.substr(kHeaderSize);
+
+      const uint8_t answer_data[]{0xC0, 0x0C,  // - NAME
+                                  0x00, 0x01,  // - TYPE
+                                  0x00, 0x01,  // - CLASS
+                                  0x00, 0x00,  //
+                                  0x18, 0x4C,  // - TTL
+                                  0x00, 0x04,  // - RDLENGTH = 4 bytes
+                                  0x7f, 0x00,  // - RDDATA, IP is 127.0.0.1
+                                  0x00, 0x01};
+      http_response->set_content(
+          std::string((char*)header_data, sizeof(header_data)) + question +
+          std::string((char*)answer_data, sizeof(answer_data)));
+      http_response->set_content_type("application/dns-udpwireformat");
+      return std::move(http_response);
+    } else {
+      test_requests_served_++;
+      std::unique_ptr<test_server::BasicHttpResponse> http_response(
+          new test_server::BasicHttpResponse);
+      http_response->set_content(kTestBody);
+      http_response->set_content_type("text/html");
+      return std::move(http_response);
+    }
+  }
+
+ protected:
+  HostResolverImpl resolver_;
+  TestURLRequestContext request_context_;
+  EmbeddedTestServer doh_server_;
+  EmbeddedTestServer test_server_;
+  uint32_t doh_queries_served_;
+  uint32_t test_requests_served_;
+};
+
+class TestHttpDelegate : public HttpStreamRequest::Delegate {
+ public:
+  TestHttpDelegate(base::RunLoop* loop) : loop_(loop) {}
+  ~TestHttpDelegate() override {}
+  void OnStreamReady(const SSLConfig& used_ssl_config,
+                     const ProxyInfo& used_proxy_info,
+                     std::unique_ptr<HttpStream> stream) override {
+    stream->Close(false);
+    loop_->Quit();
+  }
+
+  void OnWebSocketHandshakeStreamReady(
+      const SSLConfig& used_ssl_config,
+      const ProxyInfo& used_proxy_info,
+      std::unique_ptr<WebSocketHandshakeStreamBase> stream) override {}
+
+  void OnBidirectionalStreamImplReady(
+      const SSLConfig& used_ssl_config,
+      const ProxyInfo& used_proxy_info,
+      std::unique_ptr<BidirectionalStreamImpl> stream) override {}
+
+  void OnStreamFailed(int status,
+                      const NetErrorDetails& net_error_details,
+                      const SSLConfig& used_ssl_config) override {}
+
+  void OnCertificateError(int status,
+                          const SSLConfig& used_ssl_config,
+                          const SSLInfo& ssl_info) override {}
+
+  void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
+                        const SSLConfig& used_ssl_config,
+                        const ProxyInfo& used_proxy_info,
+                        HttpAuthController* auth_controller) override {}
+
+  void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
+                         SSLCertRequestInfo* cert_info) override {}
+
+  void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
+                                  const SSLConfig& used_ssl_config,
+                                  const ProxyInfo& used_proxy_info,
+                                  std::unique_ptr<HttpStream> stream) override {
+  }
+
+  void OnQuicBroken() override {}
+
+ private:
+  base::RunLoop* loop_;
+};
+
+// This test sets up a request which will reenter the connection pools by
+// triggering a DNS over HTTPS request. It also sets up an idle socket
+// which was a precondition for the crash we saw in  https://crbug.com/830917.
+TEST_F(HttpWithDnsOverHttpsTest, EndToEnd) {
+  // Create and start http server.
+  EmbeddedTestServer http_server(EmbeddedTestServer::Type::TYPE_HTTP);
+  http_server.RegisterRequestHandler(base::BindRepeating(
+      &HttpWithDnsOverHttpsTest::HandleDefaultConnect, base::Unretained(this)));
+  EXPECT_TRUE(http_server.Start());
+
+  // Set up an idle socket.
+  HttpTransactionFactory* transaction_factory =
+      request_context_.http_transaction_factory();
+  HttpStreamFactory::JobFactory default_job_factory;
+  HttpNetworkSession* network_session = transaction_factory->GetSession();
+  base::RunLoop loop;
+  TestHttpDelegate request_delegate(&loop);
+
+  HttpStreamFactory* factory = network_session->http_stream_factory();
+  HttpRequestInfo request_info;
+  request_info.method = "GET";
+  request_info.url = http_server.GetURL("localhost", "/preconnect");
+
+  std::unique_ptr<HttpStreamRequest> request(factory->RequestStream(
+      request_info, DEFAULT_PRIORITY, SSLConfig(), SSLConfig(),
+      &request_delegate, false, false, NetLogWithSource()));
+  loop.Run();
+
+  std::string group_name(request_info.url.host() + ":" +
+                         request_info.url.port());
+  EXPECT_EQ(network_session
+                ->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
+                ->IdleSocketCountInGroup(group_name),
+            1);
+
+  // Make a request that will trigger a DoH query as well.
+  TestDelegate d;
+  d.set_allow_certificate_errors(true);
+  GURL main_url = test_server_.GetURL("bar.example.com", "/test");
+  std::unique_ptr<URLRequest> req(context()->CreateRequest(
+      main_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+  req->Start();
+  base::RunLoop().Run();
+  EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
+  EXPECT_TRUE(http_server.ShutdownAndWaitUntilComplete());
+  EXPECT_TRUE(doh_server_.ShutdownAndWaitUntilComplete());
+  EXPECT_EQ(doh_queries_served_, 2u);
+  EXPECT_EQ(test_requests_served_, 1u);
+  EXPECT_TRUE(d.response_completed());
+  EXPECT_EQ(d.request_status(), 0);
+  EXPECT_EQ(d.data_received(), kTestBody);
+}
+
+}  // namespace
+}  // namespace net
diff --git a/ppapi/proxy/nacl_message_scanner.cc b/ppapi/proxy/nacl_message_scanner.cc
index b6f04d6..4fae6974 100644
--- a/ppapi/proxy/nacl_message_scanner.cc
+++ b/ppapi/proxy/nacl_message_scanner.cc
@@ -62,17 +62,32 @@
   if (handle.type() == SerializedHandle::SHARED_MEMORY) {
     // Now write the handle itself in POSIX style.
     // This serialization must be kept in sync with
-    // ParamTraits<SharedMemoryHandle>::Write and
-    // ParamTraits<UnguessableToken>::Write.
+    // ParamTraits<SharedMemoryHandle>::Write.
     if (handle.shmem().IsValid()) {
       msg->WriteBool(true);  // valid == true
       msg->WriteInt(handle_index);
-      msg->WriteUInt64(handle.shmem().GetGUID().GetHighForSerialization());
-      msg->WriteUInt64(handle.shmem().GetGUID().GetLowForSerialization());
+      IPC::WriteParam(msg, handle.shmem().GetGUID());
       msg->WriteUInt64(handle.shmem().GetSize());
     } else {
       msg->WriteBool(false);  // valid == false
     }
+  } else if (handle.type() == SerializedHandle::SHARED_MEMORY_REGION) {
+    // Write the region in POSIX style.
+    // This serialization must be kept in sync with
+    // ParamTraits<PlatformSharedMemoryRegion>::Write.
+    const auto& region = handle.shmem_region();
+    if (region.IsValid()) {
+      IPC::WriteParam(msg, true);  // valid == true
+      IPC::WriteParam(msg, region.GetMode());
+      IPC::WriteParam(msg, static_cast<uint64_t>(region.GetSize()));
+      IPC::WriteParam(msg, region.GetGUID());
+      // Writable regions are not supported, so write only one handle index.
+      DCHECK_NE(region.GetMode(),
+                base::subtle::PlatformSharedMemoryRegion::Mode::kWritable);
+      IPC::WriteParam(msg, handle_index);
+    } else {
+      msg->WriteBool(false);  // valid == false
+    }
   } else if (handle.type() != SerializedHandle::INVALID) {
     // Now write the handle itself in POSIX style.
     // This serialization must be kept in sync with
diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc
index 822c61f..b663e82 100644
--- a/ppapi/proxy/ppapi_param_traits.cc
+++ b/ppapi/proxy/ppapi_param_traits.cc
@@ -238,6 +238,9 @@
     case ppapi::proxy::SerializedHandle::SHARED_MEMORY:
       WriteParam(m, p.shmem());
       break;
+    case ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION:
+      WriteParam(m, const_cast<param_type&>(p).TakeSharedMemoryRegion());
+      break;
     case ppapi::proxy::SerializedHandle::SOCKET:
     case ppapi::proxy::SerializedHandle::FILE:
       WriteParam(m, p.descriptor());
@@ -259,33 +262,37 @@
   switch (header.type) {
     case ppapi::proxy::SerializedHandle::SHARED_MEMORY: {
       base::SharedMemoryHandle handle;
-      if (ReadParam(m, iter, &handle)) {
-        r->set_shmem(handle, header.size);
-        return true;
-      }
+      if (!ReadParam(m, iter, &handle))
+        return false;
+      r->set_shmem(handle, header.size);
+      break;
+    }
+    case ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION: {
+      base::subtle::PlatformSharedMemoryRegion region;
+      if (!ReadParam(m, iter, &region))
+        return false;
+      r->set_shmem_region(std::move(region));
       break;
     }
     case ppapi::proxy::SerializedHandle::SOCKET: {
       IPC::PlatformFileForTransit socket;
-      if (ReadParam(m, iter, &socket)) {
-        r->set_socket(socket);
-        return true;
-      }
+      if (!ReadParam(m, iter, &socket))
+        return false;
+      r->set_socket(socket);
       break;
     }
     case ppapi::proxy::SerializedHandle::FILE: {
       IPC::PlatformFileForTransit desc;
-      if (ReadParam(m, iter, &desc)) {
-        r->set_file_handle(desc, header.open_flags, header.file_io);
-        return true;
-      }
+      if (!ReadParam(m, iter, &desc))
+        return false;
+      r->set_file_handle(desc, header.open_flags, header.file_io);
       break;
     }
     case ppapi::proxy::SerializedHandle::INVALID:
-      return true;
-    // No default so the compiler will warn us if a new type is added.
+      break;
+      // No default so the compiler will warn us if a new type is added.
   }
-  return false;
+  return true;
 }
 
 // static
diff --git a/ppapi/proxy/serialized_handle.cc b/ppapi/proxy/serialized_handle.cc
index 13811b5..92f945d 100644
--- a/ppapi/proxy/serialized_handle.cc
+++ b/ppapi/proxy/serialized_handle.cc
@@ -29,6 +29,7 @@
     : type_(other.type_),
       shm_handle_(other.shm_handle_),
       size_(other.size_),
+      shm_region_(std::move(other.shm_region_)),
       descriptor_(other.descriptor_),
       open_flags_(other.open_flags_),
       file_io_(other.file_io_) {
@@ -40,6 +41,7 @@
   type_ = other.type_;
   shm_handle_ = other.shm_handle_;
   size_ = other.size_;
+  shm_region_ = std::move(other.shm_region_);
   descriptor_ = other.descriptor_;
   open_flags_ = other.open_flags_;
   file_io_ = other.file_io_;
@@ -65,6 +67,19 @@
       file_io_(0) {}
 
 SerializedHandle::SerializedHandle(
+    base::subtle::PlatformSharedMemoryRegion region)
+    : type_(SHARED_MEMORY_REGION),
+      size_(0),
+      shm_region_(std::move(region)),
+      descriptor_(IPC::InvalidPlatformFileForTransit()),
+      open_flags_(0),
+      file_io_(0) {
+  // Writable regions are not supported.
+  DCHECK_NE(shm_region_.GetMode(),
+            base::subtle::PlatformSharedMemoryRegion::Mode::kWritable);
+}
+
+SerializedHandle::SerializedHandle(
     Type type,
     const IPC::PlatformFileForTransit& socket_descriptor)
     : type_(type),
@@ -78,6 +93,8 @@
   switch (type_) {
     case SHARED_MEMORY:
       return base::SharedMemory::IsHandleValid(shm_handle_);
+    case SHARED_MEMORY_REGION:
+      return shm_region_.IsValid();
     case SOCKET:
     case FILE:
       return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
@@ -97,6 +114,9 @@
       case SHARED_MEMORY:
         base::SharedMemory::CloseHandle(shm_handle_);
         break;
+      case SHARED_MEMORY_REGION:
+        shm_region_ = base::subtle::PlatformSharedMemoryRegion();
+        break;
       case SOCKET:
       case FILE:
         base::File file_closer = IPC::PlatformFileForTransitToFile(descriptor_);
@@ -144,6 +164,7 @@
       valid_type = true;
       break;
     }
+    case SHARED_MEMORY_REGION:
     case SOCKET:
     case INVALID:
       valid_type = true;
diff --git a/ppapi/proxy/serialized_handle.h b/ppapi/proxy/serialized_handle.h
index cc1c6b4..c82008a3 100644
--- a/ppapi/proxy/serialized_handle.h
+++ b/ppapi/proxy/serialized_handle.h
@@ -12,6 +12,7 @@
 
 #include "base/atomicops.h"
 #include "base/logging.h"
+#include "base/memory/platform_shared_memory_region.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/shared_memory.h"
 #include "build/build_config.h"
@@ -32,7 +33,9 @@
 // NaClIPCAdapter for use in NaCl.
 class PPAPI_PROXY_EXPORT SerializedHandle {
  public:
-  enum Type { INVALID, SHARED_MEMORY, SOCKET, FILE };
+  // TODO(https://crbug.com/845985): Remove SHARED_MEMORY type after all clients
+  // will be converted to the SHARED_MEMORY_REGION.
+  enum Type { INVALID, SHARED_MEMORY, SHARED_MEMORY_REGION, SOCKET, FILE };
   // Header contains the fields that we send in IPC messages, apart from the
   // actual handle. See comments on the SerializedHandle fields below.
   struct Header {
@@ -62,12 +65,16 @@
   // Create a shared memory handle.
   SerializedHandle(const base::SharedMemoryHandle& handle, uint32_t size);
 
+  // Create a shared memory region handle.
+  explicit SerializedHandle(base::subtle::PlatformSharedMemoryRegion region);
+
   // Create a socket or file handle.
   SerializedHandle(const Type type,
                    const IPC::PlatformFileForTransit& descriptor);
 
   Type type() const { return type_; }
   bool is_shmem() const { return type_ == SHARED_MEMORY; }
+  bool is_shmem_region() const { return type_ == SHARED_MEMORY_REGION; }
   bool is_socket() const { return type_ == SOCKET; }
   bool is_file() const { return type_ == FILE; }
   const base::SharedMemoryHandle& shmem() const {
@@ -78,6 +85,14 @@
     DCHECK(is_shmem());
     return size_;
   }
+  const base::subtle::PlatformSharedMemoryRegion& shmem_region() const {
+    DCHECK(is_shmem_region());
+    return shm_region_;
+  }
+  base::subtle::PlatformSharedMemoryRegion TakeSharedMemoryRegion() {
+    DCHECK(is_shmem_region());
+    return std::move(shm_region_);
+  }
   const IPC::PlatformFileForTransit& descriptor() const {
     DCHECK(is_socket() || is_file());
     return descriptor_;
@@ -92,11 +107,24 @@
     size_ = size;
 
     descriptor_ = IPC::InvalidPlatformFileForTransit();
+    shm_region_ = base::subtle::PlatformSharedMemoryRegion();
+  }
+  void set_shmem_region(base::subtle::PlatformSharedMemoryRegion region) {
+    type_ = SHARED_MEMORY_REGION;
+    shm_region_ = std::move(region);
+    // Writable regions are not supported.
+    DCHECK_NE(shm_region_.GetMode(),
+              base::subtle::PlatformSharedMemoryRegion::Mode::kWritable);
+
+    descriptor_ = IPC::InvalidPlatformFileForTransit();
+    shm_handle_ = base::SharedMemoryHandle();
+    size_ = 0;
   }
   void set_socket(const IPC::PlatformFileForTransit& socket) {
     type_ = SOCKET;
     descriptor_ = socket;
 
+    shm_region_ = base::subtle::PlatformSharedMemoryRegion();
     shm_handle_ = base::SharedMemoryHandle();
     size_ = 0;
   }
@@ -106,6 +134,7 @@
     type_ = FILE;
 
     descriptor_ = descriptor;
+    shm_region_ = base::subtle::PlatformSharedMemoryRegion();
     shm_handle_ = base::SharedMemoryHandle();
     size_ = 0;
     open_flags_ = open_flags;
@@ -115,6 +144,7 @@
     type_ = INVALID;
 
     shm_handle_ = base::SharedMemoryHandle();
+    shm_region_ = base::subtle::PlatformSharedMemoryRegion();
     size_ = 0;
     descriptor_ = IPC::InvalidPlatformFileForTransit();
   }
@@ -152,6 +182,9 @@
   base::SharedMemoryHandle shm_handle_;
   uint32_t size_;
 
+  // This is valid if type == SHARED_MEMORY_REGION.
+  base::subtle::PlatformSharedMemoryRegion shm_region_;
+
   // This is valid if type == SOCKET || type == FILE.
   IPC::PlatformFileForTransit descriptor_;
 
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index e2f7a0b..4fe7beda 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -144,16 +144,10 @@
       net_log_);
 
 #if defined(OS_CHROMEOS)
-  // Set a task runner for the get network id call for NetworkQualityEstimator
-  // to workaround https://crbug.com/821607 where AddressTrackerLinux stucks
-  // with a recv() call and blocks IO thread. Using SingleThreadTaskRunner so
-  // that task scheduler does not create too many worker threads when the
-  // problem happens.
+  // Get network id asynchronously to workaround https://crbug.com/821607 where
+  // AddressTrackerLinux stucks with a recv() call and blocks IO thread.
   // TODO(https://crbug.com/821607): Remove after the bug is resolved.
-  network_quality_estimator_->set_get_network_id_task_runner(
-      base::CreateSingleThreadTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::BACKGROUND,
-           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}));
+  network_quality_estimator_->EnableGetNetworkIdAsynchronously();
 #endif
 
   host_resolver_ = CreateHostResolver();
diff --git a/services/network/public/cpp/server/http_server.cc b/services/network/public/cpp/server/http_server.cc
index 0ceda27..d82d8e8 100644
--- a/services/network/public/cpp/server/http_server.cc
+++ b/services/network/public/cpp/server/http_server.cc
@@ -178,11 +178,6 @@
   return connection;
 }
 
-void HttpServer::GetLocalAddress(
-    mojom::TCPServerSocket::GetLocalAddressCallback callback) {
-  server_socket_->GetLocalAddress(std::move(callback));
-}
-
 void HttpServer::DoAcceptLoop() {
   server_socket_->Accept(
       nullptr, /* observer */
diff --git a/services/network/public/cpp/server/http_server.h b/services/network/public/cpp/server/http_server.h
index 3fc1d7b3..c02a3473 100644
--- a/services/network/public/cpp/server/http_server.h
+++ b/services/network/public/cpp/server/http_server.h
@@ -99,12 +99,6 @@
   bool SetReceiveBufferSize(int connection_id, int32_t size);
   bool SetSendBufferSize(int connection_id, int32_t size);
 
-  // Asynchronously gets the local address of this http server. On completion,
-  // |callback| will be called with a network error code and the local address
-  // as arguments.
-  void GetLocalAddress(
-      mojom::TCPServerSocket::GetLocalAddressCallback callback);
-
  private:
   friend class HttpServerTest;
 
diff --git a/services/network/public/cpp/server/http_server_unittest.cc b/services/network/public/cpp/server/http_server_unittest.cc
index 2211ebf..273aa92 100644
--- a/services/network/public/cpp/server/http_server_unittest.cc
+++ b/services/network/public/cpp/server/http_server_unittest.cc
@@ -189,16 +189,6 @@
     EXPECT_EQ(net::OK, net_error);
 
     server_.reset(new HttpServer(std::move(server_socket_), this));
-
-    base::RunLoop run_loop2;
-    server_->GetLocalAddress(base::BindOnce(
-        [](base::RunLoop* run_loop, int net_error,
-           const base::Optional<net::IPEndPoint>& server_addr) {
-          ASSERT_THAT(net_error, IsOk());
-          run_loop->Quit();
-        },
-        base::Unretained(&run_loop2)));
-    run_loop2.Run();
   }
 
   void OnConnect(int connection_id) override {
diff --git a/services/network/public/mojom/tcp_socket.mojom b/services/network/public/mojom/tcp_socket.mojom
index cd95494..b2d1439 100644
--- a/services/network/public/mojom/tcp_socket.mojom
+++ b/services/network/public/mojom/tcp_socket.mojom
@@ -16,13 +16,6 @@
 // during reading or writing to data pipes. Consumer can close the socket by
 // destroying the interface pointer.
 interface TCPConnectedSocket {
-  // Gets the local address of this connected socket. On success, |net_error| is
-  // net::OK and |local_addr| contains the local address of the socket. On
-  // failure, |local_addr| is null and |net_error| is a net error code.
-  // DEPRECATED: Please use the |local_addr| returned in
-  // CreateTCPConnectedSocketCallback.
-  GetLocalAddress() => (int32 net_error, net.interfaces.IPEndPoint? local_addr);
-
   // Upgrades a TCP socket to a TLS client socket. Caller can optionally specify
   // a TLSClientSocketOptions to configure the connection.
   // IMPORTANT: Caller needs close the previous send and receive pipes before
@@ -93,11 +86,4 @@
           TCPConnectedSocket? connected_socket,
           handle<data_pipe_consumer>? send_stream,
           handle<data_pipe_producer>? receive_stream);
-
-  // Gets the local address of this server socket. On success, |net_error| is
-  // net::OK and |local_addr| contains the local address of the socket. On
-  // failure, |local_addr| is null and |net_error| is a net error code.
-  // DEPRECATED: Please use the |local_addr| returned in
-  // CreateTCPServerSocketCallback.
-  GetLocalAddress() => (int32 net_error, net.interfaces.IPEndPoint? local_addr);
 };
diff --git a/services/network/tcp_connected_socket.cc b/services/network/tcp_connected_socket.cc
index e9db0cf..d8d6a1cd 100644
--- a/services/network/tcp_connected_socket.cc
+++ b/services/network/tcp_connected_socket.cc
@@ -9,7 +9,6 @@
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/optional.h"
-#include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/log/net_log.h"
 #include "net/socket/client_socket_factory.h"
@@ -73,18 +72,6 @@
   OnConnectCompleted(result);
 }
 
-void TCPConnectedSocket::GetLocalAddress(GetLocalAddressCallback callback) {
-  DCHECK(socket_);
-
-  net::IPEndPoint local_addr;
-  int result = socket_->GetLocalAddress(&local_addr);
-  if (result != net::OK) {
-    std::move(callback).Run(result, base::nullopt);
-    return;
-  }
-  std::move(callback).Run(result, local_addr);
-}
-
 void TCPConnectedSocket::UpgradeToTLS(
     const net::HostPortPair& host_port_pair,
     mojom::TLSClientSocketOptionsPtr socket_options,
diff --git a/services/network/tcp_connected_socket.h b/services/network/tcp_connected_socket.h
index 1926857..b3240b7 100644
--- a/services/network/tcp_connected_socket.h
+++ b/services/network/tcp_connected_socket.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "mojo/public/cpp/system/data_pipe.h"
-#include "mojo/public/cpp/system/simple_watcher.h"
 #include "net/base/address_family.h"
 #include "net/base/completion_callback.h"
 #include "net/base/ip_endpoint.h"
@@ -20,7 +19,7 @@
 #include "net/socket/tcp_client_socket.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/net_adapters.h"
-#include "services/network/public/mojom/network_service.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/tcp_socket.mojom.h"
 #include "services/network/socket_data_pump.h"
 
@@ -69,7 +68,6 @@
       mojom::NetworkContext::CreateTCPConnectedSocketCallback callback);
 
   // mojom::TCPConnectedSocket implementation.
-  void GetLocalAddress(GetLocalAddressCallback callback) override;
   void UpgradeToTLS(
       const net::HostPortPair& host_port_pair,
       mojom::TLSClientSocketOptionsPtr socket_options,
diff --git a/services/network/tcp_server_socket.cc b/services/network/tcp_server_socket.cc
index f7e15769..58ebfe81 100644
--- a/services/network/tcp_server_socket.cc
+++ b/services/network/tcp_server_socket.cc
@@ -60,18 +60,6 @@
     ProcessNextAccept();
 }
 
-void TCPServerSocket::GetLocalAddress(GetLocalAddressCallback callback) {
-  DCHECK(socket_);
-
-  net::IPEndPoint local_addr;
-  int result = socket_->GetLocalAddress(&local_addr);
-  if (result != net::OK) {
-    std::move(callback).Run(result, base::nullopt);
-    return;
-  }
-  std::move(callback).Run(result, local_addr);
-}
-
 void TCPServerSocket::SetSocketForTest(
     std::unique_ptr<net::ServerSocket> socket) {
   socket_ = std::move(socket);
diff --git a/services/network/tcp_server_socket.h b/services/network/tcp_server_socket.h
index e15223e9..6fde43c 100644
--- a/services/network/tcp_server_socket.h
+++ b/services/network/tcp_server_socket.h
@@ -56,7 +56,6 @@
   // TCPServerSocket implementation.
   void Accept(mojom::SocketObserverPtr observer,
               AcceptCallback callback) override;
-  void GetLocalAddress(GetLocalAddressCallback callback) override;
 
   // Replaces the underlying socket implementation with |socket| in tests.
   void SetSocketForTest(std::unique_ptr<net::ServerSocket> socket);
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_base.cc b/services/resource_coordinator/coordination_unit/coordination_unit_base.cc
index 1f45ff2..e4130ff 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_base.cc
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_base.cc
@@ -4,12 +4,62 @@
 
 #include "services/resource_coordinator/coordination_unit/coordination_unit_base.h"
 
+#include <unordered_map>
+
 #include "services/resource_coordinator/coordination_unit/coordination_unit_graph.h"
 #include "services/resource_coordinator/observers/coordination_unit_graph_observer.h"
 #include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
 
 namespace resource_coordinator {
 
+namespace {
+
+using CUIDMap = std::unordered_map<CoordinationUnitID,
+                                   std::unique_ptr<CoordinationUnitBase>>;
+
+CUIDMap& g_cu_map() {
+  static CUIDMap* instance = new CUIDMap();
+  return *instance;
+}
+
+}  // namespace
+
+// static
+CoordinationUnitBase* CoordinationUnitBase::AddNewCoordinationUnit(
+    std::unique_ptr<CoordinationUnitBase> new_cu) {
+  auto it = g_cu_map().emplace(new_cu->id(), std::move(new_cu));
+  DCHECK(it.second);  // Inserted successfully
+  return it.first->second.get();
+}
+
+// static
+std::vector<CoordinationUnitBase*>
+CoordinationUnitBase::GetCoordinationUnitsOfType(CoordinationUnitType type) {
+  std::vector<CoordinationUnitBase*> results;
+  for (auto& el : g_cu_map()) {
+    if (el.first.type == type)
+      results.push_back(el.second.get());
+  }
+  return results;
+}
+
+// static
+void CoordinationUnitBase::AssertNoActiveCoordinationUnits() {
+  CHECK(g_cu_map().empty());
+}
+
+// static
+void CoordinationUnitBase::ClearAllCoordinationUnits() {
+  g_cu_map().clear();
+}
+
+// static
+CoordinationUnitBase* CoordinationUnitBase::GetCoordinationUnitByID(
+    const CoordinationUnitID cu_id) {
+  auto cu_iter = g_cu_map().find(cu_id);
+  return cu_iter != g_cu_map().end() ? cu_iter->second.get() : nullptr;
+}
+
 CoordinationUnitBase::CoordinationUnitBase(const CoordinationUnitID& id,
                                            CoordinationUnitGraph* graph)
     : graph_(graph), id_(id.type, id.id) {}
@@ -17,7 +67,9 @@
 CoordinationUnitBase::~CoordinationUnitBase() = default;
 
 void CoordinationUnitBase::Destruct() {
-  graph_->DestroyCoordinationUnit(this);
+  size_t erased_count = g_cu_map().erase(id_);
+  // After this point |this| is destructed and should not be accessed anymore.
+  DCHECK_EQ(erased_count, 1u);
 }
 
 void CoordinationUnitBase::BeforeDestroyed() {
@@ -78,10 +130,4 @@
   OnPropertyChanged(property_type, value);
 }
 
-// static
-CoordinationUnitBase* CoordinationUnitBase::PassOwnershipToGraph(
-    std::unique_ptr<CoordinationUnitBase> new_cu) {
-  return new_cu->graph()->AddNewCoordinationUnit(std::move(new_cu));
-}
-
 }  // namespace resource_coordinator
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_base.h b/services/resource_coordinator/coordination_unit/coordination_unit_base.h
index 57e55e07..2f0b91e 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_base.h
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_base.h
@@ -12,7 +12,6 @@
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/resource_coordinator/coordination_unit/coordination_unit_graph.h"
 #include "services/resource_coordinator/observers/coordination_unit_graph_observer.h"
 #include "services/resource_coordinator/public/cpp/coordination_unit_types.h"
 #include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
@@ -28,6 +27,13 @@
 // this class and can override shared funtionality when needed.
 class CoordinationUnitBase {
  public:
+  // Add the newly created coordination unit to the global coordination unit
+  // storage.
+  static CoordinationUnitBase* AddNewCoordinationUnit(
+      std::unique_ptr<CoordinationUnitBase> new_cu);
+  static void AssertNoActiveCoordinationUnits();
+  static void ClearAllCoordinationUnits();
+
   CoordinationUnitBase(const CoordinationUnitID& id,
                        CoordinationUnitGraph* graph);
   virtual ~CoordinationUnitBase();
@@ -57,6 +63,11 @@
   }
 
  protected:
+  static CoordinationUnitBase* GetCoordinationUnitByID(
+      const CoordinationUnitID cu_id);
+  static std::vector<CoordinationUnitBase*> GetCoordinationUnitsOfType(
+      CoordinationUnitType cu_type);
+
   virtual void OnEventReceived(mojom::Event event);
   virtual void OnPropertyChanged(mojom::PropertyType property_type,
                                  int64_t value);
@@ -64,10 +75,6 @@
   void SendEvent(mojom::Event event);
   void SetProperty(mojom::PropertyType property_type, int64_t value);
 
-  // Passes the ownership of the newly created |new_cu| to its graph.
-  static CoordinationUnitBase* PassOwnershipToGraph(
-      std::unique_ptr<CoordinationUnitBase> new_cu);
-
   CoordinationUnitGraph* const graph_;
   const CoordinationUnitID id_;
 
@@ -92,7 +99,7 @@
         std::make_unique<CoordinationUnitClass>(id, graph,
                                                 std::move(service_ref));
     return static_cast<CoordinationUnitClass*>(
-        PassOwnershipToGraph(std::move(new_cu)));
+        CoordinationUnitBase::AddNewCoordinationUnit(std::move(new_cu)));
   }
 
   static const CoordinationUnitClass* FromCoordinationUnitBase(
@@ -131,10 +138,9 @@
 
  protected:
   static CoordinationUnitClass* GetCoordinationUnitByID(
-      CoordinationUnitGraph* graph,
       const CoordinationUnitID cu_id) {
     DCHECK(cu_id.type == CoordinationUnitClass::Type());
-    auto* cu = graph->GetCoordinationUnitByID(cu_id);
+    auto* cu = CoordinationUnitBase::GetCoordinationUnitByID(cu_id);
     DCHECK(cu->id().type == CoordinationUnitClass::Type());
     return static_cast<CoordinationUnitClass*>(cu);
   }
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_graph.cc b/services/resource_coordinator/coordination_unit/coordination_unit_graph.cc
index 83b9fbc6..44fa487 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_graph.cc
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_graph.cc
@@ -26,8 +26,16 @@
 
 namespace resource_coordinator {
 
-CoordinationUnitGraph::CoordinationUnitGraph() = default;
-CoordinationUnitGraph::~CoordinationUnitGraph() = default;
+CoordinationUnitGraph::CoordinationUnitGraph() {
+  CoordinationUnitBase::AssertNoActiveCoordinationUnits();
+}
+
+CoordinationUnitGraph::~CoordinationUnitGraph() {
+  // TODO(oysteine): Keep the map of coordination units as a member of this
+  // class, rather than statically inside CoordinationUnitBase, to avoid this
+  // manual lifetime management.
+  CoordinationUnitBase::ClearAllCoordinationUnits();
+}
 
 void CoordinationUnitGraph::OnStart(
     service_manager::BinderRegistryWithArgs<
@@ -87,51 +95,4 @@
   return ProcessCoordinationUnitImpl::Create(id, this, std::move(service_ref));
 }
 
-CoordinationUnitBase* CoordinationUnitGraph::GetCoordinationUnitByID(
-    const CoordinationUnitID cu_id) {
-  const auto& it = coordination_units_.find(cu_id);
-  if (it == coordination_units_.end())
-    return nullptr;
-  return it->second.get();
-}
-
-std::vector<CoordinationUnitBase*>
-CoordinationUnitGraph::GetCoordinationUnitsOfType(CoordinationUnitType type) {
-  std::vector<CoordinationUnitBase*> results;
-  for (const auto& el : coordination_units_) {
-    if (el.first.type == type)
-      results.push_back(el.second.get());
-  }
-  return results;
-}
-
-std::vector<ProcessCoordinationUnitImpl*>
-CoordinationUnitGraph::GetAllProcessCoordinationUnits() {
-  auto cus = GetCoordinationUnitsOfType(CoordinationUnitType::kProcess);
-  std::vector<ProcessCoordinationUnitImpl*> process_cus;
-  for (auto* process_cu : cus) {
-    process_cus.push_back(
-        ProcessCoordinationUnitImpl::FromCoordinationUnitBase(process_cu));
-  }
-  return process_cus;
-}
-
-CoordinationUnitBase* CoordinationUnitGraph::AddNewCoordinationUnit(
-    std::unique_ptr<CoordinationUnitBase> new_cu) {
-  auto it = coordination_units_.emplace(new_cu->id(), std::move(new_cu));
-  DCHECK(it.second);  // Inserted successfully
-
-  CoordinationUnitBase* added_cu = it.first->second.get();
-  OnCoordinationUnitCreated(added_cu);
-
-  return added_cu;
-}
-
-void CoordinationUnitGraph::DestroyCoordinationUnit(CoordinationUnitBase* cu) {
-  OnBeforeCoordinationUnitDestroyed(cu);
-
-  size_t erased = coordination_units_.erase(cu->id());
-  DCHECK_EQ(1u, erased);
-}
-
 }  // namespace resource_coordinator
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_graph.h b/services/resource_coordinator/coordination_unit/coordination_unit_graph.h
index c50eb3d..9057f703 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_graph.h
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_graph.h
@@ -8,14 +8,11 @@
 #include <stdint.h>
 
 #include <memory>
-#include <unordered_map>
 #include <vector>
 
 #include "base/macros.h"
 #include "services/metrics/public/cpp/mojo_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
-#include "services/resource_coordinator/public/cpp/coordination_unit_id.h"
-#include "services/resource_coordinator/public/cpp/coordination_unit_types.h"
 #include "services/service_manager/public/cpp/service_context_ref.h"
 
 namespace service_manager {
@@ -28,6 +25,7 @@
 namespace resource_coordinator {
 
 class CoordinationUnitBase;
+struct CoordinationUnitID;
 class CoordinationUnitGraphObserver;
 class CoordinationUnitProviderImpl;
 class FrameCoordinationUnitImpl;
@@ -72,13 +70,6 @@
   // SystemCoordinationUnitImpl* FindOrCreateSystemCoordinationUnit(
   //    std::unique_ptr<service_manager::ServiceContextRef> service_ref);
 
-  // Search functions for type and ID queries.
-  std::vector<CoordinationUnitBase*> GetCoordinationUnitsOfType(
-      CoordinationUnitType type);
-
-  std::vector<ProcessCoordinationUnitImpl*> GetAllProcessCoordinationUnits();
-  CoordinationUnitBase* GetCoordinationUnitByID(const CoordinationUnitID cu_id);
-
   // Returns the singleton SystemCU.
   SystemCoordinationUnitImpl* system_cu() const { return system_cu_; }
 
@@ -88,16 +79,6 @@
   }
 
  private:
-  using CUIDMap = std::unordered_map<CoordinationUnitID,
-                                     std::unique_ptr<CoordinationUnitBase>>;
-
-  // Lifetime management functions for CoordinationUnitBase.
-  friend class CoordinationUnitBase;
-  CoordinationUnitBase* AddNewCoordinationUnit(
-      std::unique_ptr<CoordinationUnitBase> new_cu);
-  void DestroyCoordinationUnit(CoordinationUnitBase* cu);
-
-  CUIDMap coordination_units_;
   std::vector<std::unique_ptr<CoordinationUnitGraphObserver>> observers_;
   ukm::UkmRecorder* ukm_recorder_ = nullptr;
   std::unique_ptr<CoordinationUnitProviderImpl> provider_;
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc
index 3b5e669..84879fb 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.cc
@@ -8,7 +8,6 @@
 
 #include "base/process/process_handle.h"
 #include "base/time/time.h"
-#include "services/resource_coordinator/coordination_unit/coordination_unit_graph.h"
 #include "services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h"
 #include "services/resource_coordinator/coordination_unit/page_coordination_unit_impl.h"
 #include "services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h"
@@ -16,9 +15,7 @@
 
 namespace resource_coordinator {
 
-CoordinationUnitIntrospectorImpl::CoordinationUnitIntrospectorImpl(
-    CoordinationUnitGraph* graph)
-    : graph_(graph) {}
+CoordinationUnitIntrospectorImpl::CoordinationUnitIntrospectorImpl() = default;
 
 CoordinationUnitIntrospectorImpl::~CoordinationUnitIntrospectorImpl() = default;
 
@@ -26,7 +23,7 @@
     GetProcessToURLMapCallback callback) {
   std::vector<resource_coordinator::mojom::ProcessInfoPtr> process_infos;
   std::vector<ProcessCoordinationUnitImpl*> process_cus =
-      graph_->GetAllProcessCoordinationUnits();
+      ProcessCoordinationUnitImpl::GetAllProcessCoordinationUnits();
   for (auto* process_cu : process_cus) {
     int64_t pid;
     if (!process_cu->GetProperty(mojom::PropertyType::kPID, &pid))
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.h b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.h
index ad54257..43ef8ed 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.h
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_introspector_impl.h
@@ -15,12 +15,10 @@
 
 namespace resource_coordinator {
 
-class CoordinationUnitGraph;
-
 class CoordinationUnitIntrospectorImpl
     : public mojom::CoordinationUnitIntrospector {
  public:
-  explicit CoordinationUnitIntrospectorImpl(CoordinationUnitGraph* graph);
+  CoordinationUnitIntrospectorImpl();
   ~CoordinationUnitIntrospectorImpl() override;
 
   void BindToInterface(
@@ -31,7 +29,6 @@
   void GetProcessToURLMap(GetProcessToURLMapCallback callback) override;
 
  private:
-  CoordinationUnitGraph* const graph_;
   mojo::BindingSet<mojom::CoordinationUnitIntrospector> bindings_;
 
   DISALLOW_COPY_AND_ASSIGN(CoordinationUnitIntrospectorImpl);
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc
index 119a0a6..e2ff2ba 100644
--- a/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.cc
@@ -30,6 +30,8 @@
 
 void CoordinationUnitProviderImpl::OnConnectionError(
     CoordinationUnitBase* coordination_unit) {
+  coordination_unit_graph_->OnBeforeCoordinationUnitDestroyed(
+      coordination_unit);
   coordination_unit->Destruct();
 }
 
@@ -41,6 +43,7 @@
           id, service_ref_factory_->CreateRef());
 
   frame_cu->Bind(std::move(request));
+  coordination_unit_graph_->OnCoordinationUnitCreated(frame_cu);
   auto& frame_cu_binding = frame_cu->binding();
 
   frame_cu_binding.set_connection_error_handler(
@@ -56,6 +59,7 @@
           id, service_ref_factory_->CreateRef());
 
   page_cu->Bind(std::move(request));
+  coordination_unit_graph_->OnCoordinationUnitCreated(page_cu);
   auto& page_cu_binding = page_cu->binding();
 
   page_cu_binding.set_connection_error_handler(
@@ -71,6 +75,7 @@
           id, service_ref_factory_->CreateRef());
 
   process_cu->Bind(std::move(request));
+  coordination_unit_graph_->OnCoordinationUnitCreated(process_cu);
   auto& process_cu_binding = process_cu->binding();
 
   process_cu_binding.set_connection_error_handler(
diff --git a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc
index 62182a23..8d08c33a 100644
--- a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc
+++ b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc
@@ -34,7 +34,7 @@
 void FrameCoordinationUnitImpl::AddChildFrame(const CoordinationUnitID& cu_id) {
   DCHECK(cu_id != id());
   FrameCoordinationUnitImpl* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+      FrameCoordinationUnitImpl::GetCoordinationUnitByID(cu_id);
   if (!frame_cu)
     return;
   if (HasFrameCoordinationUnitInAncestors(frame_cu) ||
@@ -51,7 +51,7 @@
     const CoordinationUnitID& cu_id) {
   DCHECK(cu_id != id());
   FrameCoordinationUnitImpl* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+      FrameCoordinationUnitImpl::GetCoordinationUnitByID(cu_id);
   if (!frame_cu)
     return;
   if (RemoveChildFrame(frame_cu)) {
diff --git a/services/resource_coordinator/coordination_unit/page_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/page_coordination_unit_impl.cc
index c3e48fe..73eb241 100644
--- a/services/resource_coordinator/coordination_unit/page_coordination_unit_impl.cc
+++ b/services/resource_coordinator/coordination_unit/page_coordination_unit_impl.cc
@@ -27,7 +27,8 @@
 void PageCoordinationUnitImpl::AddFrame(const CoordinationUnitID& cu_id) {
   DCHECK(cu_id.type == CoordinationUnitType::kFrame);
   FrameCoordinationUnitImpl* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+      FrameCoordinationUnitImpl::FromCoordinationUnitBase(
+          CoordinationUnitBase::GetCoordinationUnitByID(cu_id));
   if (!frame_cu)
     return;
   if (AddFrame(frame_cu))
@@ -37,7 +38,7 @@
 void PageCoordinationUnitImpl::RemoveFrame(const CoordinationUnitID& cu_id) {
   DCHECK(cu_id != id());
   FrameCoordinationUnitImpl* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+      FrameCoordinationUnitImpl::GetCoordinationUnitByID(cu_id);
   if (!frame_cu)
     return;
   if (RemoveFrame(frame_cu))
diff --git a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc
index 0a6c68d..cf291e3 100644
--- a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc
+++ b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc
@@ -10,6 +10,19 @@
 
 namespace resource_coordinator {
 
+// static
+std::vector<ProcessCoordinationUnitImpl*>
+ProcessCoordinationUnitImpl::GetAllProcessCoordinationUnits() {
+  auto cus = CoordinationUnitBase::GetCoordinationUnitsOfType(
+      CoordinationUnitType::kProcess);
+  std::vector<ProcessCoordinationUnitImpl*> process_cus;
+  for (auto* process_cu : cus) {
+    process_cus.push_back(
+        ProcessCoordinationUnitImpl::FromCoordinationUnitBase(process_cu));
+  }
+  return process_cus;
+}
+
 ProcessCoordinationUnitImpl::ProcessCoordinationUnitImpl(
     const CoordinationUnitID& id,
     CoordinationUnitGraph* graph,
@@ -23,8 +36,7 @@
 
 void ProcessCoordinationUnitImpl::AddFrame(const CoordinationUnitID& cu_id) {
   DCHECK(cu_id.type == CoordinationUnitType::kFrame);
-  auto* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+  auto* frame_cu = FrameCoordinationUnitImpl::GetCoordinationUnitByID(cu_id);
   if (!frame_cu)
     return;
   if (AddFrame(frame_cu)) {
@@ -35,7 +47,7 @@
 void ProcessCoordinationUnitImpl::RemoveFrame(const CoordinationUnitID& cu_id) {
   DCHECK(cu_id != id());
   FrameCoordinationUnitImpl* frame_cu =
-      FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id);
+      FrameCoordinationUnitImpl::GetCoordinationUnitByID(cu_id);
   if (!frame_cu)
     return;
   if (RemoveFrame(frame_cu)) {
diff --git a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h
index 73d9213..68485700 100644
--- a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h
+++ b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h
@@ -19,6 +19,8 @@
                                        mojom::ProcessCoordinationUnit,
                                        mojom::ProcessCoordinationUnitRequest> {
  public:
+  static std::vector<ProcessCoordinationUnitImpl*>
+  GetAllProcessCoordinationUnits();
   static CoordinationUnitType Type() { return CoordinationUnitType::kProcess; }
 
   ProcessCoordinationUnitImpl(
diff --git a/services/resource_coordinator/coordination_unit/system_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/system_coordination_unit_impl.cc
index 4470295..4773b0df 100644
--- a/services/resource_coordinator/coordination_unit/system_coordination_unit_impl.cc
+++ b/services/resource_coordinator/coordination_unit/system_coordination_unit_impl.cc
@@ -29,7 +29,7 @@
     mojom::ProcessResourceMeasurementBatchPtr measurement_batch) {
   // Grab all the processes.
   std::vector<ProcessCoordinationUnitImpl*> processes =
-      graph_->GetAllProcessCoordinationUnits();
+      ProcessCoordinationUnitImpl::GetAllProcessCoordinationUnits();
 
   base::TimeDelta time_since_last_measurement;
   if (!last_measurement_batch_time_.is_null()) {
diff --git a/services/resource_coordinator/observers/coordination_unit_graph_observer_unittest.cc b/services/resource_coordinator/observers/coordination_unit_graph_observer_unittest.cc
index e4bb924..67a7103 100644
--- a/services/resource_coordinator/observers/coordination_unit_graph_observer_unittest.cc
+++ b/services/resource_coordinator/observers/coordination_unit_graph_observer_unittest.cc
@@ -72,22 +72,28 @@
       static_cast<TestCoordinationUnitGraphObserver*>(
           coordination_unit_graph()->observers_for_testing()[0].get());
 
-  {
-    auto process_cu = CreateCoordinationUnit<ProcessCoordinationUnitImpl>();
-    auto root_frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
-    auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  auto process_cu = CreateCoordinationUnit<ProcessCoordinationUnitImpl>();
+  auto root_frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
 
-    EXPECT_EQ(2u, observer->coordination_unit_created_count());
+  coordination_unit_graph()->OnCoordinationUnitCreated(process_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(root_frame_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
+  EXPECT_EQ(2u, observer->coordination_unit_created_count());
 
-    // The registered observer will only observe the events that happen to
-    // |root_frame_coordination_unit| and |frame_coordination_unit| because
-    // they are CoordinationUnitType::kFrame, so OnPropertyChanged
-    // will only be called for |root_frame_coordination_unit|.
-    root_frame_cu->SetPropertyForTesting(42);
-    process_cu->SetPropertyForTesting(42);
-    EXPECT_EQ(1u, observer->property_changed_count());
-  }
+  // The registered observer will only observe the events that happen to
+  // |root_frame_coordination_unit| and |frame_coordination_unit| because
+  // they are CoordinationUnitType::kFrame, so OnPropertyChanged
+  // will only be called for |root_frame_coordination_unit|.
+  root_frame_cu->SetPropertyForTesting(42);
+  process_cu->SetPropertyForTesting(42);
+  EXPECT_EQ(1u, observer->property_changed_count());
 
+  coordination_unit_graph()->OnBeforeCoordinationUnitDestroyed(
+      process_cu.get());
+  coordination_unit_graph()->OnBeforeCoordinationUnitDestroyed(
+      root_frame_cu.get());
+  coordination_unit_graph()->OnBeforeCoordinationUnitDestroyed(frame_cu.get());
   EXPECT_EQ(2u, observer->coordination_unit_destroyed_count());
 }
 
diff --git a/services/resource_coordinator/observers/ipc_volume_reporter_unittest.cc b/services/resource_coordinator/observers/ipc_volume_reporter_unittest.cc
index 93b619b..50d4621 100644
--- a/services/resource_coordinator/observers/ipc_volume_reporter_unittest.cc
+++ b/services/resource_coordinator/observers/ipc_volume_reporter_unittest.cc
@@ -45,6 +45,9 @@
   EXPECT_TRUE(reporter_->mock_timer()->IsRunning());
   MockSinglePageInSingleProcessCoordinationUnitGraph cu_graph(
       coordination_unit_graph());
+  coordination_unit_graph()->OnCoordinationUnitCreated(cu_graph.process.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(cu_graph.page.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(cu_graph.frame.get());
 
   cu_graph.frame->SetAudibility(true);
   cu_graph.frame->SetNetworkAlmostIdle(true);
diff --git a/services/resource_coordinator/observers/metrics_collector_unittest.cc b/services/resource_coordinator/observers/metrics_collector_unittest.cc
index 4ef16205..132a465 100644
--- a/services/resource_coordinator/observers/metrics_collector_unittest.cc
+++ b/services/resource_coordinator/observers/metrics_collector_unittest.cc
@@ -60,6 +60,8 @@
 TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstAudioStartsUMA) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
 
   page_cu->OnMainFrameNavigationCommitted();
@@ -110,6 +112,8 @@
        FromBackgroundedToFirstAudioStartsUMA5MinutesTimeout) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
 
   page_cu->AddFrame(frame_cu->id());
 
@@ -129,6 +133,7 @@
 
 TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstTitleUpdatedUMA) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
 
   page_cu->OnMainFrameNavigationCommitted();
   AdvanceClock(kTestMetricsReportDelayTimeout);
@@ -161,6 +166,7 @@
 TEST_F(MAYBE_MetricsCollectorTest,
        FromBackgroundedToFirstTitleUpdatedUMA5MinutesTimeout) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
 
   page_cu->OnMainFrameNavigationCommitted();
   page_cu->SetVisibility(false);
@@ -178,6 +184,8 @@
 TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstAlertFiredUMA) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
 
   page_cu->OnMainFrameNavigationCommitted();
@@ -212,6 +220,8 @@
        FromBackgroundedToFirstAlertFiredUMA5MinutesTimeout) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
 
   page_cu->OnMainFrameNavigationCommitted();
@@ -231,6 +241,8 @@
        FromBackgroundedToFirstNonPersistentNotificationCreatedUMA) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
 
   page_cu->OnMainFrameNavigationCommitted();
@@ -266,6 +278,8 @@
     FromBackgroundedToFirstNonPersistentNotificationCreatedUMA5MinutesTimeout) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
 
   page_cu->OnMainFrameNavigationCommitted();
@@ -283,6 +297,7 @@
 
 TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstFaviconUpdatedUMA) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
 
   page_cu->OnMainFrameNavigationCommitted();
   AdvanceClock(kTestMetricsReportDelayTimeout);
@@ -315,6 +330,7 @@
 TEST_F(MAYBE_MetricsCollectorTest,
        FromBackgroundedToFirstFaviconUpdatedUMA5MinutesTimeout) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
 
   page_cu->OnMainFrameNavigationCommitted();
   page_cu->SetVisibility(false);
@@ -332,9 +348,12 @@
 // Flaky test: https://crbug.com/833028
 TEST_F(MAYBE_MetricsCollectorTest, ResponsivenessMetric) {
   auto page_cu = CreateCoordinationUnit<PageCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(page_cu.get());
   auto process_cu = CreateCoordinationUnit<ProcessCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(process_cu.get());
 
   auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>();
+  coordination_unit_graph()->OnCoordinationUnitCreated(frame_cu.get());
   page_cu->AddFrame(frame_cu->id());
   process_cu->AddFrame(frame_cu->id());
 
diff --git a/services/resource_coordinator/resource_coordinator_service.cc b/services/resource_coordinator/resource_coordinator_service.cc
index a9557ae..622b392 100644
--- a/services/resource_coordinator/resource_coordinator_service.cc
+++ b/services/resource_coordinator/resource_coordinator_service.cc
@@ -24,7 +24,7 @@
 }
 
 ResourceCoordinatorService::ResourceCoordinatorService()
-    : introspector_(&coordination_unit_graph_), weak_factory_(this) {}
+    : weak_factory_(this) {}
 
 ResourceCoordinatorService::~ResourceCoordinatorService() = default;
 
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 139101f..7372e4b 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -339,6 +339,7 @@
       "//third_party/skia/src/codec/SkBmpStandardCodec.cpp",
       "//third_party/skia/src/codec/SkCodec.cpp",
       "//third_party/skia/src/codec/SkCodecImageGenerator.cpp",
+      "//third_party/skia/src/codec/SkColorTable.cpp",
       "//third_party/skia/src/codec/SkGifCodec.cpp",
       "//third_party/skia/src/codec/SkIcoCodec.cpp",
       "//third_party/skia/src/codec/SkJpegCodec.cpp",
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index d950ae0..e4faad2 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -194,6 +194,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -278,6 +284,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -410,6 +422,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -655,6 +673,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -740,6 +764,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -872,6 +902,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -7726,6 +7762,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -7787,6 +7829,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -7919,6 +7967,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -8178,6 +8232,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -8239,6 +8299,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -8372,6 +8438,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -8618,6 +8690,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -8679,6 +8757,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -8805,6 +8889,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -9046,6 +9136,12 @@
         "swarming": {
           "can_use_on_swarming_builders": false
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -9118,6 +9214,12 @@
         "swarming": {
           "can_use_on_swarming_builders": false
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -9250,6 +9352,12 @@
         "swarming": {
           "can_use_on_swarming_builders": false
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": false
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -9492,6 +9600,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -9552,6 +9666,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -9684,6 +9804,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -15767,6 +15893,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -15827,6 +15959,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -15959,6 +16097,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 4ab2c695..9c8f0c7 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -516,6 +516,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -600,6 +606,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -732,6 +744,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -977,6 +995,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -1062,6 +1086,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -1194,6 +1224,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
@@ -5075,6 +5111,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "filesystem_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "gcm_unit_tests"
       },
       {
@@ -5124,6 +5166,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "leveldb_service_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "libjingle_xmpp_unittests"
       },
       {
@@ -5256,6 +5304,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "traffic_annotation_auditor_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ui_base_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 84609846..788a3052 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -2585,6 +2585,7 @@
           "--test-launcher-batch-limit=1",
           "--test-launcher-print-test-stdio=always"
         ],
+        "experiment_percentage": 100,
         "swarming": {
           "can_use_on_swarming_builders": true,
           "shards": 4
@@ -2979,6 +2980,7 @@
           "--test-launcher-batch-limit=1",
           "--test-launcher-print-test-stdio=always"
         ],
+        "experiment_percentage": 100,
         "swarming": {
           "can_use_on_swarming_builders": true
         },
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
index ac87f750..c86b57e 100644
--- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -6,7 +6,6 @@
 -ServiceWorkerNavigationPreloadTest.CanceledByInterceptor
 -ServiceWorkerNavigationPreloadTest.RespondWithNavigationPreloadWithMimeSniffing
 -ServiceWorkerV8CodeCacheForCacheStorageTest.V8CacheOnCacheStorage
--ServiceWorkerVersionBrowserTest.ServiceWorkerScriptHeader
 
 # ServiceWorker restart needs to read installed scripts.
 # https://crbug.com/756312
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 3e86160..af6ad4ce 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -884,6 +884,8 @@
         'swarming': {
           'shards': 4,
         },
+        # crbug.com/848278
+        'experiment_percentage': 100,
       },
       'Linux Chromium OS ASan LSan Tests (1)': {
         # content_browsertests is slow on ASAN try bot. crbug.com/822461.
@@ -1931,6 +1933,13 @@
       'Linux ChromiumOS MSan Tests',  # https://crbug.com/831676
       'Linux MSan Tests',  # https://crbug.com/831676
     ],
+    'modifications': {
+      # chromium.memory
+      # crbug.com/848278
+      'Linux ASan LSan Tests (1)': {
+        'experiment_percentage': 100,
+      },
+    },
   },
   'not_site_per_process_browser_tests': {
     'remove_from': [
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index df97f5a..b11dabd 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -1172,7 +1172,7 @@
   },
 
   'linux_chromeos_rel_specific_gtests': {
-    'angle_unittests': {},
+    # Chrome OS only.
     'chromevox_tests': {},
     'exo_unittests': {},
     'gl_unittests_ozone': {},
@@ -1190,6 +1190,7 @@
   },
 
   'linux_chromeos_specific_gtests': {
+    # Chrome OS only.
     'app_list_presenter_unittests': {},
     'app_list_unittests': {},
     'ash_content_unittests': {},
@@ -1216,6 +1217,7 @@
   },
 
   'linux_specific_chromium_gtests': {
+    # Linux only.
     # TODO(kbr): unclear why some of these aren't run more broadly.
     'filesystem_service_unittests': {},
     'leveldb_service_unittests': {},
@@ -1813,6 +1815,7 @@
     'linux_clang_and_fyi_specific_chromium_gtests',
     'linux_flavor_specific_chromium_gtests',
     'linux_incl_clang_specific_chromium_gtests',
+    'linux_specific_chromium_gtests',
     'non_android_chromium_gtests',
     'non_android_and_cast_and_chromeos_chromium_gtests',
     'non_mac_non_clang_win_chromium_gtests',
@@ -1826,6 +1829,7 @@
     'linux_clang_and_fyi_specific_chromium_gtests',
     'linux_flavor_specific_chromium_gtests',
     'linux_incl_clang_specific_chromium_gtests',
+    'linux_specific_chromium_gtests',
     'non_android_chromium_gtests',
     'non_android_and_cast_and_chromeos_chromium_gtests',
     'non_mac_non_clang_win_chromium_gtests',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 7b28a20..b79839b 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1631,6 +1631,7 @@
     "IDBTombstoneSweeper": [
         {
             "platforms": [
+                "android",
                 "chromeos",
                 "linux",
                 "mac",
@@ -1638,9 +1639,9 @@
             ],
             "experiments": [
                 {
-                    "name": "TombstoneMetrics",
+                    "name": "TombstoneDeletion",
                     "enable_features": [
-                        "IDBTombstoneStatistics"
+                        "IDBTombstoneDeletion"
                     ]
                 }
             ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 93adb5fa..858a73f 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -501,9 +501,6 @@
 crbug.com/591099 fast/borders/border-image-border-radius.html [ Failure ]
 crbug.com/714962 fast/borders/border-image-outset-split-inline.html [ Failure ]
 crbug.com/714962 fast/borders/border-inner-bleed.html [ Failure ]
-crbug.com/591099 fast/borders/border-radius-mask-canvas-all.html [ Failure ]
-crbug.com/591099 fast/borders/border-radius-mask-canvas-with-mask.html [ Failure ]
-crbug.com/591099 fast/borders/border-radius-mask-canvas-with-shadow.html [ Failure ]
 crbug.com/714962 fast/borders/border-styles-split.html [ Failure ]
 crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/box-decoration-break/box-decoration-break-rendering.html [ Failure ]
@@ -557,7 +554,6 @@
 crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ]
 crbug.com/714962 fast/css/absolute-inline-alignment.html [ Failure ]
 crbug.com/591099 fast/css/background-image-with-baseurl.html [ Failure Pass ]
-crbug.com/591099 fast/css/bidi-override-in-anonymous-block.html [ Failure ]
 crbug.com/591099 fast/css/case-transform.html [ Failure ]
 crbug.com/591099 fast/css/containment/size-and-layout-containment.html [ Failure ]
 crbug.com/591099 fast/css/css-properties-position-relative-as-parent-fixed.html [ Failure ]
@@ -637,7 +633,6 @@
 crbug.com/591099 fast/frames/iframe-with-frameborder.html [ Failure ]
 crbug.com/591099 fast/gradients/list-item-gradient.html [ Failure ]
 crbug.com/591099 fast/gradients/unprefixed-list-item-gradient.html [ Failure ]
-crbug.com/591099 fast/history/visited-link-hover-outline-color.html [ Failure ]
 crbug.com/591099 fast/inline-block/14498-positionForCoordinates.html [ Failure ]
 crbug.com/591099 fast/inline-block/baseline-vertical.html [ Failure ]
 crbug.com/714962 fast/inline-block/tricky-baseline.html [ Failure ]
@@ -684,9 +679,7 @@
 crbug.com/824918 fast/multicol/vertical-rl/caret-range-anonymous-block-rtl.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/caret-range-anonymous-block.html [ Failure ]
 crbug.com/714962 fast/overflow/line-clamp-hides-trailing-anchor.html [ Failure ]
-crbug.com/591099 fast/overflow/line-clamp.html [ Failure ]
-crbug.com/591099 fast/overflow/overflow-rtl-vertical.html [ Failure ]
-crbug.com/591099 fast/overflow/overflow-rtl.html [ Failure ]
+crbug.com/59109caret-contenteditable-content9 fast/overflow/line-clamp.html [ Failure ]
 crbug.com/591099 fast/overflow/overflow-update-transform.html [ Failure ]
 crbug.com/591099 fast/overflow/recompute-overflow-of-layout-root-container.html [ Failure ]
 crbug.com/591099 fast/pagination/modal-dialog.html [ Failure ]
@@ -803,8 +796,6 @@
 crbug.com/591099 fast/text/emphasis-ellipsis-complextext.html [ Failure ]
 crbug.com/591099 fast/text/emphasis-overlap.html [ Failure ]
 crbug.com/591099 fast/text/hide-atomic-inlines-after-ellipsis.html [ Failure ]
-crbug.com/591099 fast/text/international/bidi-linebreak-002.html [ Failure ]
-crbug.com/591099 fast/text/international/bidi-linebreak-003.html [ Failure ]
 crbug.com/714962 fast/text/international/hindi-whitespace.html [ Failure ]
 crbug.com/796943 fast/text/international/shape-across-elements-simple.html [ Pass ]
 crbug.com/591099 fast/text/international/text-combine-image-test.html [ Failure ]
@@ -1094,7 +1085,6 @@
 crbug.com/591099 paint/invalidation/table/cached-change-row-border-width.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-table-border-width.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/cached-change-tbody-border-width.html [ Failure ]
-crbug.com/591099 paint/invalidation/table/caret-contenteditable-content-after.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/collapsed-border-cell-resize.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/collapsed-border-change-rowspan.html [ Failure ]
 crbug.com/591099 paint/invalidation/table/composited-table-row.html [ Failure ]
@@ -1166,8 +1156,6 @@
 crbug.com/714962 svg/as-background-image/svg-as-background-body.html [ Failure ]
 crbug.com/591099 svg/as-border-image/svg-as-border-image-2.html [ Failure ]
 crbug.com/591099 svg/as-border-image/svg-as-border-image.html [ Failure ]
-crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Failure ]
-crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure ]
 crbug.com/591099 svg/custom/inline-svg-use-available-width-in-stf.html [ Failure ]
 crbug.com/591099 svg/custom/object-sizing-no-width-height.xhtml [ Failure ]
 crbug.com/591099 svg/custom/stf-container-with-intrinsic-ratio-svg.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index 26b6dd8..326c644 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -7,6 +7,8 @@
 crbug.com/829417 external/wpt/html/browsers/offline/appcache/workers/appcache-worker.https.html [ Timeout ]
 crbug.com/771118 external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ]
 
+Bug(837709) external/wpt/lifecycle/freeze.html [ Crash ]
+
 # Passes on NetworkService and fails on non-NetworkService because
 # NetworkService isn't affected by https://crbug.com/595993.
 Bug(none) external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index dad00c4..037f103 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2843,6 +2843,9 @@
 crbug.com/832071 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-animations/set-animation-play-state-to-paused-002.html [ Failure ]
+crbug.com/626703 [ Win7 ] external/wpt/fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html [ Skip ]
+crbug.com/626703 [ Mac10.12 ] external/wpt/encoding/textdecoder-fatal-single-byte.html [ Timeout ]
 crbug.com/626703 [ Win10 ] external/wpt/fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html [ Skip ]
 crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/range/sw.https.window.html [ Timeout ]
 crbug.com/626703 [ Retina ] external/wpt/accelerometer/Accelerometer.https.html [ Timeout ]
@@ -4820,7 +4823,7 @@
 crbug.com/847373 [ Mac Linux ] virtual/pwa-full-code-cache/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js [ Pass Timeout ]
 
 # Sheriff 2018-05-31
-crbug.com/848258 [ Win7 ] fast/gradients/unprefixed-repeating-linear-gradient.html [ Failure ]
+crbug.com/848258 [ Win ] fast/gradients/unprefixed-repeating-linear-gradient.html [ Failure ]
 crbug.com/848281 [ Linux ] http/tests/security/cross-origin-session-storage-allowed.html [ Failure ]
 crbug.com/848354 [ Linux ] plugins/fullscreen-plugins-dont-reload.html [ Skip ]
 crbug.com/848398 [ Linux Mac ] http/tests/devtools/oopif/oopif-performance-cpu-profiles.js [ Pass Timeout Failure ]
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/add-listener-from-callback.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/add-listener-from-callback.html
index c026ac3..a9a49851 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/add-listener-from-callback.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/add-listener-from-callback.html
@@ -3,33 +3,46 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+sensor_test(async sensor => {
+  const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
 
-  var firstListenerEvents = 0;
-  var firstListener = test.step_func(event => {
-    checkOrientation(event, orientationData);
-    window.removeEventListener('deviceorientation', firstListener);
-    if (++firstListenerEvents == 1)
-      window.addEventListener('deviceorientation', secondListener);
+  let firstListener = null;
+  let secondListener = null;
+  let firstEventCount = 0;
+  let firstPromise = new Promise(resolve => {
+    firstListener = (event) => {
+      checkOrientation(event, orientationData);
+      window.removeEventListener('deviceorientation', firstListener);
+      if (++firstEventCount == 1) {
+        window.addEventListener('deviceorientation', secondListener);
+      }
+      resolve(event);
+    };
   });
 
-  var secondListenerEvents = 0;
-  var secondListener = test.step_func(event => {
-    checkOrientation(event, orientationData);
-    ++secondListenerEvents;
-    assert_equals(firstListenerEvents, 1, "Too many events fired for the first listener");
-    assert_equals(secondListenerEvents, 1, "Too many events fired for the second listener");
-    test.done();
+  let secondEventCount = 0;
+  let secondPromise = new Promise(resolve => {
+    secondListener = (event) => {
+      checkOrientation(event, orientationData);
+      window.removeEventListener('deviceorientation', secondListener);
+      ++secondEventCount;
+      resolve(event);
+    };
   });
 
-  setMockOrientation(orientationData);
+  setMockOrientationData(sensor, orientationData);
   window.addEventListener('deviceorientation', firstListener);
+  await firstPromise;
+  await secondPromise;
+  assert_equals(firstEventCount, 1, "Too many events fired for the first listener");
+  assert_equals(secondEventCount, 1, "Too many events fired for the second listener");
 }, 'Tests that adding a new deviceorientation event listener from a callback works as expected.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/basic-operation-absolute.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/basic-operation-absolute.html
index 7755ea89..e1845e60 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/basic-operation-absolute.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/basic-operation-absolute.html
@@ -3,21 +3,18 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+sensor_test(async sensor => {
+  const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
 
-  var listener = test.step_func(event => {
-    checkOrientation(event, orientationData);
-    test.done();
-  });
-
-  setMockOrientation(orientationData);
-  window.addEventListener('deviceorientationabsolute', listener);
+  setMockOrientationData(sensor, orientationData);
+  return waitForOrientation(orientationData);
 }, 'Tests basic operation of deviceorientationabsolute event using mock data.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-event-listeners.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-event-listeners.html
index 193fece..4344d89 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-event-listeners.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-event-listeners.html
@@ -3,66 +3,40 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData1 = generateOrientationData(1, 2, 3, true);
-  var orientationData2 = generateOrientationData(11, 12, 13, true);
-  var counter = 0;
+sensor_test(async sensor => {
+  const orientationData1 = generateOrientationData(1, 2, 3, false);
+  const orientationData2 = generateOrientationData(11, 12, 13, false);
 
-  var firstListener = test.step_func(event => {
-    checkOrientation(event, orientationData1);
-    ++counter;
-    proceedIfNecessary();
+  let firstListener = null;
+  let firstEventPromise = new Promise(resolve => {
+    firstListener = resolve;
   });
-
-  var secondListener = test.step_func(event => {
-    checkOrientation(event, orientationData1);
-    ++counter;
-    proceedIfNecessary();
-  });
-
-  function proceedIfNecessary() {
-    if (counter == 2) {
-      setMockOrientation(orientationData2);
-      // Note: this should not stop Device Orientation updates,
-      // because there is still one listener active.
-      window.removeEventListener('deviceorientation', secondListener);
-      setTimeout(initThirdListener, 0);
-    }
-  }
-
-  var childFrame;
-  function initThirdListener() {
-    childFrame = document.createElement('iframe');
-    document.body.appendChild(childFrame);
-    childFrame.contentWindow.addEventListener('deviceorientation', thirdListener);
-  }
-
-  var thirdListener = test.step_func(event => {
-    // Expect the cached event because Device Orientation was already active
-    // when third listener was added.
-    checkOrientation(event, orientationData1);
-    window.removeEventListener('deviceorientation', firstListener);
-    childFrame.contentWindow.removeEventListener('deviceorientation', thirdListener);
-    setTimeout(initFourthListener, 0);
-  });
-
-  function initFourthListener() {
-    window.addEventListener('deviceorientation', fourthListener);
-  }
-
-  var fourthListener = test.step_func(event => {
-    checkOrientation(event, orientationData2);
-    test.done();
-  });
-
-  setMockOrientation(orientationData1);
+  // We directly add the listener instead of using waitForOrientation
+  // because we want the listener to stay active after the first event fires.
   window.addEventListener('deviceorientation', firstListener);
-  window.addEventListener('deviceorientation', secondListener);
+  let secondEventPromise = waitForOrientation(orientationData1);
+  setMockOrientationData(sensor, orientationData1);
+  let firstEvent = await firstEventPromise;
+  checkOrientation(firstEvent, orientationData1);
+  await secondEventPromise;
+
+  // At this point only the first listener is still active.
+  setMockOrientationData(sensor, orientationData2);
+  let childFrame = document.createElement('iframe');
+  document.body.appendChild(childFrame);
+  // Expect the cached event because Device Orientation was already active
+  // when third listener was added.
+  await waitForOrientation(orientationData1, childFrame.contentWindow);
+  window.removeEventListener('deviceorientation', firstListener);
+
+  return waitForOrientation(orientationData2);
 }, 'Tests using multiple event handlers for the Device Orientation API.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-frames.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-frames.html
index e11a9322..c608704 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-frames.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/multiple-frames.html
@@ -3,41 +3,23 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
-  var hasMainFrameEventFired = false;
-  var hasChildFrameEventFired = false;
+sensor_test(async sensor => {
+  const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
 
-  var mainFrameListener = test.step_func(event => {
-    checkOrientation(event, orientationData);
-    hasMainFrameEventFired = true;
-    maybeFinishTest();
-  });
+  setMockOrientationData(sensor, orientationData);
+  await waitForOrientation(orientationData);
 
-  var childFrameListener = test.step_func(event => {
-    checkOrientation(event, orientationData);
-    hasChildFrameEventFired = true;
-    maybeFinishTest();
-  });
-
-  function maybeFinishTest() {
-    if (hasMainFrameEventFired && hasChildFrameEventFired)
-      test.done();
-  }
-
-  setMockOrientation(orientationData);
-
-  var childFrame = document.createElement('iframe');
+  let childFrame = document.createElement('iframe');
   document.body.appendChild(childFrame);
-  childFrame.contentWindow.addEventListener('deviceorientation', childFrameListener);
-
-  window.addEventListener('deviceorientation', mainFrameListener);
+  return waitForOrientation(orientationData, childFrame.contentWindow);
 }, 'Tests using DeviceOrientation from multiple frames.');
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/no-synchronous-events.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/no-synchronous-events.html
index 450d4f0..72f10341 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/no-synchronous-events.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/no-synchronous-events.html
@@ -3,21 +3,29 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
+sensor_test(async sensor => {
+  var orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
 
-  setMockOrientation(orientationData);
+  let setMockDataPromise = setMockOrientationData(sensor, orientationData);
+  // Add an empty listener to make sure the event pump is running and the mock
+  // sensor is created and configured. If the pump and fake sensor weren't set
+  // up ahead of time, then the fact that we get an asynchronous event could be
+  // due to the asynchronous set up process.
+  window.addEventListener('deviceorientation', event => {});
+  await setMockDataPromise;
 
-  var hasAddEventListenerReturned = false;
-  window.addEventListener('deviceorientation', test.step_func_done(() => {
-    assert_true(hasAddEventListenerReturned);
-  }));
-  hasAddEventListenerReturned = true;
+  return new Promise((resolve, reject) => {
+    let result = reject;
+    window.addEventListener('deviceorientation', event => result());
+    result = resolve;
+  });
 }, 'Tests that events are never fired synchronously from a call to window.addEventListener().');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/null-values.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/null-values.html
index ffd7cbf..6c66a5e 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/null-values.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/null-values.html
@@ -3,57 +3,32 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData1 = generateOrientationData(null, null, null, false);
-  var orientationData2 = generateOrientationData(1.1, null, null, true);
-  var orientationData3 = generateOrientationData(null, 2.2, null, true);
-  var orientationData4 = generateOrientationData(null, null, 3.3, true);
+sensor_test(async sensor => {
+  const orientationData1 = generateOrientationData(1.1, null, null, false);
+  const orientationData2 = generateOrientationData(null, 2.2, null, false);
+  const orientationData3 = generateOrientationData(null, null, 3.3, false);
+  // The all null event is last because DeviceSingleWindowEventController
+  // will stop updating the sensor when it sees a null event.
+  const orientationData4 = generateOrientationData(null, null, null, false);
 
-  var firstListener = test.step_func(event => {
-    checkOrientation(event, orientationData1);
-    window.removeEventListener('deviceorientation', firstListener);
-    setTimeout(initSecondListener, 0);
-  });
+  setMockOrientationData(sensor, orientationData1);
+  await waitForOrientation(orientationData1);
 
-  function initSecondListener() {
-    setMockOrientation(orientationData2);
-    window.addEventListener('deviceorientation', secondListener);
-  }
+  setMockOrientationData(sensor, orientationData2);
+  await waitForOrientation(orientationData2);
 
-  var secondListener = test.step_func(event => {
-    checkOrientation(event, orientationData2);
-    window.removeEventListener('deviceorientation', secondListener);
-    setTimeout(initThirdListener, 0);
-  });
+  setMockOrientationData(sensor, orientationData3);
+  await waitForOrientation(orientationData3);
 
-  function initThirdListener() {
-    setMockOrientation(orientationData3);
-    window.addEventListener('deviceorientation', thirdListener);
-  }
-
-  var thirdListener = test.step_func(event => {
-    checkOrientation(event, orientationData3);
-    window.removeEventListener('deviceorientation', thirdListener);
-    setTimeout(initFourthListener, 0);
-  });
-
-  function initFourthListener() {
-    setMockOrientation(orientationData4);
-    window.addEventListener('deviceorientation', fourthListener);
-  }
-
-  var fourthListener = test.step_func(event => {
-    checkOrientation(event, orientationData4);
-    test.done();
-  });
-
-  setMockOrientation(orientationData1);
-  window.addEventListener('deviceorientation', firstListener);
+  setMockOrientationData(sensor, orientationData4);
+  return waitForOrientation(orientationData4);
 }, 'Tests using null values for some of the event properties.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/page-visibility.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/page-visibility.html
index c6d3d411..0d71ea03 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/page-visibility.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/page-visibility.html
@@ -3,40 +3,45 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
+function sleep(time_ms) {
+  return new Promise(resolve => window.setTimeout(resolve, time_ms));
+}
 
-  var orientationData = generateOrientationData(1, 2, 3, true);
-  var succeedAndFinish = test.step_func_done(() => {});
+sensor_test(async sensor => {
+  const orientationData = generateOrientationData(1, 2, 3, false);
 
-  function testWithPageVisible() {
-    window.removeEventListener('deviceorientation', failAndFinish);
-    testRunner.setPageVisibility("visible");
-    window.addEventListener('deviceorientation', succeedAndFinish);
-  }
+  setMockOrientationData(sensor, orientationData);
+  await waitForOrientation(orientationData);
 
-  var failAndFinish = test.step_func_done(() => {
-    assert_unreached("Should not have received a deviceorientation event while the page was hidden");
+  testRunner.setPageVisibility('hidden');
+  let hidden = true;
+  let hiddenEventPromise = new Promise((resolve, reject) => {
+    window.addEventListener(
+        'deviceorientation',
+        event => {
+          if (hidden) {
+            reject();
+          } else {
+            resolve();
+          }
+        },
+        { once: true });
   });
 
-  function testWithPageHidden() {
-    window.removeEventListener('deviceorientation', deviceOrientationListener);
-    testRunner.setPageVisibility("hidden");
-    window.addEventListener('deviceorientation', failAndFinish);
-    setTimeout(testWithPageVisible, 100);
-  }
-
-  var deviceOrientationListener = test.step_func(() => {
-    setTimeout(testWithPageHidden, 0);
-  });
-
-  setMockOrientation(orientationData);
-  window.addEventListener('deviceorientation', deviceOrientationListener);
+  // Sleep for a while to make sure no deviceorientation events are fired
+  // while the page is hidden.
+  await sleep(100);
+  hidden = false;
+  testRunner.setPageVisibility('visible');
+  return Promise.all([hiddenEventPromise, waitForOrientation(orientationData)]);
 }, 'Tests to check that deviceorientation events are not fired when the page is not visible.');
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/device_orientation/orientation/updates.html b/third_party/WebKit/LayoutTests/device_orientation/orientation/updates.html
index 81a2fd9..cbbd94994 100644
--- a/third_party/WebKit/LayoutTests/device_orientation/orientation/updates.html
+++ b/third_party/WebKit/LayoutTests/device_orientation/orientation/updates.html
@@ -3,32 +3,22 @@
 <body>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/sensor-helpers.js"></script>
 <script src="../resources/device-orientation-helpers.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/services/device/public/mojom/sensor_provider.mojom.js"></script>
 <script>
 'use strict';
 
-async_test(test => {
-  assertTestRunner();
-  var orientationData1 = generateOrientationData(1.1, 2.2, 3.3, true);
-  var orientationData2 = generateOrientationData(11.1, 22.2, 33.3, true);
+sensor_test(async sensor => {
+  const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
+  const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
 
-  var firstListener = test.step_func(event => {
-    checkOrientation(event, orientationData1);
-    window.removeEventListener('deviceorientation', firstListener);
-    setTimeout(initUpdateListener, 0);
-  });
+  setMockOrientationData(sensor, orientationData1);
+  await waitForOrientation(orientationData1);
 
-  function initUpdateListener() {
-    setMockOrientation(orientationData2);
-    window.addEventListener('deviceorientation', updateListener);
-  }
-
-  var updateListener = test.step_func_done(event => {
-    checkOrientation(event, orientationData2);
-  });
-
-  setMockOrientation(orientationData1);
-  window.addEventListener('deviceorientation', firstListener);
+  setMockOrientationData(sensor, orientationData2);
+  return waitForOrientation(orientationData2);
 }, 'Tests that updates to the orientation causes new events to fire.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 852eaa7..b22fd67 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -28541,6 +28541,18 @@
      {}
     ]
    ],
+   "css/css-animations/set-animation-play-state-to-paused-002.html": [
+    [
+     "/css/css-animations/set-animation-play-state-to-paused-002.html",
+     [
+      [
+       "/css/css-animations/set-animation-play-state-to-paused-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-backgrounds/background-334.html": [
     [
      "/css/css-backgrounds/background-334.html",
@@ -51301,6 +51313,18 @@
      {}
     ]
    ],
+   "css/css-pseudo/placeholder-input-number.html": [
+    [
+     "/css/css-pseudo/placeholder-input-number.html",
+     [
+      [
+       "/css/css-pseudo/placeholder-input-number-notref.html",
+       "!="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-rhythm/line-height-step-basic-001.html": [
     [
      "/css/css-rhythm/line-height-step-basic-001.html",
@@ -108766,6 +108790,11 @@
      {}
     ]
    ],
+   "css/css-animations/set-animation-play-state-to-paused-002-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-backgrounds/OWNERS": [
     [
      {}
@@ -122671,6 +122700,11 @@
      {}
     ]
    ],
+   "css/css-pseudo/placeholder-input-number-notref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-rhythm/OWNERS": [
     [
      {}
@@ -135321,6 +135355,11 @@
      {}
     ]
    ],
+   "css/support/grid.css": [
+    [
+     {}
+    ]
+   ],
    "css/support/import-green.css": [
     [
      {}
@@ -156321,6 +156360,16 @@
      {}
     ]
    ],
+   "lifecycle/resources/foo.txt": [
+    [
+     {}
+    ]
+   ],
+   "lifecycle/resources/window.html": [
+    [
+     {}
+    ]
+   ],
    "longtask-timing/OWNERS": [
     [
      {}
@@ -186559,6 +186608,30 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html": [
+    [
+     "/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html": [
+    [
+     "/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html": [
+    [
+     "/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html": [
+    [
+     "/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html",
+     {}
+    ]
+   ],
    "css/css-grid/alignment/grid-fit-content-tracks-dont-stretch-001.html": [
     [
      "/css/css-grid/alignment/grid-fit-content-tracks-dont-stretch-001.html",
@@ -186679,6 +186752,30 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html": [
+    [
+     "/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html": [
+    [
+     "/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html": [
+    [
+     "/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html": [
+    [
+     "/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html",
+     {}
+    ]
+   ],
    "css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-001.html": [
     [
      "/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-001.html",
@@ -187135,6 +187232,18 @@
      {}
     ]
    ],
+   "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html": [
+    [
+     "/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html",
+     {}
+    ]
+   ],
+   "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html": [
+    [
+     "/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html",
+     {}
+    ]
+   ],
    "css/css-grid/grid-definition/grid-change-fit-content-argument-001.html": [
     [
      "/css/css-grid/grid-definition/grid-change-fit-content-argument-001.html",
@@ -219419,6 +219528,12 @@
      {}
     ]
    ],
+   "lifecycle/freeze.html": [
+    [
+     "/lifecycle/freeze.html",
+     {}
+    ]
+   ],
    "longtask-timing/longtask-attributes.html": [
     [
      "/longtask-timing/longtask-attributes.html",
@@ -271317,11 +271432,11 @@
    "testharness"
   ],
   "cookie-store/idlharness.tentative.html": [
-   "42be9e73d8e6ad3760a4c9871f6f633962f2ab85",
+   "043875184fa56ad41cda11e6f84314a7aebdb17f",
    "testharness"
   ],
   "cookie-store/idlharness_serviceworker.js": [
-   "516a0596c03b9db2446ca77d70d3eb95f060e895",
+   "42a34fc954f517498ab68ac406c0008342204466",
    "support"
   ],
   "cookie-store/idlharness_serviceworker.tentative.https.html": [
@@ -286884,6 +286999,14 @@
    "5f2bf4b6712dd230109be62407cd31800451a271",
    "testharness"
   ],
+  "css/css-animations/set-animation-play-state-to-paused-002-ref.html": [
+   "8156c889e4af141b1bdf3df52626c4337b20c611",
+   "support"
+  ],
+  "css/css-animations/set-animation-play-state-to-paused-002.html": [
+   "bd0740fea0d8b0fae749539c9702d3929b0a8093",
+   "reftest"
+  ],
   "css/css-backgrounds/OWNERS": [
    "f5ec83d4ee5ce80ae40a5fe12269d4c7c6c9d91a",
    "support"
@@ -303332,6 +303455,22 @@
    "7d1a1c21880b25fe0126affa850fb13bdf80470b",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html": [
+   "7387c69c5f442f72c4f253242823f97b7c26ed83",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html": [
+   "a95963f14832c60c44aa63915ea557fdabe3183f",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html": [
+   "e5c7e8adb9d33b307041429f708aae12b0203a58",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html": [
+   "d24ae3fb7aad80368ea4f22122e18157596bf45a",
+   "testharness"
+  ],
   "css/css-grid/alignment/grid-content-distribution-001.html": [
    "5622a264eb2dbd6cf621ac97aa4a8ae5db82c6b3",
    "reftest"
@@ -303656,6 +303795,22 @@
    "7f95db93458af40478ad2cd6b473e8f34f62f3e8",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html": [
+   "7f2b8621613e433c84b70310c64051b4b3893a67",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html": [
+   "c25d5c44d2a7d07b789a2cf669f50a21f6df4f8e",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html": [
+   "edf4aec4ce1ba1bbda1a5e6ade38a712522623c5",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html": [
+   "d83d361ef95e1a4c16b33a9057d7559aaa43a242",
+   "testharness"
+  ],
   "css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-001.html": [
    "cafc54256ea9d0cbf8990a0e04904c7ada8c5894",
    "testharness"
@@ -303976,6 +304131,14 @@
    "737ff1592425bb6e89a9edebdd072c94e926a1a9",
    "testharness"
   ],
+  "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html": [
+   "8ff9af9ade9e12c95d7e70778635efdc2263e62b",
+   "testharness"
+  ],
+  "css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html": [
+   "28a7a3372ec47cb31afde392da0752032f416512",
+   "testharness"
+  ],
   "css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-001.html": [
    "e7250b61f6dc882945f73412ec73c0de7f139aad",
    "reftest"
@@ -308608,6 +308771,14 @@
    "f11765ff416808470d52dde2500106c294243469",
    "reftest"
   ],
+  "css/css-pseudo/placeholder-input-number-notref.html": [
+   "c005e33b7e50074d19c0afd7d9790a38b29ef52e",
+   "support"
+  ],
+  "css/css-pseudo/placeholder-input-number.html": [
+   "90f5c1a64e8171cfce64820b30ad7feafd6e5b06",
+   "reftest"
+  ],
   "css/css-rhythm/OWNERS": [
    "f07bfffa1c63e98cd2a56d75ce2e6d2542972002",
    "support"
@@ -321217,7 +321388,7 @@
    "support"
   ],
   "css/css-transitions/support/properties.js": [
-   "c789935bb1a3077f539d20363e6dbeeda1d8cc6e",
+   "a9958d79bf07ddc168a9face2a9ced0f7bf3ce7a",
    "support"
   ],
   "css/css-transitions/support/ruler-h-50%.png": [
@@ -335888,6 +336059,10 @@
    "0e795989a9acaa0d153c31a0a965f6aa7600e024",
    "support"
   ],
+  "css/support/grid.css": [
+   "6bb300b8baebf700481ea162fb7b41913fcca29c",
+   "support"
+  ],
   "css/support/import-green.css": [
    "db4f420efdb292d6520be1a3bf052ed3f6f9e7e3",
    "support"
@@ -368624,6 +368799,18 @@
    "28b559875ce9514702d181cb4cb5e0a207083e2d",
    "testharness"
   ],
+  "lifecycle/freeze.html": [
+   "aca6ab2b23924ff891dc2abc26eb3067ad099e5b",
+   "testharness"
+  ],
+  "lifecycle/resources/foo.txt": [
+   "b909d6288b51d2b2dfe06382f057a5892826949b",
+   "support"
+  ],
+  "lifecycle/resources/window.html": [
+   "3c839ba3697d5ce8bcda99824af7dea7b37534c1",
+   "support"
+  ],
   "longtask-timing/OWNERS": [
    "94649180cc13aa981899b14b421551102a624332",
    "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness.tentative.html
index 9835427..b9cab34 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness.tentative.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness.tentative.html
@@ -54,8 +54,8 @@
   idl_array.add_idls(cookie_store);
 
   idl_array.add_objects({
-    CookieStore: [self.cookieStore],
-    CookieChangeEvent: [new CookieChangeEvent('change')],
+    CookieStore: ["self.cookieStore"],
+    CookieChangeEvent: ["new CookieChangeEvent('change')"],
   });
   idl_array.test();
 }, 'Interface test');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness_serviceworker.js b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness_serviceworker.js
index ba80413..1b28b289 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness_serviceworker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/cookie-store/idlharness_serviceworker.js
@@ -35,9 +35,9 @@
   idl_array.add_idls(cookie_store);
 
   idl_array.add_objects({
-    CookieStore: [self.cookieStore],
+    CookieStore: ["self.cookieStore"],
     ExtendableCookieChangeEvent: [
-        new ExtendableCookieChangeEvent('cookiechange')],
+        "new ExtendableCookieChangeEvent('cookiechange')"],
   });
   idl_array.test();
 }, 'Interface test');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002-ref.html
new file mode 100644
index 0000000..16bcb21
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Dynamically set animation-play-state to paused (reference)</title>
+    <style>
+      #container {
+        position: absolute;
+        left: 0;
+        top: 3em;
+      }
+      #coveringRectLinear, #coveringRectSteps {
+        position: absolute;
+        background: lightgreen;
+        width: 40px;
+        height: 70px;
+        left: 80px;
+        transform-origin: 50% 10%;
+        transform: translate(36px, 0) rotate(144deg);
+      }
+      #coveringRectLinear {
+        top: 50px;
+      }
+      #coveringRectSteps {
+        top: 150px;
+      }
+    </style>
+  </head>
+  <body>
+    <p>This test passes if you see two rotated green rectangles and no red.</p>
+    <div id="container">
+      <div id="coveringRectLinear"></div>
+      <div id="coveringRectSteps"></div>
+    </div>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002.html
new file mode 100644
index 0000000..210d027
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/set-animation-play-state-to-paused-002.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <meta charset="utf-8">
+    <title>Dynamically set animation-play-state to paused</title>
+    <link rel="author" title="Igalia S.L." href="https://www.igalia.com/">
+    <link rel="help" href="https://drafts.csswg.org/css-animations-1/#animation-play-state">
+    <meta name="assert" content="Visually check that complex animations stop
+                                 when animation-play-state is set to paused">
+    <link rel="match" href="set-animation-play-state-to-paused-002-ref.html">
+    <style>
+      #container {
+        position: absolute;
+        left: 0;
+        top: 3em;
+      }
+      #lineLinear, #lineSteps  {
+        position: absolute;
+        background: red;
+        width: 10px;
+        height: 50px;
+        left: 95px;
+        transform-origin: 50% 0%;
+      }
+      #coveringRectLinear, #coveringRectSteps {
+        position: absolute;
+        background: lightgreen;
+        width: 40px;
+        height: 70px;
+        left: 80px;
+        transform-origin: 50% 10%;
+        transform: translate(36px, 0) rotate(144deg);
+      }
+      #coveringRectLinear, #lineLinear {
+        top: 50px;
+      }
+      #coveringRectSteps, #lineSteps {
+        top: 150px;
+      }
+      #lineLinear {
+        animation: rotate 2s linear;
+      }
+      #lineSteps {
+        animation: rotate 2s steps(360, end);
+      }
+      .pause {
+        opacity: 0.6;
+        animation-play-state: paused !important;
+      }
+      @keyframes rotate
+      {
+        100% {
+          transform: translate(90px, 0) rotate(360deg);
+        }
+      }
+    </style>
+    <script>
+      var start = null;
+      var animationDuration = 2000;
+      var coveringRectAngle = 144;
+      var rectFinalAngle = 360;
+      function step(timestamp) {
+        if (!start) start = timestamp;
+        var progress = timestamp - start;
+
+        // Pause the animations when the squares pass under the covering rect.
+        var targetProgress = animationDuration * coveringRectAngle / rectFinalAngle;
+        if (progress >= targetProgress) {
+          document.getElementById("lineLinear").classList.add("pause");
+          document.getElementById("lineSteps").classList.add("pause");
+        }
+
+        // Wait a bit so that the squares pass the covering rect if the
+        // animation fails to be paused.
+        var delta = 200;
+        if (progress < targetProgress + delta)
+          window.requestAnimationFrame(step)
+        else
+          document.documentElement.classList.remove("reftest-wait");
+      }
+      function runTest() {
+        window.requestAnimationFrame(step);
+      }
+    </script>
+  </head>
+  <body onload="runTest()">
+    <p>This test passes if you see two rotated green rectangles and no red.</p>
+    <div id="container">
+      <div id="lineLinear"></div>
+      <div id="coveringRectLinear"></div>
+      <div id="lineSteps"></div>
+      <div id="coveringRectSteps"></div>
+    </div>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html
new file mode 100644
index 0000000..bce62cf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-001.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along column-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Grid items orthogonal to the Baseline Alignment Context should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.container { position: relative; }
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 200px 100px / 100px 200px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25  { width: 25px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 25px; }
+.paddingRight { padding-right: 25px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and verticalRL item</pre>
+
+<div class="grid width300 alignItemsBaseline">
+  <div class="firstRowFirstColumn verticalRL" data-offset-x="0"   data-offset-y="0"   data-expected-width="100" data-expected-height="200">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="firstRowSecondColumn bigFont"   data-offset-x="100" data-offset-y="160" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 height25"></div>
+</div>
+
+<pre>Horizontal grid and verticalLR item</pre>
+
+<div class="grid width300 alignItemsBaseline">
+  <div class="firstRowFirstColumn verticalLR" data-offset-x="0"   data-offset-y="0"   data-expected-width="100" data-expected-height="200">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="firstRowSecondColumn bigFont"   data-offset-x="100" data-offset-y="160" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 height25"></div>
+</div>
+
+<pre>VerticalLR grid and Horizontal item</pre>
+
+<div class="grid alignItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn horizontalTB"         data-offset-x="35" data-offset-y="0"   data-expected-width="200" data-expected-height="100">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="firstRowSecondColumn bigFont paddingLeft" data-offset-x="0"  data-offset-y="100" data-expected-width="125" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+<pre>VerticalRL grid and Horizontal item</pre>
+
+<div class="grid alignItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn horizontalTB"          data-offset-x="100" data-offset-y="0"   data-expected-width="200" data-expected-height="100">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="firstRowSecondColumn bigFont paddingRight" data-offset-x="40"  data-offset-y="100" data-expected-width="125" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html
new file mode 100644
index 0000000..d5757ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-002.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along column-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Empty grid items with fixed size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 200px 100px / 100px 200px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25  { width: 25px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.fixedHeight { height: 125px; }
+.fixedWidth  { width: 125px; }
+
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and item with fixed height</pre>
+
+<div class="grid width300 alignItemsBaseline">
+  <div class="firstRowFirstColumn fixedHeight"  data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="firstRowSecondColumn bigFont"     data-offset-x="100" data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 height25"></div>
+</div>
+
+<pre>VerticalLR grid and item with fixed width</pre>
+
+<div class="grid alignItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn fixedWidth"            data-offset-x="30" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingLeft"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+<pre>VerticalRL grid and item with fixed width</pre>
+
+<div class="grid alignItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn fixedWidth"            data-offset-x="175" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingRight" data-offset-x="115" data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html
new file mode 100644
index 0000000..22e0320
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-003.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along column-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Empty grid items with relative size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 200px 100px / 100px 200px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.height75 { height: 75px; }
+.width25  { width: 25px; }
+.width75  { width: 75px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.relativeHeight { height: 50%; }
+.relativeWidth  { width: 50%; }
+
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and item with relative height</pre>
+
+<div class="grid width300 alignItemsBaseline">
+  <div class="firstRowFirstColumn relativeHeight"  data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont"        data-offset-x="100" data-offset-y="60" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 height25"></div>
+</div>
+
+<pre>VerticalLR grid and item with relative width</pre>
+
+<div class="grid alignItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn relativeWidth"         data-offset-x="30" data-offset-y="0"   data-expected-width="100" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingLeft"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+<pre>VerticalRL grid and item with rlative width</pre>
+
+<div class="grid alignItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn relativeWidth"          data-offset-x="200" data-offset-y="0"   data-expected-width="100" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingRight"  data-offset-x="140" data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html
new file mode 100644
index 0000000..3630eee3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-column-axis-self-baseline-synthesized-004.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along column-axis on content-sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Grid items orthogonal to the Baseline Alignment Context should use their border-box 'under' edge as synthesized baseline.">
+<meta name="assert" content="Empty grid items with fixed size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: auto auto / 100px 200px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25  { width: 25px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.fixedHeight { height: 125px; }
+.fixedWidth  { width: 125px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and item with fixed height</pre>
+
+<div class="grid width300 alignItemsBaseline">
+  <div class="firstRowFirstColumn fixedHeight" data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="firstRowSecondColumn bigFont"    data-offset-x="100" data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 height25"></div>
+</div>
+
+<pre>VerticalLR grid and item with fixed width</pre>
+
+<div class="grid alignItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn fixedWidth"            data-offset-x="30" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingLeft"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
+
+<pre>VerticalRL grid and item with fixed width</pre>
+
+<div class="grid alignItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn fixedWidth"             data-offset-x="85" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="firstRowSecondColumn bigFont paddingRight"  data-offset-x="25" data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowAutoColumnSpanning2 width25"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html
new file mode 100644
index 0000000..e5a6849
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along row-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Grid items orthogonal to the Baseline Alignment Context should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.container { position: relative; }
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 100px 200px / 200px 100px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25 { width: 25px; }
+.width200 { width: 200px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 25px; }
+.paddingRight { padding-right: 25px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and verticalRL item</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn"                                   data-offset-x="60" data-offset-y="0"   data-expected-width="200" data-expected-height="100">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="secondRowFirstColumn bigFont paddingRight verticalRL"  data-offset-x="0"  data-offset-y="100" data-expected-width="125" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>Horizontal grid and verticalLR item</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn"                                  data-offset-x="35" data-offset-y="0"   data-expected-width="200" data-expected-height="100">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="secondRowFirstColumn bigFont paddingLeft verticalLR"  data-offset-x="0"  data-offset-y="100" data-expected-width="125" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>VerticalLR grid and Horizontal item</pre>
+
+<div class="grid justifyItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn"                        data-offset-x="0"   data-offset-y="0"   data-expected-width="100" data-expected-height="200">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="100" data-offset-y="160" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+<pre>VerticalLR grid and Horizontal item</pre>
+
+<div class="grid justifyItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn"                        data-offset-x="200" data-offset-y="0"   data-expected-width="100" data-expected-height="200">ÉÉ É ÉÉÉ É ÉÉ É</div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="0"   data-offset-y="160" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html
new file mode 100644
index 0000000..c43b8563
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-002.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along row-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Empty grid items with fixed size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.container { position: relative; }
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 100px 200px / 200px 100px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25 { width: 25px; }
+.width200 { width: 200px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.fixedHeight { height: 125px; }
+.fixedWidth  { width: 125px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and verticalLR item with fixed width</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn fixedWidth"                       data-offset-x="30" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingLeft verticalLR"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>Horizontal grid and verticalRL item with fixed width</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn fixedWidth"                        data-offset-x="60" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingRight verticalRL"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>VerticalLR grid and item with fixed height</pre>
+
+<div class="grid justifyItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn fixedHeight"            data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="100" data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+<pre>VerticalRL grid and item with fixed width</pre>
+
+<div class="grid justifyItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn fixedHeight"            data-offset-x="200" data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="0"   data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html
new file mode 100644
index 0000000..b9c60ff7f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-003.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along row-axis on fixed sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Empty grid items with relative size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.container { position: relative; }
+.grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 100px 200px / 200px 100px;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25 { width: 25px; }
+.width200 { width: 200px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.relativeHeight { height: 50%; }
+.relativeWidth  { width: 50%; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.grid')">
+
+<pre>Horizontal grid and verticalLR item with relative width</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn relativeWidth"                    data-offset-x="30" data-offset-y="0"   data-expected-width="100" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingLeft verticalLR"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>Horizontal grid and verticalRL item with relative width</pre>
+
+<div class="grid width300 justifyItemsBaseline">
+  <div class="firstRowFirstColumn relativeWidth"                    data-offset-x="60" data-offset-y="0"   data-expected-width="100" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingRight verticalRL" data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>VerticalLR grid and item with relative height</pre>
+
+<div class="grid justifyItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn relativeHeight"         data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="100" data-offset-y="60" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+<pre>VerticalRL grid and item with relative height</pre>
+
+<div class="grid justifyItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn relativeHeight"         data-offset-x="200" data-offset-y="0"  data-expected-width="100" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="0"   data-offset-y="60" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html
new file mode 100644
index 0000000..d1f3959
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-004.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment along row-axis on content-sized grids and synthesized baselines</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="help" href="https://drafts.csswg.org/css-align/#synthesize-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Empty grid items with fixed size should use their border-box 'under' edge as synthesized baseline.">
+<style>
+.container { position: relative; }
+.inline-grid {
+  position: relative;
+  text-orientation: sideways;
+  grid: 100px 200px / auto auto;
+  font-family: Ahem;
+}
+.bigFont  { font-size: 50px; }
+.height25 { height: 25px; }
+.width25 { width: 25px; }
+.width200 { width: 200px; }
+.width300 { width: 300px; }
+
+.paddingLeft { padding-left: 20px; }
+.paddingRight { padding-right: 20px; }
+
+.fixedHeight { height: 125px; }
+.fixedWidth  { width: 125px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.inline-grid')">
+
+<pre>Horizontal grid and verticalLR item with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline" data-expected-width="180" data-expected-height="300">
+  <div class="firstRowFirstColumn fixedWidth"                       data-offset-x="30" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingLeft verticalLR"  data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>Horizontal grid and verticalRL item with fixed width</pre>
+
+<div class="inline-grid justifyItemsBaseline" data-expected-width="210" data-expected-height="300">
+  <div class="firstRowFirstColumn fixedWidth"                       data-offset-x="60" data-offset-y="0"   data-expected-width="125" data-expected-height="100"></div>
+  <div class="secondRowFirstColumn bigFont paddingRight verticalRL" data-offset-x="0"  data-offset-y="100" data-expected-width="120" data-expected-height="200">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn width25"></div>
+</div>
+
+<pre>VerticalLR grid and item with fixed height</pre>
+
+<div class="inline-grid justifyItemsBaseline verticalLR">
+  <div class="firstRowFirstColumn fixedHeight"            data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="100" data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+<pre>VerticalRL grid and item with fixed height</pre>
+
+<div class="inline-grid justifyItemsBaseline verticalRL">
+  <div class="firstRowFirstColumn fixedHeight"            data-offset-x="200" data-offset-y="0"  data-expected-width="100" data-expected-height="125"></div>
+  <div class="secondRowFirstColumn bigFont horizontalTB"  data-offset-x="0"   data-offset-y="85" data-expected-width="200" data-expected-height="100">É É ÉÉ</div>
+  <div class="autoRowSpanning2AutoColumn height25"></div>
+</div>
+
+
+</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html
new file mode 100644
index 0000000..b35b16d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment and sizing cyclic dependency</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Grid items with relative size in the inline or block axis and an intrinsically-sized column or row respectively, don't participate in baseline alignment in the, row-like or column-like respectively, shared alignment context.">
+<style>
+.inline-grid {
+  position: relative;
+  border: solid;
+  text-orientation: sideways;
+  font-family: Ahem;
+}
+
+.columns { grid-template-columns: 100px 100px; }
+.rows { grid-template-rows: 100px 100px; }
+
+.min-content-columns { grid-auto-columns: min-content; }
+.max-content-columns { grid-auto-columns: max-content; }
+.fit-content-columns { grid-auto-columns: fit-content; }
+.flex-columns        { grid-auto-columns: 1fr; }
+.min-content-rows { grid-auto-rows: min-content; }
+.max-content-rows { grid-auto-rows: max-content; }
+.fit-content-rows { grid-auto-rows: fit-content; }
+.flex-rows        { grid-auto-rows: 1fr; }
+
+.height25  { height: 25px; }
+.height50  { height: 50px; }
+.height200 { height: 200px; }
+.width25   { width: 25px; }
+.width50   { width: 50px; }
+.width200  { width: 200px; }
+
+.height200Percent { height: 200%; }
+.width200Percent  { width: 200%; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.inline-grid')">
+
+<pre>auto-sized rows - items with relative height</pre>
+
+<div class="inline-grid alignItemsBaseline columns">
+  <div class="firstRowFirstColumn height50"          data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="50"></div>
+  <div class="firstRowSecondColumn height200Percent" data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="100"></div>
+  <div class="autoRowAutoColumnSpanning2 height25"   data-offset-x="0"   data-offset-y="50" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>min-content-sized rows - items with relative height</pre>
+
+<div class="inline-grid alignItemsBaseline columns min-content-rows">
+  <div class="firstRowFirstColumn"                   data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="80">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSecondColumn height200Percent" data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="160"></div>
+  <div class="autoRowAutoColumnSpanning2 height25"   data-offset-x="0"   data-offset-y="80" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>max-content-sized rows - items with relative height</pre>
+
+<div class="inline-grid alignItemsBaseline columns max-content-rows">
+  <div class="firstRowFirstColumn"                   data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="80">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSecondColumn height200Percent" data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="160"></div>
+  <div class="autoRowAutoColumnSpanning2 height25"   data-offset-x="0"   data-offset-y="80" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>fit-content-sized rows - items with relative height</pre>
+
+<div class="inline-grid alignItemsBaseline columns fit-content-rows">
+  <div class="firstRowFirstColumn"                   data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="80">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSecondColumn height200Percent" data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="160"></div>
+  <div class="autoRowAutoColumnSpanning2 height25"   data-offset-x="0"   data-offset-y="80" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>flexible-sized rows - items with relative height</pre>
+
+<div class="inline-grid alignItemsBaseline columns flex-rows">
+  <div class="firstRowFirstColumn height50"          data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="50"></div>
+  <div class="firstRowSecondColumn height200Percent" data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="100"></div>
+  <div class="autoRowAutoColumnSpanning2 height25"   data-offset-x="0"   data-offset-y="50" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>auto-sized columns - items with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline rows">
+  <div class="firstRowFirstColumn verticalRL width50"          data-offset-x="0"  data-offset-y="0"   data-expected-width="50"  data-expected-height="100"></div>
+  <div class="secondRowFirstColumn verticalRL width200Percent" data-offset-x="0"  data-offset-y="100" data-expected-width="100" data-expected-height="100"></div>
+  <div class="firstRowSpanning2AutoColumn verticalRL width25"  data-offset-x="50" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>min-content-sized columns - items with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline rows min-content-columns">
+  <div class="firstRowFirstColumn verticalRL"                  data-offset-x="0"  data-offset-y="0"   data-expected-width="80"  data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="secondRowFirstColumn verticalRL width200Percent" data-offset-x="0"  data-offset-y="100" data-expected-width="160" data-expected-height="100"></div>
+  <div class="firstRowSpanning2AutoColumn verticalRL width25"  data-offset-x="80" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>max-content-sized columns - items with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline rows max-content-columns">
+  <div class="firstRowFirstColumn verticalRL"                  data-offset-x="0"  data-offset-y="0"   data-expected-width="80"  data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="secondRowFirstColumn verticalRL width200Percent" data-offset-x="0"  data-offset-y="100" data-expected-width="160" data-expected-height="100"></div>
+  <div class="firstRowSpanning2AutoColumn verticalRL width25"  data-offset-x="80" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>fit-content-sized columns - items with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline rows fit-content-columns">
+  <div class="firstRowFirstColumn verticalRL"                  data-offset-x="0"  data-offset-y="0"   data-expected-width="80"  data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="secondRowFirstColumn verticalRL width200Percent" data-offset-x="0"  data-offset-y="100" data-expected-width="160" data-expected-height="100"></div>
+  <div class="firstRowSpanning2AutoColumn verticalRL width25"  data-offset-x="80" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>flexible-sized columns - items with relative width</pre>
+
+<div class="inline-grid justifyItemsBaseline rows flex-columns">
+  <div class="firstRowFirstColumn verticalRL width50"          data-offset-x="0"  data-offset-y="0"   data-expected-width="50"  data-expected-height="100"></div>
+  <div class="secondRowFirstColumn verticalRL width200Percent" data-offset-x="0"  data-offset-y="100" data-expected-width="100" data-expected-height="100"></div>
+  <div class="firstRowSpanning2AutoColumn verticalRL width25"  data-offset-x="50" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html
new file mode 100644
index 0000000..4d0f506
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-002.html
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Layout Test: Self-Baseline alignment and sizing cyclic dependency</title>
+<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#column-align">
+<link rel="help" href="https://drafts.csswg.org/css-grid-1/#row-align">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-justify-items">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#baseline-alignment">
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#valdef-justify-self-baseline">
+<link rel="stylesheet" href="../../support/grid.css">
+<link rel="stylesheet" href="../../support/alignment.css">
+<meta name="assert" content="Grid items orthogonal to the Baseline Context along the inline or block axis and an intrinsically-sized column or row respectively, don't participate in baseline alignment in the, row-like or column-like respectively, shared alignment context.">
+<style>
+.inline-grid {
+  position: relative;
+  border: solid;
+  text-orientation: sideways;
+  font-family: Ahem;
+}
+
+.columns { grid-template-columns: 100px 100px; }
+.rows { grid-template-rows: 100px 100px; }
+
+.min-content-columns { grid-auto-columns: min-content; }
+.max-content-columns { grid-auto-columns: max-content; }
+.fit-content-columns { grid-auto-columns: fit-content; }
+.flex-columns        { grid-auto-columns: 1fr; }
+.min-content-rows { grid-auto-rows: min-content; }
+.max-content-rows { grid-auto-rows: max-content; }
+.fit-content-rows { grid-auto-rows: fit-content; }
+.flex-rows        { grid-auto-rows: 1fr; }
+
+.height25  { height: 25px; }
+.height50  { height: 50px; }
+.height200 { height: 200px; }
+.width25   { width: 25px; }
+.width50   { width: 50px; }
+.width200  { width: 200px; }
+
+.bigFont { font-size: 50px; }
+.paddingLeft { padding-left: 25px; }
+.paddingBottom { padding-bottom: 25px; }
+.paddingRight { padding-right: 25px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.inline-grid')">
+
+<pre>auto-sized rows - horizonal grid and verticalLR item - column-axis baseline</pre>
+
+<div class="inline-grid alignItemsBaseline columns height200">
+  <div class="firstRowFirstColumn bigFont paddingBottom" data-offset-x="0"   data-offset-y="0"   data-expected-width="100" data-expected-height="75">É</div>
+  <div class="firstRowSecondColumn verticalLR"           data-offset-x="100" data-offset-y="0"   data-expected-width="100" data-expected-height="175">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 height25"       data-offset-x="0"   data-offset-y="175" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>min-content-sized rows - horizonal grid and verticalLR item - column-axis baseline</pre>
+
+<div class="inline-grid alignItemsBaseline columns min-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingBottom" data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="75">É</div>
+  <div class="firstRowSecondColumn verticalLR"           data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="75">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 height25"       data-offset-x="0"   data-offset-y="75" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>max-content-sized rows - horizonal grid and verticalLR item - column-axis baseline</pre>
+
+<div class="inline-grid alignItemsBaseline columns max-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingBottom" data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="75">É</div>
+  <div class="firstRowSecondColumn verticalLR"           data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="416">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 height25"       data-offset-x="0"   data-offset-y="416" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>fit-content-sized rows - horizonal grid and verticalLR item - column-axis baseline</pre>
+
+<div class="inline-grid alignItemsBaseline columns fit-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingBottom" data-offset-x="0"   data-offset-y="0"  data-expected-width="100" data-expected-height="75">É</div>
+  <div class="firstRowSecondColumn verticalLR"           data-offset-x="100" data-offset-y="0"  data-expected-width="100" data-expected-height="416">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 height25"       data-offset-x="0"   data-offset-y="416" data-expected-width="200" data-expected-height="25"></div>
+</div>
+
+<pre>auto-sized columns - horizontal grid item - row-axis baseline</pre>
+
+<div class="inline-grid justifyItemsBaseline rows width200">
+  <div class="firstRowFirstColumn bigFont verticalLR paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="secondRowFirstColumn"                               data-offset-x="0"   data-offset-y="100" data-expected-width="175" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSpanning2AutoColumn width25"                data-offset-x="175" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>min-content-sized columns - horizontal grid item - row-axis baseline</pre>
+
+<div class="inline-grid justifyItemsBaseline rows min-content-columns">
+  <div class="firstRowFirstColumn bigFont verticalLR paddingLeft" data-offset-x="0"  data-offset-y="0"   data-expected-width="75" data-expected-height="100">É</div>
+  <div class="secondRowFirstColumn"                               data-offset-x="0"  data-offset-y="100" data-expected-width="75" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSpanning2AutoColumn width25"                data-offset-x="75" data-offset-y="0"   data-expected-width="25" data-expected-height="200"></div>
+</div>
+
+<pre>max-content-sized columns - horizontal grid item - row-axis baseline</pre>
+
+<div class="inline-grid justifyItemsBaseline rows max-content-columns">
+  <div class="firstRowFirstColumn bigFont verticalLR paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="secondRowFirstColumn"                               data-offset-x="0"   data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSpanning2AutoColumn width25"                data-offset-x="416" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>fit-content-sized columns - horizontal grid item - row-axis baseline</pre>
+
+<div class="inline-grid justifyItemsBaseline rows fit-content-columns">
+  <div class="firstRowFirstColumn bigFont verticalLR paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="secondRowFirstColumn"                               data-offset-x="0"   data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="firstRowSpanning2AutoColumn width25"                data-offset-x="416" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>auto-sized rows - verticalLR grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalLR alignItemsBaseline columns width200">
+  <div class="firstRowFirstColumn bigFont paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"       data-offset-x="0"   data-offset-y="100" data-expected-width="175" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"      data-offset-x="175" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>min-content-sized rows - verticalLR grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalLR alignItemsBaseline columns min-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingLeft" data-offset-x="0"  data-offset-y="0"   data-expected-width="75" data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"       data-offset-x="0"  data-offset-y="100" data-expected-width="75" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"      data-offset-x="75" data-offset-y="0"   data-expected-width="25" data-expected-height="200"></div>
+</div>
+
+<pre>max-content-sized rows - verticalLR grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalLR alignItemsBaseline columns max-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"       data-offset-x="0"   data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"      data-offset-x="416" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>fit-content-sized rows - verticalLR grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalLR alignItemsBaseline columns fit-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingLeft" data-offset-x="0"   data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"       data-offset-x="0"   data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"      data-offset-x="416" data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>auto-sized rows - verticalRL grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalRL alignItemsBaseline columns width200">
+  <div class="firstRowFirstColumn bigFont paddingRight"  data-offset-x="125" data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"         data-offset-x="25"  data-offset-y="100" data-expected-width="175" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"        data-offset-x="0"   data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>min-content-sized rows - verticalRL grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalRL alignItemsBaseline columns min-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingRight"  data-offset-x="25" data-offset-y="0"   data-expected-width="75" data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"         data-offset-x="25" data-offset-y="100" data-expected-width="75" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"        data-offset-x="0"  data-offset-y="0"   data-expected-width="25" data-expected-height="200"></div>
+</div>
+
+<pre>max-content-sized rows - verticalRL grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalRL alignItemsBaseline columns max-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingRight"  data-offset-x="366" data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"         data-offset-x="25"  data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"        data-offset-x="0"   data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
+
+<pre>fit-content-sized rows - verticalRL grid and horizontal item - column-axis baseline</pre>
+
+<div class="inline-grid verticalRL alignItemsBaseline columns fit-content-rows">
+  <div class="firstRowFirstColumn bigFont paddingRight"  data-offset-x="366" data-offset-y="0"   data-expected-width="75"  data-expected-height="100">É</div>
+  <div class="firstRowSecondColumn horizontalTB"         data-offset-x="25"  data-offset-y="100" data-expected-width="416" data-expected-height="100">ÉÉ É ÉÉ ÉÉÉÉ É ÉÉ ÉÉÉ ÉÉ É</div>
+  <div class="autoRowAutoColumnSpanning2 width25"        data-offset-x="0"   data-offset-y="0"   data-expected-width="25"  data-expected-height="200"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number-notref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number-notref.html
new file mode 100644
index 0000000..92ae71d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number-notref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<style>
+#number::placeholder {
+  color: blue;
+}
+</style>
+<input id="number" type="number" placeholder="Placeholder">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number.html
new file mode 100644
index 0000000..a557f109
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-pseudo/placeholder-input-number.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>CSS Test: ::placeholder applies to input type="number"</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="mismatch" href="placeholder-input-number-notref.html">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#placeholder-pseudo">
+<style>
+#number::placeholder {
+  color: green;
+}
+</style>
+<input id="number" type="number" placeholder="Placeholder">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/support/properties.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/support/properties.js
index 01fb6e7..9ca23450 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/support/properties.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/support/properties.js
@@ -221,8 +221,6 @@
     'outline-width': ['length'],
 
     'clip': ['rectangle'],
-    // Note: doesn't seem implemented anywhere
-    'crop': ['rectangle'],
 
     'vertical-align': ['length', 'percentage'],
     'opacity': ['number[0,1]'],
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/support/grid.css b/third_party/WebKit/LayoutTests/external/wpt/css/support/grid.css
new file mode 100644
index 0000000..602e114
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/support/grid.css
@@ -0,0 +1,277 @@
+.grid {
+  display: grid;
+  background-color: grey;
+}
+
+.inline-grid {
+  display: inline-grid;
+  background-color: grey;
+}
+
+.firstRowFirstColumn {
+  background-color: blue;
+  grid-column: 1;
+  grid-row: 1;
+}
+
+.onlyFirstRowOnlyFirstColumn {
+  background-color: blue;
+  grid-column: 1 / 2;
+  grid-row: 1 / 2;
+}
+
+.firstRowSecondColumn {
+  background-color: lime;
+  grid-column: 2;
+  grid-row: 1;
+}
+
+.onlyFirstRowOnlySecondColumn {
+  background-color: lime;
+  grid-column: 2 / 3;
+  grid-row: 1 / 2;
+}
+
+.secondRowFirstColumn {
+  background-color: purple;
+  grid-column: 1;
+  grid-row: 2;
+}
+
+.onlySecondRowOnlyFirstColumn {
+  background-color: purple;
+  grid-column: 1 / 2;
+  grid-row: 2 / 3;
+}
+
+.secondRowSecondColumn {
+  background-color: orange;
+  grid-column: 2;
+  grid-row: 2;
+}
+
+.onlySecondRowOnlySecondColumn {
+  background-color: orange;
+  grid-column: 2 / 3;
+  grid-row: 2 / 3;
+}
+
+.endSecondRowEndSecondColumn {
+  background-color: orange;
+  grid-column-end: 3;
+  grid-row-end: 3;
+}
+
+.thirdRowSecondColumn {
+  background-color: red;
+  grid-column: 2;
+  grid-row: 3;
+}
+
+.firstRowThirdColumn {
+  background-color: magenta;
+  grid-column: 3;
+  grid-row: 1;
+}
+
+.secondRowThirdColumn {
+  background-color: navy;
+  grid-column: 3;
+  grid-row: 2;
+}
+
+.firstRowFourthColumn {
+  background-color: green;
+  grid-column: 4;
+  grid-row: 1;
+}
+
+.secondRowFourthColumn {
+  background-color: pink;
+  grid-column: 4;
+  grid-row: 2;
+}
+
+.firstAutoRowSecondAutoColumn {
+  grid-row: 1 / auto;
+  grid-column: 2 / auto;
+}
+
+.autoLastRowAutoLastColumn {
+  grid-row: auto / -1;
+  grid-column: auto / -1;
+}
+
+.autoSecondRowAutoFirstColumn {
+  grid-row: auto / 2;
+  grid-column: auto / 1;
+}
+
+.firstRowBothColumn {
+  grid-row: 1;
+  grid-column: 1 / -1;
+}
+
+.secondRowBothColumn {
+  grid-row: 2;
+  grid-column: 1 / -1;
+}
+
+.bothRowFirstColumn {
+  grid-row: 1 / -1;
+  grid-column: 1;
+}
+
+.bothRowSecondColumn {
+  grid-row: 1 / -1;
+  grid-column: 2;
+}
+
+.bothRowBothColumn {
+  grid-row: 1 / -1;
+  grid-column: 1 / -1;
+}
+
+/* Auto column / row. */
+.autoRowAutoColumn {
+  background-color: pink;
+  grid-column: auto;
+  grid-row: auto;
+}
+
+.firstRowAutoColumn {
+  background-color: blue;
+  grid-column: auto;
+  grid-row: 1;
+}
+
+.secondRowAutoColumn {
+  background-color: purple;
+  grid-column: auto;
+  grid-row: 2;
+}
+
+.thirdRowAutoColumn {
+  background-color: navy;
+  grid-column: auto;
+  grid-row: 3;
+}
+
+.autoRowFirstColumn {
+  background-color: lime;
+  grid-column: 1;
+  grid-row: auto;
+}
+
+.autoRowSecondColumn {
+  background-color: orange;
+  grid-column: 2;
+  grid-row: auto;
+}
+
+.autoRowThirdColumn {
+  background-color: magenta;
+  grid-column: 3;
+  grid-row: auto;
+}
+
+.autoRowAutoColumnSpanning2 {
+  background-color: maroon;
+  grid-column: span 2;
+  grid-row: auto;
+}
+
+.autoRowSpanning2AutoColumn {
+  background-color: aqua;
+  grid-column: auto;
+  grid-row: span 2;
+}
+
+.autoRowSpanning2AutoColumnSpanning3 {
+  background-color: olive;
+  grid-column: span 3;
+  grid-row: span 2;
+}
+
+.autoRowSpanning3AutoColumnSpanning2 {
+  background-color: indigo;
+  grid-column: span 2;
+  grid-row: span 3;
+}
+
+.autoRowFirstColumnSpanning2 {
+  background-color: maroon;
+  grid-column: 1 / span 2;
+  grid-row: auto;
+}
+
+.autoRowSecondColumnSpanning2 {
+  background-color: olive;
+  grid-column: 2 / span 2;
+  grid-row: auto;
+}
+
+.firstRowSpanning2AutoColumn {
+  background-color: maroon;
+  grid-column: auto;
+  grid-row: 1 / span 2;
+  height: 100%;
+}
+
+.secondRowSpanning2AutoColumn {
+  background-color: olive;
+  grid-column: auto;
+  grid-row: 2 / span 2;
+  height: 100%;
+}
+
+/* Grid element flow. */
+.gridAutoFlowColumnSparse {
+  grid-auto-flow: column;
+}
+
+.gridAutoFlowColumnDense {
+  grid-auto-flow: column dense;
+}
+
+.gridAutoFlowRowSparse {
+  grid-auto-flow: row;
+}
+
+.gridAutoFlowRowDense {
+  grid-auto-flow: row dense;
+}
+
+/* This rule makes sure the container is smaller than any grid items to avoid distributing any extra logical space to them. */
+.constrainedContainer {
+  width: 10px;
+  height: 10px;
+}
+
+.unconstrainedContainer {
+  width: 1000px;
+  height: 1000px;
+}
+
+.sizedToGridArea {
+  font: 10px/1 Ahem;
+  /* Make us fit our grid area. */
+  width: 100%;
+  height: 100%;
+}
+
+.verticalRL {
+  writing-mode: vertical-rl;
+}
+.verticalLR {
+  writing-mode: vertical-lr;
+}
+.horizontalTB {
+  writing-mode: horizontal-tb;
+}
+.directionRTL {
+  direction: rtl;
+}
+.directionLTR {
+  direction: ltr;
+}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/touch-events/create-touch-touchlist.html b/third_party/WebKit/LayoutTests/external/wpt/touch-events/create-touch-touchlist.html
deleted file mode 100644
index 2e6e49f4..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/touch-events/create-touch-touchlist.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>document.createTouch and document.createTouchList Tests</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="touch-support.js"></script>
-<body>
-<div id="target0"></div>
-<script>
-test(function() {
-    var touchList = document.createTouchList();
-    assert_equals(touchList.length, 0, "touchList.length is 0");
-    check_TouchList_object(touchList);
-}, "document.createTouchList exists and correctly creates a TouchList from zero Touch objects");
-
-test(function() {
-    var testTarget = document.getElementById('target0');
-    var touch1 = new Touch({identifier: 123, target: testTarget});
-    var touchList = document.createTouchList(touch1);
-    assert_equals(touchList.length, 1, "touchList.length is 1");
-    assert_equals(touchList.item(0), touch1, "touchList.item(0) is touch1");
-    check_TouchList_object(touchList);
-}, "document.createTouchList exists and correctly creates a TouchList from a single Touch");
-
-test(function() {
-    var testTarget = document.getElementById('target0');
-    var touch1 = new Touch({identifier: 123, target: testTarget});
-    var touch2 = new Touch({identifier: 124, target: target0});
-    var touchList = document.createTouchList(touch1, touch2);
-    assert_equals(touchList.length, 2, "touchList.length is 2");
-    assert_equals(touchList.item(0), touch1, "touchList.item(0) is touch1");
-    assert_equals(touchList.item(1), touch2, "touchList.item(1) is touch2");
-    check_TouchList_object(touchList);
-}, "document.createTouchList exists and correctly creates a TouchList from two Touch objects");
-</script>
-</head>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/touch-events/historical.html b/third_party/WebKit/LayoutTests/external/wpt/touch-events/historical.html
index e5db6ef..27cc88d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/touch-events/historical.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/touch-events/historical.html
@@ -26,7 +26,8 @@
   assert_false("identifiedTouch" in TouchList.prototype,
                "Should not be supported on the prototype");
 
-  var touchList = document.createTouchList();
+  var touchevent = new TouchEvent("touchstart", {});
+  var touchList = touchevent.touches;
   assert_false("identifiedTouch" in touchList,
                "Should not be supported on the instance");
 }, "TouchList::identifiedTouch");
@@ -47,4 +48,12 @@
   assert_false("createTouch" in document,
                "Should not be supported on the instance");
 }, "Document::createTouch");
+
+test(function() {
+  assert_false("createTouchList" in Document.prototype,
+               "Should not be supported on the prototype");
+
+  assert_false("createTouchList" in document,
+               "Should not be supported on the instance");
+}, "Document::createTouchList");
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-options-credentials.html b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-options-credentials.html
index 316b01d..6603eb9 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-options-credentials.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-options-credentials.html
@@ -17,61 +17,68 @@
     return 'COOKIE_VALUE';
   assert_equals(options.type, 'module');
 
-  if (!options.credentials || options.credentials == 'omit')
-    return '';
-  if (options.credentials == 'same-origin' || options.credentials == 'include')
+  if (!options.credentials ||
+      options.credentials == 'same-origin' ||
+      options.credentials == 'include') {
     return 'COOKIE_VALUE';
+  }
+  if (options.credentials == 'omit')
+    return '';
   assert_unreached('Invalid credentials option was specified: ' +
                    options.credentials);
 }
 
 // Runs a credentials test with the given WorkerOptions.
-async function runCredentialsTest(options) {
-  const worker = new Worker('resources/credentials.py', options);
+function credentials_test(options, description) {
+  promise_test(async () => {
+    const worker = new Worker('resources/credentials.py', options);
 
-  // Wait until the worker sends the actual cookie value.
-  const msg_event = await new Promise(resolve => worker.onmessage = resolve);
+    // Wait until the worker sends the actual cookie value.
+    const msg_event = await new Promise(resolve => worker.onmessage = resolve);
 
-  const expectedCookieValue = DetermineExpectedCookieValue(options);
-  assert_equals(msg_event.data, expectedCookieValue);
+    const expectedCookieValue = DetermineExpectedCookieValue(options);
+    assert_equals(msg_event.data, expectedCookieValue);
+  }, description);
 }
 
 // Tests for module scripts.
 
-promise_test(() => runCredentialsTest({ type: 'module'}),
-    'new Worker() with the default credentials option should not send ' +
-    'the credentials');
+credentials_test(
+    { type: 'module'},
+    'new Worker() with the default credentials option should behave as ' +
+    'credentials=same-origin and send the credentials');
 
-promise_test(() => runCredentialsTest({ credentials: 'omit',
-                                        type: 'module' }),
+credentials_test(
+    { credentials: 'omit', type: 'module' },
     'new Worker() with credentials=omit should not send the credentials');
 
-promise_test(() => runCredentialsTest({ credentials: 'same-origin',
-                                        type: 'module' }),
+credentials_test(
+    { credentials: 'same-origin', type: 'module' },
     'new Worker() with credentials=same-origin should send the credentials');
 
-promise_test(() => runCredentialsTest({ credentials: 'include',
-                                        type: 'module' }),
+credentials_test(
+    { credentials: 'include', type: 'module' },
     'new Worker() with credentials=include should send the credentials');
 
 // Tests for classic scripts.
 
-promise_test(() => runCredentialsTest({ type: 'classic' }),
+credentials_test(
+    { type: 'classic' },
     'new Worker() with type=classic should always send the credentials ' +
     'regardless of the credentials option (default).');
 
-promise_test(() => runCredentialsTest({ credentials: 'omit',
-                                        type: 'classic' }),
+credentials_test(
+    { credentials: 'omit', type: 'classic' },
     'new Worker() with type=classic should always send the credentials ' +
     'regardless of the credentials option (omit).');
 
-promise_test(() => runCredentialsTest({ credentials: 'same-origin',
-                                        type: 'classic' }),
+credentials_test(
+    { credentials: 'same-origin', type: 'classic' },
     'new Worker() with type=classic should always send the credentials ' +
     'regardless of the credentials option (same-origin).');
 
-promise_test(() => runCredentialsTest({ credentials: 'include',
-                                        type: 'classic' }),
+credentials_test(
+    { credentials: 'include', type: 'classic' },
     'new Worker() with type=classic should always send the credentials ' +
     'regardless of the credentials option (include).');
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter-expected.txt
deleted file mode 100644
index 1e7aceb..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter-expected.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-This tests a letter with :first-letter applied is present in innerText.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS document.getElementById('divFirst').innerText is document.getElementById('divNormal').innerText
-PASS document.getElementById('pFirst').innerText is document.getElementById('pNormal').innerText
-PASS document.getElementById('collapsedSpaceFirst').innerText is document.getElementById('collapsedSpaceNormal').innerText
-PASS document.getElementById('collapsedSpacePreFirst').innerText is document.getElementById('collapsedSpacePreNormal').innerText
-PASS document.getElementById('preLineFirst').innerText is document.getElementById('preLineNormal').innerText
-PASS document.getElementById('preWrapFirst').innerText is document.getElementById('preWrapNormal').innerText
-PASS document.getElementById('preSpaceFirst').innerText is document.getElementById('preSpaceNormal').innerText
-PASS document.getElementById('collapsedSpaceDivFirst').innerText is document.getElementById('collapsedSpaceDivNormal').innerText
-PASS document.getElementById('firstCollapsedDivFirst').innerText is document.getElementById('firstCollapsedDivNormal').innerText
-PASS document.getElementById('collapsedSpaceCollapsedDivFirst').innerText is document.getElementById('collapsedSpaceCollapsedDivNormal').innerText
-PASS document.getElementById('collapsedSpaceCollapsedDivFirst').innerText is 'foo\nabc\n'
-PASS document.getElementById('collapsedSpacePunctDivFirst').innerText is document.getElementById('collapsedSpacePunctDivNormal').innerText
-PASS document.getElementById('collapsedSpacePunctDivFirst').innerText is 'foo\n| abc\n'
-PASS document.getElementById('divSpanFirst').innerText is document.getElementById('divSpanNormal').innerText
-PASS document.getElementById('invisiblePre').innerText is ''
-PASS document.getElementById('invisiblePreFirst').innerText is 't\n'
-PASS document.getElementById('invisible').innerText is 'test\n'
-PASS document.getElementById('floatDt').innerText is 'Ab Cd E'
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter.html b/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter.html
index 1216dfcb..4a346bd 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/inner-text-first-letter.html
@@ -1,6 +1,7 @@
 <html>
 <head>
-<script src="../../resources/js-test.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <style>
 .first:first-letter {
   font-weight: bold;
@@ -71,26 +72,60 @@
 </div>
 
 <script>
-description("This tests a letter with :first-letter applied is present in innerText.");
-shouldBe("document.getElementById('divFirst').innerText", "document.getElementById('divNormal').innerText");
-shouldBe("document.getElementById('pFirst').innerText", "document.getElementById('pNormal').innerText");
-shouldBe("document.getElementById('collapsedSpaceFirst').innerText", "document.getElementById('collapsedSpaceNormal').innerText");
-shouldBe("document.getElementById('collapsedSpacePreFirst').innerText", "document.getElementById('collapsedSpacePreNormal').innerText");
-shouldBe("document.getElementById('preLineFirst').innerText", "document.getElementById('preLineNormal').innerText");
-shouldBe("document.getElementById('preWrapFirst').innerText", "document.getElementById('preWrapNormal').innerText");
-shouldBe("document.getElementById('preSpaceFirst').innerText", "document.getElementById('preSpaceNormal').innerText");
-shouldBe("document.getElementById('collapsedSpaceDivFirst').innerText", "document.getElementById('collapsedSpaceDivNormal').innerText");
-shouldBe("document.getElementById('firstCollapsedDivFirst').innerText", "document.getElementById('firstCollapsedDivNormal').innerText");
-shouldBe("document.getElementById('collapsedSpaceCollapsedDivFirst').innerText", "document.getElementById('collapsedSpaceCollapsedDivNormal').innerText");
-shouldBe("document.getElementById('collapsedSpaceCollapsedDivFirst').innerText", "'foo\\nabc\\n'");
-shouldBe("document.getElementById('collapsedSpacePunctDivFirst').innerText", "document.getElementById('collapsedSpacePunctDivNormal').innerText");
-shouldBe("document.getElementById('collapsedSpacePunctDivFirst').innerText", "'foo\\n| abc\\n'");
-shouldBe("document.getElementById('divSpanFirst').innerText", "document.getElementById('divSpanNormal').innerText");
-shouldBe("document.getElementById('invisiblePre').innerText", "''");
-shouldBe("document.getElementById('invisiblePreFirst').innerText", "'t\\n'");
-shouldBe("document.getElementById('invisible').innerText", "'test\\n'");
-shouldBe("document.getElementById('floatDt').innerText", "'Ab Cd E'");
-document.getElementById('tests').innerHTML = "";
+// This tests a letter with :first-letter applied is present in innerText.
+test(() => assert_equals(document.getElementById('divFirst').innerText, document.getElementById('divNormal').innerText),
+     'divFirst.innerText');
+
+test(() => assert_equals(document.getElementById('pFirst').innerText, document.getElementById('pNormal').innerText),
+     'pFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpaceFirst').innerText, document.getElementById('collapsedSpaceNormal').innerText),
+     'collapsedSpaceFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpacePreFirst').innerText, document.getElementById('collapsedSpacePreNormal').innerText),
+     'collapsedSpacePreFirst.innerText');
+
+test(() => assert_equals(document.getElementById('preLineFirst').innerText, document.getElementById('preLineNormal').innerText),
+     'preLineFirst.innerText');
+
+test(() => assert_equals(document.getElementById('preWrapFirst').innerText, document.getElementById('preWrapNormal').innerText),
+     'preWrapFirst.innerText');
+
+test(() => assert_equals(document.getElementById('preSpaceFirst').innerText, document.getElementById('preSpaceNormal').innerText),
+     'preSpaceFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpaceDivFirst').innerText, document.getElementById('collapsedSpaceDivNormal').innerText),
+     'collapsedSpaceDivFirst.innerText');
+
+test(() => assert_equals(document.getElementById('firstCollapsedDivFirst').innerText, document.getElementById('firstCollapsedDivNormal').innerText),
+     'firstCollapsedDivFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpaceCollapsedDivFirst').innerText, document.getElementById('collapsedSpaceCollapsedDivNormal').innerText),
+     'collapsedSpaceCollapsedDivFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpaceCollapsedDivFirst').innerText, 'foo\nabc\n'),
+     'collapsedSpaceSollapsedDivFirst.innerText literal');
+
+test(() => assert_equals(document.getElementById('collapsedSpacePunctDivFirst').innerText, document.getElementById('collapsedSpacePunctDivNormal').innerText),
+     'collapsedSpacePunctDivFirst.innerText');
+
+test(() => assert_equals(document.getElementById('collapsedSpacePunctDivFirst').innerText, 'foo\n| abc\n'),
+     'collapsedSpacePunctDivFirst.innerText literal');
+
+test(() => assert_equals(document.getElementById('divSpanFirst').innerText, document.getElementById('divSpanNormal').innerText),
+     'divSpanFirst.innerText');
+
+test(() => assert_equals(document.getElementById('invisiblePre').innerText, ''),
+     'invisiblePre.innerText');
+
+test(() => assert_equals(document.getElementById('invisiblePreFirst').innerText, 't\n'),
+     'invisiblePreFirst.innerText');
+
+test(() => assert_equals(document.getElementById('invisible').innerText, 'test\n'),
+     'invisible.innerText');
+
+test(() => assert_equals(document.getElementById('floatDt').innerText, 'Ab Cd E'),
+     'floatDt.innerText');
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash-expected.txt
deleted file mode 100644
index ab21923a..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-CONSOLE WARNING: line 1: document.createTouchList is deprecated and will be removed in M69, around September 2018. Please use TouchEvent constructor instead. See https://www.chromestatus.com/features/5668612064935936 for more details.
-This test ensures that WebKit doesn't crash when the document.createTouchList API is called with non-Touch parameters
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS document.createTouchList(document).item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS document.createTouchList({"a":1}).item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS document.createTouchList(new Array(5)).item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS document.createTouchList("string").item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS document.createTouchList(null).item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS document.createTouchList(undefined).item(0) threw exception TypeError: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'..
-PASS successfullyParsed is true
-
-TEST COMPLETE
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash.html b/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash.html
deleted file mode 100644
index 00cafc84..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-crash.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../../resources/js-test.js"></script>
-<!--
-  Touch tests that involve the ontouchstart, ontouchmove, ontouchend or ontouchcancel callbacks
-  should be written in an asynchronous fashion so they can be run on mobile platforms like Android.
-  You will need to invoke isSuccessfullyParsed() in your test script when the test completes.
--->
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/document-create-touch-list-crash.js"></script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt b/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt
deleted file mode 100644
index e491756..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-CONSOLE WARNING: line 6: document.createTouchList is deprecated and will be removed in M69, around September 2018. Please use TouchEvent constructor instead. See https://www.chromestatus.com/features/5668612064935936 for more details.
-This tests support for the document.createTouchList API.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS "createTouchList" in document is true
-PASS touchList is non-null.
-PASS touchList.length is 0
-PASS touchList.item(0) is null
-PASS touchList.item(1) is null
-PASS touchList.item() threw exception TypeError: Failed to execute 'item' on 'TouchList': 1 argument required, but only 0 present..
-PASS ts instanceof TouchEvent is true
-PASS ts.touches instanceof TouchList is true
-PASS ts.touches.length is 2
-PASS ts.touches[0] instanceof Touch is true
-PASS ts.touches[0].identifier is 12341
-PASS ts.touches[0].clientX is 60
-PASS ts.touches[1].screenY is 120
-PASS ts.ctrlKey is true
-PASS An exception was thrown: Failed to execute 'createTouchList' on 'Document': parameter 1 is not of type 'Touch'.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list.html b/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list.html
deleted file mode 100644
index c6c933b3..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/document-create-touch-list.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../../resources/js-test.js"></script>
-<!--
-  Touch tests that involve the ontouchstart, ontouchmove, ontouchend or ontouchcancel callbacks
-  should be written in an asynchronous fashion so they can be run on mobile platforms like Android.
-  You will need to invoke isSuccessfullyParsed() in your test script when the test completes.
--->
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="script-tests/document-create-touch-list.js"></script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list-crash.js b/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list-crash.js
deleted file mode 100644
index 1355737d0..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list-crash.js
+++ /dev/null
@@ -1,10 +0,0 @@
-description("This test ensures that WebKit doesn't crash when the document.createTouchList API is called with non-Touch parameters");
-
-shouldThrow('document.createTouchList(document).item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-shouldThrow('document.createTouchList({"a":1}).item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-shouldThrow('document.createTouchList(new Array(5)).item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-shouldThrow('document.createTouchList("string").item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-shouldThrow('document.createTouchList(null).item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-shouldThrow('document.createTouchList(undefined).item(0)', '"TypeError: Failed to execute \'createTouchList\' on \'Document\': parameter 1 is not of type \'Touch\'."');
-
-isSuccessfullyParsed();
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js b/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js
deleted file mode 100644
index 6349304..0000000
--- a/third_party/WebKit/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js
+++ /dev/null
@@ -1,51 +0,0 @@
-description("This tests support for the document.createTouchList API.");
-
-shouldBeTrue('"createTouchList" in document');
-
-// Test createTouchList with no arguments.
-var touchList = document.createTouchList();
-shouldBeNonNull("touchList");
-shouldBe("touchList.length", "0");
-shouldBeNull("touchList.item(0)");
-shouldBeNull("touchList.item(1)");
-shouldThrow("touchList.item()");
-
-// Test createTouchList with Touch objects as arguments.
-try {
-    var t = new Touch({identifier: 12341, target: document.body, clientX: 60, clientY:65, screenX:100, screenY: 105});
-    var t2 = new Touch({identifier: 12341, target: document.body, clientX: 50, clientY:55, screenX:115, screenY: 120});
-    var tl = document.createTouchList(t, t2);
-
-    var evt = new TouchEvent("touchstart", {
-        view: window,
-        touches: tl,
-        targetTouches: tl,
-        changedTouches: tl,
-        ctrlKey: true,
-    });
-
-    document.body.addEventListener("touchstart", function handleTouchStart(ev) {
-        ts = ev;
-        shouldBeTrue("ts instanceof TouchEvent");
-        shouldBeTrue("ts.touches instanceof TouchList");
-        shouldBe("ts.touches.length", "2");
-        shouldBeTrue("ts.touches[0] instanceof Touch");
-        shouldBe("ts.touches[0].identifier", "12341");
-        shouldBe("ts.touches[0].clientX", "60");
-        shouldBe("ts.touches[1].screenY", "120");
-        shouldBe("ts.ctrlKey", "true");
-    });
-
-    document.body.dispatchEvent(evt);
-} catch(e) {
-    testFailed("An exception was thrown: " + e.message);
-}
-
-// Test createTouchList with invalid arguments which throws exceptions.
-try {
-    var tl = document.createTouchList(1, 2);
-} catch(e) {
-    testPassed("An exception was thrown: " + e.message);
-}
-isSuccessfullyParsed();
-
diff --git a/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event-expected.txt b/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event-expected.txt
deleted file mode 100644
index 82cb6187..0000000
--- a/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Test ensures that scrollingElement.scrollTop/Left properties are available by the time DOMContentLoaded event fires.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS document.scrollingElement.scrollTop is 2000
-PASS document.scrollingElement.scrollLeft is 1000
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-    
-
-
diff --git a/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event.html b/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event.html
index 04c7577..2c42d00 100644
--- a/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event.html
+++ b/third_party/WebKit/LayoutTests/fast/loader/scroll-position-restored-on-back-at-load-event.html
@@ -1,39 +1,42 @@
 <!DOCTYPE html>
-<html>
-  <head>
-    <script src="../../resources/js-test.js"></script>
-    <script>
-    description('Test ensures that scrollingElement.scrollTop/Left properties are available by the time DOMContentLoaded event fires.');
-    // Navigation steps:
-    // 1- page gets first loaded and scrolled.
-    // 2- loaded page away and then 'back'.
-    // Test: ensure that by the time DOMContenLoaded fires (after a back navigation), scrollingElement.scrollTop/Left are set.
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src='../../resources/gesture-util.js'></script>
 
-    function init(evt) {
-        if (window.name == 'second/load') {
-            shouldBe('document.scrollingElement.scrollTop', '2000');
-            shouldBe('document.scrollingElement.scrollLeft', '1000');
-            window.name = "";
+<style>
+  #overflow {
+    width: 9999px;
+    height: 9999px;
+    float: left;
+  }
+</style>
 
-            if (window.testRunner)
-                finishJSTest();
-        } else {
-            window.scrollTo(1000, 2000);
+<div id='overflow'></div>
 
-            window.name = "second/load";
-        }
-    }
-    function onLoad() {
-        setTimeout('window.location = "../../resources/back.html"', 0);
-    }
+<script>
+  // Navigation steps:
+  // 1- page gets first loaded and scrolled.
+  // 2- loaded page away and then 'back'.
+  // Test: ensure that by the time DOMContenLoaded fires (after a back navigation), scrollingElement.scrollTop/Left are set.
 
-    window.addEventListener('DOMContentLoaded', init, true);
-    window.onunload = function() {}  // prevent caching
+  let t = async_test('Test ensures that scrollingElement.scrollTop/Left properties are available by the time DOMContentLoaded event fires.');
 
-    var jsTestIsAsync = true;
-    </script>
-    <body onload="onLoad()">
-        <div id="overflow" style='width: 9999px; height:9999px; float:left;'></div>
-        <h1 id='console'/>
-    </body>
-</html>
+  function init() {
+    t.step(() => {
+      if (window.name == 'second/load') {
+        assert_equals(document.scrollingElement.scrollTop, 2000);
+        assert_equals(document.scrollingElement.scrollLeft, 1000);
+        window.name = '';
+
+        t.done();
+      } else {
+        window.scrollTo(1000, 2000);
+
+        window.name = 'second/load';
+        setTimeout(() => { window.location = '../../resources/back.html'; }, 0);
+      }
+    });
+  }
+
+  window.addEventListener('DOMContentLoaded', init, true);
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-all-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-all-expected.png
deleted file mode 100644
index 8fa80012..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-all-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-mask-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-mask-expected.png
deleted file mode 100644
index 6c7deffd..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-mask-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-shadow-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-shadow-expected.png
deleted file mode 100644
index 20fca7c9..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/borders/border-radius-mask-canvas-with-shadow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.png
deleted file mode 100644
index 96b94666..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.txt
deleted file mode 100644
index ade8302a..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css/bidi-override-in-anonymous-block-expected.txt
+++ /dev/null
@@ -1,240 +0,0 @@
-layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1296
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 785x1296 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 785x1296.03
-    LayoutNGBlockFlow {BODY} at (8,16) size 769x1272.03
-      LayoutNGBlockFlow {P} at (0,0) size 769x20
-        LayoutText {#text} at (0,0) size 161x19
-          text run at (0,0) width 161: "div, span, nested div/span"
-      LayoutNGBlockFlow {P} at (0,36) size 769x20
-        LayoutText {#text} at (0,0) size 64x19
-          text run at (0,0) width 64: "Single div"
-      LayoutNGBlockFlow {DIV} at (1.47,72) size 766.06x22.94 [border: (1.47px solid #000000)]
-        LayoutText {#text} at (742,1) size 23x20
-          text run at (742,1) width 23: "abc"
-      LayoutNGBlockFlow {P} at (0,110.94) size 769x20
-        LayoutText {#text} at (0,0) size 410x19
-          text run at (0,0) width 410: "The following 2 lines should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow {DIV} at (1.47,146.94) size 766.06x42.94 [border: (1.47px solid #000000)]
-        LayoutNGBlockFlow (anonymous) at (1.47,1.47) size 763.13x20
-          LayoutText {#text} at (741,0) size 23x19
-            text run at (741,0) width 23: "abc"
-        LayoutNGBlockFlow {DIV} at (1.47,21.47) size 763.13x20
-          LayoutText {#text} at (741,0) size 23x19
-            text run at (741,0) width 23: "cba"
-      LayoutNGBlockFlow {P} at (0,205.88) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow {DIV} at (1.47,241.88) size 766.06x22.94 [border: (1.47px solid #000000)]
-        LayoutText {#text} at (738,1) size 27x20
-          text run at (738,1) width 27: "abc "
-        LayoutInline {SPAN} at (0,0) size 23x20
-          LayoutText {#text} at (716,1) size 23x20
-            text run at (716,1) width 23: "abc"
-      LayoutNGBlockFlow {P} at (0,280.81) size 769x20
-        LayoutText {#text} at (0,0) size 410x19
-          text run at (0,0) width 410: "The following 2 lines should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow {DIV} at (1.47,316.81) size 766.06x42.94 [border: (1.47px solid #000000)]
-        LayoutNGBlockFlow {DIV} at (1.47,1.47) size 763.13x20
-          LayoutText {#text} at (741,0) size 23x19
-            text run at (741,0) width 23: "cba"
-        LayoutNGBlockFlow (anonymous) at (1.47,21.47) size 763.13x20
-          LayoutText {#text} at (741,0) size 23x19
-            text run at (741,0) width 23: "abc"
-      LayoutNGBlockFlow {P} at (0,375.75) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow {DIV} at (1.47,411.75) size 766.06x22.94 [border: (1.47px solid #000000)]
-        LayoutInline {SPAN} at (0,0) size 27x20
-          LayoutText {#text} at (738,1) size 27x20
-            text run at (738,1) width 27: "abc "
-        LayoutText {#text} at (716,1) size 23x20
-          text run at (716,1) width 23: "abc"
-      LayoutNGBlockFlow {P} at (0,450.69) size 769x20
-        LayoutText {#text} at (0,0) size 73x19
-          text run at (0,0) width 73: "Single span"
-      LayoutNGBlockFlow (anonymous) at (0,486.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 26x23 [border: (1.47px solid #000000)]
-          LayoutText {#text} at (2,0) size 23x19
-            text run at (2,0) width 23: "abc"
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,522.69) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow (anonymous) at (0,558.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 52x23 [border: (1.47px solid #000000)]
-          LayoutText {#text} at (24,0) size 27x19
-            text run at (24,0) width 27: "abc "
-          LayoutInline {SPAN} at (0,0) size 23x19
-            LayoutText {#text} at (2,0) size 23x19
-              text run at (2,0) width 23: "abc"
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,594.69) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow (anonymous) at (0,630.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 52x23 [border: (1.47px solid #000000)]
-          LayoutInline {SPAN} at (0,0) size 27x19
-            LayoutText {#text} at (24,0) size 27x19
-              text run at (24,0) width 27: "abc "
-          LayoutText {#text} at (2,0) size 23x19
-            text run at (2,0) width 23: "abc"
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,666.69) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow (anonymous) at (0,702.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 24x23 [border: (1.47px solid #000000)]
-          LayoutText {#text} at (0,0) size 22x19
-            text run at (0,0) width 22: "abc"
-      LayoutNGBlockFlow (anonymous) at (0,722.69) size 769x20
-        LayoutNGBlockFlow {DIV} at (0,0) size 769x20
-          LayoutText {#text} at (747,0) size 22x19
-            text run at (747,0) width 22: "cba"
-      LayoutNGBlockFlow (anonymous) at (0,742.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 2x23 [border: (1.47px solid #000000)]
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,778.69) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 textes should be identical, ignorning whitespaces:"
-      LayoutNGBlockFlow (anonymous) at (0,814.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 2x23 [border: (1.47px solid #000000)]
-      LayoutNGBlockFlow (anonymous) at (0,834.69) size 769x20
-        LayoutNGBlockFlow {DIV} at (0,0) size 769x20
-          LayoutText {#text} at (747,0) size 22x19
-            text run at (747,0) width 22: "cba"
-      LayoutNGBlockFlow (anonymous) at (0,854.69) size 769x20
-        LayoutInline {SPAN} at (0,0) size 24x23 [border: (1.47px solid #000000)]
-          LayoutText {#text} at (2,0) size 23x19
-            text run at (2,0) width 23: "abc"
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,890.69) size 769x20
-        LayoutText {#text} at (0,0) size 29x19
-          text run at (0,0) width 29: "ruby"
-      LayoutNGBlockFlow {DIV} at (0,926.69) size 769x22.94 [border: (1.47px solid #000000)]
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (166.56,1.47) size 22x20
-            LayoutRubyText {RT} at (0,-12) size 22x12
-              LayoutText {#text} at (5,0) size 12x12
-                text run at (5,0) width 12: "def"
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutText {#text} at (0,0) size 22x19
-                text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (161,1) size 5x20
-          text run at (161,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (137.63,1.47) size 22x20
-            LayoutRubyText {RT} at (0,-12) size 22x12
-              LayoutText {#text} at (5,0) size 12x12
-                text run at (5,0) width 12 RTL override: "def"
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutText {#text} at (0,0) size 22x19
-                text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (132,1) size 5x20
-          text run at (132,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (108.69,1.47) size 22x20
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutText {#text} at (0,0) size 22x19
-                text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (103,1) size 5x20
-          text run at (103,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 13x20
-          LayoutRubyRun (anonymous) at (89.75,18.47) size 12x0
-            LayoutRubyText {RT} at (0,-12) size 12x12
-              LayoutText {#text} at (0,0) size 12x12
-                text run at (0,0) width 12: "def"
-        LayoutText {#text} at (84,1) size 5x20
-          text run at (84,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (60.81,1.47) size 22x20
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutInline {RB} at (0,0) size 22x19
-                LayoutText {#text} at (0,0) size 22x19
-                  text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (55,1) size 5x20
-          text run at (55,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (31.88,1.47) size 22x20
-            LayoutRubyText {RT} at (0,-12) size 22x12
-              LayoutText {#text} at (5,0) size 12x12
-                text run at (5,0) width 12: "def"
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutInline {RB} at (0,0) size 22x19
-                LayoutText {#text} at (0,0) size 22x19
-                  text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (26,1) size 5x20
-          text run at (26,1) width 5: " "
-        LayoutRuby (inline) {RUBY} at (0,0) size 23x21
-          LayoutRubyRun (anonymous) at (2.94,1.47) size 22x20
-            LayoutRubyText {RT} at (0,-12) size 22x12
-              LayoutText {#text} at (5,0) size 12x12
-                text run at (5,0) width 12: "def"
-            LayoutRubyBase (anonymous) at (0,0) size 22x20
-              LayoutInline {RB} at (0,0) size 22x19
-                LayoutText {#text} at (0,0) size 22x19
-                  text run at (0,0) width 22 RTL override: "abc"
-        LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow {P} at (0,965.63) size 769x20
-        LayoutText {#text} at (0,0) size 417x19
-          text run at (0,0) width 417: "The following 2 tables should be identical, ignorning whitespaces:"
-      LayoutTable {TABLE} at (1.47,1001.63) size 83x72 [border: (1px solid #808080)]
-        LayoutBlockFlow {CAPTION} at (0,0) size 83x20
-          LayoutText {#text} at (0,0) size 83x19
-            text run at (0,0) width 83: "NormalTable"
-        LayoutTableSection {TBODY} at (1,21) size 81x50
-          LayoutTableRow {TR} at (0,2) size 81x22
-            LayoutNGTableCell {TD} at (43,2) size 36x22 [r=0 c=0 rs=1 cs=1]
-              LayoutText {#text} at (13,1) size 22x19
-                text run at (13,1) width 22: "abc"
-            LayoutNGTableCell {TD} at (2,2) size 39x22 [r=0 c=1 rs=1 cs=1]
-              LayoutText {#text} at (18,1) size 20x19
-                text run at (18,1) width 20: "def"
-          LayoutTableRow {TR} at (0,26) size 81x22
-            LayoutNGTableCell {TD} at (43,26) size 36x22 [r=1 c=0 rs=1 cs=1]
-              LayoutText {#text} at (19,1) size 16x19
-                text run at (19,1) width 16: "hij"
-            LayoutNGTableCell {TD} at (2,26) size 39x22 [r=1 c=1 rs=1 cs=1]
-              LayoutText {#text} at (14,1) size 24x19
-                text run at (14,1) width 24: "opq"
-      LayoutTable {DIV} at (1.47,1075.09) size 144x62 [border: (1px solid #000000)]
-        LayoutBlockFlow {DIV} at (0,0) size 144x20
-          LayoutText {#text} at (0,0) size 144x19
-            text run at (0,0) width 144: "AnonymousTableRow"
-        LayoutTableSection (anonymous) at (1,21) size 142x40
-          LayoutTableRow {DIV} at (0,0) size 142x20
-            LayoutNGTableCell {DIV} at (75,0) size 67x20 [r=0 c=0 rs=1 cs=1]
-              LayoutText {#text} at (45,0) size 22x19
-                text run at (45,0) width 22: "abc"
-            LayoutNGTableCell {DIV} at (0,0) size 75x20 [r=0 c=1 rs=1 cs=1]
-              LayoutText {#text} at (55,0) size 20x19
-                text run at (55,0) width 20: "def"
-          LayoutTableRow {DIV} at (0,20) size 142x20
-            LayoutNGTableCell {DIV} at (75,20) size 67x20 [r=1 c=0 rs=1 cs=1]
-              LayoutText {#text} at (51,0) size 16x19
-                text run at (51,0) width 16: "hij"
-            LayoutNGTableCell {DIV} at (0,20) size 75x20 [r=1 c=1 rs=1 cs=1]
-              LayoutText {#text} at (51,0) size 24x19
-                text run at (51,0) width 24: "opq"
-      LayoutNGBlockFlow {P} at (0,1153.09) size 769x20
-        LayoutText {#text} at (0,0) size 516x19
-          text run at (0,0) width 516: "Anonymous TABLE, TABLE_ROW, TABLE_ROW_GROUP, TABLE_CELL"
-      LayoutNGBlockFlow {DIV} at (0,1189.09) size 769x82.94 [border: (1.47px solid #000000)]
-        LayoutTable (anonymous) at (1.47,1.47) size 24x80
-          LayoutTableSection (anonymous) at (0,20) size 24x40
-            LayoutTableRow {DIV} at (0,0) size 24x20
-              LayoutTableCell (anonymous) at (0,0) size 24x20 [r=0 c=0 rs=1 cs=1]
-                LayoutText {#text} at (2,0) size 22x19
-                  text run at (2,0) width 22 RTL override: "abc"
-            LayoutTableRow (anonymous) at (0,20) size 24x20
-              LayoutNGTableCell {DIV} at (0,20) size 24x20 [r=1 c=0 rs=1 cs=1]
-                LayoutText {#text} at (4,0) size 20x19
-                  text run at (4,0) width 20: "def"
-          LayoutBlockFlow {DIV} at (0,0) size 24x20
-            LayoutText {#text} at (8,0) size 16x19
-              text run at (8,0) width 16 RTL override: "hij"
-          LayoutTableSection {DIV} at (0,60) size 24x20
-            LayoutTableRow (anonymous) at (0,0) size 24x20
-              LayoutTableCell (anonymous) at (0,0) size 24x20 [r=0 c=0 rs=1 cs=1]
-                LayoutText {#text} at (0,0) size 24x19
-                  text run at (0,0) width 24 RTL override: "opq"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-expected.png
deleted file mode 100644
index 56b55ca2..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-vertical-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-vertical-expected.png
deleted file mode 100644
index 1223c991..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/overflow/overflow-rtl-vertical-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-002-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-002-expected.png
new file mode 100644
index 0000000..c430b59f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-003-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-003-expected.png
new file mode 100644
index 0000000..c430b59f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/international/bidi-linebreak-003-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/caret-contenteditable-content-after-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/caret-contenteditable-content-after-expected.txt
deleted file mode 100644
index a68ffbf..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/table/caret-contenteditable-content-after-expected.txt
+++ /dev/null
@@ -1,340 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "drawsContent": false,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "bounds": [800, 600],
-      "drawsContent": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "paintInvalidations": [
-        {
-          "object": "LayoutBlockFlow DIV id='editor'",
-          "rect": [7, 47, 786, 22],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='editor'",
-          "rect": [7, 47, 786, 22],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutBlockFlow DIV id='editor'",
-          "rect": [7, 47, 786, 22],
-          "reason": "geometry"
-        },
-        {
-          "object": "LayoutNGBlockFlow HTML",
-          "rect": [7, 47, 786, 22],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 8, 361, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "NGPaintFragment",
-          "rect": [8, 28, 216, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "InlineTextBox 'abc'",
-          "rect": [8, 48, 22, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'ab'",
-          "rect": [8, 48, 15, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'ab'",
-          "rect": [8, 48, 15, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [30, 48, 8, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [23, 48, 8, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [23, 48, 8, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [15, 48, 8, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [15, 48, 8, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "InlineTextBox 'x'",
-          "rect": [8, 48, 8, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "InlineTextBox 'a'",
-          "rect": [8, 48, 7, 19],
-          "reason": "appeared"
-        },
-        {
-          "object": "InlineTextBox 'a'",
-          "rect": [8, 48, 7, 19],
-          "reason": "disappeared"
-        },
-        {
-          "object": "Caret",
-          "rect": [8, 48, 1, 20],
-          "reason": "appeared"
-        },
-        {
-          "object": "Caret",
-          "rect": [8, 48, 1, 20],
-          "reason": "caret"
-        },
-        {
-          "object": "Caret",
-          "rect": [30, 48, 1, 19],
-          "reason": "caret"
-        },
-        {
-          "object": "Caret",
-          "rect": [23, 48, 1, 19],
-          "reason": "caret"
-        },
-        {
-          "object": "Caret",
-          "rect": [23, 48, 1, 19],
-          "reason": "caret"
-        },
-        {
-          "object": "Caret",
-          "rect": [15, 48, 1, 19],
-          "reason": "caret"
-        },
-        {
-          "object": "Caret",
-          "rect": [15, 48, 1, 19],
-          "reason": "caret"
-        }
-      ]
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutBlockFlow DIV id='editor'",
-      "reason": "style change"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "style change"
-    },
-    {
-      "object": "Caret",
-      "reason": "caret"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='editor'",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "Caret",
-      "reason": "caret"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "appeared"
-    },
-    {
-      "object": "InlineTextBox 'a'",
-      "reason": "appeared"
-    },
-    {
-      "object": "LayoutTextFragment (anonymous)",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'x'",
-      "reason": "geometry"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='editor'",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "Caret",
-      "reason": "caret"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'ab'",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutTextFragment (anonymous)",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'x'",
-      "reason": "geometry"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "NGPaintFragment",
-      "reason": "subtree"
-    },
-    {
-      "object": "LayoutBlockFlow DIV id='editor'",
-      "reason": "geometry"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "geometry"
-    },
-    {
-      "object": "Caret",
-      "reason": "caret"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'abc'",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutTextFragment (anonymous)",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'x'",
-      "reason": "geometry"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
index ee23a5fd..9a38297 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
@@ -13,8 +13,12 @@
 # Install gen-certurl command from [1]
 go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-certurl
 
-# Install gen-signedexchange command from [2]
+# Install gen-signedexchange command from [2],
 go get github.com/nyaxt/webpackage/go/signedexchange/cmd/gen-signedexchange
+# and cherry-pick the following changes from [1].
+https://github.com/WICG/webpackage/commit/c173772a4fb3c923d705a319e5e9f2fb1fd569d7
+https://github.com/WICG/webpackage/commit/2635cc5d8fc3177092806ce19826e9cd8f8461c9
+https://github.com/WICG/webpackage/commit/2e88a4422a565221178891f50ed68c71cbcb6086
 
 # Make dummy OCSP data for cbor certificate chains.
 echo -n OCSP >/tmp/ocsp
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
index 40278c2e..d974d06 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
index 9e361e91..38769cdb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics-expected.txt
index 09472c2..4bcb7d2c 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics-expected.txt
@@ -1,66 +1,24 @@
-Test that page performance metrics are retrieved.
-Received metrics:
-Received metrics:
-	Timestamp
-	AudioHandlers
-	Documents
-	Frames
-	JSEventListeners
-	LayoutObjects
-	MediaKeySessions
-	MediaKeys
-	Nodes
-	Resources
-	ScriptPromises
-	PausableObjects
-	V8PerContextDatas
-	WorkerGlobalScopes
-	UACSSResources
-	RTCPeerConnections
-	ResourceFetchers
-	AdSubframes
-	DetachedScriptStates
-	LayoutCount
-	RecalcStyleCount
-	LayoutDuration
-	RecalcStyleDuration
-	ScriptDuration
-	TaskDuration
-	JSHeapUsedSize
-	JSHeapTotalSize
-	FirstMeaningfulPaint
-	DomContentLoaded
-	NavigationStart
-Received metrics:
-	Timestamp
-	AudioHandlers
-	Documents
-	Frames
-	JSEventListeners
-	LayoutObjects
-	MediaKeySessions
-	MediaKeys
-	Nodes
-	Resources
-	ScriptPromises
-	PausableObjects
-	V8PerContextDatas
-	WorkerGlobalScopes
-	UACSSResources
-	RTCPeerConnections
-	ResourceFetchers
-	AdSubframes
-	DetachedScriptStates
-	LayoutCount
-	RecalcStyleCount
-	LayoutDuration
-	RecalcStyleDuration
-	ScriptDuration
-	TaskDuration
-	JSHeapUsedSize
-	JSHeapTotalSize
-	FirstMeaningfulPaint
-	DomContentLoaded
-	NavigationStart
-Received metrics:
+Test that page performance metrics are retrieved and the list is stable.
+DO NOT modify the list, it's exposed over public protocol.
+
+Metrics:
+
+
+Metrics:
+Documents
+Frames
+JSEventListeners
+JSHeapTotalSize
+JSHeapUsedSize
+LayoutCount
+LayoutDuration
+Nodes
+RecalcStyleCount
+RecalcStyleDuration
+ScriptDuration
+TaskDuration
+Timestamp
+
+Metrics:
+
 
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics.js b/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics.js
index c9c0d79..073d361d 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics.js
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/performance/perf-metrics.js
@@ -1,26 +1,51 @@
 (async function(testRunner) {
   var {page, session, dp} = await testRunner.startBlank(
-      'Test that page performance metrics are retrieved.');
+      `Test that page performance metrics are retrieved and the list is stable.\n` +
+      `DO NOT modify the list, it's exposed over public protocol.`);
 
   await dumpMetrics();
   await dp.Performance.enable();
   await dumpMetrics();
-  await dumpMetrics();
   await dp.Performance.disable();
   await dumpMetrics();
 
-  async function dumpMetrics() {
+  async function retrieveMetrics() {
     const {result:{metrics}} = await dp.Performance.getMetrics();
-    testRunner.log('Received metrics:');
+    const map = new Map();
     for (const metric of metrics)
-      testRunner.log(`\t${metric.name}`);
+      map.set(metric.name, metric.value);
+    return map;
+  }
+
+  async function dumpMetrics() {
+    const metrics = await retrieveMetrics();
+    const metricsToCheck = new Set([
+      'Timestamp',
+      'Documents',
+      'Frames',
+      'JSEventListeners',
+      'Nodes',
+      'LayoutCount',
+      'RecalcStyleCount',
+      'LayoutDuration',
+      'RecalcStyleDuration',
+      'ScriptDuration',
+      'TaskDuration',
+      'JSHeapUsedSize',
+      'JSHeapTotalSize',
+    ]);
+
+    testRunner.log('\nMetrics:');
+    testRunner.log(Array.from(metrics.keys()).filter(n => metricsToCheck.has(n)).sort().join('\n'));
+
     checkMetric('Documents');
     checkMetric('Nodes');
+    checkMetric('JSHeapUsedSize');
+    checkMetric('JSHeapTotalSize');
 
     function checkMetric(name) {
-      const metric = metrics.find(metric => metric.name === name);
-      if (metrics.length && !metric.value)
-        testRunner.log(`Error: Metric ${name} has a bad value ${metric.value}`);
+      if (metrics.size && !metrics.get(name))
+        testRunner.log(`Error: Metric ${name} has a bad value ${metrics.get(name)}`);
     }
   }
 
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 2999e7e3..0e86b56 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1321,7 +1321,6 @@
     method createProcessingInstruction
     method createRange
     method createTextNode
-    method createTouchList
     method createTreeWalker
     method elementFromPoint
     method elementsFromPoint
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 2bdcee7..269fb2c 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1642,7 +1642,6 @@
     method createProcessingInstruction
     method createRange
     method createTextNode
-    method createTouchList
     method createTreeWalker
     method elementFromPoint
     method elementsFromPoint
diff --git a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
index 0eeff0fc..2e8de07 100644
--- a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
+++ b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
@@ -274,10 +274,21 @@
     }
   }
 
-  requestSession() {
-    return Promise.resolve({success:true});
+  requestSession(options) {
+    return this.supportsSession(options).then((result) => {
+      return result = {
+        success: result.supportsSession,
+      };
+    });
   }
 
+  supportsSession(options) {
+    return Promise.resolve({
+      supportsSession:
+          !options.exclusive || this.displayInfo_.capabilities.canPresent
+    });
+  };
+
   requestPresent(submitFrameClient, request, presentOptions) {
     this.presentation_provider_.bind(
         submitFrameClient, request, presentOptions);
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index efaab94..821d586d 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -52,6 +52,7 @@
     # TODO(https://crbug.com/822804): Remove when mojom bindings deps checks
     # get fixed.
     "//services/network/public/mojom:data_pipe_interfaces",
+    "//skia/public/interfaces",
     "//ui/gfx/geometry/mojo",
     "//url/mojom:url_mojom_gurl",
     "//url/mojom:url_mojom_origin",
diff --git a/third_party/blink/public/mojom/clipboard/clipboard.mojom b/third_party/blink/public/mojom/clipboard/clipboard.mojom
index fe1c24a8..4a8c347 100644
--- a/third_party/blink/public/mojom/clipboard/clipboard.mojom
+++ b/third_party/blink/public/mojom/clipboard/clipboard.mojom
@@ -5,8 +5,7 @@
 module blink.mojom;
 
 import "mojo/public/mojom/base/string16.mojom";
-import "third_party/blink/public/mojom/blob/serialized_blob.mojom";
-import "ui/gfx/geometry/mojo/geometry.mojom";
+import "skia/public/interfaces/bitmap.mojom";
 import "url/mojom/url.mojom";
 
 enum ClipboardFormat {
@@ -27,68 +26,62 @@
 
 interface ClipboardHost {
   [Sync]
-  GetSequenceNumber(blink.mojom.ClipboardBuffer buffer) => (uint64 result);
+  GetSequenceNumber(ClipboardBuffer buffer) => (uint64 result);
 
   [Sync]
-  IsFormatAvailable(blink.mojom.ClipboardFormat format,
-                    blink.mojom.ClipboardBuffer buffer) => (bool result);
+  IsFormatAvailable(ClipboardFormat format,
+                    ClipboardBuffer buffer) => (bool result);
 
   [Sync]
-  ReadAvailableTypes(blink.mojom.ClipboardBuffer buffer) =>
+  ReadAvailableTypes(ClipboardBuffer buffer) =>
       (array<mojo_base.mojom.String16> types, bool result);
 
   [Sync]
-  ReadText(blink.mojom.ClipboardBuffer buffer) =>
+  ReadText(ClipboardBuffer buffer) => (mojo_base.mojom.BigString16 result);
+
+  [Sync]
+  ReadHtml(ClipboardBuffer buffer) => (mojo_base.mojom.BigString16 markup,
+                                      url.mojom.Url url,
+                                      uint32 fragment_start,
+                                      uint32 fragment_end);
+
+  [Sync]
+  ReadRtf(ClipboardBuffer buffer) => (string result);
+
+  [Sync]
+  ReadImage(ClipboardBuffer buffer) => (skia.mojom.Bitmap? image);
+
+  [Sync]
+  ReadCustomData(ClipboardBuffer buffer, mojo_base.mojom.String16 type) =>
       (mojo_base.mojom.BigString16 result);
 
-  [Sync]
-  ReadHtml(blink.mojom.ClipboardBuffer buffer) =>
-      (mojo_base.mojom.BigString16 markup,
-       url.mojom.Url url,
-       uint32 fragment_start,
-       uint32 fragment_end);
-
-  [Sync]
-  ReadRtf(blink.mojom.ClipboardBuffer buffer) => (string result);
-
-  [Sync]
-  ReadImage(blink.mojom.ClipboardBuffer buffer) => (SerializedBlob? blob);
-
-  [Sync]
-  ReadCustomData(blink.mojom.ClipboardBuffer buffer,
-                 mojo_base.mojom.String16 type) =>
-                     (mojo_base.mojom.BigString16 result);
-
   // Writing to the clipboard via IPC is a two-phase operation. First, the
   // sender sends the different types of data it'd like to write to the
   // receiver. Then, it sends a commit message to commit the data to the system
   // clipboard.
-  WriteText(blink.mojom.ClipboardBuffer buffer,
-            mojo_base.mojom.BigString16 text);
+  WriteText(ClipboardBuffer buffer, mojo_base.mojom.BigString16 text);
 
-  WriteHtml(blink.mojom.ClipboardBuffer buffer,
+  WriteHtml(ClipboardBuffer buffer,
             mojo_base.mojom.BigString16 markup,
             url.mojom.Url url);
 
-  WriteSmartPasteMarker(blink.mojom.ClipboardBuffer buffer);
+  WriteSmartPasteMarker(ClipboardBuffer buffer);
 
   WriteCustomData(
-      blink.mojom.ClipboardBuffer buffer,
+      ClipboardBuffer buffer,
       map<mojo_base.mojom.String16, mojo_base.mojom.BigString16> data);
 
   // TODO(dcheng): The |url| parameter should really be a GURL, but <canvas>'s
   // copy as image tries to set very long data: URLs on the clipboard. Using
   // GURL causes the browser to kill the renderer for sending a bad IPC (GURLs
   // bigger than 2 megabytes are considered to be bad). https://crbug.com/459822
-  WriteBookmark(blink.mojom.ClipboardBuffer buffer,
+  WriteBookmark(ClipboardBuffer buffer,
                 string url,
                 mojo_base.mojom.String16 title);
 
-  WriteImage(blink.mojom.ClipboardBuffer buffer,
-             gfx.mojom.Size size_in_pixels,
-             handle<shared_buffer> shared_buffer_handle);
+  WriteImage(ClipboardBuffer buffer, skia.mojom.Bitmap image);
 
-  CommitWrite(blink.mojom.ClipboardBuffer buffer);
+  CommitWrite(ClipboardBuffer buffer);
 
   [EnableIf=is_mac]
   WriteStringToFindPboard(mojo_base.mojom.String16 text);
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index 7264332d..820d9e1 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1836,7 +1836,6 @@
   kAnimationWorkletRegisterAnimator = 2365,
   kWorkletAnimationConstructor = 2366,
   kScrollTimelineConstructor = 2367,
-  kV8Document_CreateTouchList_Method = 2368,
   kAsyncClipboardAPIRead = 2369,
   kAsyncClipboardAPIWrite = 2370,
   kAsyncClipboardAPIReadText = 2371,
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
index ec939fd..85296441 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc
@@ -82,6 +82,7 @@
     if (!type->IsString())
       continue;
     String type_string = ToCoreStringWithNullCheck(type.As<v8::String>());
+    items.reserve(items.size() + 1);
     items.emplace_back();
     WebMenuItemInfo& item_info = items[items.size() - 1];
     if (type_string == "separator") {
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 80edcb67..f0d1dd8 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -2017,7 +2017,6 @@
     "paint/first_meaningful_paint_detector_test.cc",
     "paint/fragment_data_test.cc",
     "paint/html_canvas_painter_test.cc",
-    "paint/layer_clip_recorder_test.cc",
     "paint/link_highlight_impl_test.cc",
     "paint/ng/ng_paint_fragment_test.cc",
     "paint/ng/ng_paint_fragment_traversal_test.cc",
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS
index 5e17bfb..05a67eaf 100644
--- a/third_party/blink/renderer/core/DEPS
+++ b/third_party/blink/renderer/core/DEPS
@@ -54,7 +54,7 @@
         "+third_party/blink/renderer/core/frame/web_remote_frame_impl.h",
         "+gin"
     ],
-
+    "data_object_item.cc" : [ "+ui/gfx/codec" ],
     "find_in_page.cc" : [
         "+third_party/blink/renderer/core/frame/web_local_frame_impl.h",
     ],
diff --git a/third_party/blink/renderer/core/clipboard/BUILD.gn b/third_party/blink/renderer/core/clipboard/BUILD.gn
index e1fc73f..33c128c 100644
--- a/third_party/blink/renderer/core/clipboard/BUILD.gn
+++ b/third_party/blink/renderer/core/clipboard/BUILD.gn
@@ -22,4 +22,8 @@
     "system_clipboard.cc",
     "system_clipboard.h",
   ]
+
+  deps = [
+    "//ui/gfx/codec",
+  ]
 }
diff --git a/third_party/blink/renderer/core/clipboard/data_object_item.cc b/third_party/blink/renderer/core/clipboard/data_object_item.cc
index e5bfdfe2..302def2 100644
--- a/third_party/blink/renderer/core/clipboard/data_object_item.cc
+++ b/third_party/blink/renderer/core/clipboard/data_object_item.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/platform/clipboard/clipboard_mime_types.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
+#include "ui/gfx/codec/png_codec.h"
 
 namespace blink {
 
@@ -126,12 +127,17 @@
 
   DCHECK_EQ(source_, kClipboardSource);
   if (GetType() == kMimeTypeImagePng) {
-    scoped_refptr<BlobDataHandle> blob =
-        SystemClipboard::GetInstance().ReadImage(
-            mojom::ClipboardBuffer::kStandard);
-    if (!blob)
-      return nullptr;
-    return File::Create("image.png", CurrentTimeMS(), std::move(blob));
+    SkBitmap image = SystemClipboard::GetInstance().ReadImage(
+        mojom::ClipboardBuffer::kStandard);
+    std::vector<unsigned char> png_data;
+    if (gfx::PNGCodec::FastEncodeBGRASkBitmap(image, false, &png_data)) {
+      std::unique_ptr<BlobData> data = BlobData::Create();
+      data->SetContentType(kMimeTypeImagePng);
+      data->AppendBytes(png_data.data(), png_data.size());
+      const uint64_t length = data->length();
+      auto blob = BlobDataHandle::Create(std::move(data), length);
+      return File::Create("image.png", CurrentTimeMS(), std::move(blob));
+    }
   }
 
   return nullptr;
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.cc b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
index e42539a0..a51a2a3 100644
--- a/third_party/blink/renderer/core/clipboard/system_clipboard.cc
+++ b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -154,13 +154,11 @@
   return rtf;
 }
 
-scoped_refptr<BlobDataHandle> SystemClipboard::ReadImage(
-    mojom::ClipboardBuffer buffer) {
-  if (!IsValidBufferType(buffer))
-    return nullptr;
-  scoped_refptr<BlobDataHandle> blob;
-  clipboard_->ReadImage(buffer, &blob);
-  return blob;
+SkBitmap SystemClipboard::ReadImage(mojom::ClipboardBuffer buffer) {
+  SkBitmap image;
+  if (IsValidBufferType(buffer))
+    clipboard_->ReadImage(buffer, &image);
+  return image;
 }
 
 void SystemClipboard::WriteImage(Image* image,
@@ -177,26 +175,12 @@
 
   // Only 32-bit bitmaps are supported.
   DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
-  const WebSize size(bitmap.width(), bitmap.height());
   void* pixels = bitmap.getPixels();
   // TODO(piman): this should not be NULL, but it is. crbug.com/369621
   if (!pixels)
     return;
 
-  CheckedNumeric<uint32_t> checked_buf_size = 4;
-  checked_buf_size *= size.width;
-  checked_buf_size *= size.height;
-  if (!checked_buf_size.IsValid())
-    return;
-
-  // Allocate a shared memory buffer to hold the bitmap bits.
-  uint32_t buf_size = checked_buf_size.ValueOrDie();
-  auto shared_buffer = mojo::SharedBufferHandle::Create(buf_size);
-  auto mapping = shared_buffer->Map(buf_size);
-  memcpy(mapping.get(), pixels, buf_size);
-
-  clipboard_->WriteImage(mojom::ClipboardBuffer::kStandard, size,
-                         std::move(shared_buffer));
+  clipboard_->WriteImage(mojom::ClipboardBuffer::kStandard, bitmap);
 
   if (url.IsValid() && !url.IsEmpty()) {
     clipboard_->WriteBookmark(mojom::ClipboardBuffer::kStandard,
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.h b/third_party/blink/renderer/core/clipboard/system_clipboard.h
index fa645c3..e63b7646 100644
--- a/third_party/blink/renderer/core/clipboard/system_clipboard.h
+++ b/third_party/blink/renderer/core/clipboard/system_clipboard.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_SYSTEM_CLIPBOARD_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_SYSTEM_CLIPBOARD_H_
 
-#include "base/memory/scoped_refptr.h"
 #include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -13,7 +12,6 @@
 
 namespace blink {
 
-class BlobDataHandle;
 class DataObject;
 class Image;
 class KURL;
@@ -51,7 +49,7 @@
 
   String ReadRTF();
 
-  scoped_refptr<BlobDataHandle> ReadImage(mojom::ClipboardBuffer);
+  SkBitmap ReadImage(mojom::ClipboardBuffer);
   void WriteImage(Image*, const KURL&, const String& title);
 
   String ReadCustomData(const String& type);
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index f54e4c51..0df22c6 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6684,10 +6684,6 @@
   scripted_idle_task_controller_->CancelCallback(id);
 }
 
-TouchList* Document::createTouchList(HeapVector<Member<Touch>>& touches) const {
-  return TouchList::Adopt(touches);
-}
-
 DocumentLoader* Document::Loader() const {
   if (!frame_)
     return nullptr;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 6a5a2eb..d067879 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -181,8 +181,6 @@
 class StylePropertyMapReadOnly;
 class StyleSheetList;
 class TextAutosizer;
-class Touch;
-class TouchList;
 class TransformSource;
 class TreeWalker;
 class V8NodeFilter;
@@ -1166,8 +1164,6 @@
   // This calls checkCompleted() sync and thus can cause JavaScript execution.
   void DecrementLoadEventDelayCountAndCheckLoadEvent();
 
-  TouchList* createTouchList(HeapVector<Member<Touch>>&) const;
-
   const DocumentTiming& GetTiming() const { return document_timing_; }
 
   int RequestAnimationFrame(FrameRequestCallbackCollection::FrameCallback*);
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl
index a94432f6..3af7387 100644
--- a/third_party/blink/renderer/core/dom/document.idl
+++ b/third_party/blink/renderer/core/dom/document.idl
@@ -167,8 +167,6 @@
     attribute EventHandler onpointerlockerror;
     [MeasureAs=DocumentExitPointerLock] void exitPointerLock();
 
-    [OriginTrialEnabled=TouchEventFeatureDetection, DeprecateAs=V8Document_CreateTouchList_Method] TouchList createTouchList(Touch... touches);
-
     // Custom Elements
     // https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-register
     // FIXME: The registerElement return type should be Function.
diff --git a/third_party/blink/renderer/core/editing/frame_selection_test.cc b/third_party/blink/renderer/core/editing/frame_selection_test.cc
index 3024c0f..2a2a2b87 100644
--- a/third_party/blink/renderer/core/editing/frame_selection_test.cc
+++ b/third_party/blink/renderer/core/editing/frame_selection_test.cc
@@ -144,12 +144,8 @@
   std::unique_ptr<PaintController> paint_controller = PaintController::Create();
   {
     GraphicsContext context(*paint_controller);
-
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-      paint_controller->UpdateCurrentPaintChunkProperties(
-          root_paint_chunk_id_, PropertyTreeState::Root());
-    }
-
+    paint_controller->UpdateCurrentPaintChunkProperties(
+        root_paint_chunk_id_, PropertyTreeState::Root());
     Selection().PaintCaret(context, LayoutPoint());
   }
   paint_controller->CommitNewDisplayItems();
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index bf6387b..0895b17 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -458,6 +458,9 @@
 void WebPluginContainerImpl::EnqueueMessageEvent(
     const WebDOMMessageEvent& event) {
   static_cast<Event*>(event)->SetTarget(element_);
+  CHECK(element_);
+  CHECK(element_->GetExecutionContext());
+  CHECK(element_->GetExecutionContext()->GetEventQueue());
   element_->GetExecutionContext()->GetEventQueue()->EnqueueEvent(FROM_HERE,
                                                                  event);
 }
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
index 63a0c52..aec7a2f 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
+++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -314,6 +314,7 @@
                                   file_reader_loader_read_errors_histogram,
                                   ("Storage.Blob.FileReaderLoader.ReadError"));
   if (status != net::OK) {
+    net_error_ = status;
     file_reader_loader_read_errors_histogram.Sample(std::max(0, -net_error_));
     Failed(status == net::ERR_FILE_NOT_FOUND ? FileError::kNotFoundErr
                                              : FileError::kNotReadableErr,
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index dec6b4a..16a21d0dc 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -563,13 +563,6 @@
                             "value for <input type='image'>",
                             kM68, "5672688152477696")};
 
-
-    case WebFeature::kV8Document_CreateTouchList_Method:
-      return {"V8Document_CreateTouchList_Method", kM69,
-              ReplacedWillBeRemoved("document.createTouchList",
-                                    "TouchEvent constructor", kM69,
-                                    "5668612064935936")};
-
     case WebFeature::kDocumentOrigin:
       return {"DocumentOrigin", kM70,
               ReplacedWillBeRemoved("document.origin",
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.h b/third_party/blink/renderer/core/input/touch_event_manager.h
index 5da87c6..60357035 100644
--- a/third_party/blink/renderer/core/input/touch_event_manager.h
+++ b/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -22,6 +22,7 @@
 
 class LocalFrame;
 class Document;
+class Touch;
 
 // This class takes care of dispatching all touch events and
 // maintaining related states.
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc b/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
index 2805438d..6e75294e3 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
@@ -12,7 +12,6 @@
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 
 namespace blink {
 
@@ -1062,8 +1061,6 @@
 }
 
 TEST_F(LayoutBoxModelObjectTest, BackfaceVisibilityChange) {
-  ScopedSlimmingPaintV175ForTest spv175(true);
-
   AtomicString base_style =
       "width: 100px; height: 100px; background: blue; position: absolute";
   SetBodyInnerHTML("<div id='target' style='" + base_style + "'></div>");
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index 7154da5a..6cd2207 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -1635,6 +1635,10 @@
   if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
     auto fragments = NGPaintFragment::InlineFragmentsFor(this);
     if (fragments.IsInLayoutNGInlineFormattingContext()) {
+      if (Container()->IsLayoutNGMixin() && StyleRef().HasOutline()) {
+        Container()->InvalidateDisplayItemClients(
+            PaintInvalidationReason::kOutline);
+      }
       for (NGPaintFragment* fragment : fragments) {
         paint_invalidator.InvalidateDisplayItemClient(*fragment,
                                                       invalidation_reason);
diff --git a/third_party/blink/renderer/core/layout/layout_table_col_test.cc b/third_party/blink/renderer/core/layout/layout_table_col_test.cc
index 354b522..20df3f2a 100644
--- a/third_party/blink/renderer/core/layout/layout_table_col_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_col_test.cc
@@ -5,36 +5,12 @@
 #include "third_party/blink/renderer/core/layout/layout_table_col.h"
 
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 
 namespace blink {
 
 using LayoutTableColTest = RenderingTest;
 
-TEST_F(LayoutTableColTest, LocalVisualRectSPv1) {
-  ScopedSlimmingPaintV175ForTest spv175(false);
-  SetBodyInnerHTML(R"HTML(
-    <table id='table' style='width: 200px; height: 200px'>
-      <col id='col1' style='visibility: hidden'>
-      <col id='col2' style='visibility: collapse'>
-      <col id='col3'>
-      <tr><td></td><td></td></tr>
-    </table>
-  )HTML");
-
-  auto table_local_visual_rect =
-      GetLayoutObjectByElementId("table")->LocalVisualRect();
-  EXPECT_NE(LayoutRect(), table_local_visual_rect);
-  EXPECT_EQ(table_local_visual_rect,
-            GetLayoutObjectByElementId("col1")->LocalVisualRect());
-  EXPECT_EQ(table_local_visual_rect,
-            GetLayoutObjectByElementId("col2")->LocalVisualRect());
-  EXPECT_EQ(table_local_visual_rect,
-            GetLayoutObjectByElementId("col3")->LocalVisualRect());
-}
-
-TEST_F(LayoutTableColTest, LocalVisualRectSPv175) {
-  ScopedSlimmingPaintV175ForTest spv175(true);
+TEST_F(LayoutTableColTest, LocalVisualRect) {
   SetBodyInnerHTML(R"HTML(
     <table style='width: 200px; height: 200px'>
       <col id='col1' style='visibility: hidden'>
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index ff2e044..de64228b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -215,8 +215,9 @@
   }
 }
 
-NGPhysicalOffsetRect NGPhysicalBoxFragment::VisualRectWithContents() const {
-  if (HasOverflowClip() || Style().HasMask())
+NGPhysicalOffsetRect NGPhysicalBoxFragment::VisualRectWithContents(
+    bool clip_overflow) const {
+  if ((clip_overflow && HasOverflowClip()) || Style().HasMask())
     return SelfVisualRect();
 
   NGPhysicalOffsetRect visual_rect = SelfVisualRect();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index f2f8a3b..2f2ae61 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -58,7 +58,7 @@
   NGPhysicalOffsetRect SelfVisualRect() const;
 
   // VisualRect of itself including contents, in the local coordinate.
-  NGPhysicalOffsetRect VisualRectWithContents() const;
+  NGPhysicalOffsetRect VisualRectWithContents(bool clip_overflow) const;
 
   void AddSelfOutlineRects(Vector<LayoutRect>*,
                            const LayoutPoint& additional_offset) const;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
index 675d046..257d344 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -317,10 +317,12 @@
   return {{}, Size()};
 }
 
-NGPhysicalOffsetRect NGPhysicalFragment::VisualRectWithContents() const {
+NGPhysicalOffsetRect NGPhysicalFragment::VisualRectWithContents(
+    bool clip_overflow) const {
   switch (Type()) {
     case NGPhysicalFragment::kFragmentBox:
-      return ToNGPhysicalBoxFragment(*this).VisualRectWithContents();
+      return ToNGPhysicalBoxFragment(*this).VisualRectWithContents(
+          clip_overflow);
     case NGPhysicalFragment::kFragmentText:
       return ToNGPhysicalTextFragment(*this).SelfVisualRect();
     case NGPhysicalFragment::kFragmentLineBox:
@@ -442,7 +444,7 @@
 
 #ifndef NDEBUG
 void NGPhysicalFragment::ShowFragmentTree() const {
-  DumpFlags dump_flags = DumpAll & ~DumpOverflow;
+  DumpFlags dump_flags = DumpAll;  //& ~DumpOverflow;
   LOG(INFO) << "\n" << DumpFragmentTree(dump_flags).Utf8().data();
 }
 #endif  // !NDEBUG
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
index 1932d3eb..7b52e0a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -173,7 +173,7 @@
   NGPhysicalOffsetRect SelfVisualRect() const;
 
   // VisualRect of itself including contents, in the local coordinate.
-  NGPhysicalOffsetRect VisualRectWithContents() const;
+  NGPhysicalOffsetRect VisualRectWithContents(bool clip_overflow = true) const;
 
   // Scrollable overflow. including contents, in the local coordinate.
   NGPhysicalOffsetRect ScrollableOverflow() const;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
index 3656318..65370a29 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
@@ -133,10 +133,13 @@
     return false;
 
   FloatPoint local_point = local_transform.Inverse().MapPoint(point_in_parent);
-
   if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
+    LayoutPoint point_in_foreign_object(local_point);
+    // |local_point| already includes the offset of the <foreignObject> element,
+    // but PaintLayer::HitTestLayer assumes it has not been.
+    point_in_foreign_object.MoveBy(-Layer()->LayoutBoxLocation());
     HitTestResult layer_result(result.GetHitTestRequest(),
-                               LayoutPoint(local_point));
+                               point_in_foreign_object);
     bool retval = Layer()->HitTest(layer_result);
     result = layer_result;
     return retval;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
index f65f050..f591878 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
@@ -256,4 +256,58 @@
   EXPECT_EQ(svg, GetDocument().ElementFromPoint(400, 400));
 }
 
+TEST_F(LayoutSVGForeignObjectTest,
+       HitTestUnderClippedPositionedForeignObjectDescendant) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      * {
+        margin: 0
+      }
+    </style>
+    <svg id="svg" style="width: 600px; height: 600px">
+      <foreignObject id="foreignObject" x="200" y="200" width="100"
+          height="100">
+        <div id="target" style="overflow: hidden; position: relative;
+            width: 100px; height: 50px; left: 5px"></div>
+      </foreignObject>
+    </svg>
+  )HTML");
+
+  const auto& svg = *GetDocument().getElementById("svg");
+  const auto& target = *GetDocument().getElementById("target");
+  const auto& foreignObject = *GetDocument().getElementById("foreignObject");
+
+  EXPECT_EQ(svg, GetDocument().ElementFromPoint(1, 1));
+  EXPECT_EQ(foreignObject, GetDocument().ElementFromPoint(201, 201));
+  EXPECT_EQ(target, GetDocument().ElementFromPoint(206, 206));
+  EXPECT_EQ(foreignObject, GetDocument().ElementFromPoint(205, 255));
+}
+
+TEST_F(LayoutSVGForeignObjectTest,
+       HitTestUnderTransformedForeignObjectDescendant) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      * {
+        margin: 0
+      }
+    </style>
+    <svg id="svg" style="width: 600px; height: 600px">
+      <foreignObject id="foreignObject" x="200" y="200" width="100"
+          height="100" transform="translate(30)">
+        <div id="target" style="overflow: hidden; position: relative;
+            width: 100px; height: 50px; left: 5px"></div>
+      </foreignObject>
+    </svg>
+  )HTML");
+
+  const auto& svg = *GetDocument().getElementById("svg");
+  const auto& target = *GetDocument().getElementById("target");
+  const auto& foreignObject = *GetDocument().getElementById("foreignObject");
+
+  EXPECT_EQ(svg, GetDocument().ElementFromPoint(1, 1));
+  EXPECT_EQ(foreignObject, GetDocument().ElementFromPoint(231, 201));
+  EXPECT_EQ(target, GetDocument().ElementFromPoint(236, 206));
+  EXPECT_EQ(foreignObject, GetDocument().ElementFromPoint(235, 255));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
index f890185..fa97017 100644
--- a/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc
@@ -35,14 +35,6 @@
     if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
       EXPECT_EQ(&ancestor, &object.ContainerForPaintInvalidation());
 
-    if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-      EXPECT_EQ(expected_visual_rect_in_ancestor, object.VisualRect());
-      if (!object.FirstFragment().NextFragment()) {
-        EXPECT_EQ(expected_visual_rect_in_ancestor,
-                  object.FirstFragment().VisualRect());
-      }
-    }
-
     CheckVisualRect(object, ancestor, rect, expected_visual_rect_in_ancestor,
                     AdjustForBacking);
   }
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc
index 21fc239..d1d87d4 100644
--- a/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -54,6 +54,7 @@
 #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/core/script/script_loader.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
@@ -492,6 +493,9 @@
   // |document| is the node document here, and its context document is the
   // relevant settings object.
   Document* context_document = document.ContextDocument();
+  SettingsObject* settings_object =
+      SettingsObject::Create(context_document->GetSecurityOrigin(),
+                             context_document->GetReferrerPolicy());
 
   Modulator* modulator =
       Modulator::From(ToScriptStateForMainWorld(context_document->GetFrame()));
@@ -535,8 +539,8 @@
   // destination, options, settings object, "client", and with the top-level
   // module fetch flag set. Wait until algorithm asynchronously completes with
   // result." [spec text]
-  modulator->FetchSingle(request, ModuleGraphLevel::kDependentModuleFetch,
-                         link_loader);
+  modulator->FetchSingle(request, settings_object,
+                         ModuleGraphLevel::kDependentModuleFetch, link_loader);
 
   Settings* settings = document.GetSettings();
   if (settings && settings->GetLogPreload()) {
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc
index e8fcedd..2b9ebf64 100644
--- a/third_party/blink/renderer/core/loader/link_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -463,6 +463,7 @@
       : params_(params), fetched_(false) {}
 
   void FetchSingle(const ModuleScriptFetchRequest& request,
+                   SettingsObject* fetch_client_settings_object,
                    ModuleGraphLevel,
                    SingleModuleClient*) override {
     fetched_ = true;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
index a284747a..f678a826 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/workers/main_thread_worklet_global_scope.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
@@ -77,6 +78,7 @@
 }
 
 void ModuleScriptLoader::Fetch(const ModuleScriptFetchRequest& module_request,
+                               SettingsObject* fetch_client_settings_object,
                                ModuleGraphLevel level) {
   // https://html.spec.whatwg.org/#fetch-a-single-module-script
 
@@ -131,7 +133,8 @@
   // [SMSR] "... and its credentials mode to options's credentials mode."
   // [spec text]
   fetch_params.SetCrossOriginAccessControl(
-      modulator_->GetSecurityOriginForFetch(), options_.CredentialsMode());
+      fetch_client_settings_object->GetSecurityOrigin(),
+      options_.CredentialsMode());
 
   // Step 5. "... referrer is referrer, ..." [spec text]
   if (!module_request.GetReferrer().IsNull()) {
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
index e6e619b..d7b782e 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
@@ -20,6 +20,7 @@
 class ModuleScript;
 class ModuleScriptLoaderClient;
 class ModuleScriptLoaderRegistry;
+class SettingsObject;
 enum class ModuleGraphLevel;
 
 // ModuleScriptLoader is responsible for loading a new single ModuleScript.
@@ -54,6 +55,7 @@
   ~ModuleScriptLoader();
 
   void Fetch(const ModuleScriptFetchRequest&,
+             SettingsObject* fetch_client_settings_object,
              ModuleGraphLevel);
 
   // Implements ModuleScriptFetcher::Client.
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
index eb8b543a..dcf09136 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.cc
@@ -14,6 +14,7 @@
 
 ModuleScriptLoader* ModuleScriptLoaderRegistry::Fetch(
     const ModuleScriptFetchRequest& request,
+    SettingsObject* fetch_client_settings_object,
     ModuleGraphLevel level,
     Modulator* modulator,
     ModuleScriptLoaderClient* client) {
@@ -21,7 +22,7 @@
       ModuleScriptLoader::Create(modulator, request.Options(), this, client);
   DCHECK(loader->IsInitialState());
   active_loaders_.insert(loader);
-  loader->Fetch(request, level);
+  loader->Fetch(request, fetch_client_settings_object, level);
   return loader;
 }
 
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
index c3dd895..6ecc964 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_registry.h
@@ -16,6 +16,7 @@
 class ModuleScriptFetchRequest;
 class ModuleScriptLoader;
 class ModuleScriptLoaderClient;
+class SettingsObject;
 enum class ModuleGraphLevel;
 
 // ModuleScriptLoaderRegistry keeps active ModuleLoaders alive.
@@ -28,6 +29,7 @@
   void Trace(blink::Visitor*);
 
   ModuleScriptLoader* Fetch(const ModuleScriptFetchRequest&,
+                            SettingsObject* fetch_client_settings_object,
                             ModuleGraphLevel,
                             Modulator*,
                             ModuleScriptLoaderClient*);
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
index a19f9c61..77e3376a 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/core/script/script.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/testing/dummy_modulator.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
@@ -75,10 +76,6 @@
 
   ~ModuleScriptLoaderTestModulator() override = default;
 
-  const SecurityOrigin* GetSecurityOriginForFetch() override {
-    return security_origin_.get();
-  }
-
   ScriptState* GetScriptState() override { return script_state_.get(); }
 
   ScriptModule CompileModule(const String& script,
@@ -160,6 +157,7 @@
   std::unique_ptr<MainThreadWorkletReportingProxy> reporting_proxy_;
   Persistent<ModuleScriptLoaderTestModulator> modulator_;
   Persistent<MainThreadWorkletGlobalScope> global_scope_;
+  Persistent<SettingsObject> fetch_client_settings_object_;
 };
 
 void ModuleScriptLoaderTest::SetUp() {
@@ -176,6 +174,8 @@
   modulator_ = new ModuleScriptLoaderTestModulator(
       ToScriptStateForMainWorld(&GetFrame()), GetDocument().GetSecurityOrigin(),
       fetcher);
+  fetch_client_settings_object_ = SettingsObject::Create(
+      GetDocument().GetSecurityOrigin(), GetDocument().GetReferrerPolicy());
 }
 
 void ModuleScriptLoaderTest::InitializeForWorklet() {
@@ -198,6 +198,8 @@
   modulator_ = new ModuleScriptLoaderTestModulator(
       global_scope_->ScriptController()->GetScriptState(),
       GetDocument().GetSecurityOrigin(), fetcher);
+  fetch_client_settings_object_ = SettingsObject::Create(
+      GetDocument().GetSecurityOrigin(), GetDocument().GetReferrerPolicy());
 }
 
 void ModuleScriptLoaderTest::TestFetchDataURL(
@@ -205,6 +207,7 @@
   ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create();
   KURL url("data:text/javascript,export default 'grapes';");
   registry->Fetch(ModuleScriptFetchRequest::CreateForTest(url),
+                  fetch_client_settings_object_.Get(),
                   ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(),
                   client);
 }
@@ -256,6 +259,7 @@
   KURL url("data:text/javascript,import 'invalid';export default 'grapes';");
   GetModulator()->SetModuleRequests({"invalid"});
   registry->Fetch(ModuleScriptFetchRequest::CreateForTest(url),
+                  fetch_client_settings_object_.Get(),
                   ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(),
                   client);
 }
@@ -293,6 +297,7 @@
   KURL url;
   EXPECT_FALSE(url.IsValid());
   registry->Fetch(ModuleScriptFetchRequest::CreateForTest(url),
+                  fetch_client_settings_object_.Get(),
                   ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(),
                   client);
 }
@@ -328,6 +333,7 @@
 
   ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create();
   registry->Fetch(ModuleScriptFetchRequest::CreateForTest(url),
+                  fetch_client_settings_object_.Get(),
                   ModuleGraphLevel::kTopLevelModuleFetch, GetModulator(),
                   client);
 }
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
index acfc9a2d..3ff5d1d 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
 #include "third_party/blink/renderer/core/script/layered_api.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loading_log.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -19,36 +20,40 @@
 
 ModuleTreeLinker* ModuleTreeLinker::Fetch(
     const KURL& url,
+    SettingsObject* fetch_client_settings_object,
     const KURL& base_url,
     WebURLRequest::RequestContext destination,
     const ScriptFetchOptions& options,
     Modulator* modulator,
     ModuleTreeLinkerRegistry* registry,
     ModuleTreeClient* client) {
-  ModuleTreeLinker* fetcher =
-      new ModuleTreeLinker(destination, modulator, registry, client);
+  ModuleTreeLinker* fetcher = new ModuleTreeLinker(
+      fetch_client_settings_object, destination, modulator, registry, client);
   fetcher->FetchRoot(url, base_url, options);
   return fetcher;
 }
 
 ModuleTreeLinker* ModuleTreeLinker::FetchDescendantsForInlineScript(
     ModuleScript* module_script,
+    SettingsObject* fetch_client_settings_object,
     WebURLRequest::RequestContext destination,
     Modulator* modulator,
     ModuleTreeLinkerRegistry* registry,
     ModuleTreeClient* client) {
   DCHECK(module_script);
-  ModuleTreeLinker* fetcher =
-      new ModuleTreeLinker(destination, modulator, registry, client);
+  ModuleTreeLinker* fetcher = new ModuleTreeLinker(
+      fetch_client_settings_object, destination, modulator, registry, client);
   fetcher->FetchRootInline(module_script);
   return fetcher;
 }
 
-ModuleTreeLinker::ModuleTreeLinker(WebURLRequest::RequestContext destination,
+ModuleTreeLinker::ModuleTreeLinker(SettingsObject* fetch_client_settings_object,
+                                   WebURLRequest::RequestContext destination,
                                    Modulator* modulator,
                                    ModuleTreeLinkerRegistry* registry,
                                    ModuleTreeClient* client)
-    : destination_(destination),
+    : fetch_client_settings_object_(fetch_client_settings_object),
+      destination_(destination),
       modulator_(modulator),
       registry_(registry),
       client_(client) {
@@ -58,6 +63,7 @@
 }
 
 void ModuleTreeLinker::Trace(blink::Visitor* visitor) {
+  visitor->Trace(fetch_client_settings_object_);
   visitor->Trace(modulator_);
   visitor->Trace(registry_);
   visitor->Trace(client_);
@@ -176,7 +182,8 @@
   // ... with the top-level module fetch flag set. ...
   ModuleScriptFetchRequest request(
       url, destination_, options, Referrer::NoReferrer(),
-      modulator_->GetReferrerPolicy(), TextPosition::MinimumPosition());
+      fetch_client_settings_object_->GetReferrerPolicy(),
+      TextPosition::MinimumPosition());
 
   InitiateInternalModuleScriptGraphFetching(
       request, ModuleGraphLevel::kTopLevelModuleFetch);
@@ -214,7 +221,8 @@
   ++num_incomplete_fetches_;
 
   // [IMSGF] Step 2. Fetch a single module script given ...
-  modulator_->FetchSingle(request, level, this);
+  modulator_->FetchSingle(request, fetch_client_settings_object_.Get(), level,
+                          this);
 
   // [IMSGF] Step 3-- are executed when NotifyModuleLoadFinished() is called.
 }
@@ -366,7 +374,7 @@
     // procedure given ... with the top-level module fetch flag unset. ...
     ModuleScriptFetchRequest request(
         urls[i], destination_, options, module_script->BaseURL().GetString(),
-        modulator_->GetReferrerPolicy(), positions[i]);
+        fetch_client_settings_object_->GetReferrerPolicy(), positions[i]);
     InitiateInternalModuleScriptGraphFetching(
         request, ModuleGraphLevel::kDependentModuleFetch);
   }
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
index abcc61db..92388ad 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
@@ -18,6 +18,7 @@
 
 class ModuleScriptFetchRequest;
 class ModuleTreeLinkerRegistry;
+class SettingsObject;
 
 // A ModuleTreeLinker is responsible for running and keeping intermediate states
 // for a top-level [IMSGF] "internal module script graph fetching procedure" or
@@ -40,6 +41,7 @@
   // TODO(hiroshige): |base_url| is used only for Layered APIs and will be
   // removed soon once an upcoming spec change lands.
   static ModuleTreeLinker* Fetch(const KURL&,
+                                 SettingsObject* fetch_client_settings_object,
                                  const KURL& base_url,
                                  WebURLRequest::RequestContext destination,
                                  const ScriptFetchOptions&,
@@ -50,6 +52,7 @@
   // [FDaI] for an inline script.
   static ModuleTreeLinker* FetchDescendantsForInlineScript(
       ModuleScript*,
+      SettingsObject* fetch_client_settings_object,
       WebURLRequest::RequestContext destination,
       Modulator*,
       ModuleTreeLinkerRegistry*,
@@ -64,7 +67,8 @@
   bool HasFinished() const { return state_ == State::kFinished; }
 
  private:
-  ModuleTreeLinker(WebURLRequest::RequestContext destination,
+  ModuleTreeLinker(SettingsObject* fetch_client_settings_object,
+                   WebURLRequest::RequestContext destination,
                    Modulator*,
                    ModuleTreeLinkerRegistry*,
                    ModuleTreeClient*);
@@ -107,6 +111,7 @@
   ScriptValue FindFirstParseError(ModuleScript*,
                                   HeapHashSet<Member<ModuleScript>>*) const;
 
+  const Member<SettingsObject> fetch_client_settings_object_;
   const WebURLRequest::RequestContext destination_;
   const Member<Modulator> modulator_;
   HashSet<KURL> visited_set_;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
index 7ba86bdf..2c5e7da 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
 
 #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
 
@@ -16,13 +17,15 @@
 
 ModuleTreeLinker* ModuleTreeLinkerRegistry::Fetch(
     const KURL& url,
+    SettingsObject* fetch_client_settings_object,
     const KURL& base_url,
     WebURLRequest::RequestContext destination,
     const ScriptFetchOptions& options,
     Modulator* modulator,
     ModuleTreeClient* client) {
-  ModuleTreeLinker* fetcher = ModuleTreeLinker::Fetch(
-      url, base_url, destination, options, modulator, this, client);
+  ModuleTreeLinker* fetcher =
+      ModuleTreeLinker::Fetch(url, fetch_client_settings_object, base_url,
+                              destination, options, modulator, this, client);
   DCHECK(fetcher->IsFetching());
   active_tree_linkers_.insert(fetcher);
   return fetcher;
@@ -30,11 +33,13 @@
 
 ModuleTreeLinker* ModuleTreeLinkerRegistry::FetchDescendantsForInlineScript(
     ModuleScript* module_script,
+    SettingsObject* fetch_client_settings_object,
     WebURLRequest::RequestContext destination,
     Modulator* modulator,
     ModuleTreeClient* client) {
   ModuleTreeLinker* fetcher = ModuleTreeLinker::FetchDescendantsForInlineScript(
-      module_script, destination, modulator, this, client);
+      module_script, fetch_client_settings_object, destination, modulator, this,
+      client);
   DCHECK(fetcher->IsFetching());
   active_tree_linkers_.insert(fetcher);
   return fetcher;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
index 7536cd15..c8fbfe2 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h
@@ -19,6 +19,7 @@
 class ModuleTreeLinker;
 class ModuleScript;
 class ScriptFetchOptions;
+class SettingsObject;
 
 // ModuleTreeLinkerRegistry keeps active ModuleTreeLinkers alive.
 class CORE_EXPORT ModuleTreeLinkerRegistry
@@ -34,6 +35,7 @@
   }
 
   ModuleTreeLinker* Fetch(const KURL&,
+                          SettingsObject* fetch_client_settings_object,
                           const KURL& base_url,
                           WebURLRequest::RequestContext destination,
                           const ScriptFetchOptions&,
@@ -41,6 +43,7 @@
                           ModuleTreeClient*);
   ModuleTreeLinker* FetchDescendantsForInlineScript(
       ModuleScript*,
+      SettingsObject* fetch_client_settings_object,
       WebURLRequest::RequestContext destination,
       Modulator*,
       ModuleTreeClient*);
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
index 0beb09e7..5c2b549 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/testing/dummy_modulator.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -120,10 +121,10 @@
  private:
   // Implements Modulator:
 
-  ReferrerPolicy GetReferrerPolicy() override { return kReferrerPolicyDefault; }
   ScriptState* GetScriptState() override { return script_state_.get(); }
 
   void FetchSingle(const ModuleScriptFetchRequest& request,
+                   SettingsObject*,
                    ModuleGraphLevel,
                    SingleModuleClient* client) override {
     EXPECT_FALSE(pending_clients_.Contains(request.Url()));
@@ -183,6 +184,10 @@
   void SetUp() override;
 
   ModuleTreeLinkerTestModulator* GetModulator() { return modulator_.Get(); }
+  SettingsObject* CreateFetchClientSettingsObject() {
+    return SettingsObject::Create(GetDocument().GetSecurityOrigin(),
+                                  GetDocument().GetReferrerPolicy());
+  }
 
  protected:
   Persistent<ModuleTreeLinkerTestModulator> modulator_;
@@ -200,8 +205,9 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -220,8 +226,9 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -244,8 +251,9 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -269,8 +277,9 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -307,8 +316,9 @@
 
   KURL url("http://example.com/root.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -364,8 +374,9 @@
 
   KURL url("http://example.com/depth1.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
@@ -388,8 +399,9 @@
 
   KURL url("http://example.com/a.js");
   TestModuleTreeClient* client = new TestModuleTreeClient;
-  registry->Fetch(url, NullURL(), WebURLRequest::kRequestContextScript,
-                  ScriptFetchOptions(), GetModulator(), client);
+  registry->Fetch(url, CreateFetchClientSettingsObject(), NullURL(),
+                  WebURLRequest::kRequestContextScript, ScriptFetchOptions(),
+                  GetModulator(), client);
 
   EXPECT_FALSE(client->WasNotifyFinished())
       << "ModuleTreeLinker should always finish asynchronously.";
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
index c1035e3..306f653e 100644
--- a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
+++ b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
@@ -96,37 +96,6 @@
 
 INSTANTIATE_PAINT_TEST_CASE_P(BoxPaintInvalidatorTest);
 
-TEST_P(BoxPaintInvalidatorTest, SlowMapToVisualRectInAncestorSpaceLayoutView) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
-  SetBodyInnerHTML(
-      "<!doctype html>"
-      "<style>"
-      "#parent {"
-      "    display: inline-block;"
-      "    width: 300px;"
-      "    height: 300px;"
-      "    margin-top: 200px;"
-      "    filter: blur(3px);"  // Forces the slow path in
-                                // SlowMapToVisualRectInAncestorSpace.
-      "    border: 1px solid rebeccapurple;"
-      "}"
-      "</style>"
-      "<div id=parent>"
-      "  <iframe id='target' src='data:text/html,<body style='background: "
-      "blue;'></body>'></iframe>"
-      "</div>");
-
-  auto& target = *GetDocument().getElementById("target");
-  EXPECT_EQ(IntRect(2, 202, 318, 168),
-            EnclosingIntRect(ToHTMLFrameOwnerElement(target)
-                                 .contentDocument()
-                                 ->GetLayoutView()
-                                 ->FirstFragment()
-                                 .VisualRect()));
-}
-
 TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonPaintingNothing) {
   SetUpHTML();
   auto& target = *GetDocument().getElementById("target");
@@ -180,14 +149,6 @@
       PaintInvalidationReason::kNone,
       ComputePaintInvalidationReason(box, visual_rect, visual_rect.Location()));
 
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    // Location change.
-    EXPECT_EQ(
-        PaintInvalidationReason::kGeometry,
-        ComputePaintInvalidationReason(
-            box, visual_rect, visual_rect.Location() + LayoutSize(10, 20)));
-  }
-
   // Visual rect size change.
   LayoutRect old_visual_rect = visual_rect;
   target.setAttribute(HTMLNames::styleAttr, "background: blue; width: 200px");
@@ -225,8 +186,7 @@
   auto& target = *GetDocument().getElementById("target");
 
   // The target initially has border.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    ExpectFullPaintInvalidationOnGeometryChange("With border");
+  ExpectFullPaintInvalidationOnGeometryChange("With border");
 
   // Clear border.
   target.setAttribute(HTMLNames::classAttr, "");
diff --git a/third_party/blink/renderer/core/paint/layer_clip_recorder_test.cc b/third_party/blink/renderer/core/paint/layer_clip_recorder_test.cc
deleted file mode 100644
index 9356632..0000000
--- a/third_party/blink/renderer/core/paint/layer_clip_recorder_test.cc
+++ /dev/null
@@ -1,90 +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 "third_party/blink/renderer/core/paint/layer_clip_recorder.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
-#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
-#include "third_party/blink/renderer/core/paint/paint_layer.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
-
-namespace blink {
-namespace {
-
-class LayerClipRecorderTest : public PaintControllerPaintTestBase {
- private:
-  void SetUp() override {
-    PaintControllerPaintTestBase::SetUp();
-    EnableCompositing();
-  }
-};
-
-void DrawEmptyClip(GraphicsContext& context,
-                   LayoutView& layout_view,
-                   PaintPhase phase) {
-  LayoutRect rect(1, 1, 9, 9);
-  ClipRect clip_rect(rect);
-  LayerClipRecorder layer_clip_recorder(
-      context, *layout_view.Compositor()->RootLayer(),
-      DisplayItem::kClipLayerForeground, clip_rect, nullptr, LayoutPoint(),
-      PaintLayerFlags(),
-      layout_view.Compositor()->RootLayer()->GetLayoutObject());
-}
-
-void DrawRectInClip(GraphicsContext& context,
-                    LayoutView& layout_view,
-                    PaintPhase phase) {
-  IntRect rect(1, 1, 9, 9);
-  ClipRect clip_rect((LayoutRect(rect)));
-  LayerClipRecorder layer_clip_recorder(
-      context, *layout_view.Compositor()->RootLayer(),
-      DisplayItem::kClipLayerForeground, clip_rect, nullptr, LayoutPoint(),
-      PaintLayerFlags(),
-      layout_view.Compositor()->RootLayer()->GetLayoutObject());
-  if (!DrawingRecorder::UseCachedDrawingIfPossible(context, layout_view,
-                                                   phase)) {
-    DrawingRecorder recorder(context, layout_view, phase);
-    context.DrawRect(rect);
-  }
-}
-
-TEST_F(LayerClipRecorderTest, Single) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
-  RootPaintController().InvalidateAll();
-  GraphicsContext context(RootPaintController());
-  EXPECT_EQ((size_t)0, RootPaintController().GetDisplayItemList().size());
-
-  DrawRectInClip(context, GetLayoutView(), PaintPhase::kForeground);
-  RootPaintController().CommitNewDisplayItems();
-  EXPECT_EQ((size_t)3, RootPaintController().GetDisplayItemList().size());
-  EXPECT_TRUE(DisplayItem::IsClipType(
-      RootPaintController().GetDisplayItemList()[0].GetType()));
-  EXPECT_TRUE(DisplayItem::IsDrawingType(
-      RootPaintController().GetDisplayItemList()[1].GetType()));
-  EXPECT_TRUE(DisplayItem::IsEndClipType(
-      RootPaintController().GetDisplayItemList()[2].GetType()));
-}
-
-TEST_F(LayerClipRecorderTest, Empty) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
-  RootPaintController().InvalidateAll();
-  GraphicsContext context(RootPaintController());
-  EXPECT_EQ((size_t)0, RootPaintController().GetDisplayItemList().size());
-
-  DrawEmptyClip(context, GetLayoutView(), PaintPhase::kForeground);
-  RootPaintController().CommitNewDisplayItems();
-  EXPECT_EQ((size_t)0, RootPaintController().GetDisplayItemList().size());
-}
-
-}  // namespace
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index a1406f8..c848635 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -256,7 +256,7 @@
 
   DCHECK(PhysicalFragment().ChildrenInline());
 
-  LayoutRect overflow_rect(box_fragment_.VisualOverflowRect());
+  LayoutRect overflow_rect(box_fragment_.VisualContentsRect());
   overflow_rect.MoveBy(paint_offset);
   if (!paint_info.GetCullRect().IntersectsCullRect(overflow_rect))
     return;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index c6c4ec4d..45fa2af 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -158,6 +158,10 @@
   return physical_fragment_->VisualRectWithContents().ToLayoutRect();
 }
 
+LayoutRect NGPaintFragment::VisualContentsRect() const {
+  return physical_fragment_->VisualRectWithContents(false).ToLayoutRect();
+}
+
 // Populate descendants from NGPhysicalFragment tree.
 void NGPaintFragment::PopulateDescendants(
     const NGPhysicalOffset inline_offset_to_container_box,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index faea365..7918bc2a 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -76,7 +76,11 @@
   bool HasSelfPaintingLayer() const;
   LayoutRect VisualRect() const override { return visual_rect_; }
   void SetVisualRect(const LayoutRect& rect) { visual_rect_ = rect; }
+  // CSS ink overflow https://www.w3.org/TR/css-overflow-3/#ink
+  // Encloses all pixels painted by self + children.
   LayoutRect VisualOverflowRect() const;
+  // Union of children's ink overflows.
+  LayoutRect VisualContentsRect() const;
 
   LayoutRect PartialInvalidationRect() const override;
 
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
index aec9c0e..172e69da 100644
--- a/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
+++ b/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
@@ -282,8 +282,7 @@
   EXPECT_TRUE(target->MayNeedPaintInvalidation());
 
   GetDocument().View()->UpdateLifecycleToPrePaintClean();
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled() ||
-      !RuntimeEnabledFeatures::PartialRasterInvalidationEnabled())
+  if (!RuntimeEnabledFeatures::PartialRasterInvalidationEnabled())
     EXPECT_EQ(LayoutRect(), target->PartialInvalidationRect());
   GetDocument().View()->UpdateAllLifecyclePhases();
   EXPECT_EQ(LayoutRect(), target->PartialInvalidationRect());
diff --git a/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc b/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
index 84a50e34..9f99ded 100644
--- a/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
@@ -77,9 +77,6 @@
 }
 
 TEST_P(PaintControllerPaintTest, ChunkIdClientCacheFlag) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='div' style='width: 200px; height: 200px; opacity: 0.5'>
       <div style='width: 100px; height: 100px; background-color:
@@ -120,9 +117,6 @@
 }
 
 TEST_P(PaintControllerPaintTest, CompositingNoFold) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='div' style='width: 200px; height: 200px; opacity: 0.5'>
       <div style='width: 100px; height: 100px; background-color:
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index c525c96..e537bf4 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1854,16 +1854,6 @@
     ConvertToLayerCoords(root_layer, offset);
   }
   offset.MoveBy(translation_offset);
-  // The location of a foreignObject element is added *after* transform, not
-  // before (all SVG child elements have this behavior). Therefore, remove
-  // the offset here to avoid applying it before the transform. It will be
-  // added later.
-  // TODO(chrishtr): this ugliness can be removed if we change the code to
-  // to be based on PaintOffset rather than PaintLayer offsets, like the
-  // paint code does. This is a larger effort though, that involves using
-  // property trees to drive hit testing coordinate spaces.
-  if (GetLayoutObject().IsSVGForeignObject())
-    offset.MoveBy(-LayoutBoxLocation());
 
   LayoutObject* container_layout_object =
       container_layer ? &container_layer->GetLayoutObject() : nullptr;
@@ -1941,7 +1931,11 @@
   if (result.GetHitTestRequest().IgnoreClipping())
     clip_behavior = kIgnoreOverflowClip;
 
-  bool use_transform = Transform();
+  // We can only reach an SVG foreign object's PaintLayer from
+  // LayoutSVGForeignObject::NodeAtFloatPoint (because
+  // IsReplacedNormalFlowStacking() true for LayoutSVGForeignObject),
+  // where the hit_test_rect has already been transformed to local coordinates.
+  bool use_transform = Transform() && !GetLayoutObject().IsSVGForeignObject();
 
   // Apply a transform if we have one.
   if (use_transform && !applied_transform) {
@@ -2081,10 +2075,6 @@
   }
 
   LayoutPoint offset = -LayoutBoxLocation();
-  // See comment in CreateLocalTransformState. The code here is
-  // where we re-add the location.
-  if (root_layer->GetLayoutObject().IsSVGForeignObject())
-    offset.MoveBy(root_layer->LayoutBoxLocation());
 
   // Next we want to see if the mouse pos is inside the child LayoutObjects of
   // the layer. Check every fragment in reverse order.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
index 7e3db25..e127181 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -22,8 +22,8 @@
   void ExpectPaintedOutputInvisible(const char* element_name,
                                     bool expected_value) {
     // The optimization to skip painting for effectively-invisible content is
-    // limited to SPv1.
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
+    // limited to pre-SPv2.
+    if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
       return;
 
     PaintLayer* target_layer =
@@ -35,9 +35,8 @@
             .PaintedOutputInvisible(target_layer->GetLayoutObject().StyleRef(),
                                     painting_info.GetGlobalPaintFlags());
     EXPECT_EQ(expected_value, invisible)
-        << "Failed painted output visibility [spv175_enabled="
-        << RuntimeEnabledFeatures::SlimmingPaintV175Enabled()
-        << ", expected=" << expected_value << ", actual=" << invisible << "].";
+        << "Failed painted output visibility, expected=" << expected_value
+        << ", actual=" << invisible << "].";
   }
 
   PaintController& MainGraphicsLayerPaintController() {
@@ -153,8 +152,7 @@
                    other_chunk_state));
   };
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    check_chunks();
+  check_chunks();
 
   ToHTMLElement(content1.GetNode())
       ->setAttribute(HTMLNames::styleAttr,
@@ -177,8 +175,7 @@
       TestDisplayItem(filler2, kBackgroundType));
 
   // We should still have the paint chunks forced by the cached subsequences.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    check_chunks();
+  check_chunks();
 }
 
 TEST_P(PaintLayerPainterTest, CachedSubsequenceOnInterestRectChange) {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc
index 19628a9..67117546 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -283,10 +283,7 @@
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
   EXPECT_EQ(LayoutPoint(-1000, -1000), content_layer->Location());
   EXPECT_TRUE(scroll_layer->NeedsRepaint());
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    EXPECT_FALSE(content_layer->NeedsRepaint());
-  else
-    EXPECT_TRUE(content_layer->NeedsRepaint());
+  EXPECT_FALSE(content_layer->NeedsRepaint());
   GetDocument().View()->UpdateAllLifecyclePhases();
 }
 
@@ -566,15 +563,9 @@
   scroller->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 20),
                                                  kProgrammaticScroll);
   GetDocument().View()->UpdateAllLifecyclePhases();
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(LayoutRect(0, 30, 50, 10),
-              content_layer->FirstFragment().VisualRect());
-    EXPECT_EQ(LayoutRect(0, 30, 50, 5), content->FirstFragment().VisualRect());
-  } else {
-    EXPECT_EQ(LayoutRect(0, 10, 50, 10),
-              content_layer->FirstFragment().VisualRect());
-    EXPECT_EQ(LayoutRect(0, 10, 50, 5), content->FirstFragment().VisualRect());
-  }
+  EXPECT_EQ(LayoutRect(0, 30, 50, 10),
+            content_layer->FirstFragment().VisualRect());
+  EXPECT_EQ(LayoutRect(0, 30, 50, 5), content->FirstFragment().VisualRect());
 }
 
 TEST_P(PaintLayerTest, PaintInvalidationOnCompositedScroll) {
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index e751203..423e205 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -77,8 +77,7 @@
 
 #define CHECK_VISUAL_RECT(expected, source_object, ancestor, slop_factor)      \
   do {                                                                         \
-    if ((source_object)->HasLayer() && (ancestor)->HasLayer() &&               \
-        RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {                  \
+    if ((source_object)->HasLayer() && (ancestor)->HasLayer()) {               \
       LayoutRect actual((source_object)->LocalVisualRect());                   \
       (source_object)                                                          \
           ->MapToVisualRectInAncestorSpace(ancestor, actual,                   \
@@ -295,10 +294,7 @@
   EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
   EXPECT_EQ(properties->PaintOffsetTranslation(),
             overflow_clip->LocalTransformSpace());
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    EXPECT_EQ(FloatRoundedRect(10, 10, 101, 100), overflow_clip->ClipRect());
-  else
-    EXPECT_EQ(FloatRoundedRect(10, 10, 100.5, 100), overflow_clip->ClipRect());
+  EXPECT_EQ(FloatRoundedRect(10, 10, 101, 100), overflow_clip->ClipRect());
 
   PaintLayer* paint_layer =
       ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
@@ -306,13 +302,8 @@
                   ->VerticalScrollbar()
                   ->IsOverlayScrollbar());
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(FloatRoundedRect(10, 10, 94, 93),
-              overflow_clip->ClipRectExcludingOverlayScrollbars());
-  } else {
-    EXPECT_EQ(FloatRoundedRect(10, 10, 93.5, 93),
-              overflow_clip->ClipRectExcludingOverlayScrollbars());
-  }
+  EXPECT_EQ(FloatRoundedRect(10, 10, 94, 93),
+            overflow_clip->ClipRectExcludingOverlayScrollbars());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) {
@@ -607,7 +598,7 @@
   if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
     EXPECT_EQ(nullptr, transform_properties->PaintOffsetTranslation());
   } else {
-    // SPv175 creates PaintOffsetTranslation for composited layers.
+    // Pre-SPv2 creates PaintOffsetTranslation for composited layers.
     EXPECT_EQ(TransformationMatrix().Translate(50, 100),
               transform_properties->PaintOffsetTranslation()->Matrix());
   }
@@ -672,10 +663,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, NestedOpacityEffect) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='nodeWithoutOpacity' style='width: 100px; height: 200px'>
       <div id='childWithOpacity'
@@ -732,10 +719,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, TransformNodeDoesNotAffectEffectNodes) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <style>
       #nodeWithOpacity {
@@ -797,9 +780,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <div id='nodeWithOpacity'
         style='opacity: 0.6; width: 100px; height: 200px'>
@@ -847,10 +827,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, EffectNodesInSVG) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg id='svgRoot'>
       <g id='groupWithOpacity' opacity='0.6'>
@@ -901,10 +877,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossHTMLSVGBoundary) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='divWithOpacity' style='opacity: 0.2;'>
       <svg id='svgRootWithOpacity' style='opacity: 0.3;'>
@@ -936,10 +908,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossSVGHTMLBoundary) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg id='svgRootWithOpacity' style='opacity: 0.3;'>
       <foreignObject id='foreignObjectWithOpacity' opacity='0.4'>
@@ -1236,10 +1204,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, ForeignObjectWithMask) {
-  // SPV1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <style> body { margin: 0px; } </style>
     <svg id='svg' style='position; relative'>
@@ -1296,9 +1260,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, SVGViewportContainer) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <!-- border radius of inner svg elemnents should be ignored. -->
     <style>svg { border-radius: 10px }</style>
@@ -1359,9 +1320,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, SVGForeignObjectOverflowClip) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg id='svg'>
       <foreignObject id='object1' x='10' y='20' width='30' height='40'
@@ -1809,11 +1767,8 @@
     EXPECT_EQ(child.FirstFragment().PaintProperties()->PaintOffsetTranslation(),
               child.FirstFragment().LocalBorderBoxProperties().Transform());
   }
-  // SPv1 has no effect tree.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(scroller_properties->Effect(),
-              child.FirstFragment().LocalBorderBoxProperties().Effect());
-  }
+  EXPECT_EQ(scroller_properties->Effect(),
+            child.FirstFragment().LocalBorderBoxProperties().Effect());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 800, 10000), &scroller,
                           GetDocument().View()->GetLayoutView());
   CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 100, 200), &child,
@@ -1995,10 +1950,7 @@
   LayoutRect local_clip_rect(40, 10, 40, 60);
   LayoutRect absolute_clip_rect = local_clip_rect;
   // Moved by 124 pixels due to pixel-snapping.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    absolute_clip_rect.Move(124, 456);
-  else
-    absolute_clip_rect.Move(LayoutUnit(123.5f), LayoutUnit(456));
+  absolute_clip_rect.Move(124, 456);
 
   auto* clip = GetLayoutObjectByElementId("clip");
   const ObjectPaintProperties* clip_properties =
@@ -4415,10 +4367,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, FloatUnderInline) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div style='position: absolute; top: 55px; left: 66px'>
       <span id='span'
@@ -4477,21 +4425,12 @@
 
   EXPECT_EQ(LayoutPoint(FloatPoint(31.5, 20)),
             clipper->FirstFragment().PaintOffset());
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    // Result is pixel-snapped.
-    EXPECT_EQ(FloatRect(32, 20, 400, 300),
-              clip_properties->OverflowClip()->ClipRect().Rect());
-  } else {
-    EXPECT_EQ(FloatRect(31.5, 20, 400, 300),
-              clip_properties->OverflowClip()->ClipRect().Rect());
-  }
+  // Result is pixel-snapped.
+  EXPECT_EQ(FloatRect(32, 20, 400, 300),
+            clip_properties->OverflowClip()->ClipRect().Rect());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='target' style='width:300px; height:200px;
         -webkit-mask:linear-gradient(red,red)'>
@@ -4520,10 +4459,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, MaskWithOutset) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <div id='target' style='width:300px; height:200px;
         -webkit-mask-box-image-source:linear-gradient(red,red);
@@ -4553,10 +4488,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   // This test verifies an abs-pos element still escape the scroll of a
   // static-pos ancestor, but gets clipped due to the presence of a mask.
   SetBodyInnerHTML(R"HTML(
@@ -4625,10 +4556,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, MaskInline) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   LoadAhem();
   // This test verifies CSS mask applied on an inline element is clipped to
   // the line box of the said element. In this test the masked element has
@@ -4741,10 +4668,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg id='svgroot' 'width=100' height='100'
         style='position: relative; z-index: 0'>
@@ -4980,13 +4903,7 @@
   const auto* properties1 = PaintPropertiesForElement("div1");
   ASSERT_NE(nullptr, properties1);
   const auto* overflow_controls_clip = properties1->OverflowControlsClip();
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(FloatRect(0, 0, 6, 50),
-              overflow_controls_clip->ClipRect().Rect());
-  } else {
-    EXPECT_EQ(FloatRect(0, 0, 5.5, 50),
-              overflow_controls_clip->ClipRect().Rect());
-  }
+  EXPECT_EQ(FloatRect(0, 0, 6, 50), overflow_controls_clip->ClipRect().Rect());
 
   const auto* properties2 = PaintPropertiesForElement("div2");
   ASSERT_NE(nullptr, properties2);
@@ -5017,13 +4934,8 @@
 
   EXPECT_EQ(LayoutPoint(), first_fragment.PaintOffset());
   EXPECT_EQ(LayoutPoint(390, -10), second_fragment->PaintOffset());
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(LayoutRect(0, 0, 20, 20), first_fragment.VisualRect());
-    EXPECT_EQ(LayoutRect(390, -10, 20, 20), second_fragment->VisualRect());
-  } else {
-    EXPECT_EQ(LayoutRect(0, 50, 20, 10), first_fragment.VisualRect());
-    EXPECT_EQ(LayoutRect(390, 50, 20, 10), second_fragment->VisualRect());
-  }
+  EXPECT_EQ(LayoutRect(0, 0, 20, 20), first_fragment.VisualRect());
+  EXPECT_EQ(LayoutRect(390, -10, 20, 20), second_fragment->VisualRect());
 }
 
 // The following test tests that we restrict actual column count, to not run
@@ -5058,24 +4970,13 @@
   const auto* second_clip =
       FragmentAt(flow_thread, 1).PaintProperties()->FragmentClip();
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_EQ(FloatRect(-999992, -999992, 1000025, 1000050),
-              first_clip->ClipRect().Rect());
-    EXPECT_EQ(FloatRect(33, 8, 1000000, 999951),
-              second_clip->ClipRect().Rect());
-  } else {
-    EXPECT_EQ(FloatRect(-999992, -999992, 1000024.75, 1000049.5),
-              first_clip->ClipRect().Rect());
-    EXPECT_EQ(FloatRect(32.75, 8, 1000000, 999950.5),
-              second_clip->ClipRect().Rect());
-  }
+  EXPECT_EQ(FloatRect(-999992, -999992, 1000025, 1000050),
+            first_clip->ClipRect().Rect());
+  EXPECT_EQ(FloatRect(33, 8, 1000000, 999951), second_clip->ClipRect().Rect());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest,
        UpdateUnderChangedEffectUnderCompositedLayer) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <div id="opacity" style="isolation: isolate; width: 100px: height: 100px">
       <div id="target"
@@ -5092,15 +4993,12 @@
   opacity_element->setAttribute(HTMLNames::styleAttr, "opacity: 0.5");
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
 
-  // In SPv175 mode, all paint chunks contained by the new opacity effect
-  // node need to be re-painted.
+  // All paint chunks contained by the new opacity effect node need to be
+  // re-painted.
   EXPECT_TRUE(ToLayoutBoxModelObject(target)->Layer()->NeedsRepaint());
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, SVGRootWithMask) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <svg id="svg" width="16" height="16" mask="url(#test)">
       <rect width="100%" height="16" fill="#fff"></rect>
@@ -5120,9 +5018,6 @@
 }
 
 TEST_P(PaintPropertyTreeBuilderTest, SVGRootWithCSSMask) {
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <svg id="svg" width="16" height="16" style="-webkit-mask-image: url(fake);">
     </svg>
@@ -5136,10 +5031,6 @@
 TEST_P(PaintPropertyTreeBuilderTest, ClearClipPathEffectNode) {
   // This test makes sure ClipPath effect node is cleared properly upon
   // removal of a clip-path.
-
-  // SPv1 has no effect tree.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <svg>
       <clipPath clip-path="circle()" id="clip"></clipPath>
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
index 533f038c..190f7f4 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_printer_test.cc
@@ -46,9 +46,6 @@
 }
 
 TEST_P(PaintPropertyTreePrinterTest, SimpleEffectTree) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML("<div style='opacity: 0.9;'>hello world</div>");
   String effect_tree_as_string =
       effectPropertyTreeAsString(*GetDocument().View());
@@ -100,9 +97,6 @@
 }
 
 TEST_P(PaintPropertyTreePrinterTest, SimpleEffectTreePath) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML("<div id='effect' style='opacity: 0.9;'></div>");
   LayoutObject* effect_object =
       GetDocument().getElementById("effect")->GetLayoutObject();
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
index d878e97..9c59052d 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -848,9 +848,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, BoxAddRemoveMask) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <style>#target {width: 100px; height: 100px}</style>
     <div id='target'>
@@ -879,9 +876,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeBoxSizeChange) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <style>
     #target {
@@ -910,9 +904,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, InlineAddRemoveMask) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(
       "<span id='target'><img id='img' style='width: 50px'></span>");
 
@@ -937,9 +928,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeInlineBoundsChange) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <span id='target' style='-webkit-mask: linear-gradient(red, blue)'>
       <img id='img' style='width: 50px'>
@@ -961,9 +949,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, AddRemoveSVGMask) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg width='200' height='200'>
       <rect id='rect' x='0' y='100' width='100' height='100' fill='blue'/>
@@ -993,9 +978,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, SVGMaskTargetBoundsChange) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg width='500' height='500'>
       <g id='target' mask='url(#mask)'>
@@ -1103,9 +1085,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, SVGViewportContainerOverflowChange) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg>
       <svg id='target' width='30' height='40'></svg>
@@ -1130,9 +1109,6 @@
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, SVGForeignObjectOverflowChange) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   SetBodyInnerHTML(R"HTML(
     <svg>
       <foreignObject id='target' x='10' y='20' width='30' height='40'
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
index 9198dee..47176d21 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
@@ -122,9 +122,6 @@
 }
 
 TEST_P(PrePaintTreeWalkTest, PropertyTreesRebuiltWithOpacityInvalidation) {
-  // In SPv1 mode, we don't need or store property tree nodes for effects.
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
   SetBodyInnerHTML(R"HTML(
     <style>
       .opacityA { opacity: 0.9; }
@@ -277,12 +274,7 @@
   GetDocument().getElementById("parent")->removeAttribute("style");
   GetDocument().View()->UpdateAllLifecyclePhases();
 
-  // In SPv175 mode, VisualRects are in the space of the containing transform
-  // node without applying any ancestor property nodes, including clip.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    EXPECT_EQ(200, grandchild->FirstFragment().VisualRect().Height());
-  else
-    EXPECT_EQ(75, grandchild->FirstFragment().VisualRect().Height());
+  EXPECT_EQ(200, grandchild->FirstFragment().VisualRect().Height());
 }
 
 TEST_P(PrePaintTreeWalkTest, ClipChangeHasRadius) {
diff --git a/third_party/blink/renderer/core/paint/table_painter_test.cc b/third_party/blink/renderer/core/paint/table_painter_test.cc
index b257404..7075a87 100644
--- a/third_party/blink/renderer/core/paint/table_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/table_painter_test.cc
@@ -133,23 +133,11 @@
   IntRect interest_rect(200, 0, 200, 200);
   Paint(&interest_rect);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    EXPECT_DISPLAY_LIST(
-        RootPaintController().GetDisplayItemList(), 3,
-        TestDisplayItem(ViewBackgroundClient(),
-                        DisplayItem::kDocumentBackground),
-        TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
-        TestDisplayItem(cell1, DisplayItem::kBoxDecorationBackground));
-  } else {
-    EXPECT_DISPLAY_LIST(
-        RootPaintController().GetDisplayItemList(), 5,
-        TestDisplayItem(ViewBackgroundClient(),
-                        DisplayItem::kDocumentBackground),
-        TestDisplayItem(row, DisplayItem::kBeginCompositing),
-        TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
-        TestDisplayItem(cell1, DisplayItem::kBoxDecorationBackground),
-        TestDisplayItem(row, DisplayItem::kEndCompositing));
-  }
+  EXPECT_DISPLAY_LIST(
+      RootPaintController().GetDisplayItemList(), 3,
+      TestDisplayItem(ViewBackgroundClient(), DisplayItem::kDocumentBackground),
+      TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
+      TestDisplayItem(cell1, DisplayItem::kBoxDecorationBackground));
 
   GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
   // Intersects the spacing only.
@@ -165,23 +153,12 @@
   interest_rect = IntRect(450, 0, 200, 200);
   Paint(&interest_rect);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_DISPLAY_LIST(
         RootPaintController().GetDisplayItemList(), 3,
         TestDisplayItem(ViewBackgroundClient(),
                         DisplayItem::kDocumentBackground),
         TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
         TestDisplayItem(cell2, DisplayItem::kBoxDecorationBackground));
-  } else {
-    EXPECT_DISPLAY_LIST(
-        RootPaintController().GetDisplayItemList(), 5,
-        TestDisplayItem(ViewBackgroundClient(),
-                        DisplayItem::kDocumentBackground),
-        TestDisplayItem(row, DisplayItem::kBeginCompositing),
-        TestDisplayItem(row, DisplayItem::kBoxDecorationBackground),
-        TestDisplayItem(cell2, DisplayItem::kBoxDecorationBackground),
-        TestDisplayItem(row, DisplayItem::kEndCompositing));
-  }
 }
 
 TEST_P(TablePainterTest, CollapsedBorderAndOverflow) {
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc
index 33f180f..bd160ca6 100644
--- a/third_party/blink/renderer/core/paint/view_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -49,7 +49,6 @@
   layout_viewport->SetScrollOffset(scroll_offset, kUserScroll);
   frame_view->UpdateAllLifecyclePhases();
 
-  bool v175 = RuntimeEnabledFeatures::SlimmingPaintV175Enabled();
   CompositedLayerMapping* clm =
       GetLayoutView().Layer()->GetCompositedLayerMapping();
 
@@ -64,8 +63,7 @@
   }
   const DisplayItemList& display_items =
       layer_for_background->GetPaintController().GetDisplayItemList();
-  const DisplayItem& background =
-      display_items[!prefer_compositing_to_lcd_text && !v175 ? 2 : 0];
+  const DisplayItem& background = display_items[0];
   EXPECT_EQ(background.GetType(), kDocumentBackgroundType);
   DisplayItemClient* expected_client;
   if (!prefer_compositing_to_lcd_text)
@@ -112,9 +110,6 @@
       RootPaintController().GetDisplayItemList(), 1,
       TestDisplayItem(*background_item_client, kDocumentBackgroundType));
 
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   const auto& chunks = RootPaintController().GetPaintArtifact().PaintChunks();
   EXPECT_EQ(1u, chunks.size());
   const auto& chunk = chunks[0];
diff --git a/third_party/blink/renderer/core/script/BUILD.gn b/third_party/blink/renderer/core/script/BUILD.gn
index 952d7798..6d10618 100644
--- a/third_party/blink/renderer/core/script/BUILD.gn
+++ b/third_party/blink/renderer/core/script/BUILD.gn
@@ -48,6 +48,8 @@
     "script_runner.cc",
     "script_runner.h",
     "script_scheduling_type.h",
+    "settings_object.cc",
+    "settings_object.h",
     "worker_modulator_impl.cc",
     "worker_modulator_impl.h",
     "worklet_modulator_impl.cc",
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
index b6fa9c62..515d419 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "v8/include/v8.h"
 
@@ -213,7 +214,15 @@
   // with result."
   auto* tree_client =
       DynamicImportTreeClient::Create(url, modulator_.Get(), promise_resolver);
-  modulator_->FetchTree(url, WebURLRequest::kRequestContextScript, options,
+  // TODO(kouhei): ExecutionContext::From(modulator_->GetScriptState()) is
+  // highly discouraged since it breaks layering. Rewrite this.
+  auto* execution_context =
+      ExecutionContext::From(modulator_->GetScriptState());
+  auto* settings_object =
+      SettingsObject::Create(execution_context->GetSecurityOrigin(),
+                             execution_context->GetReferrerPolicy());
+  modulator_->FetchTree(url, settings_object,
+                        WebURLRequest::kRequestContextScript, options,
                         tree_client);
 
   // Steps 2.[5-8] are implemented at
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index dc92c1f..0a9e6f9 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -51,7 +51,6 @@
 
  private:
   // Implements Modulator:
-  ReferrerPolicy GetReferrerPolicy() override { return kReferrerPolicyDefault; }
   ScriptState* GetScriptState() final { return script_state_.get(); }
 
   ModuleScript* GetFetchedModuleScript(const KURL& url) final {
@@ -62,6 +61,7 @@
   }
 
   void FetchTree(const KURL& url,
+                 SettingsObject*,
                  WebURLRequest::RequestContext,
                  const ScriptFetchOptions&,
                  ModuleTreeClient* client) final {
diff --git a/third_party/blink/renderer/core/script/modulator.h b/third_party/blink/renderer/core/script/modulator.h
index 269ee2be..197fdcb0 100644
--- a/third_party/blink/renderer/core/script/modulator.h
+++ b/third_party/blink/renderer/core/script/modulator.h
@@ -32,7 +32,7 @@
 class ScriptPromiseResolver;
 class ScriptState;
 class ScriptValue;
-class SecurityOrigin;
+class SettingsObject;
 
 // A SingleModuleClient is notified when single module script node (node as in a
 // module tree graph) load is complete and its corresponding entry is created in
@@ -90,20 +90,14 @@
   virtual ScriptModuleResolver* GetScriptModuleResolver() = 0;
   virtual base::SingleThreadTaskRunner* TaskRunner() = 0;
 
-  // Get the default referrer policy of this modulator as the environment
-  // settings object.
-  // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-referrer-policy
-  virtual ReferrerPolicy GetReferrerPolicy() = 0;
-
-  // Returns the security origin of the "fetch client settings object".
-  // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
-  // This should be called only from ModuleScriptLoader.
-  virtual const SecurityOrigin* GetSecurityOriginForFetch() = 0;
-
   virtual ScriptState* GetScriptState() = 0;
 
   // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree
+  // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
+  // Note that |this| is the "module map settings object" used in the "fetch a
+  // module worker script graph" algorithm.
   virtual void FetchTree(const KURL&,
+                         SettingsObject* fetch_client_settings_object,
                          WebURLRequest::RequestContext destination,
                          const ScriptFetchOptions&,
                          ModuleTreeClient*) = 0;
@@ -111,12 +105,15 @@
   // Asynchronously retrieve a module script from the module map, or fetch it
   // and put it in the map if it's not there already.
   // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
+  // Note that |this| is the "module map settings object".
   virtual void FetchSingle(const ModuleScriptFetchRequest&,
+                           SettingsObject* fetch_client_settings_object,
                            ModuleGraphLevel,
                            SingleModuleClient*) = 0;
 
   virtual void FetchDescendantsForInlineScript(
       ModuleScript*,
+      SettingsObject* fetch_client_settings_object,
       WebURLRequest::RequestContext destination,
       ModuleTreeClient*) = 0;
 
@@ -184,9 +181,11 @@
   // This is triggered from fetchSingle() implementation (which is in ModuleMap)
   // if the cached entry doesn't exist.
   // The client can be notified either synchronously or asynchronously.
-  virtual void FetchNewSingleModule(const ModuleScriptFetchRequest&,
-                                    ModuleGraphLevel,
-                                    ModuleScriptLoaderClient*) = 0;
+  virtual void FetchNewSingleModule(
+      const ModuleScriptFetchRequest&,
+      SettingsObject* fetch_client_settings_object,
+      ModuleGraphLevel,
+      ModuleScriptLoaderClient*) = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.cc b/third_party/blink/renderer/core/script/modulator_impl_base.cc
index 3346171..bba1291 100644
--- a/third_party/blink/renderer/core/script/modulator_impl_base.cc
+++ b/third_party/blink/renderer/core/script/modulator_impl_base.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/core/script/module_map.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/core/script/script_module_resolver_impl.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 
 namespace blink {
@@ -39,19 +40,12 @@
 
 ModulatorImplBase::~ModulatorImplBase() {}
 
-ReferrerPolicy ModulatorImplBase::GetReferrerPolicy() {
-  return GetExecutionContext()->GetReferrerPolicy();
-}
-
-const SecurityOrigin* ModulatorImplBase::GetSecurityOriginForFetch() {
-  return GetExecutionContext()->GetSecurityOrigin();
-}
-
 // [fetch-a-module-script-tree]
 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree
 // [fetch-a-module-worker-script-tree]
 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
 void ModulatorImplBase::FetchTree(const KURL& url,
+                                  SettingsObject* fetch_client_settings_object,
                                   WebURLRequest::RequestContext destination,
                                   const ScriptFetchOptions& options,
                                   ModuleTreeClient* client) {
@@ -68,8 +62,9 @@
   // of this algorithm specified custom perform the fetch steps, pass those
   // along as well.</spec>
 
-  tree_linker_registry_->Fetch(url, GetExecutionContext()->BaseURL(),
-                               destination, options, this, client);
+  tree_linker_registry_->Fetch(url, fetch_client_settings_object,
+                               GetExecutionContext()->BaseURL(), destination,
+                               options, this, client);
 
   // <spec label="fetch-a-module-script-tree" step="3">When the internal module
   // script graph fetching procedure asynchronously completes with result,
@@ -84,23 +79,29 @@
 
 void ModulatorImplBase::FetchDescendantsForInlineScript(
     ModuleScript* module_script,
+    SettingsObject* fetch_client_settings_object,
     WebURLRequest::RequestContext destination,
     ModuleTreeClient* client) {
   tree_linker_registry_->FetchDescendantsForInlineScript(
-      module_script, destination, this, client);
+      module_script, fetch_client_settings_object, destination, this, client);
 }
 
-void ModulatorImplBase::FetchSingle(const ModuleScriptFetchRequest& request,
-                                    ModuleGraphLevel level,
-                                    SingleModuleClient* client) {
-  map_->FetchSingleModuleScript(request, level, client);
+void ModulatorImplBase::FetchSingle(
+    const ModuleScriptFetchRequest& request,
+    SettingsObject* fetch_client_settings_object,
+    ModuleGraphLevel level,
+    SingleModuleClient* client) {
+  map_->FetchSingleModuleScript(request, fetch_client_settings_object, level,
+                                client);
 }
 
 void ModulatorImplBase::FetchNewSingleModule(
     const ModuleScriptFetchRequest& request,
+    SettingsObject* fetch_client_settings_object,
     ModuleGraphLevel level,
     ModuleScriptLoaderClient* client) {
-  loader_registry_->Fetch(request, level, this, client);
+  loader_registry_->Fetch(request, fetch_client_settings_object, level, this,
+                          client);
 }
 
 ModuleScript* ModulatorImplBase::GetFetchedModuleScript(const KURL& url) {
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.h b/third_party/blink/renderer/core/script/modulator_impl_base.h
index 6d497dee..a20a891 100644
--- a/third_party/blink/renderer/core/script/modulator_impl_base.h
+++ b/third_party/blink/renderer/core/script/modulator_impl_base.h
@@ -47,23 +47,25 @@
   base::SingleThreadTaskRunner* TaskRunner() override {
     return task_runner_.get();
   }
-  ReferrerPolicy GetReferrerPolicy() override;
-  const SecurityOrigin* GetSecurityOriginForFetch() override;
 
   void FetchTree(const KURL&,
+                 SettingsObject* fetch_client_settings_object,
                  WebURLRequest::RequestContext destination,
                  const ScriptFetchOptions&,
                  ModuleTreeClient*) override;
   void FetchDescendantsForInlineScript(
       ModuleScript*,
+      SettingsObject* fetch_client_settings_object,
       WebURLRequest::RequestContext destination,
       ModuleTreeClient*) override;
   void FetchSingle(const ModuleScriptFetchRequest&,
+                   SettingsObject* fetch_client_settings_object,
                    ModuleGraphLevel,
                    SingleModuleClient*) override;
   ModuleScript* GetFetchedModuleScript(const KURL&) override;
   bool HasValidContext() override;
   void FetchNewSingleModule(const ModuleScriptFetchRequest&,
+                            SettingsObject* fetch_client_settings_object,
                             ModuleGraphLevel,
                             ModuleScriptLoaderClient*) override;
   void ResolveDynamically(const String& specifier,
diff --git a/third_party/blink/renderer/core/script/module_map.cc b/third_party/blink/renderer/core/script/module_map.cc
index 22c2082..8e02cc2a 100644
--- a/third_party/blink/renderer/core/script/module_map.cc
+++ b/third_party/blink/renderer/core/script/module_map.cc
@@ -103,9 +103,11 @@
 }
 
 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
-void ModuleMap::FetchSingleModuleScript(const ModuleScriptFetchRequest& request,
-                                        ModuleGraphLevel level,
-                                        SingleModuleClient* client) {
+void ModuleMap::FetchSingleModuleScript(
+    const ModuleScriptFetchRequest& request,
+    SettingsObject* fetch_client_settings_object,
+    ModuleGraphLevel level,
+    SingleModuleClient* client) {
   // <spec step="1">Let moduleMap be module map settings object's module
   // map.</spec>
   //
@@ -121,7 +123,8 @@
 
     // Steps 4-9 loads a new single module script.
     // Delegates to ModuleScriptLoader via Modulator.
-    modulator_->FetchNewSingleModule(request, level, entry);
+    modulator_->FetchNewSingleModule(request, fetch_client_settings_object,
+                                     level, entry);
   }
   DCHECK(entry);
 
diff --git a/third_party/blink/renderer/core/script/module_map.h b/third_party/blink/renderer/core/script/module_map.h
index 52e39433..b8c2cac 100644
--- a/third_party/blink/renderer/core/script/module_map.h
+++ b/third_party/blink/renderer/core/script/module_map.h
@@ -19,6 +19,7 @@
 class Modulator;
 class ModuleScript;
 class ModuleScriptFetchRequest;
+class SettingsObject;
 class SingleModuleClient;
 enum class ModuleGraphLevel;
 
@@ -37,6 +38,7 @@
 
   // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script
   void FetchSingleModuleScript(const ModuleScriptFetchRequest&,
+                               SettingsObject* fetch_client_settings_object,
                                ModuleGraphLevel,
                                SingleModuleClient*);
 
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc
index a8c368e..e3ce0a3f 100644
--- a/third_party/blink/renderer/core/script/module_map_test.cc
+++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/core/script/script_module_resolver.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/testing/dummy_modulator.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -102,6 +103,7 @@
   };
 
   void FetchNewSingleModule(const ModuleScriptFetchRequest&,
+                            SettingsObject*,
                             ModuleGraphLevel,
                             ModuleScriptLoaderClient*) override;
 
@@ -132,6 +134,7 @@
 
 void ModuleMapTestModulator::FetchNewSingleModule(
     const ModuleScriptFetchRequest& request,
+    SettingsObject*,
     ModuleGraphLevel,
     ModuleScriptLoaderClient* client) {
   TestRequest* test_request =
@@ -175,12 +178,15 @@
   platform->AdvanceClockSeconds(1.);  // For non-zero DocumentParserTimings
 
   KURL url(NullURL(), "https://example.com/foo.js");
+  scoped_refptr<SecurityOrigin> security_origin = SecurityOrigin::Create(url);
+  auto* settings_object =
+      SettingsObject::Create(security_origin.get(), kReferrerPolicyDefault);
 
   // First request
   TestSingleModuleClient* client = new TestSingleModuleClient;
-  Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url),
-                                 ModuleGraphLevel::kTopLevelModuleFetch,
-                                 client);
+  Map()->FetchSingleModuleScript(
+      ModuleScriptFetchRequest::CreateForTest(url), settings_object,
+      ModuleGraphLevel::kTopLevelModuleFetch, client);
   Modulator()->ResolveFetches();
   EXPECT_FALSE(client->WasNotifyFinished())
       << "fetchSingleModuleScript shouldn't complete synchronously";
@@ -195,9 +201,9 @@
 
   // Secondary request
   TestSingleModuleClient* client2 = new TestSingleModuleClient;
-  Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url),
-                                 ModuleGraphLevel::kTopLevelModuleFetch,
-                                 client2);
+  Map()->FetchSingleModuleScript(
+      ModuleScriptFetchRequest::CreateForTest(url), settings_object,
+      ModuleGraphLevel::kTopLevelModuleFetch, client2);
   Modulator()->ResolveFetches();
   EXPECT_FALSE(client2->WasNotifyFinished())
       << "fetchSingleModuleScript shouldn't complete synchronously";
@@ -218,18 +224,21 @@
   platform->AdvanceClockSeconds(1.);  // For non-zero DocumentParserTimings
 
   KURL url(NullURL(), "https://example.com/foo.js");
+  scoped_refptr<SecurityOrigin> security_origin = SecurityOrigin::Create(url);
+  auto* settings_object =
+      SettingsObject::Create(security_origin.get(), kReferrerPolicyDefault);
 
   // First request
   TestSingleModuleClient* client = new TestSingleModuleClient;
-  Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url),
-                                 ModuleGraphLevel::kTopLevelModuleFetch,
-                                 client);
+  Map()->FetchSingleModuleScript(
+      ModuleScriptFetchRequest::CreateForTest(url), settings_object,
+      ModuleGraphLevel::kTopLevelModuleFetch, client);
 
   // Secondary request (which should join the first request)
   TestSingleModuleClient* client2 = new TestSingleModuleClient;
-  Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url),
-                                 ModuleGraphLevel::kTopLevelModuleFetch,
-                                 client2);
+  Map()->FetchSingleModuleScript(
+      ModuleScriptFetchRequest::CreateForTest(url), settings_object,
+      ModuleGraphLevel::kTopLevelModuleFetch, client2);
 
   Modulator()->ResolveFetches();
   EXPECT_FALSE(client->WasNotifyFinished())
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc
index ae5b0da..adcb40c 100644
--- a/third_party/blink/renderer/core/script/script_loader.cc
+++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/core/script/script.h"
 #include "third_party/blink/renderer/core/script/script_element_base.h"
 #include "third_party/blink/renderer/core/script/script_runner.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/svg_names.h"
 #include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
@@ -366,6 +367,9 @@
   // object's environment settings object.</spec>
   //
   // Note: We use |element_document| as "settings object" in the steps below.
+  SettingsObject* settings_object =
+      SettingsObject::Create(element_document.GetSecurityOrigin(),
+                             element_document.GetReferrerPolicy());
 
   // <spec step="23">If the element has a src content attribute, then:</spec>
   if (element_->HasSourceAttribute()) {
@@ -434,7 +438,7 @@
       // options.</spec>
       Modulator* modulator = Modulator::From(
           ToScriptStateForMainWorld(context_document->GetFrame()));
-      FetchModuleScriptTree(url, modulator, options);
+      FetchModuleScriptTree(url, settings_object, modulator, options);
     }
     // <spec step="23.6">When the chosen algorithm asynchronously completes, set
     // the script's script to the result. At that time, the script is ready.
@@ -519,8 +523,8 @@
         // script is ready.</spec>
         auto* module_tree_client = ModulePendingScriptTreeClient::Create();
         modulator->FetchDescendantsForInlineScript(
-            module_script, WebURLRequest::kRequestContextScript,
-            module_tree_client);
+            module_script, settings_object,
+            WebURLRequest::kRequestContextScript, module_tree_client);
         prepared_pending_script_ = ModulePendingScript::Create(
             element_, module_tree_client, is_external_script_);
         break;
@@ -696,6 +700,7 @@
 }
 
 void ScriptLoader::FetchModuleScriptTree(const KURL& url,
+                                         SettingsObject* settings_object,
                                          Modulator* modulator,
                                          const ScriptFetchOptions& options) {
   // <spec
@@ -705,7 +710,8 @@
   // Fetch a module script graph given url, settings object, "script", and
   // options.</spec>
   auto* module_tree_client = ModulePendingScriptTreeClient::Create();
-  modulator->FetchTree(url, WebURLRequest::kRequestContextScript, options,
+  modulator->FetchTree(url, settings_object,
+                       WebURLRequest::kRequestContextScript, options,
                        module_tree_client);
   prepared_pending_script_ = ModulePendingScript::Create(
       element_, module_tree_client, is_external_script_);
diff --git a/third_party/blink/renderer/core/script/script_loader.h b/third_party/blink/renderer/core/script/script_loader.h
index 4c550d9..2707fad 100644
--- a/third_party/blink/renderer/core/script/script_loader.h
+++ b/third_party/blink/renderer/core/script/script_loader.h
@@ -42,9 +42,8 @@
 
 class ScriptElementBase;
 class Script;
-
 class ScriptResource;
-
+class SettingsObject;
 class Modulator;
 
 class CORE_EXPORT ScriptLoader final
@@ -130,6 +129,7 @@
                           const WTF::TextEncoding&);
   // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree
   void FetchModuleScriptTree(const KURL&,
+                             SettingsObject*,
                              Modulator*,
                              const ScriptFetchOptions&);
 
diff --git a/third_party/blink/renderer/core/script/settings_object.cc b/third_party/blink/renderer/core/script/settings_object.cc
new file mode 100644
index 0000000..4dc7322b
--- /dev/null
+++ b/third_party/blink/renderer/core/script/settings_object.cc
@@ -0,0 +1,18 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/script/settings_object.h"
+
+namespace blink {
+
+SettingsObject* SettingsObject::Create(const SecurityOrigin* security_origin,
+                                       ReferrerPolicy referrer_policy) {
+  return new SettingsObject(security_origin, referrer_policy);
+}
+
+SettingsObject::SettingsObject(const SecurityOrigin* security_origin,
+                               ReferrerPolicy referrer_policy)
+    : security_origin_(security_origin), referrer_policy_(referrer_policy) {}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/script/settings_object.h b/third_party/blink/renderer/core/script/settings_object.h
new file mode 100644
index 0000000..71abc9c
--- /dev/null
+++ b/third_party/blink/renderer/core/script/settings_object.h
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SETTINGS_OBJECT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SETTINGS_OBJECT_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+
+namespace blink {
+
+// This is an implementation of the "settings object" concept defined in the
+// HTML spec:
+// "An environment settings object, containing various settings that are shared
+// with other scripts in the same context."
+// https://html.spec.whatwg.org/multipage/webappapis.html#settings-object
+class CORE_EXPORT SettingsObject final
+    : public GarbageCollectedFinalized<SettingsObject> {
+ public:
+  static SettingsObject* Create(const SecurityOrigin*, ReferrerPolicy);
+
+  virtual ~SettingsObject() = default;
+
+  // "An origin used in security checks."
+  // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-origin
+  const SecurityOrigin* GetSecurityOrigin() { return security_origin_.get(); }
+
+  // "The default referrer policy for fetches performed using this environment
+  // settings object as a request client."
+  // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-referrer-policy
+  ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
+
+  virtual void Trace(blink::Visitor*) {}
+
+ private:
+  SettingsObject(const SecurityOrigin*, ReferrerPolicy);
+
+  const scoped_refptr<const SecurityOrigin> security_origin_;
+  ReferrerPolicy referrer_policy_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SETTINGS_OBJECT_H_
diff --git a/third_party/blink/renderer/core/script/worklet_modulator_impl.cc b/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
index 28dbba1..ca70f906 100644
--- a/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
+++ b/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
@@ -18,10 +18,6 @@
     scoped_refptr<ScriptState> script_state)
     : ModulatorImplBase(std::move(script_state)) {}
 
-const SecurityOrigin* WorkletModulatorImpl::GetSecurityOriginForFetch() {
-  return ToWorkletGlobalScope(GetExecutionContext())->DocumentSecurityOrigin();
-}
-
 ModuleScriptFetcher* WorkletModulatorImpl::CreateModuleScriptFetcher() {
   WorkletGlobalScope* global_scope =
       ToWorkletGlobalScope(GetExecutionContext());
diff --git a/third_party/blink/renderer/core/script/worklet_modulator_impl.h b/third_party/blink/renderer/core/script/worklet_modulator_impl.h
index 569ba2b..6ba8f9e 100644
--- a/third_party/blink/renderer/core/script/worklet_modulator_impl.h
+++ b/third_party/blink/renderer/core/script/worklet_modulator_impl.h
@@ -22,7 +22,6 @@
   static ModulatorImplBase* Create(scoped_refptr<ScriptState>);
 
   // Implements ModulatorImplBase.
-  const SecurityOrigin* GetSecurityOriginForFetch() override;
   ModuleScriptFetcher* CreateModuleScriptFetcher() override;
 
  private:
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc
index b4639b1..a4052ca 100644
--- a/third_party/blink/renderer/core/style/computed_style_test.cc
+++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/core/style/clip_path_operation.h"
 #include "third_party/blink/renderer/core/style/shape_value.h"
 #include "third_party/blink/renderer/core/style/style_difference.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 
 namespace blink {
 
@@ -81,13 +80,6 @@
   EXPECT_TRUE(style->IsStackingContext());
 }
 
-TEST(ComputedStyleTest, SVGStackingContextSPv1) {
-  ScopedSlimmingPaintV175ForTest spv175(false);
-  scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
-  style->UpdateIsStackingContext(false, false, true);
-  EXPECT_FALSE(style->IsStackingContext());
-}
-
 TEST(ComputedStyleTest, Preserve3dForceStackingContext) {
   scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
   style->SetTransformStyle3D(ETransformStyle3D::kPreserve3d);
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.cc b/third_party/blink/renderer/core/testing/dummy_modulator.cc
index 46a969b..9ffd0c9 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.cc
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -44,16 +44,6 @@
   Modulator::Trace(visitor);
 }
 
-ReferrerPolicy DummyModulator::GetReferrerPolicy() {
-  NOTREACHED();
-  return kReferrerPolicyDefault;
-}
-
-const SecurityOrigin* DummyModulator::GetSecurityOriginForFetch() {
-  NOTREACHED();
-  return nullptr;
-}
-
 ScriptState* DummyModulator::GetScriptState() {
   NOTREACHED();
   return nullptr;
@@ -69,6 +59,7 @@
 };
 
 void DummyModulator::FetchTree(const KURL&,
+                               SettingsObject*,
                                WebURLRequest::RequestContext,
                                const ScriptFetchOptions&,
                                ModuleTreeClient*) {
@@ -76,6 +67,7 @@
 }
 
 void DummyModulator::FetchSingle(const ModuleScriptFetchRequest&,
+                                 SettingsObject*,
                                  ModuleGraphLevel,
                                  SingleModuleClient*) {
   NOTREACHED();
@@ -83,6 +75,7 @@
 
 void DummyModulator::FetchDescendantsForInlineScript(
     ModuleScript*,
+    SettingsObject* fetch_client_settings_object,
     WebURLRequest::RequestContext,
     ModuleTreeClient*) {
   NOTREACHED();
@@ -94,6 +87,7 @@
 }
 
 void DummyModulator::FetchNewSingleModule(const ModuleScriptFetchRequest&,
+                                          SettingsObject*,
                                           ModuleGraphLevel,
                                           ModuleScriptLoaderClient*) {
   NOTREACHED();
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.h b/third_party/blink/renderer/core/testing/dummy_modulator.h
index 0b26440..c915d99 100644
--- a/third_party/blink/renderer/core/testing/dummy_modulator.h
+++ b/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -12,9 +12,10 @@
 
 namespace blink {
 
+class ModuleScriptFetchRequest;
 class ModuleScriptLoaderClient;
 class ScriptModuleResolver;
-class ModuleScriptFetchRequest;
+class SettingsObject;
 
 // DummyModulator provides empty Modulator interface implementation w/
 // NOTREACHED().
@@ -33,23 +34,25 @@
 
   ScriptModuleResolver* GetScriptModuleResolver() override;
   base::SingleThreadTaskRunner* TaskRunner() override;
-  ReferrerPolicy GetReferrerPolicy() override;
-  const SecurityOrigin* GetSecurityOriginForFetch() override;
   ScriptState* GetScriptState() override;
 
   void FetchTree(const KURL&,
+                 SettingsObject* fetch_client_settings_object,
                  WebURLRequest::RequestContext destination,
                  const ScriptFetchOptions&,
                  ModuleTreeClient*) override;
   void FetchSingle(const ModuleScriptFetchRequest&,
+                   SettingsObject* fetch_client_settings_object,
                    ModuleGraphLevel,
                    SingleModuleClient*) override;
   void FetchDescendantsForInlineScript(
       ModuleScript*,
+      SettingsObject* fetch_client_settings_object,
       WebURLRequest::RequestContext destination,
       ModuleTreeClient*) override;
   ModuleScript* GetFetchedModuleScript(const KURL&) override;
   void FetchNewSingleModule(const ModuleScriptFetchRequest&,
+                            SettingsObject* fetch_client_settings_object,
                             ModuleGraphLevel,
                             ModuleScriptLoaderClient*) override;
   bool HasValidContext() override;
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index 4702f03..1af3161 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/inspector/thread_debugger.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h"
 #include "third_party/blink/renderer/core/workers/dedicated_worker_thread.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
@@ -72,8 +73,13 @@
   // Step 13: "... Fetch a module worker script graph given url, outside
   // settings, destination, the value of the credentials member of options, and
   // inside settings."
-  FetchModuleScript(module_url_record, destination, credentials_mode,
-                    new WorkerModuleTreeClient(modulator));
+  // TODO(nhiroki): Currently we specify inside settings' referrer policy and
+  // security origin here. These should be replaced with outside settings'
+  // referrer policy and security origin (https://crbug.com/842553).
+  SettingsObject* outside_settings_object =
+      SettingsObject::Create(GetSecurityOrigin(), GetReferrerPolicy());
+  FetchModuleScript(module_url_record, outside_settings_object, destination,
+                    credentials_mode, new WorkerModuleTreeClient(modulator));
 }
 
 void DedicatedWorkerGlobalScope::postMessage(
diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
index 4b47f551..6e803af 100644
--- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
@@ -35,7 +35,6 @@
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/allowed_by_nosniff.h"
 #include "third_party/blink/renderer/core/loader/resource/script_resource.h"
-#include "third_party/blink/renderer/core/loader/worker_threadable_loader.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
@@ -82,9 +81,8 @@
   resource_loader_options.parser_disposition =
       ParserDisposition::kNotParserInserted;
 
-  WorkerThreadableLoader::LoadResourceSynchronously(
-      ToWorkerGlobalScope(execution_context), request, *this, options,
-      resource_loader_options);
+  ThreadableLoader::LoadResourceSynchronously(execution_context, request, *this,
+                                              options, resource_loader_options);
 }
 
 void WorkerClassicScriptLoader::LoadAsynchronously(
diff --git a/third_party/blink/renderer/core/workers/worker_options.idl b/third_party/blink/renderer/core/workers/worker_options.idl
index 7c0a63d..5a96bbaa 100644
--- a/third_party/blink/renderer/core/workers/worker_options.idl
+++ b/third_party/blink/renderer/core/workers/worker_options.idl
@@ -5,7 +5,7 @@
 // https://html.spec.whatwg.org/multipage/workers.html#workeroptions
 dictionary WorkerOptions {
     WorkerType type = "classic";
-    RequestCredentials credentials = "omit";
+    RequestCredentials credentials = "same-origin";
     // TODO(nhiroki): Implement "name" option (https://crbug.com/721219)
     // DOMString name = "";
 };
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index 028c668..85cff03 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -203,6 +203,7 @@
 
 void WorkerOrWorkletGlobalScope::FetchModuleScript(
     const KURL& module_url_record,
+    SettingsObject* fetch_client_settings_object,
     WebURLRequest::RequestContext destination,
     network::mojom::FetchCredentialsMode credentials_mode,
     ModuleTreeClient* client) {
@@ -219,7 +220,8 @@
 
   Modulator* modulator = Modulator::From(ScriptController()->GetScriptState());
   // Step 3. "Perform the internal module script graph fetching procedure ..."
-  modulator->FetchTree(module_url_record, destination, options, client);
+  modulator->FetchTree(module_url_record, fetch_client_settings_object,
+                       destination, options, client);
 }
 
 void WorkerOrWorkletGlobalScope::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index 84ec2a3..e81b7b8 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -24,6 +24,7 @@
 class Modulator;
 class ModuleTreeClient;
 class ResourceFetcher;
+class SettingsObject;
 class V8AbstractEventListener;
 class WorkerOrWorkletScriptController;
 class WorkerReportingProxy;
@@ -113,6 +114,7 @@
   // HTML spec:
   // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree
   void FetchModuleScript(const KURL& module_url_record,
+                         SettingsObject* settings_object,
                          WebURLRequest::RequestContext destination,
                          network::mojom::FetchCredentialsMode,
                          ModuleTreeClient*);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
index f69dad5..6e17c05f 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
+#include "third_party/blink/renderer/core/script/settings_object.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
 #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
 #include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
@@ -93,6 +94,9 @@
     WorkletPendingTasks* pending_tasks) {
   DCHECK(IsContextThread());
 
+  SettingsObject* outside_settings_object =
+      SettingsObject::Create(DocumentSecurityOrigin(), GetReferrerPolicy());
+
   // Step 1: "Let insideSettings be the workletGlobalScope's associated
   // environment settings object."
   // Step 2: "Let script by the result of fetch a worklet script given
@@ -110,7 +114,8 @@
   // spec (e.g., "paint worklet", "audio worklet").
   WebURLRequest::RequestContext destination =
       WebURLRequest::kRequestContextScript;
-  FetchModuleScript(module_url_record, destination, credentials_mode, client);
+  FetchModuleScript(module_url_record, outside_settings_object, destination,
+                    credentials_mode, client);
 }
 
 KURL WorkletGlobalScope::CompleteURL(const String& url) const {
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
index d76cc4b..ba9bd117 100644
--- a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
+++ b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
@@ -49,7 +49,7 @@
     this._filter = new Console.ConsoleViewFilter(this._onFilterChanged.bind(this));
     this._isBelowPromptEnabled = Runtime.experiments.isEnabled('consoleBelowPrompt');
 
-    const toolbar = new UI.Toolbar('', this.element);
+    const consoleToolbarContainer = this.element.createChild('div', 'console-toolbar-container');
     this._splitWidget =
         new UI.SplitWidget(true /* isVertical */, false /* secondIsSidebar */, 'console.sidebar.width', 100);
     this._splitWidget.setMainWidget(this._searchableView);
@@ -60,7 +60,6 @@
     this._isSidebarOpen = this._splitWidget.showMode() === UI.SplitWidget.ShowMode.Both;
     if (this._isSidebarOpen)
       this._filter._levelMenuButton.setEnabled(false);
-    toolbar.appendToolbarItem(this._splitWidget.createShowHideSidebarButton('console sidebar'));
     this._splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged, event => {
       this._isSidebarOpen = event.data === UI.SplitWidget.ShowMode.Both;
       this._filter._levelMenuButton.setEnabled(!this._isSidebarOpen);
@@ -98,6 +97,9 @@
     const groupSimilarToggle =
         new UI.ToolbarSettingCheckbox(this._groupSimilarSetting, Common.UIString('Group similar'));
 
+    const toolbar = new UI.Toolbar('console-main-toolbar', consoleToolbarContainer);
+    const rightToolbar = new UI.Toolbar('', consoleToolbarContainer);
+    toolbar.appendToolbarItem(this._splitWidget.createShowHideSidebarButton('console sidebar'));
     toolbar.appendToolbarItem(UI.Toolbar.createActionButton(
         /** @type {!UI.Action }*/ (UI.actionRegistry.action('console.clear'))));
     toolbar.appendSeparator();
@@ -107,10 +109,9 @@
     toolbar.appendToolbarItem(this._filter._levelMenuButton);
     toolbar.appendToolbarItem(groupSimilarToggle);
     toolbar.appendToolbarItem(this._progressToolbarItem);
-    toolbar.appendSpacer();
-    toolbar.appendToolbarItem(this._filterStatusText);
-    toolbar.appendSeparator();
-    toolbar.appendToolbarItem(this._showSettingsPaneButton);
+    rightToolbar.appendSeparator();
+    rightToolbar.appendToolbarItem(this._filterStatusText);
+    rightToolbar.appendToolbarItem(this._showSettingsPaneButton);
 
     this._preserveLogCheckbox = new UI.ToolbarSettingCheckbox(
         Common.moduleSetting('preserveConsoleLog'), Common.UIString('Do not clear log on page reload / navigation'),
diff --git a/third_party/blink/renderer/devtools/front_end/console/consoleView.css b/third_party/blink/renderer/devtools/front_end/console/consoleView.css
index 265e899..e7652e8 100644
--- a/third_party/blink/renderer/devtools/front_end/console/consoleView.css
+++ b/third_party/blink/renderer/devtools/front_end/console/consoleView.css
@@ -32,7 +32,15 @@
     overflow: hidden;
 }
 
-.console-view > .toolbar {
+.console-toolbar-container {
+    display: flex;
+}
+
+.console-main-toolbar {
+    flex: 1 1 auto;
+}
+
+.console-toolbar-container > .toolbar {
     background-color: var(--toolbar-bg-color);
     border-bottom: var(--divider-border);
 }
diff --git a/third_party/blink/renderer/devtools/front_end/emulation/DeviceModeToolbar.js b/third_party/blink/renderer/devtools/front_end/emulation/DeviceModeToolbar.js
index 17bc7cd..d8ee0a7 100644
--- a/third_party/blink/renderer/devtools/front_end/emulation/DeviceModeToolbar.js
+++ b/third_party/blink/renderer/devtools/front_end/emulation/DeviceModeToolbar.js
@@ -48,7 +48,7 @@
     this._fillModeToolbar(modeToolbar);
     rightContainer.createChild('div', 'device-mode-toolbar-spacer');
     const optionsToolbar = new UI.Toolbar('device-mode-toolbar-options', rightContainer);
-    optionsToolbar.makeWrappable(true);
+    optionsToolbar.makeWrappable();
     this._fillOptionsToolbar(optionsToolbar);
 
     this._emulatedDevicesList = Emulation.EmulatedDevicesList.instance();
@@ -189,12 +189,11 @@
    * @param {!UI.Toolbar} toolbar
    */
   _fillOptionsToolbar(toolbar) {
+    toolbar.appendToolbarItem(
+        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
     const moreOptionsButton = new UI.ToolbarMenuButton(this._appendOptionsMenuItems.bind(this));
     moreOptionsButton.setTitle(Common.UIString('More options'));
     toolbar.appendToolbarItem(moreOptionsButton);
-
-    toolbar.appendToolbarItem(
-        this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
   }
 
   /**
diff --git a/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js b/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js
index a8f3da1..6e9691ff 100644
--- a/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js
+++ b/third_party/blink/renderer/devtools/front_end/resources/ServiceWorkersView.js
@@ -16,7 +16,7 @@
     this._currentWorkersView.element.classList.add('service-workers-this-origin');
 
     this._toolbar = this._currentWorkersView.createToolbar();
-    this._toolbar.makeWrappable(false, true);
+    this._toolbar.makeWrappable(true /* growVertically */);
 
     /** @type {!Map<!SDK.ServiceWorkerRegistration, !Resources.ServiceWorkersView.Section>} */
     this._sections = new Map();
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js
index 29bd3d3..920d344 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js
@@ -74,7 +74,9 @@
     this._showMemorySetting.setTitle(Common.UIString('Memory'));
     this._showMemorySetting.addChangeListener(this._onModeChanged, this);
 
-    this._panelToolbar = new UI.Toolbar('', this.element);
+    const timelineToolbarContainer = this.element.createChild('div', 'timeline-toolbar-container');
+    this._panelToolbar = new UI.Toolbar('timeline-main-toolbar', timelineToolbarContainer);
+    this._panelRightToolbar = new UI.Toolbar('', timelineToolbarContainer);
     this._createSettingsPane();
     this._updateShowSettingsToolbarButton();
 
@@ -228,10 +230,8 @@
     this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));
 
     // Settings
-    this._panelToolbar.appendSpacer();
-    this._panelToolbar.appendText('');
-    this._panelToolbar.appendSeparator();
-    this._panelToolbar.appendToolbarItem(this._showSettingsPaneButton);
+    this._panelRightToolbar.appendSeparator();
+    this._panelRightToolbar.appendToolbarItem(this._showSettingsPaneButton);
   }
 
   _createSettingsPane() {
@@ -514,6 +514,7 @@
     this._historyManager.setEnabled(this._state === state.Idle);
     this._clearButton.setEnabled(this._state === state.Idle);
     this._panelToolbar.setEnabled(this._state !== state.Loading);
+    this._panelRightToolbar.setEnabled(this._state !== state.Loading);
     this._dropTarget.setEnabled(this._state === state.Idle);
     this._loadButton.setEnabled(this._state === state.Idle);
     this._saveButton.setEnabled(this._state === state.Idle && !!this._performanceModel);
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/timelinePanel.css b/third_party/blink/renderer/devtools/front_end/timeline/timelinePanel.css
index 4d11a809d..e9349e6 100644
--- a/third_party/blink/renderer/devtools/front_end/timeline/timelinePanel.css
+++ b/third_party/blink/renderer/devtools/front_end/timeline/timelinePanel.css
@@ -27,11 +27,19 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-.panel.timeline > .toolbar {
+.timeline-toolbar-container {
+    display: flex;
+}
+
+.timeline-toolbar-container > .toolbar {
     background-color: var(--toolbar-bg-color);
     border-bottom: var(--divider-border);
 }
 
+.timeline-main-toolbar {
+    flex: 1 1 auto;
+}
+
 .timeline-settings-pane {
     flex: none;
     background-color: var(--toolbar-bg-color);
diff --git a/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js b/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js
index d04dfc3..ecf4c21f 100644
--- a/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js
+++ b/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js
@@ -39,7 +39,6 @@
   constructor(className, parentElement) {
     /** @type {!Array.<!UI.ToolbarItem>} */
     this._items = [];
-    this._reverse = false;
     this.element = parentElement ? parentElement.createChild('div') : createElement('div');
     this.element.className = className;
     this.element.classList.add('toolbar');
@@ -201,14 +200,10 @@
   }
 
   /**
-   * @param {boolean=} reverse
    * @param {boolean=} growVertically
    */
-  makeWrappable(reverse, growVertically) {
+  makeWrappable(growVertically) {
     this._contentElement.classList.add('wrappable');
-    this._reverse = !!reverse;
-    if (reverse)
-      this._contentElement.classList.add('wrappable-reverse');
     if (growVertically)
       this._contentElement.classList.add('toolbar-grow-vertical');
   }
@@ -246,10 +241,7 @@
     item._toolbar = this;
     if (!this._enabled)
       item._applyEnabledState(false);
-    if (this._reverse)
-      this._contentElement.insertBefore(item.element, this._insertionPoint.nextSibling);
-    else
-      this._contentElement.insertBefore(item.element, this._insertionPoint);
+    this._contentElement.insertBefore(item.element, this._insertionPoint);
     this._hideSeparatorDupes();
   }
 
diff --git a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
index 57662ed2..6dcd7d3 100644
--- a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
+++ b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
@@ -25,10 +25,6 @@
     overflow: visible;
 }
 
-.toolbar-shadow.wrappable-reverse {
-    flex-direction: row-reverse;
-}
-
 .toolbar-shadow.toolbar-grow-vertical {
     height: initial;
 }
diff --git a/third_party/blink/renderer/modules/storage/storage_area.cc b/third_party/blink/renderer/modules/storage/storage_area.cc
index c856132..b562e26 100644
--- a/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -167,8 +167,8 @@
   for (Page* page : Page::OrdinaryPages()) {
     for (Frame* frame = page->MainFrame(); frame;
          frame = frame->Tree().TraverseNext()) {
-      // FIXME: We do not yet have a way to dispatch events to out-of-process
-      // frames.
+      // Remote frames are cross-origin and do not need to be notified of
+      // events.
       if (!frame->IsLocalFrame())
         continue;
       LocalFrame* local_frame = ToLocalFrame(frame);
@@ -219,8 +219,7 @@
 
   for (Frame* frame = page->MainFrame(); frame;
        frame = frame->Tree().TraverseNext()) {
-    // FIXME: We do not yet have a way to dispatch events to out-of-process
-    // frames.
+    // Remote frames are cross-origin and do not need to be notified of events.
     if (!frame->IsLocalFrame())
       continue;
     LocalFrame* local_frame = ToLocalFrame(frame);
diff --git a/third_party/blink/renderer/modules/xr/xr_device.cc b/third_party/blink/renderer/modules/xr/xr_device.cc
index ddd3223..01568d2 100644
--- a/third_party/blink/renderer/modules/xr/xr_device.cc
+++ b/third_party/blink/renderer/modules/xr/xr_device.cc
@@ -58,13 +58,9 @@
 
 const char* XRDevice::checkSessionSupport(
     const XRSessionCreationOptions& options) const {
-  if (options.exclusive()) {
-    // Validation for exclusive sessions.
-    if (!supports_exclusive_) {
-      return kExclusiveNotSupported;
-    }
-  } else {
-    // Validation for non-exclusive sessions.
+  if (!options.exclusive()) {
+    // Validation for non-exclusive sessions. Validation for exclusive sessions
+    // happens browser side.
     if (!options.hasOutputContext()) {
       return kNoOutputContext;
     }
@@ -94,7 +90,7 @@
 
 ScriptPromise XRDevice::supportsSession(
     ScriptState* script_state,
-    const XRSessionCreationOptions& options) const {
+    const XRSessionCreationOptions& options) {
   // Check to see if the device is capable of supporting the requested session
   // options. Note that reporting support here does not guarantee that creating
   // a session with those options will succeed, as other external and
@@ -110,10 +106,29 @@
   // may specify a value to be returned here.
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
-  resolver->Resolve();
+
+  device::mojom::blink::XRSessionOptionsPtr session_options =
+      device::mojom::blink::XRSessionOptions::New();
+  session_options->exclusive = options.exclusive();
+
+  display_->SupportsSession(
+      std::move(session_options),
+      WTF::Bind(&XRDevice::OnSupportsSessionReturned, WrapPersistent(this),
+                WrapPersistent(resolver)));
+
   return promise;
 }
 
+void XRDevice::OnSupportsSessionReturned(ScriptPromiseResolver* resolver,
+                                         bool supports_session) {
+  // kExclusiveNotSupported is currently the only reason that SupportsSession
+  // rejects on the browser side. That or there are no devices, but that should
+  // technically not be possible.
+  supports_session ? resolver->Resolve()
+                   : resolver->Reject(DOMException::Create(
+                         kNotSupportedError, kExclusiveNotSupported));
+}
+
 int64_t XRDevice::GetSourceId() const {
   return xr_->GetSourceId();
 }
@@ -167,14 +182,19 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
 
-  display_->RequestSession(WTF::Bind(&XRDevice::OnRequestSessionComplete,
-                                     WrapWeakPersistent(this),
-                                     WrapPersistent(resolver), options));
+  device::mojom::blink::XRSessionOptionsPtr session_options =
+      device::mojom::blink::XRSessionOptions::New();
+  session_options->exclusive = options.exclusive();
+
+  display_->RequestSession(
+      std::move(session_options),
+      WTF::Bind(&XRDevice::OnRequestSessionReturned, WrapWeakPersistent(this),
+                WrapPersistent(resolver), options));
 
   return promise;
 }
 
-void XRDevice::OnRequestSessionComplete(ScriptPromiseResolver* resolver,
+void XRDevice::OnRequestSessionReturned(ScriptPromiseResolver* resolver,
                                         const XRSessionCreationOptions& options,
                                         bool success) {
   if (!success) {
diff --git a/third_party/blink/renderer/modules/xr/xr_device.h b/third_party/blink/renderer/modules/xr/xr_device.h
index e9ab87b..53bfa40 100644
--- a/third_party/blink/renderer/modules/xr/xr_device.h
+++ b/third_party/blink/renderer/modules/xr/xr_device.h
@@ -8,6 +8,7 @@
 #include "device/vr/public/mojom/vr_service.mojom-blink.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/modules/xr/xr_session_creation_options.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -35,8 +36,7 @@
 
   bool external() const { return is_external_; }
 
-  ScriptPromise supportsSession(ScriptState*,
-                                const XRSessionCreationOptions&) const;
+  ScriptPromise supportsSession(ScriptState*, const XRSessionCreationOptions&);
   ScriptPromise requestSession(ScriptState*, const XRSessionCreationOptions&);
 
   // EventTarget overrides.
@@ -87,9 +87,11 @@
 
   const char* checkSessionSupport(const XRSessionCreationOptions&) const;
 
-  void OnRequestSessionComplete(ScriptPromiseResolver* resolver,
+  void OnRequestSessionReturned(ScriptPromiseResolver* resolver,
                                 const XRSessionCreationOptions& options,
                                 bool success);
+  void OnSupportsSessionReturned(ScriptPromiseResolver* resolver,
+                                 bool supports_session);
 
   // There are two components to focus - whether the frame itself has
   // traditional focus and whether the device reports that we have focus. These
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
index 0f9b03a0..2bb296b 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
@@ -82,10 +82,8 @@
     layer_tree_view_->RegisterViewportLayers(viewport_layers);
     layer_tree_view_->SetViewportSize(WebSize(1, 1));
 
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       graphics_layer_->SetLayerState(
           PropertyTreeState(PropertyTreeState::Root()), IntPoint());
-    }
   }
 
   ~GraphicsLayerTest() override {
@@ -129,7 +127,6 @@
 INSTANTIATE_TEST_CASE_P(All,
                         GraphicsLayerTest,
                         testing::Values(0,
-                                        kSlimmingPaintV175,
                                         kBlinkGenPropertyTrees));
 
 class AnimationForTesting : public CompositorAnimationClient {
@@ -225,9 +222,6 @@
 }
 
 TEST_P(GraphicsLayerTest, PaintRecursively) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   IntRect interest_rect(1, 2, 3, 4);
   auto* transform_root = TransformPaintPropertyNode::Root();
   auto transform1 =
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
index fba18fe..9e6dfbc 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
@@ -134,10 +134,11 @@
     OverlayScrollbarClipBehavior clip_behavior,
     InclusiveIntersectOrNot inclusive_behavior) {
   bool success = false;
-  return LocalToAncestorVisualRectInternal(local_state, ancestor_state,
-                                           mapping_rect, clip_behavior,
-                                           inclusive_behavior, success);
+  bool result = LocalToAncestorVisualRectInternal(local_state, ancestor_state,
+                                                  mapping_rect, clip_behavior,
+                                                  inclusive_behavior, success);
   DCHECK(success);
+  return result;
 }
 
 bool GeometryMapper::PointVisibleInAncestorSpace(
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
index 58e7eac..f334489 100644
--- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
@@ -708,7 +708,8 @@
 }
 
 TEST_P(GeometryMapperTest, InvertedClip) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
+  // This test is invalid for SPv2.
+  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
     return;
 
   auto clip = CreateClip(ClipPaintPropertyNode::Root(),
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc b/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
index 074f9f8..d74be6e9 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc
@@ -7,7 +7,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
 
 using testing::ElementsAre;
 
@@ -15,11 +14,7 @@
 
 namespace {
 
-class PaintChunkerTest : public testing::Test,
-                         private ScopedSlimmingPaintV175ForTest {
- public:
-  PaintChunkerTest() : ScopedSlimmingPaintV175ForTest(true) {}
-
+class PaintChunkerTest : public testing::Test {
  protected:
   class TestDisplayItemClient : public DisplayItemClient {
     String DebugName() const final { return "Test"; }
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc b/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
index ca3bad0..0689945 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
@@ -6,10 +6,6 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/clip_path_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/clip_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/compositing_recorder.h"
 #include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
 #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
 #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -34,11 +30,9 @@
     All,
     PaintControllerTest,
     testing::Values(0,
-                    kSlimmingPaintV175,
                     kBlinkGenPropertyTrees,
                     kSlimmingPaintV2,
                     kUnderInvalidationChecking,
-                    kSlimmingPaintV175 | kUnderInvalidationChecking,
                     kBlinkGenPropertyTrees | kUnderInvalidationChecking,
                     kSlimmingPaintV2 | kUnderInvalidationChecking));
 
@@ -47,14 +41,9 @@
   FakeDisplayItemClient client("client", LayoutRect(100, 100, 200, 200));
   InitRootChunk();
 
-  {
-    ClipRecorder clip_recorder(context, client, kClipType,
-                               IntRect(100, 100, 50, 50));
-    DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 200, 200));
-  }
+  DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 200, 200));
   GetPaintController().CommitNewDisplayItems();
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 1,
                         TestDisplayItem(client, kBackgroundType));
 
@@ -62,13 +51,6 @@
     // Raster invalidation for the whole chunk will be issued during
     // PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
-  } else {
-    EXPECT_DISPLAY_LIST(
-        GetPaintController().GetDisplayItemList(), 3,
-        TestDisplayItem(client, kClipType),
-        TestDisplayItem(client, kBackgroundType),
-        TestDisplayItem(client, DisplayItem::ClipTypeToEndClipType(kClipType)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateBasic) {
@@ -90,15 +72,12 @@
                       TestDisplayItem(second, kBackgroundType),
                       TestDisplayItem(first, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     // Raster invalidation for the whole chunk will be issued during
     // PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
 
     InitRootChunk();
-  }
-
   DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 300, 300));
   DrawRect(context, first, kForegroundType, FloatRect(100, 100, 300, 300));
 
@@ -115,12 +94,10 @@
                       TestDisplayItem(first, kBackgroundType),
                       TestDisplayItem(first, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // |second| disappeared from the chunk.
                 UnorderedElementsAre(FloatRect(100, 100, 200, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateSwapOrder) {
@@ -171,12 +148,10 @@
                       TestDisplayItem(unaffected, kBackgroundType),
                       TestDisplayItem(unaffected, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // Bounds of |second| (old and new are the same).
                 UnorderedElementsAre(FloatRect(100, 100, 50, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateSwapOrderWithInvalidation) {
@@ -228,14 +203,12 @@
                       TestDisplayItem(unaffected, kBackgroundType),
                       TestDisplayItem(unaffected, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // Bounds of |first| (old and new are the same).
                 UnorderedElementsAre(FloatRect(100, 100, 100, 100)));
     // No need to invalidate raster of |second|, because the client (|first|)
     // which swapped order with it has been invalidated.
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateNewItemInMiddle) {
@@ -273,12 +246,10 @@
                       TestDisplayItem(third, kBackgroundType),
                       TestDisplayItem(second, kBackgroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // |third| newly appeared in the chunk.
                 UnorderedElementsAre(FloatRect(125, 100, 200, 50)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateInvalidationWithPhases) {
@@ -331,18 +302,13 @@
                       TestDisplayItem(second, kForegroundType),
                       TestDisplayItem(third, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // Bounds of |second| (old and new are the same).
                 UnorderedElementsAre(FloatRect(100, 100, 50, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, IncrementalRasterInvalidation) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   LayoutRect initial_rect(100, 100, 100, 100);
   std::unique_ptr<FakeDisplayItemClient> clients[6];
   for (auto& client : clients)
@@ -417,7 +383,6 @@
                       TestDisplayItem(second, kBackgroundType),
                       TestDisplayItem(second, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(
         *GetRasterInvalidationRects(0),
@@ -428,8 +393,6 @@
             FloatRect(200, 200, 50, 50), FloatRect(150, 250, 100, 100)));
 
     InitRootChunk();
-  }
-
   DrawRect(context, second, kBackgroundType, FloatRect(150, 250, 100, 100));
   DrawRect(context, second, kForegroundType, FloatRect(150, 250, 100, 100));
 
@@ -446,12 +409,10 @@
                       TestDisplayItem(second, kBackgroundType),
                       TestDisplayItem(second, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // |first| disappeared from the chunk.
                 UnorderedElementsAre(FloatRect(100, 100, 150, 150)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateAddLastOverlap) {
@@ -486,7 +447,6 @@
                       TestDisplayItem(second, kBackgroundType),
                       TestDisplayItem(second, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 UnorderedElementsAre(
@@ -496,8 +456,6 @@
                     FloatRect(200, 200, 50, 50)));
 
     InitRootChunk();
-  }
-
   first.SetDisplayItemsUncached();
   first.SetVisualRect(LayoutRect(100, 100, 150, 150));
   second.SetDisplayItemsUncached();
@@ -510,7 +468,6 @@
                       TestDisplayItem(first, kBackgroundType),
                       TestDisplayItem(first, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 UnorderedElementsAre(
@@ -518,7 +475,6 @@
                     FloatRect(100, 100, 150, 150),
                     // |second| disappeared from the chunk.
                     FloatRect(200, 200, 50, 50)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateClip) {
@@ -526,37 +482,20 @@
   FakeDisplayItemClient second("second", LayoutRect(100, 100, 200, 200));
   GraphicsContext context(GetPaintController());
 
-  scoped_refptr<ClipPaintPropertyNode> clip =
-      CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
-
-  {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-      PaintChunk::Id id(first, kClipType);
-      auto properties = DefaultPaintChunkProperties();
-      properties.SetClip(clip.get());
-      GetPaintController().UpdateCurrentPaintChunkProperties(id, properties);
-    }
-    ClipRecorder clip_recorder(context, first, kClipType, IntRect(1, 1, 2, 2));
-    DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
-    DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
-  }
+  auto clip = CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
+  auto properties = DefaultPaintChunkProperties();
+  properties.SetClip(clip.get());
+  GetPaintController().UpdateCurrentPaintChunkProperties(
+      PaintChunk::Id(first, kClipType), properties);
+  DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
+  DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
   GetPaintController().CommitNewDisplayItems();
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 2,
                         TestDisplayItem(first, kBackgroundType),
                         TestDisplayItem(second, kBackgroundType));
 
     InitRootChunk();
-  } else {
-    EXPECT_DISPLAY_LIST(
-        GetPaintController().GetDisplayItemList(), 4,
-        TestDisplayItem(first, kClipType),
-        TestDisplayItem(first, kBackgroundType),
-        TestDisplayItem(second, kBackgroundType),
-        TestDisplayItem(first, DisplayItem::ClipTypeToEndClipType(kClipType)));
-  }
-
   first.SetDisplayItemsUncached();
   DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
   DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
@@ -574,34 +513,23 @@
                       TestDisplayItem(first, kBackgroundType),
                       TestDisplayItem(second, kBackgroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     // This is a new chunk. Raster invalidation for the whole chunk will be
     // issued during PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
 
     InitRootChunk();
-  }
-
   second.SetDisplayItemsUncached();
   DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
 
-  scoped_refptr<ClipPaintPropertyNode> clip2 =
-      CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
-
-  {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-      PaintChunk::Id id(second, kClipType);
-      auto properties = DefaultPaintChunkProperties();
-      properties.SetClip(clip2.get());
-      GetPaintController().UpdateCurrentPaintChunkProperties(id, properties);
-    }
-    ClipRecorder clip_recorder(context, second, kClipType, IntRect(1, 1, 2, 2));
-    DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
-  }
+  auto clip2 = CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
+  auto properties2 = DefaultPaintChunkProperties();
+  properties2.SetClip(clip2.get());
+  GetPaintController().UpdateCurrentPaintChunkProperties(
+      PaintChunk::Id(second, kClipType), properties2);
+  DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
   GetPaintController().CommitNewDisplayItems();
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 2,
                         TestDisplayItem(first, kBackgroundType),
                         TestDisplayItem(second, kBackgroundType));
@@ -613,23 +541,13 @@
     // This is a new chunk. Raster invalidation for the whole chunk will be
     // issued during PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(1));
-  } else {
-    EXPECT_DISPLAY_LIST(
-        GetPaintController().GetDisplayItemList(), 4,
-        TestDisplayItem(first, kBackgroundType),
-        TestDisplayItem(second, kClipType),
-        TestDisplayItem(second, kBackgroundType),
-        TestDisplayItem(second, DisplayItem::ClipTypeToEndClipType(kClipType)));
-  }
 }
 
 TEST_P(PaintControllerTest, CachedDisplayItems) {
   FakeDisplayItemClient first("first");
   FakeDisplayItemClient second("second");
   GraphicsContext context(GetPaintController());
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    InitRootChunk();
-  }
+  InitRootChunk();
 
   DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
   DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 150, 150));
@@ -653,9 +571,7 @@
   EXPECT_FALSE(ClientCacheIsValid(first));
   EXPECT_TRUE(ClientCacheIsValid(second));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    InitRootChunk();
-  }
+  InitRootChunk();
   DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150));
   DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 150, 150));
   GetPaintController().CommitNewDisplayItems();
@@ -737,7 +653,6 @@
                       TestDisplayItem(content1, kForegroundType),
                       TestDisplayItem(container1, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(
         *GetRasterInvalidationRects(0),
@@ -746,7 +661,6 @@
             FloatRect(100, 200, 100, 100),
             // Bounds of |content2| which was moved along with |container2|.
             FloatRect(100, 200, 50, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, UpdateSwapOrderWithChildrenAndInvalidation) {
@@ -804,7 +718,6 @@
                       TestDisplayItem(content1, kForegroundType),
                       TestDisplayItem(container1, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(
         *GetRasterInvalidationRects(0),
@@ -815,12 +728,10 @@
             FloatRect(100, 200, 100, 100),
             // Bounds of |content2| which was moved along with |container2|.
             FloatRect(100, 200, 50, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled() ||
-      RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
+  if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
     return;
 
   GraphicsContext context(GetPaintController());
@@ -898,10 +809,9 @@
   container2_properties.SetEffect(container2_effect.get());
 
   {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container1, kBackgroundType), container1_properties);
-    }
+
     SubsequenceRecorder r(context, container1);
     DrawRect(context, container1, kBackgroundType,
              FloatRect(100, 100, 100, 100));
@@ -911,10 +821,9 @@
              FloatRect(100, 100, 100, 100));
   }
   {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container2, kBackgroundType), container2_properties);
-    }
+
     SubsequenceRecorder r(context, container2);
     DrawRect(context, container2, kBackgroundType,
              FloatRect(100, 200, 100, 100));
@@ -946,7 +855,6 @@
   EXPECT_EQ(4u, markers->start);
   EXPECT_EQ(8u, markers->end);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(2u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container1, kBackgroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -956,7 +864,6 @@
     // PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
     EXPECT_FALSE(GetRasterInvalidationRects(1));
-  }
 
   // Simulate the situation when |container1| gets a z-index that is greater
   // than that of |container2|.
@@ -967,11 +874,10 @@
     EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
         context, container2));
     {
-      if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
         PaintChunk::Id id(container2, kBackgroundType);
         GetPaintController().UpdateCurrentPaintChunkProperties(
             id, container2_properties);
-      }
+
       SubsequenceRecorder r(context, container2);
       DrawRect(context, container2, kBackgroundType,
                FloatRect(100, 200, 100, 100));
@@ -985,11 +891,10 @@
     EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
         context, container1));
     {
-      if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
         PaintChunk::Id id(container1, kBackgroundType);
         GetPaintController().UpdateCurrentPaintChunkProperties(
             id, container1_properties);
-      }
+
       SubsequenceRecorder r(context, container1);
       DrawRect(context, container1, kBackgroundType,
                FloatRect(100, 100, 100, 100));
@@ -1036,7 +941,6 @@
   EXPECT_EQ(4u, markers->start);
   EXPECT_EQ(8u, markers->end);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(2u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container2, kBackgroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -1045,7 +949,6 @@
     // Swapping order of chunks should not invalidate anything.
     EXPECT_FALSE(GetRasterInvalidationRects(0));
     EXPECT_FALSE(GetRasterInvalidationRects(1));
-  }
 }
 
 TEST_P(PaintControllerTest, CachedSubsequenceAndDisplayItemsSwapOrder) {
@@ -1139,9 +1042,6 @@
 }
 
 TEST_P(PaintControllerTest, CachedSubsequenceContainingFragments) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   GraphicsContext context(GetPaintController());
   FakeDisplayItemClient root("root");
   constexpr size_t kFragmentCount = 3;
@@ -1227,24 +1127,16 @@
   auto container2_properties = DefaultPaintChunkProperties();
   container2_properties.SetEffect(container2_effect.get());
 
-  {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container1, kBackgroundType), container1_properties);
-    }
     DrawRect(context, container1, kBackgroundType,
              FloatRect(100, 100, 100, 100));
     DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
-  }
-  {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container2, kBackgroundType), container2_properties);
-    }
     DrawRect(context, container2, kBackgroundType,
              FloatRect(100, 200, 100, 100));
     DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
-  }
   GetPaintController().CommitNewDisplayItems();
 
   EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 4,
@@ -1253,7 +1145,6 @@
                       TestDisplayItem(container2, kBackgroundType),
                       TestDisplayItem(content2, kBackgroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(2u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container1, kBackgroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -1263,20 +1154,15 @@
     // PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
     EXPECT_FALSE(GetRasterInvalidationRects(1));
-  }
 
   // Move content2 into container1, without invalidation.
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     GetPaintController().UpdateCurrentPaintChunkProperties(
         PaintChunk::Id(container1, kBackgroundType), container1_properties);
-  }
   DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100));
   DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
   DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     GetPaintController().UpdateCurrentPaintChunkProperties(
         PaintChunk::Id(container2, kBackgroundType), container2_properties);
-  }
   DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100));
 
   EXPECT_EQ(4, NumCachedNewItems());
@@ -1294,7 +1180,6 @@
                       TestDisplayItem(content2, kBackgroundType),
                       TestDisplayItem(container2, kBackgroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(2u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container1, kBackgroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -1305,7 +1190,6 @@
                 UnorderedElementsAre(FloatRect(100, 200, 50, 200)));
     EXPECT_THAT(*GetRasterInvalidationRects(1),
                 UnorderedElementsAre(FloatRect(100, 200, 50, 200)));
-  }
 }
 
 TEST_P(PaintControllerTest, OutOfOrderNoCrash) {
@@ -1369,48 +1253,38 @@
   content2_properties.SetEffect(content2_effect.get());
 
   {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container1, kBackgroundType),
           container1_background_properties);
-    }
     SubsequenceRecorder r(context, container1);
     DrawRect(context, container1, kBackgroundType,
              FloatRect(100, 100, 100, 100));
 
     {
-      if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
         GetPaintController().UpdateCurrentPaintChunkProperties(
             PaintChunk::Id(content1, kBackgroundType), content1_properties);
-      }
       SubsequenceRecorder r(context, content1);
       DrawRect(context, content1, kBackgroundType,
                FloatRect(100, 100, 50, 200));
       DrawRect(context, content1, kForegroundType,
                FloatRect(100, 100, 50, 200));
     }
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container1, kForegroundType),
           container1_foreground_properties);
-    }
     DrawRect(context, container1, kForegroundType,
              FloatRect(100, 100, 100, 100));
   }
   {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container2, kBackgroundType),
           container2_background_properties);
-    }
     SubsequenceRecorder r(context, container2);
     DrawRect(context, container2, kBackgroundType,
              FloatRect(100, 200, 100, 100));
     {
-      if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
         GetPaintController().UpdateCurrentPaintChunkProperties(
             PaintChunk::Id(content2, kBackgroundType), content2_properties);
-      }
       SubsequenceRecorder r(context, content2);
       DrawRect(context, content2, kBackgroundType,
                FloatRect(100, 200, 50, 200));
@@ -1446,7 +1320,6 @@
   EXPECT_EQ(5u, markers->start);
   EXPECT_EQ(6u, markers->end);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(5u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container1, kBackgroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -1465,7 +1338,6 @@
     EXPECT_FALSE(GetRasterInvalidationRects(2));
     EXPECT_FALSE(GetRasterInvalidationRects(3));
     EXPECT_FALSE(GetRasterInvalidationRects(4));
-  }
 
   // Invalidate container1 but not content1.
   container1.SetDisplayItemsUncached();
@@ -1481,10 +1353,8 @@
       SubsequenceRecorder::UseCachedSubsequenceIfPossible(context, content2));
   // Content2 now outputs foreground only.
   {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(content2, kForegroundType), content2_properties);
-    }
     SubsequenceRecorder r(context, content2);
     DrawRect(context, content2, kForegroundType, FloatRect(100, 200, 50, 200));
   }
@@ -1500,10 +1370,8 @@
       // expected to create the same painting as in the previous paint.
       EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
           context, content1));
-      if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
         GetPaintController().UpdateCurrentPaintChunkProperties(
             PaintChunk::Id(content1, kBackgroundType), content1_properties);
-      }
       SubsequenceRecorder r(context, content1);
       DrawRect(context, content1, kBackgroundType,
                FloatRect(100, 100, 50, 200));
@@ -1513,11 +1381,9 @@
       EXPECT_TRUE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
           context, content1));
     }
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           PaintChunk::Id(container1, kForegroundType),
           container1_foreground_properties);
-    }
     DrawRect(context, container1, kForegroundType,
              FloatRect(100, 100, 100, 100));
   }
@@ -1552,7 +1418,6 @@
   EXPECT_EQ(1u, markers->start);
   EXPECT_EQ(3u, markers->end);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(3u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(content2, kForegroundType),
               GetPaintController().PaintChunks()[0].id);
@@ -1568,7 +1433,6 @@
     // |container1| is invalidated.
     EXPECT_THAT(*GetRasterInvalidationRects(2),
                 UnorderedElementsAre(FloatRect(100, 100, 100, 100)));
-  }
 }
 
 TEST_P(PaintControllerTest, SkipCache) {
@@ -1604,15 +1468,12 @@
           .GetPaintRecord();
   EXPECT_NE(record1, record2);
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     // Raster invalidation for the whole chunk will be issued during
     // PaintArtifactCompositor::Update().
     EXPECT_FALSE(GetRasterInvalidationRects(0));
 
     InitRootChunk();
-  }
-
   // Draw again with nothing invalidated.
   EXPECT_TRUE(ClientCacheIsValid(multicol));
   DrawRect(context, multicol, kBackgroundType, FloatRect(100, 200, 100, 100));
@@ -1642,15 +1503,12 @@
                          GetPaintController().GetDisplayItemList()[2])
                          .GetPaintRecord());
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 // Bounds of |content| (old and new are the same);
                 UnorderedElementsAre(FloatRect(100, 100, 100, 100)));
 
     InitRootChunk();
-  }
-
   // Now the multicol becomes 3 columns and repaints.
   multicol.SetDisplayItemsUncached();
   DrawRect(context, multicol, kBackgroundType, FloatRect(100, 100, 100, 100));
@@ -1676,7 +1534,6 @@
 
   GetPaintController().CommitNewDisplayItems();
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
     EXPECT_EQ(1u, GetPaintController().PaintChunks().size());
     EXPECT_THAT(*GetRasterInvalidationRects(0),
                 UnorderedElementsAre(
@@ -1684,7 +1541,6 @@
                     FloatRect(100, 100, 200, 200),
                     // Bounds of |content| (old and new are the same);
                     FloatRect(100, 100, 100, 100)));
-  }
 }
 
 TEST_P(PaintControllerTest, PartialSkipCache) {
@@ -1759,63 +1615,8 @@
                          .GetPaintRecord());
 }
 
-TEST_P(PaintControllerTest, OptimizeNoopPairs) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
-  FakeDisplayItemClient first("first");
-  FakeDisplayItemClient second("second");
-  FakeDisplayItemClient third("third");
-
-  GraphicsContext context(GetPaintController());
-  DrawRect(context, first, kBackgroundType, FloatRect(0, 0, 100, 100));
-  {
-    ClipPathRecorder clip_recorder(context, second, Path());
-    DrawRect(context, second, kBackgroundType, FloatRect(0, 0, 100, 100));
-  }
-  DrawRect(context, third, kBackgroundType, FloatRect(0, 0, 100, 100));
-
-  GetPaintController().CommitNewDisplayItems();
-  EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 5,
-                      TestDisplayItem(first, kBackgroundType),
-                      TestDisplayItem(second, DisplayItem::kBeginClipPath),
-                      TestDisplayItem(second, kBackgroundType),
-                      TestDisplayItem(second, DisplayItem::kEndClipPath),
-                      TestDisplayItem(third, kBackgroundType));
-
-  DrawRect(context, first, kBackgroundType, FloatRect(0, 0, 100, 100));
-  {
-    ClipRecorder clip_recorder(context, second, kClipType, IntRect(1, 1, 2, 2));
-    // Do not draw anything for second.
-  }
-  DrawRect(context, third, kBackgroundType, FloatRect(0, 0, 100, 100));
-  GetPaintController().CommitNewDisplayItems();
-
-  // Empty clips should have been optimized out.
-  EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 2,
-                      TestDisplayItem(first, kBackgroundType),
-                      TestDisplayItem(third, kBackgroundType));
-
-  second.SetDisplayItemsUncached();
-  DrawRect(context, first, kBackgroundType, FloatRect(0, 0, 100, 100));
-  {
-    ClipRecorder clip_recorder(context, second, kClipType, IntRect(1, 1, 2, 2));
-    {
-      ClipPathRecorder clip_path_recorder(context, second, Path());
-      // Do not draw anything for second.
-    }
-  }
-  DrawRect(context, third, kBackgroundType, FloatRect(0, 0, 100, 100));
-  GetPaintController().CommitNewDisplayItems();
-
-  // Empty clips should have been optimized out.
-  EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 2,
-                      TestDisplayItem(first, kBackgroundType),
-                      TestDisplayItem(third, kBackgroundType));
-}
 
 TEST_P(PaintControllerTest, SmallPaintControllerHasOnePaintChunk) {
-  ScopedSlimmingPaintV2ForTest enable_s_pv2(true);
   FakeDisplayItemClient client("test client");
 
   InitRootChunk();
@@ -1894,9 +1695,6 @@
 }
 
 TEST_P(PaintControllerTest, PartialInvalidation) {
-  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
   FakeDisplayItemClient client("client", LayoutRect(100, 100, 300, 300));
   GraphicsContext context(GetPaintController());
 
@@ -2089,43 +1887,6 @@
     GetPaintController().CommitNewDisplayItems();
   }
 
-  void TestNoopPairsInSubsequence() {
-    EXPECT_FALSE(GetPaintController().LastDisplayItemIsSubsequenceEnd());
-
-    FakeDisplayItemClient container("container");
-    GraphicsContext context(GetPaintController());
-
-    InitRootChunk();
-    {
-      SubsequenceRecorder r(context, container);
-      DrawRect(context, container, kBackgroundType,
-               FloatRect(100, 100, 100, 100));
-    }
-    GetPaintController().CommitNewDisplayItems();
-
-    InitRootChunk();
-    EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
-        context, container));
-    {
-      // Generate some no-op pairs which should not affect under-invalidation
-      // checking.
-      ClipRecorder r1(context, container, kClipType, IntRect(1, 1, 9, 9));
-      ClipRecorder r2(context, container, kClipType, IntRect(1, 1, 2, 2));
-      ClipRecorder r3(context, container, kClipType, IntRect(1, 1, 3, 3));
-      ClipPathRecorder r4(context, container, Path());
-    }
-    {
-      EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
-          context, container));
-      SubsequenceRecorder r(context, container);
-      DrawRect(context, container, kBackgroundType,
-               FloatRect(100, 100, 100, 100));
-    }
-    EXPECT_TRUE(GetPaintController().LastDisplayItemIsSubsequenceEnd());
-
-    GetPaintController().CommitNewDisplayItems();
-  }
-
   void TestChangeDrawingInSubsequence() {
     FakeDisplayItemClient first("first");
     GraphicsContext context(GetPaintController());
@@ -2194,34 +1955,6 @@
     GetPaintController().CommitNewDisplayItems();
   }
 
-  void TestChangeNonDrawingInSubsequence() {
-    FakeDisplayItemClient container("container");
-    FakeDisplayItemClient content("content");
-    GraphicsContext context(GetPaintController());
-
-    InitRootChunk();
-    {
-      SubsequenceRecorder r(context, container);
-      { ClipPathRecorder clip_path_recorder(context, container, Path()); }
-      ClipRecorder clip(context, container, kClipType, IntRect(1, 1, 9, 9));
-      DrawRect(context, content, kBackgroundType,
-               FloatRect(100, 100, 300, 300));
-    }
-    GetPaintController().CommitNewDisplayItems();
-
-    InitRootChunk();
-    {
-      EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
-          context, container));
-      SubsequenceRecorder r(context, container);
-      { ClipPathRecorder clip_path_recorder(context, container, Path()); }
-      ClipRecorder clip(context, container, kClipType, IntRect(1, 1, 30, 30));
-      DrawRect(context, content, kBackgroundType,
-               FloatRect(100, 100, 300, 300));
-    }
-    GetPaintController().CommitNewDisplayItems();
-  }
-
   void TestInvalidationInSubsequence() {
     FakeDisplayItemClient container("container");
     FakeDisplayItemClient content("content");
@@ -2285,11 +2018,6 @@
   TestLessDrawing();
 }
 
-TEST_F(PaintControllerUnderInvalidationTest, NoopPairsInSubsequence) {
-  // This should not die.
-  TestNoopPairsInSubsequence();
-}
-
 TEST_F(PaintControllerUnderInvalidationTest, ChangeDrawingInSubsequence) {
   EXPECT_DEATH(TestChangeDrawingInSubsequence(),
                "In cached subsequence for first.*"
@@ -2307,14 +2035,6 @@
                "under-invalidation: new subsequence wrong length");
 }
 
-TEST_F(PaintControllerUnderInvalidationTest, ChangeNonDrawingInSubsequence) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-  EXPECT_DEATH(TestChangeNonDrawingInSubsequence(),
-               "In cached subsequence for first.*"
-               "under-invalidation: new subsequence wrong length");
-}
-
 TEST_F(PaintControllerUnderInvalidationTest, InvalidationInSubsequence) {
   // We allow invalidated display item clients as long as they would produce the
   // same display items. The cases of changed display items are tested by other
@@ -2393,50 +2113,6 @@
   GetPaintController().CommitNewDisplayItems();
 }
 
-TEST_F(PaintControllerUnderInvalidationTest,
-       PairAfterNoopPairInCachedSubsequence) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
-    return;
-
-  FakeDisplayItemClient client("client");
-  GraphicsContext context(GetPaintController());
-
-  {
-    SubsequenceRecorder subsequence_recorder(context, client);
-    {
-      ClipRecorder clip_recorder(context, client, kClipType,
-                                 IntRect(100, 100, 50, 50));
-    }
-    {
-      ClipRecorder clip_recorder(context, client, kClipType,
-                                 IntRect(100, 100, 50, 50));
-      DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 200, 200));
-    }
-  }
-  GetPaintController().CommitNewDisplayItems();
-  EXPECT_DISPLAY_LIST(
-      GetPaintController().GetDisplayItemList(), 3,
-      TestDisplayItem(client, kClipType),
-      TestDisplayItem(client, kBackgroundType),
-      TestDisplayItem(client, DisplayItem::ClipTypeToEndClipType(kClipType)));
-
-  {
-    EXPECT_FALSE(
-        SubsequenceRecorder::UseCachedSubsequenceIfPossible(context, client));
-    SubsequenceRecorder subsequence_recorder(context, client);
-    {
-      ClipRecorder clip_recorder(context, client, kClipType,
-                                 IntRect(100, 100, 50, 50));
-    }
-    {
-      ClipRecorder clip_recorder(context, client, kClipType,
-                                 IntRect(100, 100, 50, 50));
-      DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 200, 200));
-    }
-  }
-  GetPaintController().CommitNewDisplayItems();
-}
-
 #endif  // defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h b/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
index e7a0d4c..28ee07f 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CONTROLLER_TEST_H_
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/graphics/paint/clip_recorder.h"
 #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
 #include "third_party/blink/renderer/platform/testing/fake_display_item_client.h"
@@ -44,10 +43,8 @@
   }
 
   void InitRootChunk() {
-    if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
       GetPaintController().UpdateCurrentPaintChunkProperties(
           root_paint_chunk_id_, DefaultPaintChunkProperties());
-    }
   }
 
  protected:
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc
index ec9bd09..8e74315 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc
@@ -34,10 +34,7 @@
 }
 
 TEST_F(PaintRecordBuilderTest, LastingPaintController) {
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    GetPaintController().UpdateCurrentPaintChunkProperties(
-        base::nullopt, PropertyTreeState::Root());
-  }
+  InitRootChunk();
 
   PaintRecordBuilder builder(nullptr, nullptr, &GetPaintController());
   auto& context = builder.Context();
@@ -58,11 +55,7 @@
                       TestDisplayItem(client, kBackgroundType),
                       TestDisplayItem(client, kForegroundType));
 
-  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
-    GetPaintController().UpdateCurrentPaintChunkProperties(
-        base::nullopt, PropertyTreeState::Root());
-  }
-
+  InitRootChunk();
   EXPECT_TRUE(DrawingRecorder::UseCachedDrawingIfPossible(context, client,
                                                           kBackgroundType));
   EXPECT_TRUE(DrawingRecorder::UseCachedDrawingIfPossible(context, client,
diff --git a/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/third_party/blink/renderer/platform/testing/paint_test_configurations.h
index 4b9c7d8..fafe1ad 100644
--- a/third_party/blink/renderer/platform/testing/paint_test_configurations.h
+++ b/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -12,22 +12,19 @@
 namespace blink {
 
 enum {
-  kSlimmingPaintV175 = 1 << 0,
-  kBlinkGenPropertyTrees = 1 << 1,
-  kSlimmingPaintV2 = 1 << 2,
-  kUnderInvalidationChecking = 1 << 3,
+  kBlinkGenPropertyTrees = 1 << 0,
+  kSlimmingPaintV2 = 1 << 1,
+  kUnderInvalidationChecking = 1 << 2,
 };
 
 class PaintTestConfigurations
     : public testing::WithParamInterface<unsigned>,
-      private ScopedSlimmingPaintV175ForTest,
       private ScopedBlinkGenPropertyTreesForTest,
       private ScopedSlimmingPaintV2ForTest,
       private ScopedPaintUnderInvalidationCheckingForTest {
  public:
   PaintTestConfigurations()
-      : ScopedSlimmingPaintV175ForTest(GetParam() & kSlimmingPaintV175),
-        ScopedBlinkGenPropertyTreesForTest(GetParam() & kBlinkGenPropertyTrees),
+      : ScopedBlinkGenPropertyTreesForTest(GetParam() & kBlinkGenPropertyTrees),
         ScopedSlimmingPaintV2ForTest(GetParam() & kSlimmingPaintV2),
         ScopedPaintUnderInvalidationCheckingForTest(
             GetParam() & kUnderInvalidationChecking) {}
@@ -37,11 +34,10 @@
   }
 };
 
-#define INSTANTIATE_PAINT_TEST_CASE_P(test_class)                   \
-  INSTANTIATE_TEST_CASE_P(                                          \
-      All, test_class,                                              \
-      ::testing::Values(kSlimmingPaintV175, kBlinkGenPropertyTrees, \
-                        kSlimmingPaintV2))
+#define INSTANTIATE_PAINT_TEST_CASE_P(test_class) \
+  INSTANTIATE_TEST_CASE_P(                        \
+      All, test_class,                            \
+      ::testing::Values(0, kBlinkGenPropertyTrees, kSlimmingPaintV2))
 
 #define INSTANTIATE_SPV2_TEST_CASE_P(test_class) \
   INSTANTIATE_TEST_CASE_P(All, test_class, ::testing::Values(kSlimmingPaintV2))
diff --git a/third_party/blink/tools/audit_non_blink_usage.py b/third_party/blink/tools/audit_non_blink_usage.py
index 8367e9c..9cc06f04 100755
--- a/third_party/blink/tools/audit_non_blink_usage.py
+++ b/third_party/blink/tools/audit_non_blink_usage.py
@@ -191,6 +191,10 @@
         'allowed': ['gin::.+'],
     },
     {
+        'paths': ['third_party/blink/renderer/core/clipboard'],
+        'allowed': ['gfx::PNGCodec'],
+    },
+    {
         'paths': ['third_party/blink/renderer/core/css'],
         'allowed': [
             # Internal implementation details for CSS.
diff --git a/third_party/openvr/README.chromium b/third_party/openvr/README.chromium
index c8f4078..95d8d0c 100644
--- a/third_party/openvr/README.chromium
+++ b/third_party/openvr/README.chromium
@@ -17,6 +17,7 @@
 of JSON_FAIL_MESSAGE because "cannot use 'throw' with exceptions disabled".
 openvr.h has been modified to remove dllimport/dllexport when building a
 non-component build so this can be built as a static library.
+Redefined VRLog to avoid logspam on startup.
 
 Copy the correct files with these commands:
 copy %openvrsdk%\README.md %chromium%\src\third_party\openvr\src
diff --git a/third_party/openvr/src/src/vrcommon/vrpathregistry_public.cpp b/third_party/openvr/src/src/vrcommon/vrpathregistry_public.cpp
index cf61c866..137b36f 100644
--- a/third_party/openvr/src/src/vrcommon/vrpathregistry_public.cpp
+++ b/third_party/openvr/src/src/vrcommon/vrpathregistry_public.cpp
@@ -23,13 +23,11 @@
 #include <algorithm>
 
 #ifndef VRLog
-	#if defined( WIN32 )
-		#define VRLog(fmt, ...)		fprintf(stderr, fmt, __VA_ARGS__)
-	#else
-		#define VRLog(args...)		fprintf(stderr, args)
-	#endif
+	#undef VRLog
 #endif
 
+#define VRLog(...)
+
 /** Returns the root of the directory the system wants us to store user config data in */
 static std::string GetAppSettingsPath()
 {
diff --git a/tools/mb/mb.py b/tools/mb/mb.py
index 94bf68e..40af9b3 100755
--- a/tools/mb/mb.py
+++ b/tools/mb/mb.py
@@ -385,9 +385,9 @@
       ('infra/tools/luci/logdog/butler/${platform}',
        'git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c'),
       ('infra/tools/luci/vpython-native/${platform}',
-       'git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c'),
+       'git_revision:ad60019cb66a75b59991d43b95a43f68e3fff81b'),
       ('infra/tools/luci/vpython/${platform}',
-       'git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c'),
+       'git_revision:ad60019cb66a75b59991d43b95a43f68e3fff81b'),
     ]
     for pkg, vers in cipd_packages:
       cmd.append('--cipd-package=.swarming_module:%s:%s' % (pkg, vers))
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index de807f4d..bc09e21 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -5029,6 +5029,7 @@
   <int value="4" label="Both Valid, Different Details"/>
   <int value="5" label="Both Error, Different Details"/>
   <int value="6" label="Ignored Mac Undesired Revocation Checking"/>
+  <int value="7" label="Ignored Multiple EV Policies and One Matches Root"/>
 </enum>
 
 <enum name="ChannelLayout">
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index e5e6d48..b306e44 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -166,7 +166,7 @@
 crbug.com/822925 [ Android_Webview ] smoothness.gpu_rasterization.top_25_smooth/yahoo_sports [ Skip ]
 
 # Benchmark: smoothness.gpu_rasterization.tough_pinch_zoom_cases
-crbug.com/822925 [ Android_Webview ] smoothness.gpu_rasterization.tough_pinch_zoom_cases/http://games.yahoo.com [ Skip ]
+crbug.com/822925 [ Android_Webview ] smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_games_pinch [ Skip ]
 
 # Benchmark: smoothness.key_desktop_move_cases
 crbug.com/750131 [ Win ] smoothness.key_desktop_move_cases/gmail_move [ Skip ]
@@ -232,7 +232,7 @@
 crbug.com/825234 [ Android_Webview ] smoothness.tough_canvas_cases/bouncing_balls_shadow [ Skip ]
 
 # Benchmark: smoothness.tough_pinch_zoom_cases
-crbug.com/822925 [ Android_Webview ] smoothness.tough_pinch_zoom_cases/http://games.yahoo.com [ Skip ]
+crbug.com/822925 [ Android_Webview ] smoothness.tough_pinch_zoom_cases/yahoo_games_pinch [ Skip ]
 
 # Benchmark: smoothness.tough_scrolling_cases
 crbug.com/785473 [ Android_Webview ] smoothness.tough_scrolling_cases/canvas_15000_pixels_per_second [ Skip ]
diff --git a/tools/perf/page_sets/data/tough_pinch_zoom_cases.json b/tools/perf/page_sets/data/tough_pinch_zoom_cases.json
index f62640d..671e8e4 100644
--- a/tools/perf/page_sets/data/tough_pinch_zoom_cases.json
+++ b/tools/perf/page_sets/data/tough_pinch_zoom_cases.json
@@ -1,66 +1,60 @@
 {
     "archives": {
-        "Blogger": {
+        "blogspot_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "ESPN": {
+        "espn_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "Facebook": {
+        "facebook_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "LinkedIn": {
+        "linkedin_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "Twitter": {
+        "twitter_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "Weather.com": {
+        "weather_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://answers.yahoo.com": {
+        "booking_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://booking.com": {
+        "yahoo_games_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://games.yahoo.com": {
+        "yahoo_news_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://news.yahoo.com": {
+        "yahoo_sports_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://sports.yahoo.com/": {
+        "amazon_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://www.amazon.com": {
+        "cnn_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://www.cnn.com": {
+        "ebay_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://www.ebay.com": {
+        "youtube_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "http://www.youtube.com": {
+        "gmail_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "https://mail.google.com/mail/": {
+        "google_search_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "https://plus.google.com/+BarackObama/posts": {
+        "google_calendar_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         },
-        "https://www.google.com/#hl=en&q=barack+obama": {
-            "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
-        },
-        "https://www.google.com/calendar/": {
-            "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
-        },
-        "https://www.google.com/search?q=cats&tbm=isch": {
+        "google_image_pinch": {
             "DEFAULT": "tough_pinch_zoom_cases_000.wprgo"
         }
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
\ No newline at end of file
+}
diff --git a/tools/perf/page_sets/data/tough_webgl_cases.json b/tools/perf/page_sets/data/tough_webgl_cases.json
index 1786d0f..f6d04ea 100644
--- a/tools/perf/page_sets/data/tough_webgl_cases.json
+++ b/tools/perf/page_sets/data/tough_webgl_cases.json
@@ -3,7 +3,7 @@
         "aquarium_20k": {
             "DEFAULT": "tough_webgl_cases_006.wprgo"
         },
-        "ken_russell": {
+        "animometer_webgl": {
             "DEFAULT": "tough_webgl_cases_006.wprgo"
         },
         "aquarium": {
@@ -21,7 +21,7 @@
         "particles": {
             "DEFAULT": "tough_webgl_cases_006.wprgo"
         },
-        "sans_angeles": {
+        "san_angeles": {
             "DEFAULT": "tough_webgl_cases_006.wprgo"
         },
         "earth": {
diff --git a/tools/perf/page_sets/tough_pinch_zoom_cases.py b/tools/perf/page_sets/tough_pinch_zoom_cases.py
index 2df13b2b..c1068a5 100644
--- a/tools/perf/page_sets/tough_pinch_zoom_cases.py
+++ b/tools/perf/page_sets/tough_pinch_zoom_cases.py
@@ -8,9 +8,7 @@
 
 class ToughPinchZoomCasesPage(page_module.Page):
 
-  def __init__(self, url, page_set, name=''):
-    if name == '':
-      name = url
+  def __init__(self, url, page_set, name):
     super(ToughPinchZoomCasesPage, self).__init__(
         url=url, page_set=page_set, name=name,
         shared_page_state_class=shared_page_state.SharedDesktopPageState)
@@ -42,6 +40,7 @@
 
   def __init__(self, page_set):
     super(GoogleSearchPage, self).__init__(
+      name='google_search_pinch',
       url='https://www.google.com/#hl=en&q=barack+obama',
       page_set=page_set)
 
@@ -56,6 +55,7 @@
 
   def __init__(self, page_set):
     super(GmailPage, self).__init__(
+      name='gmail_pinch',
       url='https://mail.google.com/mail/',
       page_set=page_set)
 
@@ -72,6 +72,7 @@
 
   def __init__(self, page_set):
     super(GoogleCalendarPage, self).__init__(
+      name='google_calendar_pinch',
       url='https://www.google.com/calendar/',
       page_set=page_set)
 
@@ -85,6 +86,7 @@
 
   def __init__(self, page_set):
     super(GoogleImageSearchPage, self).__init__(
+      name='google_image_pinch',
       url='https://www.google.com/search?q=cats&tbm=isch',
       page_set=page_set)
 
@@ -95,6 +97,7 @@
 
   def __init__(self, page_set):
     super(YoutubePage, self).__init__(
+      name='youtube_pinch',
       url='http://www.youtube.com',
       page_set=page_set)
 
@@ -111,8 +114,9 @@
 
   def __init__(self, page_set):
     super(BlogSpotPage, self).__init__(
+      name='blogspot_pinch',
       url='http://googlewebmastercentral.blogspot.com/',
-      page_set=page_set, name='Blogger')
+      page_set=page_set)
 
   def RunNavigateSteps(self, action_runner):
     super(BlogSpotPage, self).RunNavigateSteps(action_runner)
@@ -125,8 +129,9 @@
 
   def __init__(self, page_set):
     super(FacebookPage, self).__init__(
+      name='facebook_pinch',
       url='http://www.facebook.com/barackobama',
-      page_set=page_set, name='Facebook')
+      page_set=page_set)
 
   def RunNavigateSteps(self, action_runner):
     super(FacebookPage, self).RunNavigateSteps(action_runner)
@@ -139,8 +144,9 @@
 
   def __init__(self, page_set):
     super(LinkedinPage, self).__init__(
+      name='linkedin_pinch',
       url='http://www.linkedin.com/in/linustorvalds',
-      page_set=page_set, name='LinkedIn')
+      page_set=page_set)
 
 
 class TwitterPage(ToughPinchZoomCasesPage):
@@ -149,8 +155,9 @@
 
   def __init__(self, page_set):
     super(TwitterPage, self).__init__(
+      name='twitter_pinch',
       url='https://twitter.com/katyperry',
-      page_set=page_set, name='Twitter')
+      page_set=page_set)
 
   def RunNavigateSteps(self, action_runner):
     super(TwitterPage, self).RunNavigateSteps(action_runner)
@@ -162,8 +169,9 @@
 
   def __init__(self, page_set):
     super(ESPNPage, self).__init__(
+      name='espn_pinch',
       url='http://espn.go.com/nba',
-      page_set=page_set, name='ESPN')
+      page_set=page_set)
 
 
 class WeatherDotComPage(ToughPinchZoomCasesPage):
@@ -172,9 +180,10 @@
 
   def __init__(self, page_set):
     super(WeatherDotComPage, self).__init__(
+      name='weather_pinch',
       # pylint: disable=line-too-long
       url='http://www.weather.com/weather/right-now/Mountain+View+CA+94043',
-      page_set=page_set, name='Weather.com')
+      page_set=page_set)
 
 
 class YahooGamePage(ToughPinchZoomCasesPage):
@@ -183,6 +192,7 @@
 
   def __init__(self, page_set):
     super(YahooGamePage, self).__init__(
+      name='yahoo_games_pinch',
       url='http://games.yahoo.com',
       page_set=page_set)
 
@@ -214,27 +224,38 @@
     self.AddStory(ESPNPage(self))
 
     # Why: #1 news worldwide (Alexa global)
-    self.AddStory(ToughPinchZoomCasesPage('http://news.yahoo.com', self))
-
+    self.AddStory(ToughPinchZoomCasesPage(url='http://news.yahoo.com',
+                                          page_set=self,
+                                          name='yahoo_news_pinch'))
     # Why: #2 news worldwide
-    self.AddStory(ToughPinchZoomCasesPage('http://www.cnn.com', self))
+    self.AddStory(ToughPinchZoomCasesPage(url='http://www.cnn.com',
+                                          page_set=self,
+                                          name='cnn_pinch'))
 
     self.AddStory(WeatherDotComPage(self))
 
     # Why: #1 world commerce website by visits; #3 commerce in the US by time
     # spent
-    self.AddStory(ToughPinchZoomCasesPage('http://www.amazon.com', self))
+    self.AddStory(ToughPinchZoomCasesPage(url='http://www.amazon.com',
+                                          page_set=self,
+                                          name='amazon_pinch'))
 
     # Why: #1 commerce website by time spent by users in US
-    self.AddStory(ToughPinchZoomCasesPage('http://www.ebay.com', self))
+    self.AddStory(ToughPinchZoomCasesPage(url='http://www.ebay.com',
+                                          page_set=self,
+                                          name='ebay_pinch'))
 
     self.AddStory(YahooGamePage(self))
 
     # Why: #1 Alexa recreation
-    self.AddStory(ToughPinchZoomCasesPage('http://booking.com', self))
+    self.AddStory(ToughPinchZoomCasesPage(url='http://booking.com',
+                                          page_set=self,
+                                          name='booking_pinch'))
 
     # Why: #1 Alexa sports
-    self.AddStory(ToughPinchZoomCasesPage('http://sports.yahoo.com/', self))
+    self.AddStory(ToughPinchZoomCasesPage(url='http://sports.yahoo.com/',
+                                          page_set=self,
+                                          name='yahoo_sports_pinch'))
 
 
 class AndroidToughPinchZoomCasesPageSet(ToughPinchZoomCasesPageSet):
diff --git a/tools/perf/page_sets/tough_webgl_cases.py b/tools/perf/page_sets/tough_webgl_cases.py
index 0a631e39..c0b4b81 100644
--- a/tools/perf/page_sets/tough_webgl_cases.py
+++ b/tools/perf/page_sets/tough_webgl_cases.py
@@ -53,7 +53,7 @@
        'nvidia_vertex_buffer_object'),
       # pylint: disable=line-too-long
       ('http://www.khronos.org/registry/webgl/sdk/demos/google/san-angeles/index.html',
-       'sans_angeles'),
+       'san_angeles'),
       # pylint: disable=line-too-long
       ('http://www.khronos.org/registry/webgl/sdk/demos/google/particles/index.html',
        'particles'),
@@ -72,7 +72,7 @@
        'dynamic_cube_map'),
       # pylint: disable=line-too-long
       ('http://kenrussell.github.io/webgl-animometer/Animometer/tests/3d/webgl.html',
-       'ken_russell')
+       'animometer_webgl')
     ]
     for url, name in urls_list:
       self.AddStory(ToughWebglCasesPage(url, self, name))
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc
index bda516b..464990d 100644
--- a/ui/accessibility/ax_tree.cc
+++ b/ui/accessibility/ax_tree.cc
@@ -244,17 +244,17 @@
         // Totally offscreen. Find the nearest edge or corner.
         // Make the minimum dimension 1 instead of 0.
         if (clipped.x() >= container_bounds.width()) {
-          clipped.set_x(container_bounds.width() - 1);
+          clipped.set_x(container_bounds.right() - 1);
           clipped.set_width(1);
         } else if (clipped.x() + clipped.width() <= 0) {
-          clipped.set_x(0);
+          clipped.set_x(container_bounds.x());
           clipped.set_width(1);
         }
         if (clipped.y() >= container_bounds.height()) {
-          clipped.set_y(container_bounds.height() - 1);
+          clipped.set_y(container_bounds.bottom() - 1);
           clipped.set_height(1);
         } else if (clipped.y() + clipped.height() <= 0) {
-          clipped.set_y(0);
+          clipped.set_y(container_bounds.y());
           clipped.set_height(1);
         }
       }
diff --git a/ui/app_list/views/suggestion_chip_view.cc b/ui/app_list/views/suggestion_chip_view.cc
index 0c1aa195..ae92172a 100644
--- a/ui/app_list/views/suggestion_chip_view.cc
+++ b/ui/app_list/views/suggestion_chip_view.cc
@@ -5,6 +5,7 @@
 #include "ui/app_list/views/suggestion_chip_view.h"
 
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
@@ -16,8 +17,8 @@
 
 // Colors.
 constexpr SkColor kBackgroundColor = SK_ColorWHITE;
-constexpr SkColor kStrokeColor = SkColorSetRGB(0xDA, 0xDC, 0xE0);  // G Grey 300
-constexpr SkColor kTextColor = SkColorSetRGB(0x3C, 0x40, 0x43);    // G Grey 800
+constexpr SkColor kStrokeColor = SkColorSetA(gfx::kGoogleGrey900, 0x24);
+constexpr SkColor kTextColor = gfx::kGoogleGrey900;
 
 // Dimensions.
 constexpr int kIconMarginDip = 8;
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index 734330e..ac1e21f 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -543,13 +543,21 @@
     int64_t display_id,
     WindowMus* window,
     ui::LocatedEvent* event) const {
-  // TODO(sky): this function should be removed when --mash goes away.
-  // https://crbug.com/842365.
-  if (!is_using_pixels())
-    return;
-
   // PointerEvents shouldn't have the target set.
   DCHECK(!event->target());
+
+  // TODO(sky): this function should be removed when --mash goes away.
+  // https://crbug.com/842365.
+  if (!is_using_pixels()) {
+    if (!window) {
+      // When there is no window force the root and location to be the same.
+      // They may differ if |window| was valid at the time of the event, but
+      // was since deleted.
+      event->set_location_f(event->root_location_f());
+    }
+    return;
+  }
+
   if (window_manager_delegate_) {
     ConvertPointerEventLocationToDipInWindowManager(display_id, window, event);
     return;
@@ -1652,17 +1660,12 @@
 
   if (matches_pointer_watcher && has_pointer_watcher_) {
     DCHECK(event->IsPointerEvent());
-    if (is_using_pixels()) {
-      std::unique_ptr<ui::Event> event_in_dip(ui::Event::Clone(*event));
-      ConvertPointerEventLocationToDip(display_id, window,
-                                       event_in_dip->AsLocatedEvent());
-      delegate_->OnPointerEventObserved(*event_in_dip->AsPointerEvent(),
-                                        display_id,
-                                        window ? window->GetWindow() : nullptr);
-    } else {
-      delegate_->OnPointerEventObserved(*event->AsPointerEvent(), display_id,
-                                        window ? window->GetWindow() : nullptr);
-    }
+    std::unique_ptr<ui::Event> event_in_dip(ui::Event::Clone(*event));
+    ConvertPointerEventLocationToDip(display_id, window,
+                                     event_in_dip->AsLocatedEvent());
+    delegate_->OnPointerEventObserved(*event_in_dip->AsPointerEvent(),
+                                      display_id,
+                                      window ? window->GetWindow() : nullptr);
   }
 
   // If the window has already been deleted, use |event| to update event states
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc
index c0e068e..131dfe1 100644
--- a/ui/aura/mus/window_tree_client_unittest.cc
+++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -2741,9 +2741,10 @@
   Window* top_level = window_tree_host.window();
   window_tree_host.InitHost();
 
+  gfx::Rect bounds(2, 4, 6, 8);
   ui::mojom::WindowDataPtr data = ui::mojom::WindowData::New();
   data->window_id = server_id(top_level);
-  data->bounds.SetRect(2, 4, 6, 8);
+  data->bounds = bounds;
   const int64_t display_id = 10;
   uint32_t change_id;
   ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
@@ -2752,9 +2753,12 @@
                                           display_id, true, base::nullopt);
 
   // aura::Window should operate in DIP and aura::WindowTreeHost should operate
-  // in pixels.
-  EXPECT_EQ(gfx::Rect(0, 0, 3, 4), top_level->bounds());
-  EXPECT_EQ(gfx::Rect(2, 4, 6, 8), top_level->GetHost()->GetBoundsInPixels());
+  // in pixels. Only the size is compared for |top_level| as the WindowTreeHost
+  // is the place that maintains the location.
+  EXPECT_EQ(bounds.size(), top_level->bounds().size());
+  const float device_scale_factor = 2.0f;
+  EXPECT_EQ(gfx::ConvertRectToPixel(device_scale_factor, bounds),
+            top_level->GetHost()->GetBoundsInPixels());
 }
 
 TEST_F(WindowTreeClientClientTestHighDPI, PointerEventsInDip) {
@@ -2772,11 +2776,10 @@
   window_tree_client_impl()->StartPointerWatcher(false /* want_moves */);
 
   // Simulate the server sending an observed event.
-  const gfx::Point location_pixels(10, 12);
-  const gfx::Point root_location_pixels(14, 16);
+  const gfx::Point location(10, 12);
+  const gfx::Point root_location(14, 16);
   std::unique_ptr<ui::PointerEvent> pointer_event_down(new ui::PointerEvent(
-      ui::ET_POINTER_DOWN, location_pixels, root_location_pixels,
-      ui::EF_CONTROL_DOWN, 0,
+      ui::ET_POINTER_DOWN, location, root_location, ui::EF_CONTROL_DOWN, 0,
       ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1),
       base::TimeTicks()));
   window_tree_client()->OnPointerEventObserved(std::move(pointer_event_down),
@@ -2787,10 +2790,8 @@
   ASSERT_TRUE(last_event);
   // NOTE: the root and location are the same as there was no window supplied to
   // OnPointerEventObserved().
-  EXPECT_EQ(gfx::ConvertPointToDIP(2.0f, root_location_pixels),
-            last_event->location());
-  EXPECT_EQ(gfx::ConvertPointToDIP(2.0f, root_location_pixels),
-            last_event->root_location());
+  EXPECT_EQ(root_location, last_event->location());
+  EXPECT_EQ(root_location, last_event->root_location());
 }
 
 TEST_F(WindowTreeClientClientTestHighDPI, InputEventsInDip) {
@@ -2829,31 +2830,22 @@
 
   // child1 has a custom targeter set which would always return itself as the
   // target window therefore event should go to child1 and should be in dip.
-  const gfx::Point event_location_in_pixels(50, 60);
+  const gfx::Point event_location(50, 60);
   uint32_t event_id = 1;
   window_delegate1.set_event_id(event_id);
   window_delegate2.set_event_id(event_id);
-  std::unique_ptr<ui::Event> ui_event(new ui::MouseEvent(
-      ui::ET_MOUSE_MOVED, event_location_in_pixels, event_location_in_pixels,
-      ui::EventTimeForNow(), ui::EF_NONE, 0));
+  std::unique_ptr<ui::Event> ui_event(
+      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, event_location,
+                         ui::EventTimeForNow(), ui::EF_NONE, 0));
   window_tree_client()->OnWindowInputEvent(
       event_id, server_id(&child1), window_tree_host.display_id(), ui::Id(),
-      gfx::PointF(event_location_in_pixels), ui::Event::Clone(*ui_event.get()),
-      0);
+      gfx::PointF(event_location), ui::Event::Clone(*ui_event.get()), 0);
   EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
   EXPECT_EQ(ui::mojom::EventResult::HANDLED,
             window_tree()->GetEventResult(event_id));
   EXPECT_EQ(1, window_delegate1.move_count());
   EXPECT_EQ(0, window_delegate2.move_count());
-  const gfx::Point event_location_in_dip(25, 30);
-  EXPECT_EQ(event_location_in_dip, window_delegate1.last_event_location());
-#if defined(USE_OZONE)
-  // For ozone there should be NativeEvent.
-  EXPECT_TRUE(window_delegate1.last_mouse_event_had_native_event());
-  // And the location of the NativeEvent should be in pixels.
-  EXPECT_EQ(event_location_in_pixels,
-            window_delegate1.last_native_event_location());
-#endif
+  EXPECT_EQ(event_location, window_delegate1.last_event_location());
   window_delegate1.reset();
   window_delegate2.reset();
 
@@ -2863,17 +2855,15 @@
   window_delegate2.set_event_id(event_id);
   window_tree_client()->OnWindowInputEvent(
       event_id, server_id(&child2), window_tree_host.display_id(), ui::Id(),
-      gfx::PointF(event_location_in_pixels), ui::Event::Clone(*ui_event.get()),
-      0);
+      gfx::PointF(event_location), ui::Event::Clone(*ui_event.get()), 0);
   EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
   EXPECT_EQ(ui::mojom::EventResult::HANDLED,
             window_tree()->GetEventResult(event_id));
   EXPECT_EQ(1, window_delegate1.move_count());
   EXPECT_EQ(0, window_delegate2.move_count());
-  gfx::Point transformed_event_location_in_dip(event_location_in_dip.x() + 20,
-                                               event_location_in_dip.y() + 30);
-  EXPECT_EQ(transformed_event_location_in_dip,
-            window_delegate1.last_event_location());
+  gfx::Point transformed_event_location(event_location.x() + 20,
+                                        event_location.y() + 30);
+  EXPECT_EQ(transformed_event_location, window_delegate1.last_event_location());
 }
 
 using WindowTreeClientDestructionTest = test::AuraTestBaseMus;
diff --git a/ui/aura/mus/window_tree_host_mus.cc b/ui/aura/mus/window_tree_host_mus.cc
index c72c5d7..adc3c2a 100644
--- a/ui/aura/mus/window_tree_host_mus.cc
+++ b/ui/aura/mus/window_tree_host_mus.cc
@@ -60,7 +60,13 @@
   // If window-server is hosting viz, then use the FrameSinkId from the server.
   // In other cases, let a valid FrameSinkId be selected by
   // context_factory_private().
-  CreateCompositor(window_mus->GenerateFrameSinkIdFromServerId());
+  const bool force_software_compositor = false;
+  const bool external_begin_frames_enabled = false;
+  const bool are_events_in_pixels =
+      init_params.window_tree_client->is_using_pixels();
+  CreateCompositor(window_mus->GenerateFrameSinkIdFromServerId(),
+                   force_software_compositor, external_begin_frames_enabled,
+                   are_events_in_pixels);
   gfx::AcceleratedWidget accelerated_widget;
 // We need accelerated widget numbers to be different for each window and
 // fit in the smallest sizeof(AcceleratedWidget) uint32_t has this property.
diff --git a/ui/aura/test/aura_mus_test_base.cc b/ui/aura/test/aura_mus_test_base.cc
index 4611eda..c77a656 100644
--- a/ui/aura/test/aura_mus_test_base.cc
+++ b/ui/aura/test/aura_mus_test_base.cc
@@ -25,7 +25,7 @@
 void AuraMusClientTestBase::SetUp() {
   // Run AuraTestBase::SetUp() first because it puts an InProcessContextFactory
   // in env.
-  EnableMusWithTestWindowTree();
+  ConfigureBackend(BackendType::MUS2);
   set_window_manager_delegate(nullptr);
   AuraTestBase::SetUp();
 }
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index aa4b27540..c8d3e1242 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -247,8 +247,13 @@
 
 void AuraTestHelper::InitWindowTreeClient() {
   window_tree_client_setup_ = std::make_unique<TestWindowTreeClientSetup>();
-  window_tree_client_setup_->InitForWindowManager(window_tree_delegate_,
-                                                  window_manager_delegate_);
+  if (mode_ == Mode::MUS2_CREATE_WINDOW_TREE_CLIENT) {
+    window_tree_client_setup_->InitWithoutEmbed(
+        window_tree_delegate_, WindowTreeClient::Config::kMus2);
+  } else {
+    window_tree_client_setup_->InitForWindowManager(window_tree_delegate_,
+                                                    window_manager_delegate_);
+  }
   window_tree_client_ = window_tree_client_setup_->window_tree_client();
   window_tree_client_->capture_synchronizer()->AttachToCaptureClient(
       capture_client_.get());
diff --git a/ui/aura/test/mus/test_window_tree.cc b/ui/aura/test/mus/test_window_tree.cc
index 827fdb8..b36b863 100644
--- a/ui/aura/test/mus/test_window_tree.cc
+++ b/ui/aura/test/mus/test_window_tree.cc
@@ -8,7 +8,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/display/manager/display_manager.h"
 
 namespace aura {
 
@@ -41,22 +40,6 @@
   return std::move(last_new_window_properties_);
 }
 
-void TestWindowTree::NotifyClientAboutAcceleratedWidgets(
-    display::DisplayManager* display_manager) {
-  int synth_accelerated_widget = 1;
-  for (const auto& display : display_manager->active_display_list()) {
-#if defined(OS_WIN)
-    gfx::AcceleratedWidget widget =
-        reinterpret_cast<gfx::AcceleratedWidget>(synth_accelerated_widget);
-#else
-    gfx::AcceleratedWidget widget =
-        static_cast<gfx::AcceleratedWidget>(synth_accelerated_widget);
-#endif
-    window_manager_->WmOnAcceleratedWidgetForDisplay(display.id(), widget);
-    ++synth_accelerated_widget;
-  }
-}
-
 void TestWindowTree::AddScheduledEmbedToken(
     const base::UnguessableToken& token) {
   DCHECK_NE(token, scheduled_embed_);
diff --git a/ui/aura/test/mus/test_window_tree.h b/ui/aura/test/mus/test_window_tree.h
index 2c92a136..58bf6b1 100644
--- a/ui/aura/test/mus/test_window_tree.h
+++ b/ui/aura/test/mus/test_window_tree.h
@@ -14,10 +14,6 @@
 #include "services/ui/public/interfaces/window_tree.mojom.h"
 #include "ui/aura/mus/mus_types.h"
 
-namespace display {
-class DisplayManager;
-}
-
 namespace aura {
 
 enum class WindowTreeChangeType {
@@ -75,11 +71,6 @@
 
   size_t number_of_changes() const { return changes_.size(); }
 
-  // Notifies the client about the accelerated widget when mus is not hosting
-  // viz.
-  void NotifyClientAboutAcceleratedWidgets(
-      display::DisplayManager* display_manager);
-
   // Pretends that there is a scheduled embed request for |token|.
   void AddScheduledEmbedToken(const base::UnguessableToken& token);
 
diff --git a/ui/aura/test/mus/test_window_tree_client_setup.cc b/ui/aura/test/mus/test_window_tree_client_setup.cc
index e3f9346..2f8ac00 100644
--- a/ui/aura/test/mus/test_window_tree_client_setup.cc
+++ b/ui/aura/test/mus/test_window_tree_client_setup.cc
@@ -43,11 +43,6 @@
       .SetTree(window_tree_.get());
 }
 
-void TestWindowTreeClientSetup::NotifyClientAboutAcceleratedWidgets(
-    display::DisplayManager* display_manager) {
-  window_tree_->NotifyClientAboutAcceleratedWidgets(display_manager);
-}
-
 std::unique_ptr<WindowTreeClient>
 TestWindowTreeClientSetup::OwnWindowTreeClient() {
   DCHECK(window_tree_client_);
diff --git a/ui/aura/test/mus/test_window_tree_client_setup.h b/ui/aura/test/mus/test_window_tree_client_setup.h
index b6dd8fb..ae7354fa5 100644
--- a/ui/aura/test/mus/test_window_tree_client_setup.h
+++ b/ui/aura/test/mus/test_window_tree_client_setup.h
@@ -10,10 +10,6 @@
 #include "base/macros.h"
 #include "ui/aura/mus/window_tree_client.h"
 
-namespace display {
-class DisplayManager;
-}
-
 namespace aura {
 
 class TestWindowManagerClient;
@@ -40,11 +36,6 @@
   // The WindowTree that WindowTreeClient talks to.
   TestWindowTree* window_tree() { return window_tree_.get(); }
 
-  // Notifies the client about the accelerated widget when mus is not hosting
-  // viz.
-  void NotifyClientAboutAcceleratedWidgets(
-      display::DisplayManager* display_manager);
-
   // Returns ownership of WindowTreeClient to the caller.
   std::unique_ptr<WindowTreeClient> OwnWindowTreeClient();
 
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc
index 6d107d8..e33e4e7 100644
--- a/ui/aura/test/test_screen.cc
+++ b/ui/aura/test/test_screen.cc
@@ -46,7 +46,8 @@
 
 WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() {
   DCHECK(!host_);
-  if (window_tree_client_) {
+  if (window_tree_client_ &&
+      window_tree_client_->config() == WindowTreeClient::Config::kMash) {
     host_ = WindowTreeClientPrivate(window_tree_client_)
                 .CallWmNewDisplayAdded(GetPrimaryDisplay());
   } else {
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 7d3f2ec5..7c119aa 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -98,19 +98,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 // WindowEventDispatcher, public:
 
-WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host)
+WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host,
+                                             bool are_events_in_pixels)
     : host_(host),
-      mouse_pressed_handler_(NULL),
-      mouse_moved_handler_(NULL),
-      touchpad_pinch_handler_(nullptr),
-      event_dispatch_target_(NULL),
-      old_dispatch_target_(NULL),
-      synthesize_mouse_move_(false),
-      move_hold_count_(0),
-      dispatching_held_event_(nullptr),
-      observer_manager_(this),
-      event_targeter_(new WindowTargeter),
-      skip_ime_(false),
+      are_events_in_pixels_(are_events_in_pixels),
+      event_targeter_(std::make_unique<WindowTargeter>()),
       repost_event_factory_(this),
       held_event_factory_(this) {
   ui::GestureRecognizer::Get()->AddGestureEventHelper(this);
@@ -549,8 +541,10 @@
   // The held events are already in |window()|'s coordinate system. So it is
   // not necessary to apply the transform to convert from the host's
   // coordinate system to |window()|'s coordinate system.
-  if (event->IsLocatedEvent() && !is_dispatched_held_event(*event))
+  if (event->IsLocatedEvent() && !is_dispatched_held_event(*event) &&
+      are_events_in_pixels_) {
     TransformEventForDeviceScaleFactor(static_cast<ui::LocatedEvent*>(event));
+  }
 
   if (mus_mouse_location_updater_)
     mus_mouse_location_updater_->OnEventProcessingStarted(*event);
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h
index cb803d59..d0e9604 100644
--- a/ui/aura/window_event_dispatcher.h
+++ b/ui/aura/window_event_dispatcher.h
@@ -57,7 +57,10 @@
                                           public WindowObserver,
                                           public EnvObserver {
  public:
-  explicit WindowEventDispatcher(WindowTreeHost* host);
+  // |are_events_in_pixels| indicates if events are
+  // received in pixels. If |are_events_in_pixels| is false, events are
+  // received in DIPs.
+  WindowEventDispatcher(WindowTreeHost* host, bool are_events_in_pixels);
   ~WindowEventDispatcher() override;
 
   WindowTreeHost* host() { return host_; }
@@ -280,16 +283,18 @@
 
   WindowTreeHost* host_;
 
-  Window* mouse_pressed_handler_;
-  Window* mouse_moved_handler_;
-  Window* touchpad_pinch_handler_;
-  Window* event_dispatch_target_;
-  Window* old_dispatch_target_;
+  const bool are_events_in_pixels_;
+
+  Window* mouse_pressed_handler_ = nullptr;
+  Window* mouse_moved_handler_ = nullptr;
+  Window* touchpad_pinch_handler_ = nullptr;
+  Window* event_dispatch_target_ = nullptr;
+  Window* old_dispatch_target_ = nullptr;
 
   ui::FractionOfTimeWithoutUserInputRecorder
       fraction_of_time_without_user_input_recorder_;
 
-  bool synthesize_mouse_move_;
+  bool synthesize_mouse_move_ = false;
 
   // Whether a OnWindowTargetTransformChanging() call didn't have its
   // corresponding OnWindowTransformed() call yet.
@@ -297,7 +302,7 @@
 
   // How many move holds are outstanding. We try to defer dispatching
   // touch/mouse moves while the count is > 0.
-  int move_hold_count_;
+  int move_hold_count_ = 0;
   // The location of |held_move_event_| is in |window_|'s coordinate.
   std::unique_ptr<ui::LocatedEvent> held_move_event_;
 
@@ -305,16 +310,16 @@
   std::unique_ptr<ui::LocatedEvent> held_repostable_event_;
 
   // Set when dispatching a held event.
-  ui::LocatedEvent* dispatching_held_event_;
+  ui::LocatedEvent* dispatching_held_event_ = nullptr;
 
-  ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
+  ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_{this};
 
   std::unique_ptr<MusMouseLocationUpdater> mus_mouse_location_updater_;
 
   // The default EventTargeter for WindowEventDispatcher generated events.
   std::unique_ptr<WindowTargeter> event_targeter_;
 
-  bool skip_ime_;
+  bool skip_ime_ = false;
 
   // This callback is called when the held move event is dispatched, or when
   // pointer moves are released and there is no held move event.
@@ -325,10 +330,10 @@
   std::queue<std::unique_ptr<ObserverNotifier>> observer_notifiers_;
 
   // Used to schedule reposting an event.
-  base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_;
+  base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_{this};
 
   // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0.
-  base::WeakPtrFactory<WindowEventDispatcher> held_event_factory_;
+  base::WeakPtrFactory<WindowEventDispatcher> held_event_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcher);
 };
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 50df6aa..a4658e0 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -326,7 +326,8 @@
 
 void WindowTreeHost::CreateCompositor(const viz::FrameSinkId& frame_sink_id,
                                       bool force_software_compositor,
-                                      bool external_begin_frames_enabled) {
+                                      bool external_begin_frames_enabled,
+                                      bool are_events_in_pixels) {
   DCHECK(Env::GetInstance());
   ui::ContextFactory* context_factory = Env::GetInstance()->context_factory();
   DCHECK(context_factory);
@@ -350,7 +351,8 @@
     window()->Init(ui::LAYER_NOT_DRAWN);
     window()->set_host(this);
     window()->SetName("RootWindow");
-    dispatcher_.reset(new WindowEventDispatcher(this));
+    dispatcher_ =
+        std::make_unique<WindowEventDispatcher>(this, are_events_in_pixels);
   }
 }
 
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index 8faf9d8..052d9dd 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -227,11 +227,14 @@
   void DestroyDispatcher();
 
   // If frame_sink_id is not passed in, one will be grabbed from
-  // ContextFactoryPrivate.
+  // ContextFactoryPrivate. |are_events_in_pixels| indicates if events are
+  // received in pixels. If |are_events_in_pixels| is false, events are
+  // received in DIPs.
   void CreateCompositor(
       const viz::FrameSinkId& frame_sink_id = viz::FrameSinkId(),
       bool force_software_compositor = false,
-      bool external_begin_frames_enabled = false);
+      bool external_begin_frames_enabled = false,
+      bool are_events_in_pixels = true);
 
   void InitCompositor();
   void OnAcceleratedWidgetAvailable();
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 2b40fba..c540c954 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -3208,6 +3208,12 @@
 }
 
 TEST_P(WindowTest, RootWindowUsesCompositorFrameSinkId) {
+  // MUS2 doesn't create context_factory_private, which results in this test
+  // failing.
+  // TODO(sky): figure out the right thing here.
+  if (GetParam() == BackendType::MUS2)
+    return;
+
   EXPECT_EQ(host()->compositor()->frame_sink_id(),
             root_window()->GetFrameSinkId());
   EXPECT_TRUE(root_window()->GetFrameSinkId().is_valid());
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
index c8c9266..a0d1f73 100644
--- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -13,11 +13,17 @@
     windowId = results.windowId;
 
     // Add destination directory.
-    return new addEntries(['local'], [
-      new TestEntryInfo(
-          EntryType.DIRECTORY, null, 'destination', null, SharedOption.NONE,
-          'Jan 1, 1980, 11:59 PM', 'destination', '--', 'Folder')
-    ]);
+    return new addEntries(['local'], [new TestEntryInfo({
+                            type: EntryType.DIRECTORY,
+                            sourceFileName: null,
+                            targetPath: 'destination',
+                            mimeType: null,
+                            sharedOption: SharedOption.NONE,
+                            lastModifiedTime: 'Jan 1, 1980, 11:59 PM',
+                            nameText: 'destination',
+                            sizeText: '--',
+                            typeText: 'Folder'
+                          })]);
   }).then(function() {
     return windowId;
   });
@@ -31,12 +37,18 @@
 /**
  * @const
  */
-var ITEMS_IN_DEST_DIR_AFTER_PASTE = TestEntryInfo.getExpectedRows([
-  new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'photos',
-      null, SharedOption.NONE, 'Jan 1, 1980, 11:59 PM',
-      'photos', '--', 'Folder')
-]);
+var ITEMS_IN_DEST_DIR_AFTER_PASTE =
+    TestEntryInfo.getExpectedRows([new TestEntryInfo({
+      type: EntryType.DIRECTORY,
+      sourceFileName: null,
+      targetPath: 'photos',
+      mimeType: null,
+      sharedOption: SharedOption.NONE,
+      lastModifiedTime: 'Jan 1, 1980, 11:59 PM',
+      nameText: 'photos',
+      sizeText: '--',
+      typeText: 'Folder'
+    })]);
 
 /**
  * Expands tree item.
diff --git a/ui/file_manager/integration_tests/file_manager/open_audio_files.js b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
index 43f99e4..cce1b65 100644
--- a/ui/file_manager/integration_tests/file_manager/open_audio_files.js
+++ b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
@@ -314,18 +314,24 @@
       audioPlayerApp.callRemoteTestUtil(
           'fakeMouseClick', audioAppId, repeatButton, this.next);
     },
+    // Leap forward in time.
     function(result) {
       chrome.test.assertTrue(result, 'Failed to click the repeat button');
-
-      var selector = 'audio-player[playing][playcount="1"]';
-      audioPlayerApp.waitForElement(audioAppId, selector).then(this.next);
-    },
-    // Check: Beautiful Song.ogg should be playing.
-    function(element) {
-      chrome.test.assertEq(audioFileSystemURL(path, 'Beautiful Song.ogg'),
-          element.attributes.currenttrackurl);
+      audioTimeLeapForward(audioAppId);
       this.next();
     },
+    // Check: the same file should still be playing (non-repeated).
+    function() {
+      const playFile = audioPlayingQuery('Beautiful Song.ogg');
+      const initial = playFile + '[playcount="0"]';
+      audioPlayerApp.waitForElement(audioAppId, initial).then(this.next);
+    },
+    // When it ends, Audio Player should replay it (repeat-all).
+    function() {
+      const playFile = audioPlayingQuery('Beautiful Song.ogg');
+      const repeats = playFile + '[playcount="1"]';
+      audioPlayerApp.waitForElement(audioAppId, repeats).then(this.next);
+    },
     function() {
       checkIfNoErrorsOccured(this.next);
     }
diff --git a/ui/file_manager/integration_tests/gallery/thumbnail_mode.js b/ui/file_manager/integration_tests/gallery/thumbnail_mode.js
index 6c5b849..6e85c98 100644
--- a/ui/file_manager/integration_tests/gallery/thumbnail_mode.js
+++ b/ui/file_manager/integration_tests/gallery/thumbnail_mode.js
@@ -5,10 +5,17 @@
 /**
  * Additional test image entry.
  */
-ENTRIES.image4 = new TestEntryInfo(
-      EntryType.FILE, 'image3.jpg', 'image4.jpg',
-      'image/jpeg', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
-      'image3.jpg', '3 KB', 'JPEG image');
+ENTRIES.image4 = new TestEntryInfo({
+  type: EntryType.FILE,
+  sourceFileName: 'image3.jpg',
+  targetPath: 'image4.jpg',
+  mimeType: 'image/jpeg',
+  sharedOption: SharedOption.NONE,
+  lastModifiedTime: 'Jan 18, 2038, 1:02 AM',
+  nameText: 'image3.jpg',
+  sizeText: '3 KB',
+  typeText: 'JPEG image'
+});
 
 /**
  * Renames an image in thumbnail mode and confirms that thumbnail of renamed
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index 818f257..fd5e392 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -225,38 +225,67 @@
 });
 
 /**
+ *
+ * @record
+ * @struct
+ */
+function TestEntryInfoOptions() {}
+
+/**
+ * @type {EntryType} Entry type.
+ */
+TestEntryInfoOptions.prototype.type;
+
+/**
+ * @type {string|undefined} Source file name that provides file contents.
+ */
+TestEntryInfoOptions.prototype.sourceFileName;
+/**
+ * @type {string} Name of entry on the test file system.
+ */
+TestEntryInfoOptions.prototype.targetPath;
+/**
+ * @type {string|undefined} Mime type.
+ */
+TestEntryInfoOptions.prototype.mimeType;
+/**
+ * @type {SharedOption} Shared option.
+ */
+TestEntryInfoOptions.prototype.sharedOption;
+/**
+ * @type {string} Last modified time as a text to be shown in the last modified
+ *     column.
+ */
+TestEntryInfoOptions.prototype.lastModifiedTime;
+/**
+ * @type {string} File name to be shown in the name column.
+ */
+TestEntryInfoOptions.prototype.nameText;
+/**
+ * @type {string} Size text to be shown in the size column.
+ */
+TestEntryInfoOptions.prototype.sizeText;
+/**
+ * @type {string} Type name to be shown in the type column.
+ */
+TestEntryInfoOptions.prototype.typeText;
+
+
+/**
  * File system entry information for tests.
  *
- * @param {EntryType} type Entry type.
- * @param {string} sourceFileName Source file name that provides file contents.
- * @param {string} targetName Name of entry on the test file system.
- * @param {string} mimeType Mime type.
- * @param {SharedOption} sharedOption Shared option.
- * @param {string} lastModifiedTime Last modified time as a text to be shown in
- *     the last modified column.
- * @param {string} nameText File name to be shown in the name column.
- * @param {string} sizeText Size text to be shown in the size column.
- * @param {string} typeText Type name to be shown in the type column.
- * @constructor
+ * @param {TestEntryInfoOptions} options Parameters to create the TestEntryInfo.
  */
-function TestEntryInfo(type,
-                       sourceFileName,
-                       targetPath,
-                       mimeType,
-                       sharedOption,
-                       lastModifiedTime,
-                       nameText,
-                       sizeText,
-                       typeText) {
-  this.type = type;
-  this.sourceFileName = sourceFileName || '';
-  this.targetPath = targetPath;
-  this.mimeType = mimeType || '';
-  this.sharedOption = sharedOption;
-  this.lastModifiedTime = lastModifiedTime;
-  this.nameText = nameText;
-  this.sizeText = sizeText;
-  this.typeText = typeText;
+function TestEntryInfo(options) {
+  this.type = options.type;
+  this.sourceFileName = options.sourceFileName || '';
+  this.targetPath = options.targetPath;
+  this.mimeType = options.mimeType || '';
+  this.sharedOption = options.sharedOption;
+  this.lastModifiedTime = options.lastModifiedTime;
+  this.nameText = options.nameText;
+  this.sizeText = options.sizeText;
+  this.typeText = options.typeText;
   Object.freeze(this);
 }
 
@@ -277,104 +306,235 @@
  * @const
  */
 var ENTRIES = {
-  hello: new TestEntryInfo(
-      EntryType.FILE, 'text.txt', 'hello.txt',
-      'text/plain', SharedOption.NONE, 'Sep 4, 1998, 12:34 PM',
-      'hello.txt', '51 bytes', 'Plain text'),
+  hello: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'text.txt',
+    targetPath: 'hello.txt',
+    mimeType: 'text/plain',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Sep 4, 1998, 12:34 PM',
+    nameText: 'hello.txt',
+    sizeText: '51 bytes',
+    typeText: 'Plain text'
+  }),
 
-  world: new TestEntryInfo(
-      EntryType.FILE, 'video.ogv', 'world.ogv',
-      'video/ogg', SharedOption.NONE, 'Jul 4, 2012, 10:35 AM',
-      'world.ogv', '59 KB', 'OGG video'),
+  world: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'video.ogv',
+    targetPath: 'world.ogv',
+    mimeType: 'video/ogg',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jul 4, 2012, 10:35 AM',
+    nameText: 'world.ogv',
+    sizeText: '59 KB',
+    typeText: 'OGG video'
+  }),
 
-  unsupported: new TestEntryInfo(
-      EntryType.FILE, 'random.bin', 'unsupported.foo',
-      'application/x-foo', SharedOption.NONE, 'Jul 4, 2012, 10:36 AM',
-      'unsupported.foo', '8 KB', 'FOO file'),
+  unsupported: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'random.bin',
+    targetPath: 'unsupported.foo',
+    mimeType: 'application/x-foo',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jul 4, 2012, 10:36 AM',
+    nameText: 'unsupported.foo',
+    sizeText: '8 KB',
+    typeText: 'FOO file'
+  }),
 
-  desktop: new TestEntryInfo(
-      EntryType.FILE, 'image.png', 'My Desktop Background.png',
-      'image/png', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
-      'My Desktop Background.png', '272 bytes', 'PNG image'),
+  desktop: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'image.png',
+    targetPath: 'My Desktop Background.png',
+    mimeType: 'image/png',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 18, 2038, 1:02 AM',
+    nameText: 'My Desktop Background.png',
+    sizeText: '272 bytes',
+    typeText: 'PNG image'
+  }),
 
   // An image file without an extension, to confirm that file type detection
   // using mime types works fine.
-  image2: new TestEntryInfo(
-      EntryType.FILE, 'image2.png', 'image2',
-      'image/png', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
-      'image2', '4 KB', 'PNG image'),
+  image2: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'image2.png',
+    targetPath: 'image2',
+    mimeType: 'image/png',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 18, 2038, 1:02 AM',
+    nameText: 'image2',
+    sizeText: '4 KB',
+    typeText: 'PNG image'
+  }),
 
-  image3: new TestEntryInfo(
-      EntryType.FILE, 'image3.jpg', 'image3.jpg',
-      'image/jpeg', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
-      'image3.jpg', '3 KB', 'JPEG image'),
+  image3: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'image3.jpg',
+    targetPath: 'image3.jpg',
+    mimeType: 'image/jpeg',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 18, 2038, 1:02 AM',
+    nameText: 'image3.jpg',
+    sizeText: '3 KB',
+    typeText: 'JPEG image'
+  }),
 
   // An ogg file without a mime type, to confirm that file type detection using
   // file extensions works fine.
-  beautiful: new TestEntryInfo(
-      EntryType.FILE, 'music.ogg', 'Beautiful Song.ogg',
-      null, SharedOption.NONE, 'Nov 12, 2086, 12:00 PM',
-      'Beautiful Song.ogg', '14 KB', 'OGG audio'),
+  beautiful: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'music.ogg',
+    targetPath: 'Beautiful Song.ogg',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Nov 12, 2086, 12:00 PM',
+    nameText: 'Beautiful Song.ogg',
+    sizeText: '14 KB',
+    typeText: 'OGG audio'
+  }),
 
-  photos: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'photos',
-      null, SharedOption.NONE, 'Jan 1, 1980, 11:59 PM',
-      'photos', '--', 'Folder'),
+  photos: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'photos',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 1980, 11:59 PM',
+    nameText: 'photos',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  testDocument: new TestEntryInfo(
-      EntryType.FILE, null, 'Test Document',
-      'application/vnd.google-apps.document',
-      SharedOption.NONE, 'Apr 10, 2013, 4:20 PM',
-      'Test Document.gdoc', '--', 'Google document'),
+  testDocument: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: null,
+    targetPath: 'Test Document',
+    mimeType: 'application/vnd.google-apps.document',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Apr 10, 2013, 4:20 PM',
+    nameText: 'Test Document.gdoc',
+    sizeText: '--',
+    typeText: 'Google document'
+  }),
 
-  testSharedDocument: new TestEntryInfo(
-      EntryType.FILE, null, 'Test Shared Document',
-      'application/vnd.google-apps.document',
-      SharedOption.SHARED, 'Mar 20, 2013, 10:40 PM',
-      'Test Shared Document.gdoc', '--', 'Google document'),
+  testSharedDocument: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: null,
+    targetPath: 'Test Shared Document',
+    mimeType: 'application/vnd.google-apps.document',
+    sharedOption: SharedOption.SHARED,
+    lastModifiedTime: 'Mar 20, 2013, 10:40 PM',
+    nameText: 'Test Shared Document.gdoc',
+    sizeText: '--',
+    typeText: 'Google document'
+  }),
 
-  newlyAdded: new TestEntryInfo(
-      EntryType.FILE, 'music.ogg', 'newly added file.ogg',
-      'audio/ogg', SharedOption.NONE, 'Sep 4, 1998, 12:00 AM',
-      'newly added file.ogg', '14 KB', 'OGG audio'),
+  newlyAdded: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'music.ogg',
+    targetPath: 'newly added file.ogg',
+    mimeType: 'audio/ogg',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Sep 4, 1998, 12:00 AM',
+    nameText: 'newly added file.ogg',
+    sizeText: '14 KB',
+    typeText: 'OGG audio'
+  }),
 
-  directoryA: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'A',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'A', '--', 'Folder'),
+  directoryA: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'A',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'A',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  directoryB: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'A/B',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'B', '--', 'Folder'),
+  directoryB: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'A/B',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'B',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  directoryC: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'A/B/C',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'C', '--', 'Folder'),
+  directoryC: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'A/B/C',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'C',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  directoryD: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'D',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'D', '--', 'Folder'),
+  directoryD: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'D',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'D',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  directoryE: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'D/E',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'E', '--', 'Folder'),
+  directoryE: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'D/E',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'E',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  directoryF: new TestEntryInfo(
-      EntryType.DIRECTORY, null, 'D/E/F',
-      null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
-      'F', '--', 'Folder'),
+  directoryF: new TestEntryInfo({
+    type: EntryType.DIRECTORY,
+    sourceFileName: null,
+    targetPath: 'D/E/F',
+    mimeType: null,
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2000, 1:00 AM',
+    nameText: 'F',
+    sizeText: '--',
+    typeText: 'Folder'
+  }),
 
-  zipArchive: new TestEntryInfo(
-      EntryType.FILE, 'archive.zip', 'archive.zip',
-      'application/x-zip', SharedOption.NONE, 'Jan 1, 2014, 1:00 AM',
-      'archive.zip', '533 bytes', 'Zip archive'),
+  zipArchive: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'archive.zip',
+    targetPath: 'archive.zip',
+    mimeType: 'application/x-zip',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Jan 1, 2014, 1:00 AM',
+    nameText: 'archive.zip',
+    sizeText: '533 bytes',
+    typeText: 'Zip archive'
+  }),
 
-  hiddenFile: new TestEntryInfo(
-    EntryType.FILE, 'text.txt', '.hiddenfile.txt',
-    'text/plain', SharedOption.NONE, 'Sep 30, 2014, 3:30 PM',
-    '.hiddenfile.txt', '51 bytes', 'Plain text')
+  hiddenFile: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'text.txt',
+    targetPath: '.hiddenfile.txt',
+    mimeType: 'text/plain',
+    sharedOption: SharedOption.NONE,
+    lastModifiedTime: 'Sep 30, 2014, 3:30 PM',
+    nameText: '.hiddenfile.txt',
+    sizeText: '51 bytes',
+    typeText: 'Plain text'
+  })
 };
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 85be463..fbda0b1 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -270,7 +270,6 @@
   ui_->GetInputMethod()->RemoveObserver(this);
   for (KeyboardControllerObserver& observer : observer_list_)
     observer.OnKeyboardClosed();
-  observer_list_.Clear();
   ui_->SetController(nullptr);
   ui_.reset();
 }
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc
index 89d74f106..dba8a75 100644
--- a/ui/keyboard/keyboard_controller_unittest.cc
+++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -236,6 +236,7 @@
 
   KeyboardUI* ui() { return controller_.ui(); }
   KeyboardController& controller() { return controller_; }
+  KeyboardLayoutDelegate* layout_delegate() { return layout_delegate_.get(); }
 
   void ShowKeyboard() {
     test_text_input_client_.reset(
@@ -265,6 +266,7 @@
     is_available_number_of_calls_++;
   }
   void OnKeyboardClosed() override { keyboard_closed_ = true; }
+  void ClearKeyboardClosed() { keyboard_closed_ = false; }
 
   int visible_bounds_number_of_calls() const {
     return visible_bounds_number_of_calls_;
@@ -894,4 +896,28 @@
   EXPECT_TRUE(keyboard_container()->IsVisible());
 }
 
+// Checks DisableKeyboard() doesn't clear the observer list.
+TEST_F(KeyboardControllerTest, DontClearObserverList) {
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
+  aura::Window* keyboard_container(controller().GetContainerWindow());
+  root_window()->AddChild(keyboard_container);
+
+  ShowKeyboard();
+  EXPECT_TRUE(keyboard_container->IsVisible());
+  EXPECT_FALSE(IsKeyboardClosed());
+
+  root_window()->RemoveChild(keyboard_container);
+  controller().DisableKeyboard();
+  EXPECT_TRUE(IsKeyboardClosed());
+
+  controller().EnableKeyboard(
+      std::make_unique<TestKeyboardUI>(host()->GetInputMethod()),
+      layout_delegate());
+  ClearKeyboardClosed();
+  EXPECT_FALSE(IsKeyboardClosed());
+
+  controller().DisableKeyboard();
+  EXPECT_TRUE(IsKeyboardClosed());
+}
+
 }  // namespace keyboard
diff --git a/ui/web_dialogs/web_dialog_ui.h b/ui/web_dialogs/web_dialog_ui.h
index 3262980..62d83ee3 100644
--- a/ui/web_dialogs/web_dialog_ui.h
+++ b/ui/web_dialogs/web_dialog_ui.h
@@ -97,7 +97,7 @@
   // content::WebUIController:
   void RenderFrameCreated(
       content::RenderFrameHost* render_frame_host) override {
-    MojoWebUIControllerBase::RenderFrameCreated(render_frame_host);
+    content::WebUIController::RenderFrameCreated(render_frame_host);
     HandleRenderFrameCreated(render_frame_host);
   }
 
diff --git a/ui/webui/mojo_web_ui_controller.cc b/ui/webui/mojo_web_ui_controller.cc
index 91db5e5..e2de8d2 100644
--- a/ui/webui/mojo_web_ui_controller.cc
+++ b/ui/webui/mojo_web_ui_controller.cc
@@ -9,16 +9,15 @@
 
 namespace ui {
 
-MojoWebUIControllerBase::MojoWebUIControllerBase(content::WebUI* contents)
-    : content::WebUIController(contents) {
-  contents->SetBindings(content::BINDINGS_POLICY_WEB_UI);
+MojoWebUIController::MojoWebUIController(content::WebUI* contents,
+                                         bool enable_chrome_send)
+    : content::WebUIController(contents),
+      content::WebContentsObserver(contents->GetWebContents()) {
+  int bindings = content::BINDINGS_POLICY_MOJO_WEB_UI;
+  if (enable_chrome_send)
+    bindings |= content::BINDINGS_POLICY_WEB_UI;
+  contents->SetBindings(bindings);
 }
-
-MojoWebUIControllerBase::~MojoWebUIControllerBase() = default;
-
-MojoWebUIController::MojoWebUIController(content::WebUI* contents)
-    : MojoWebUIControllerBase(contents),
-      content::WebContentsObserver(contents->GetWebContents()) {}
 MojoWebUIController::~MojoWebUIController() = default;
 
 void MojoWebUIController::OnInterfaceRequestFromFrame(
diff --git a/ui/webui/mojo_web_ui_controller.h b/ui/webui/mojo_web_ui_controller.h
index cf7ce306..bd3d7cc2 100644
--- a/ui/webui/mojo_web_ui_controller.h
+++ b/ui/webui/mojo_web_ui_controller.h
@@ -18,26 +18,20 @@
 
 namespace ui {
 
-class MojoWebUIControllerBase : public content::WebUIController {
- public:
-  explicit MojoWebUIControllerBase(content::WebUI* contents);
-  ~MojoWebUIControllerBase() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MojoWebUIControllerBase);
-};
-
-// MojoWebUIController is intended for web ui pages that use mojo. It is
+// MojoWebUIController is intended for WebUI pages that use Mojo. It is
 // expected that subclasses will do two things:
 // . In the constructor invoke AddMojoResourcePath() to register the bindings
 //   files, eg:
-//     AddMojoResourcePath("chrome/browser/ui/webui/omnibox/omnibox.mojom",
-//                         IDR_OMNIBOX_MOJO_JS);
+//     AddResourcePath("chrome/browser/ui/webui/omnibox/omnibox.mojom",
+//                     IDR_OMNIBOX_MOJO_JS);
 // . Call AddHandlerToRegistry for all Mojo Interfaces it wishes to handle.
-class MojoWebUIController : public MojoWebUIControllerBase,
+class MojoWebUIController : public content::WebUIController,
                             public content::WebContentsObserver {
  public:
-  explicit MojoWebUIController(content::WebUI* contents);
+  // By default MojoWebUIControllers do not have normal WebUI bindings. Pass
+  // |enable_chrome_send| as true if these are needed.
+  explicit MojoWebUIController(content::WebUI* contents,
+                               bool enable_chrome_send = false);
   ~MojoWebUIController() override;
 
   // content::WebContentsObserver implementation.
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 664e3c3..4914a0d 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -14,6 +14,7 @@
     "cr_dialog:closure_compile",
     "cr_drawer:closure_compile",
     "cr_expand_button:closure_compile",
+    "cr_input:closure_compile",
     "cr_link_row:closure_compile",
     "cr_profile_avatar_selector:closure_compile",
     "cr_radio_button:closure_compile",
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.html b/ui/webui/resources/cr_elements/cr_input/cr_input.html
index 6b3d132..ce54984c 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input.html
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input.html
@@ -27,7 +27,7 @@
         margin-top: 8px;
       }
 
-      :host(:focus-within) #label {
+      :host(:focus-within:not([readonly]):not([invalid])) #label {
         color: var(--cr-input-focus-color);
       }
 
@@ -50,6 +50,7 @@
         box-sizing: border-box;
         caret-color: var(--cr-input-focus-color);
         color: inherit;
+        font-size: inherit;
         line-height: inherit;
         outline: none;
         padding: 6px 8px;
@@ -64,6 +65,10 @@
         caret-color: var(--cr-input-error-color);
       }
 
+      :host([readonly]) input {
+        opacity: 0.6;
+      }
+
       /* Underline styling below. */
       #underline {
         border-bottom: 2px solid var(--cr-input-focus-color);
@@ -83,7 +88,7 @@
       }
 
       :host([invalid]) #underline,
-      :host(:focus-within) #underline {
+      :host(:focus-within:not([readonly])) #underline {
         opacity: 1;
         transition: width 180ms ease-out, opacity 120ms ease-in;
         width: 100%;
@@ -113,8 +118,12 @@
     </style>
     <div id="label" hidden="[[!label]]">[[label]]</div>
     <div id="input-container">
+      <!-- Only attributes that are named inconsistently between html and js
+           need to use attr$="", such as |tabindex| vs .tabIndex and |readonly|
+           vs .readOnly. -->
       <input id="input" disabled="[[disabled]]" autofocus="[[autofocus]]"
-          value="{{value::input}}" tabindex$="[[tabIndex]]">
+          value="{{value::input}}" tabindex$="[[tabIndex]]" type="[[type]]"
+          readonly$="[[readonly]]">
       <div id="underline"></div>
     </div>
     <div id="error">[[errorMessage]]</div>
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.js b/ui/webui/resources/cr_elements/cr_input/cr_input.js
index 2810bf9a..0305876 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input.js
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input.js
@@ -43,8 +43,15 @@
       observer: 'placeholderChanged_',
     },
 
+    readonly: Boolean,
+
     tabIndex: String,
 
+    type: {
+      type: String,
+      value: 'text',  // Only 'text' and 'password' are currently supported.
+    },
+
     value: {
       type: String,
       value: '',
@@ -61,10 +68,16 @@
     'input.change': 'onInputChange_',
   },
 
+  /** @return {!HTMLInputElement} */
+  get inputElement() {
+    return this.$.input;
+  },
+
   /** @private */
   disabledChanged_: function() {
     this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
-    this.$.input.blur();  // In case input was focused when disabled changes.
+    // In case input was focused when disabled changes.
+    this.inputElement.blur();
   },
 
   /**
@@ -75,9 +88,14 @@
    */
   placeholderChanged_: function() {
     if (this.placeholder || this.placeholder == '')
-      this.$.input.setAttribute('placeholder', this.placeholder);
+      this.inputElement.setAttribute('placeholder', this.placeholder);
     else
-      this.$.input.removeAttribute('placeholder');
+      this.inputElement.removeAttribute('placeholder');
+  },
+
+  focus: function() {
+    if (this.shadowRoot.activeElement != this.inputElement)
+      this.inputElement.focus();
   },
 
   /**
@@ -89,5 +107,5 @@
    */
   onInputChange_: function(e) {
     this.fire('change', {sourceEvent: e});
-  }
+  },
 });
\ No newline at end of file